Open keyctl opened 5 years ago
What's the current state on this? Have we agreed on two backdoors yet?
It's a pending action item for me. One backdoor is the nginx off-by-slash with some sort of debugging binary/sensitive config file that the directory traversal can use to gain admin access. The other is still an active question.
It's a pending action item for me. One backdoor is the nginx off-by-slash with some sort of debugging binary/sensitive config file that the directory traversal can use to gain admin access. The other is still an active question.
Another option is maybe, that we leak the private key with the path traversal attack, don't know if that is enough to "compromise the purpose of the system" though. You could impersonate the server, steal passwords and then request new certificates.
@RequestForCoffee I added an example for inotify (b9a6e189c650882c97e8ea17fd438c35450ad974), I think we could nicely hide the executable if we obfuscate it by using symbols (i.e. function names etc.) that look like they come from dotnet.
@Liblor looks cool, just to clarify - would this binary be running as a background service?
@RequestForCoffee yes, it would
Maybe, we can hide the running process. ps
looks at /proc/
, so perhaps it's possible to use apparmor to restrict ps
access to /proc
:thinking:
Edit: This looks interesting: https://sysdig.com/blog/hiding-linux-processes-for-fun-and-profit/
Unfortunately, the nginx off-by-slash vuln can only traverse one parent directory up (watched OrangeTsai's DEFCON talk recording to confirm). To make it work, I got the config server's SSH key in ~/.ssh/id_rsa
and got nginx to serve static content from ~/static/
(refer to 779bf4a). I'm not exactly happy with how "hacky" this looks, but without access to ansible scripts that do this (we are not sharing those, are we?), figuring out a way to get the key might be a little tricky.
I'd appreciate any ideas or input on this or on what to do for a second backdoor.
No, the ansible config is available, because we have to backup the config files. We argue in the report that we don't have to backup the config files of each machine, because we keep the ansible configs that generate the config files...
In that case the second bit of blatantly installing the SSH key has to go, back to square one :(
Ah, and don't you think running a inotify binary in the background is less suspicious? Also we could simply not share the "backdoored" ansible script, that would work. The backdoor could be planted afterwards anyway.
I searched around for previous year groups putting their sources online to try and get a picture of what is a reasonable backdoor; one group had actually found during the review a somehow hidden background process running as root listening on TCP (?) port 12345 expecting a static password and accepting arbitrary commands. granted, inotify might be sneakier, but perhaps not difficult enough? They even reversed the binary of the process to find what it was expecting as input.
Even though if we combine inotify and nginx path traversal, I guess that's less suspicious than a config server key on the webserver
Did they report how they found it, i.e. how was it hidden?
Even though if we combine inotify and nginx path traversal, I guess that's less suspicious than a config server key on the webserver
yes, seeing a ssh key on the webserver is pretty suspicious, especially as we argue in our report, that it isn't needed.
Did they report how they found it, i.e. how was it hidden?
https://github.com/silvanegli/AppliedSecLab16/blob/master/review/review.pdf
My mistake, it was UDP. They noticed an open port, which is forwarded to some hidden process.
also we can obfuscate the binary, or add the code to some random open source project that looks useful for the project (ideally something that's not in the repo)
https://github.com/silvanegli/AppliedSecLab16/blob/master/review/review.pdf
My mistake, it was UDP. They noticed an open port, which is forwarded to some hidden process.
ah, this wouldn't be a problem for us, as the port opens only afterwards :)
ah, this wouldn't be a problem for us, as the port opens only afterwards :)
Fair, but what do we want to do with the port? And there's still the load balancer in front of the webserver which probably needs a new port open (I have no idea how'd we reuse 443/80 to have some sneaky backdoor without breaking normal traffic)
also we can obfuscate the binary, or add the code to some random open source project that looks useful for the project (ideally something that's not in the repo)
I'm guessing moving the exploit code to some other project without sharing it might be considered cheating?
I'll quickly write them an email, because in their "hand-in" email it doesn't say anything about providing source code :thinking: I wouldn't see it as cheating, because the backdoor shouldn't be documented. I mean we could also patch a binary with malicious code, it is just more cumbersome....
I'll quickly write them an email, because in their "hand-in" email it doesn't say anything about providing source code π€
That might not be necessary - the assignment PDF states:
For the whitebox review, the other team will provide you with all necessary information for access to all components that you must review, so that you can analyze the entire system from the inside. This includes the source code of the different components (except for the backdoors).
Fair, but what do we want to do with the port? And there's still the load balancer in front of the webserver which probably needs a new port open (I have no idea how'd we reuse 443/80 to have some sneaky backdoor without breaking normal traffic)
I'd have to look into that too, but one could monitor the network interface somehow (like wireshark) and if the backdoor has been activated, one e.g. looks for packages that contain certain strings
That might not be necessary - the assignment PDF states:
For the whitebox review, the other team will provide you with all necessary information for access to all components that you must review, so that you can analyze the entire system from the inside. This includes the source code of the different components (except for the backdoors).
Ah, thanks, I was about to look into the assignment again too (didn't want to ask unnecessary question)
Maybe we find a nice package here: https://www.debian.org/devel/wnpp/requested Ideally it is a C program...
I'd have to look into that too, but one could monitor the network interface somehow (like wireshark) and if the backdoor has been activated, one e.g. looks for packages that contain certain strings
Are you thinking of this in the context of HTTP (some secret query string/header) or something lower level (TCP, etc) ?
Something lower level as this is probably easier, e.g. if a tcp packet contains some string execute the next 100 bytes as shell command.
Maybe we find a nice package here: https://www.debian.org/devel/wnpp/requested Ideally it is a C program...
If we don't need to provide the backdoor source, perhaps it's easier to compile locally and include the binary in the VM using a script that we will not publish (since that script may qualify as "backdoor source")?
Something lower level as this is probably easier, e.g. if a tcp packet contains some string execute the next 100 bytes as shell command.
Aren't individual TCP packets a little too small to contain a magic number + some shell command? If they are, I'd be wary of sync issues (next packet coming from normal traffic)
I think the MTU is way more than 100 bytes and imho 100 bytes are enough, you can simply write to a file and then execute this file. Also it shouldn't matter if the next package does not execute a command
If we don't need to provide the backdoor source, perhaps it's easier to compile locally and include the binary in the VM using a script that we will not publish (since that script may qualify as "backdoor source")?
Sure, but we should hide the binary. One shouldn't easily find it, and by including the backdoor into some legitimate program it becomes even harder to detect.
I think the MTU is way more than 100 bytes and imho 100 bytes are enough, you can simply write to a file and then execute this file. Also it shouldn't matter if the next package does not execute a command
I've never worked with transport layer packets directly, so I'm not entirely sure about the technical side of this.
Sure, but we should hide the binary. One shouldn't easily find it, and by including the backdoor into some legitimate program it becomes even harder to detect.
What if we patch the backdoor into our normal .NET code but only provide the original source (compile and install the backdoor binary manually)?
yes, if dotnet supports this functionality on linux, sure! Then we could even work on HTTP level.
It would be even cooler, if we could manipulate the dotnet compiler on a system and then argue in our report that we have reproducible builds. They can compile our code on the client to see that the source is legit. But this takes probably too much time and are reproducible builds even possible with dotnet?
Edit: support seems to be there: https://docs.microsoft.com/en-us/dotnet/api/system.io.filesystemwatcher?view=netcore-3.0
The .NET compiler platform (Roslyn) is indeed open source, but I'm not sure I can manage patching a compiler on top of the other remaining work (2nd backdoor & report) in time π’
Yes, I agree, this is too time intensive.
To sum up the first backdoor:
If we obfuscate this procedure nicely we could take it as difficult backdoor :thinking:, because at the moment I can't really think of a more difficult one...
It is much more difficult to think of a good backdoor than I expected...
For the second backdoor: What if we add a binary to a server that fetches commands from a website once a day, executes them and then posts the results. E.g. it gets evil.com/commands.txt
executes all commands and posts their output back to this url.
It would be almost impossible to find with blackbox testing, since the connection is inside-out and only happens ones per day (we could even hide the traffic, e.g. in DNS requests or ICMP to make it even more sneaky). Then we would only have to hide the running binary so that it is difficult to find in whitebox testing, but I guess we have to do that for most backdoors. Maybe by giving it a generic name and only provide the compiled code, maybe even obfuscated.
It is much more difficult to think of a good backdoor than I expected...
Cannot agree more π
For the second backdoor: What if we add a binary to a server that fetches commands from a website once a day, executes them and then posts the results. E.g. it gets
evil.com/commands.txt
executes all commands and posts their output back to this url. It would be almost impossible to find with blackbox testing, since the connection is inside-out and only happens ones per day (we could even hide the traffic, e.g. in DNS requests or ICMP to make it even more sneaky). Then we would only have to hide the running binary so that it is difficult to find in whitebox testing, but I guess we have to do that for most backdoors. Maybe by giving it a generic name and only provide the compiled code, maybe even obfuscated.
Sounds like a nice idea!
Wait, are you saying the first one is easy? π€£
Reworked the backdoor into a FileSystemWatcher
in e4b9c59.
Deployment:
BACKDOOR_1
); currently enabled by default. For hand-in, we would compile and deploy with the code and then remove it from the source before hand-in. Sneaky measures:
Exploitation:
appsettings.json
file 5+ times (might want to increase?) through the nginx path traversal, e.g. curl -k https://imovies.ch/static../appsettings.json
x 5 within a 5-minute sliding windowcurl -k https://imovies.ch/Account/Login?cmd=url%20encoded%20bash%cmd
appsettings.json
access counterNote:
I'm still not 100% confident providing binaries compiled using slightly modified source code is allowed, but it feels like we can argue they said backdoor code need not be included π€
I'm still not 100% confident providing binaries compiled using slightly modified source code is allowed, but it feels like we can argue they said backdoor code need not be included thinking
Yes, I think it should be fine. An attacker could also patch the executable, right?
For the second backdoor: What if we add a binary to a server that fetches commands from a website once a day, executes them and then posts the results. E.g. it gets
evil.com/commands.txt
executes all commands and posts their output back to this url. It would be almost impossible to find with blackbox testing, since the connection is inside-out and only happens ones per day (we could even hide the traffic, e.g. in DNS requests or ICMP to make it even more sneaky). Then we would only have to hide the running binary so that it is difficult to find in whitebox testing, but I guess we have to do that for most backdoors. Maybe by giving it a generic name and only provide the compiled code, maybe even obfuscated.Sounds like a nice idea!
Sounds interesting, although I'm not sure if that suits the assignment - the reviewing group won't be able to exploit it unless they have control of the iMovies network/local hosts file or the website, neither of which they can access (imagining the VMs as physical boxes, their only access point being the public-facing webpage and a source code/VM image dump)
They only have to be able to find the backdoor, no? Maybe I have to reread the assignment ...
I would interpret it as being "feasible" to be exploited by anyone with the knowledge as opposed to having some kind of exclusive secret (e.g. account credentials on the hosting provider where evil.com
is registered). Otherwise I would argue the config server is a "backdoor" to the entire thing if you have the SSH key π€£
true... but maybe if we didn't document a key, it could be considered a backdoor as well :sunglasses:
I agree with @Liblor, in my opinion a backdoor must be exploitable by whoever planted it. The task of the other group is only to find it. In the case of the SSH key, that would be so trivial that it's probably not considered to be a backdoor. But I think itβs nowhere mentioned that the backdoor must be exploitable for everyone.
Second backdoor up in 2feb94e.
Deployment: same as the first; prior to hand in, we remove the backdoor code (under BACKDOOR_2
) from the source, and manually upload a patched build to GH release repo.
Obfuscation:
CertServer
with info-level logging (i.e. visible in sudo journalctl -u asl-certserver | tail -100
) that legitimately polls the release repo and compares the latest release publish date against the last write date of the installed binaries, logging the resultExploitation:
#/bin/bash
, saves it to a temp location, executes and deletes ittouch /home/coreca/WebServer.dll
. I'm contemplating of leaving this as-is for the submission both to hint and to confuse whoever looks at the deployed files π€£
Notes:
Increased number of reads on https://imovies.ch/static.../appsettings.json
required to trigger the other backdoor to 10.
According to the assignment, two backdoors have to be included in the system for other teams to find them.