The second part of the challenge uses an already known technique to break out from “sandboxes”.
Namely: overwriting the contents of the /proc/self/mem. This is possible because the calculator contains two methods: READ and WRITE with which we can read and write arbitrary files. (Note: I tried to read “flag2”, but unfortunately it did not exist… :))
So I leaked the memory mappings with reading the /proc/self/maps file. Then I overwrote the “open” call’s GOT entry to system. And simply called the READ call again with /bin/sh which instead of opening the file, opened a shell for me (btw I tried to call “sh” first, but it turned out it calls a stat function first, and “sh” did not work, but “/bin/sh” did the trick).
Also there were some character encoding problem (it probably tried to interpret the binary input as UTF8 characters), so I only overwrote 3 bytes instead of the full address and the exploit is not reliable: only works if ASLR gives an address with characters which are lower than 0x80.
After calling an “ls” it turned out the flag was in the flag2-03dae19b720939043d87fbf67342c2e8.txt file.
Calc.exe is a .NET program (finally :D), which can evaluate (mostly) mathematical expressions.
At first no functions are enabled except some basic mathematical operations like addition, subtraction, etc.
But we can enable different functions by using a digitally signed X509 certficates.
We also got an example cert “guestCert.crt” which enabled some basic math and trigonomical functions.
The program also adds a function called FLAG which returns the flag as string.
The problem is we cannot load any certificate as there is a lot of checks before, so we had to find some vulnerability. The program uses a known crypto library, called BouncyCastle and the attached “BouncyCastle.Crypto.dll” is exactly the same as the one we can download from NuGet. As no known vulnerability exists for this library (or at least at the certificate verification part), we had to look for vulnerabilities in the program.
Although the certificate loaded into the store while it is checked, no self-signed certificates are allowed and it is removed as soon as its verification fails.
But there is a bug in the code: although some checks like the VerifyCertificate is in a try-catch block and returns a boolean value, the IsCalcExeCert can throw exception while calling SingleOrDefault method. To trigger the exception we have to put two values with the 220.127.116.117 key into the SubjectName’s field.
Although our certificate is not deleted from the trusted CA store, it is not loaded into the program, so we cannot call the FLAG function yet. But we can sign a new client certificate with this now trusted cert as a CA (certificate authority). This way our new certificate will be accepted.
The attached C# code snippet (calcexe1.cs) will generate the fake CA and the fake certificate.
We got an RSA public key (pub.key) encoded in PEM format and the encrypted flag (flag.enc).
These are the converted parameters:
The public exponent is too large thus we can suspect that the private exponent is possible too small.
I tried to attack it with Wiener’s attack: https://en.wikipedia.org/wiki/Wiener%27s_attack with the following implementation, but it did not worked: https://github.com/pablocelayes/rsa-wiener-attack
So I remembered other RSA attacks from previous CTFs and how much time this page helped me: https://github.com/mimoo/RSA-and-LLL-attacks
The last attack is the Boneh Durfee attack, which is you know BO-neh DU-rfee => BODU just like the challenge’s name, so I instantly know this will solve the challenge (also a lot of other teams are already solved it, so it should be not too hard challenge either).
Running budo.sage will give us the private exponent (d):
The executing pow(c,d,N) in python give us the following plaintext:
This challenge was solved by and the write up was written by one of my teammates, gym.
In this challange we are provided with a pcap file, loading it in wireshark and after a quick glance at the exported objects we can see they were using 0bin pastebin (https://github.com/sametmax/0bin).
0bin encrypts the data client side and provides a decryption key. This key if appended to the URL with a hash mark ‘#’ is used to decrypt the received data. Ideally this part of the URL should not be sent to the server, thus the server operators cannot know the content of the paste.
However in the pcap 0bin is used in conjunction with piwik, witch send the entire URL in the request, thus we have the key to decrypt the data.
We can find three such key-id pairs in the pcap, the first one results in a fake flag, the second one has expired and the third one gives us an ASCII art of the real flag.
The first step was NOPing out the ptrace “anti-debug” call and finding out the main hash function which was at the 0x401B40 address.
This accepted the flag as an input and used big integer math to calculate it’s hash. This hash was compared to a static buffer (there was a little trick that only every 4th number was used from that buffer).
The hash function can be summarized with this python code:
And we know that the hash of the real flag was:
So we could calculate the flag easily with the following code snippet: