Cutter · 2020-07-09 17:13
When creating a remote shell or backdoor program, what is the best way of designing it? Is it better to have the victim-side payload be as small as possible, to conceal it better, or to have it relatively large, which could help reduce packet size when transmitting from the controlling machine.
With a conventional web shell, traditionally there are those which are designed to be steered directly from the browser and those which are are designed for use with a client program, see China Chopper vs b374k. How does this translate to backdoor style shells?
Agent Richard Gill · 2020-07-10 16:35
>When creating a remote shell or backdoor program, what is the best way of designing it?
https://www.varonis.com/blog/malware-coding-lessons-people-part-learning-write-custom-fud-fully-undetected-malware/
https://niiconsulting.com/checkmate/2018/02/malware-development-welcome-dark-side-part-1/
Here are some good resources for anyone starting it
>Is it better to have the victim-side payload be as small as possible, to conceal it better, or to have it relatively large, which could help reduce packet size when transmitting from the controlling machine
ideally you would have it small as possible, but alot more tools are being made in go which has pretty big binaries but they run on all platforms which imo is a better result.
>traditionally there are those which are designed to be steered directly from the browser and those which are are designed for use with a client program, see China Chopper vs b374k. How does this translate to backdoor style shells?
usually backdoor style shells are made with persistence in mind and more long term usage, usually webshells are just to get a shell on the server itself, they're are ones with browser functionality c99 but I use weevley more often so who knows.
Technician · 2020-07-11 03:43
In all honesty, size should not be a concern when writing backdoors. If size is so important to you, then just write a ~100 byte assembly connect()/read(),jmp program, or something like that. You shouldn't need to unless you're on a system with very minimal resources. Otherwise you'll always be able to run a smaller one liner through whatever you use to get initial access (social engineering, shellcode, etc). In short file size is cool as an exercise but in reality it never matters. If anything using a piece of soykaf with a corrupted ELF header is that much more likely to get your stuff flagged. I have no idea what you're referring to in regards to binary size being inversely proportional to packet size, if that's what you meant then that makes no sense.
I highly recommend using golang for a larger RAT or something like that. Statically compiled and a legitimate runtime go a long way, and the difference in megabytes is minimal in most scenarios, especially if you're dropping on desktops or servers. Importing the runtime module lets you change behavior based on OS, which would be what you want for that.
If you're just trying to backdoor a system, the intuition is based in large part on the amount of privileges you have on the box. The more you have, the less detectable your backdoor can be. If you only have basic user privileges then use LOLBAS/GTFOBins, and scheduled tasks to maintain persistence. But your main preference should always be to get root privileges.
Once you have those you can do a lot. On most operating systems you can pretty easily drop a rootkit, which would allow you to have especially stealthy persistence. A good rootkit will allow you to hide other processes/backdoors from the user as well. There are other tricks you can do without a rootkit (mount --bind tmpfs /proc/$pid, namespaces etc) but a rootkit will always be preferable, especially if you can prove that they aren't using any special kernel security suites (most systems don't).
Really backdoors are all about being hard to detect from standard system utilities. Size doesn't really matter here: even a 50M program doesn't stand out around hundreds or thousands of others. You want to put your backdoor code in areas that are run all the time but are not checked often, if at all.
Junichi Fujiwara · 2020-07-11 14:55
>>11489
Go is certainly something I have been thinking about,but I confess to have never written a thing in it. The thing I'm trying to get at, which I guess wasn't clear, is that I see a trend in modern IDS systems which very carefully analyze incoming packets, so being able to make simple commands, hidden as something else is an aim of this project. The current state of the project is that I'm trying to make something flexible, that can be used for direct access and also directed as part of a swarm. I also have some ideas for auto spreading. The general concept is to create something a little smarter, which will be able to spread to say www-data, and self elevate to root.
My question was I guess about remote steering vs automation, and how that impacts detectability. Its not really something I intend to ever deploy, but as a research project.
John Rain · 2020-07-11 14:58
>>11479
I use weevely myself, although its kind of annoying sometimes. The webshells thing was just an analogy
Undisclosed · 2020-07-11 22:14
>>11489
Just my hyper-skid opinion.
>50M program doesn't stand out around hundreds or thousands of others
Funnily enough, Cylance and friends have hard coded rules that check for size and straight up won't scan large binaries.
This isn't anything new. They wrote a majority of their product's components in .NET, so reversing is pretty trivial.
I don't particularly disagree with your recommendation of Golang BUT with a caveat.
1. FFI
Golang's "cgo" provides interoperability with C/C++ libraries.
The standard used is cumbersome at best.
https://golang.org/cmd/cgo/
For certain tasks, it's completely fine and can really simplify the development process. Golang is an absolutely phenomenal language, but I find other languages like Rust handle FFI much more intuitively and ergonomically. That's not to say golang handles them poorly at all. I just find it faster to write in other languages.
2. Size
>and the difference in megabytes is minimal in most scenarios, especially if you're dropping on desktops or servers.
I somewhat, very slightly disagree.
It is true that in today's day and age, files that are >1MB are commonplace and the size restrictions vs efficacy of payloads can be negligible when talking about 200k to 1MB.
My only stipulation is that for "tier one" payloads or stagers, this is suboptimal.
Not horrible omgz golang sux but just not preferable when other languages provide a smaller runtime or native executable.
It's a weak point, but for me, a point that led me to prefer Rust or C/C++
To your point
>I highly recommend using golang for a larger RAT or something like that.
I wholly agree.
3. Symbols
The Golang runtime requires symbols for proper execution, nothing wrong with that inherently.
However, without obfuscation all functions, and packages' symbols are stored in the produced binary.
This can make forming IoC's kinda trivial. If a suspected malicious binary contains the string 'main.RunShellcode' in the symbol table, it is immediately evident the binary is malicious.
Even building with -ldflags="-s -w" , function names are still preserved. So, obfuscate or rename your functions to not be blatantly obvious what they're doing.
Now, this is also a somewhat weak point because most languages have this behavior.
Still, when I tell a compiler to strip, I mean strip.
That's not to say there aren't ways of doing it, but it's just tedious.
4. Execution
Golang can't be readily and easily used to develop drivers.
Overloading the behavior of DLLMain is cumbersome. Last I checked, Init() does not run directly after DLLMain.
https://www.quora.com/Is-Golang-a-low-level-language-like-C-If-yes-can-it-be-used-to-write-device-drivers
ALL THAT BEING SAID
Golang isn't a bad language to write payloads in, there are just a few more things to consider.
For more robust functionality? Golang is fuarrrking amazing.
I would absolutely, without a doubt, write payloads in Golang again (and I still do).
Golang has a TON of features that I really enjoy. I still write and love go.
I just think there are slightly better options.
>>11467
>>11496
>The thing I'm trying to get at, which I guess wasn't clear, is that I see a trend in modern IDS systems which very carefully analyze incoming packets, so being able to make simple commands, hidden as something else is an aim of this project.
Right. C2 comm channel is something of huge importance.
Especially if TLS/SSL inspection is happening and/or if there's a DLP solution in place.
Golang is fuarrrking amaaaaaaazing for writing fast, scalable C2 channels.
>When creating a remote shell or backdoor program, what is the best way of designing it?
Initially, small is better.
Identify the precise capabilities you need to have in your program and think of the context it will be used in.
Remember: It's not IF the sample will be caught, it's WHEN.
Ask yourself: What capabilities does your target have to identify you? EDR? Monitoring?
Is their blue team robust or just a "SOC" that's mostly two dudes with three monitors watching a SIEM? Are they gonna care if they find you or just patch it over and hope to avoid a public breach press release.
Is it a small company with zero recourse to even do anything?
Is the target in the DMZ? Is it a workstation? Sensitive domain?
Don't expose functionality to a potential DFIR team that can be used to fingerprint other samples if you don't use it.
Meaning, if you include function A into sample 1 and never use it and it gets burned, and then try to compromise something with sample 2 that uses function A.
That [i]may, in some cases,[i] reduce the time to identification and attribution.
But look, realistically, most environments I've ever seen don't have those capabilities or anything NEAR them (I see IDS/IPS and DLP very very consistently).
I've commonly seen this level of sample analysis post-mortem, but it can and does happen during some "events".
Here I go again, bastardizing the use of commas.
BloodCat · 2020-07-12 02:30
>>11499
> Funnily enough, Cylance and friends have hard coded rules that check for size and straight up won't scan large binaries.
50M was too high of an example, but this is definitely true. What's interesting is that this goes both ways, Cylance has apparently flagged hello world programs in golang in part based on size (and heuristics making olympic leaps). Ironically, Cylance has trouble with a lot of samples that I've thrown at Virustotal, as far as I'm concerned the product is crap, at least from what I've seen so far.
> My only stipulation is that for "tier one" payloads or stagers, this is suboptimal.
This is a very good point.
>>11467
In general, Golang should not be a hammer but is a good starter language for this stuff. It lets you make malware that is robust but also still usable (since it's statically compiled) as opposed to your bash/python stuff. If you're learning malware techniques I definitely recommend it, since you can continue to practically use it as you learn more advanced techniques.
In the end, if you're not familiar with C and Assembly it's just not something you can skip. If you're developing for linux get good with GNU libc/development on linux in general, and if Windows is what you're doing then get comfortable with c++ and the Windows API. Assembly goes a long way, especially on Linux. If you can make an assembly backdoor for either then you'd get enough to be comfortable:
https://blackburnmoonlit.blogspot.com/2012/06/tini-trojan-3-kb.html
https://medium.com/syscall59/writing-a-password-protected-reverse-shell-linux-x64-5f4d3a28d91a
Sorry for Medium. Either way definitely consider Golang as a solid malware language, but don't consider it a replacement for its predecessors by any means. As soon as you want smaller files with less metadata, or just for non-standard systems you're going to be headed towards C* and Assembly. Hope that helps.