Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- toddler
- rev
- FSB
- TUCTF
- Bottle
- pwnable
- Toddler's Bottle
- ASM
- BOF
- practicalmalwareanalysis
- CTF
- writeup
- pwnable.kr
- pwn
- Reverse
- pico
- CANARY
- 2018
- shellcraft
- shellcode
- anti
- Read
- string
- picoCTF
- reversing
- PMA
- format
- Rookiss
- Bug
- Leak
Archives
- Today
- Total
제리의 블로그
TokyoWesterns CTF 4th 2018 twctf dec_dec_dec 본문
요약
리버싱 문제로
flag 를 base64, rot13, 또 다른 인코딩.
이렇게 3단계 인코딩을 거쳐 strcmp로 비교한다.
(세번째 인코딩은 uu 인코딩이란다)
풀이방법은 gdb script 로 브루트포싱을 했습니다.
void __fastcall main(int argc, char **argv, char **env)
{
size_t len; // rax@4
char *flag; // ST18_8@4
size_t len_; // rdx@4
char *enc1; // rax@4
char *enc2; // rax@4
char *enc3; // ST18_8@4
if ( argc != 2 )
{
puts("./dec_dec_dec flag_string_is_here ");
exit(0);
}
len = strlen(argv[1]);
flag = (char *)malloc(len + 1);
len_ = strlen(argv[1]);
strncpy(flag, argv[1], len_);
enc1 = base64enc(flag);
enc2 = rot13(enc1);
enc3 = uuencode(enc2);
if ( !strcmp(enc3, "@25-Q44E233=,>E-M34=,,$LS5VEQ45)M2S-),7-$/3T ") )
puts("correct :)");
else
puts("incorrect :(");
}
메인을 보면 입력값(flag)을
base64 인코딩을하고
rot13 인코딩을하고
또 다른 인코딩(uuencode)을 한번 더 한 값을
특정 문자열과 비교하고 있었습니다.
고정된 문자열이라서 브포로 어떻게 비벼볼 수 있을거 같습니다.
base64, rot13 같은 인코딩은 input 길이와 output 길이가 비례하기 때문에
flag의 길이를 파악하는 것은 간단했습니다.
일단
TWCTF{aaaaaaaaaaaaaaa}
로 초기화한 상태에서 하나하나 찾았습니다.# ./dec_dec_dec TWCTF{base64_rot13_uu}
correct :)
import string
ip = dec_dec_dec.entry + (0x1109 - 0x730)
gdb.Breakpoint('*' + hex(ip))
flag = list('base64_rot13_uu')
rsi = '@25-Q44E233=,>E-M34=,,$LS5VEQ45)M2S-),7-$/3T '
idx = 14
chset = string.ascii_lowercase+string.digits+'_'
l = []
for c in chset:
flag[idx] = c
flag2 = 'TWCTF{' + ''.join(flag) + '}'
gdb.execute('r ' + flag2)
print(flag2)
rdi = gdb.parse_and_eval('$rdi')
rdi = gdb.execute('printf "%s", ' + hex(rdi), to_string=True)
print(rdi)
print(rsi)
# @25-Q44E233=,>E-M34=,,$LS5VEQ45)M2S-),7-$/3T
if '@25-Q44E233=,>E-M34=,,$LS5VEQ45)M2S-),7-$/3T ' in rdi:
print("[+] found!")
l += [c]
#break
print(l)
gdb.execute('q')
10분 걸리는 gdb 브루트포스 스크립트
import string
######## inital ########
#flag = list('base64_rot13_uu')
flag = list('aaaaaaaaaaaaaaa')
idx = 0
chset = string.ascii_lowercase+string.digits+'_'
#chset = '0ubase64_rot13'
########################
ip = dec_dec_dec.entry + (0x1109 - 0x730)
bp = gdb.Breakpoint('*' + hex(ip))
bp.silent = True
rsi = '@25-Q44E233=,>E-M34=,,$LS5VEQ45)M2S-),7-$/3T '
def set_pivot():
flag2 = 'TWCTF{' + ''.join(flag) + '}'
gdb.execute('r ' + flag2)
rdi = gdb.parse_and_eval('$rdi')
rdi = gdb.execute('printf "%s", ' + hex(rdi), to_string=True)
pivot = 0
for i in range(len(rdi)):
if rdi[i] == rsi[i]:
pivot += 1
else: break
pivot += 1
return pivot
pivot = set_pivot()
print('pivot = {}'.format(pivot))
def check(idx, pivot, chset):
candidate = []
for c in chset:
flag[idx] = c
flag2 = 'TWCTF{' + ''.join(flag) + '}'
gdb.execute('r ' + flag2)
print(flag2)
rdi = gdb.parse_and_eval('$rdi')
rdi = gdb.execute('printf "%s", ' + hex(rdi), to_string=True)
print(rdi)
print(rsi)
if rsi[:pivot] in rdi:
print("found!")
candidate += [c]
print('candidate: {}'.format(candidate))
return candidate
chset2 = chset
is_loop = 0
stack = []
while idx < len(flag):
l2 = check(idx, pivot, chset2)
if not l2:
if stack and stack[-1][0] == idx - 1:
print('Before STACK: {}'.format(stack))
flag[idx-1] = stack[-1][1].pop(0)
if not len(stack[-1][1]):
del stack[-1]
print('After STACK: {}'.format(stack))
else:
is_loop += 1
pivot -= 1
elif len(l2) == 1:
is_loop = 0
flag[idx] = l2[0]
chset2 = chset
pivot += 1
idx += 1
elif len(l2) == len(chset):
idx -= 1
if stack and stack[-1][0] == idx:
print('Before STACK: {}'.format(stack))
flag[idx] = stack[-1][1].pop(0)
if not len(stack[-1][1]):
del stack[-1]
print('After STACK: {}'.format(stack))
idx += 1
pivot += 1
else:
is_loop *= 2
chset2 = l2
pivot += 1
if is_loop > 7:
print('[-] loop!')
if not stack:
stack += [[idx, l2]]
elif stack[-1][0] == idx:
pass
else:
stack += [[idx, l2]]
print('Before STACK: {}'.format(stack))
if not stack:
print('[-] Error')
idx = stack[-1][0]
flag[idx] = stack[-1][1].pop(0)
if not len(stack[-1][1]):
del stack[-1]
print('After STACK: {}'.format(stack))
is_loop = 0
idx += 1
chset2 = chset
print('TWCTF{' + ''.join(flag) + '}')
gdb.execute('q')
'''
real 9m43.874s
user 8m36.962s
sys 0m44.821s
'''
이건 6분짜리 브포
import string
######## inital ########
flag = list('abaaaaaaaaaaaaa')
idx = 0
chset = string.ascii_lowercase+string.digits+'_'
########################
ip = dec_dec_dec.entry + (0x1109 - 0x730)
bp = gdb.Breakpoint('*' + hex(ip))
bp.silent = True
rsi = '@25-Q44E233=,>E-M34=,,$LS5VEQ45)M2S-),7-$/3T '
pivot = -1
chset2 = chset
while idx < len(flag):
if flag[idx] == chset[-1]: # 못찾음
flag[idx] = chset[0]
idx -= 1
pivot -= 1
a02 = chset.index(flag[idx])
chset2 = chset[a02+1:]
else:
chset2 = chset
c2 = ''
for c in chset2:
flag[idx] = c
flag2 = 'TWCTF{' + ''.join(flag) + '}'
gdb.execute('r ' + flag2)
print(flag2)
rdi = gdb.parse_and_eval('$rdi')
rdi = gdb.execute('printf "%s", ' + hex(rdi), to_string=True)
print(rdi)
print(rsi)
if pivot < 0: # init pivot
for i in range(len(rsi)):
if rsi[i] == rdi[i]:
pivot = i
else: break
#pivot += 1
continue
tmp = 0
for i in range(pivot+1, len(rsi)):
if rsi[i] == rdi[i]:
tmp = i
else: break
if tmp > pivot:
print('found!')
c2 = c
#idx += 1
pivot = tmp
#chset2 = chset
#break
if c2:
flag[idx] = c2
idx += 1
print('TWCTF{' + ''.join(flag) + '}')
gdb.execute('q')
'''
real 5m58.036s
user 5m17.771s
sys 0m27.468s
'''
'CTF > reversing' 카테고리의 다른 글
picoCTF 2018 keygen-me-2 Reversing (0) | 2018.10.03 |
---|---|
picoCTF 2018 assembly-3 Reversing (0) | 2018.10.02 |
picoCTF 2018 be-quick-or-be-dead-1 Reversing (0) | 2018.09.30 |
IceCTF 2018 Reverse Engineering - 1. Locked Out (0) | 2018.09.18 |
dingJMax @ Samsung CTF (SCTF) 2018 (0) | 2018.07.20 |
Comments