tmxklab

[HackCTF/Pwnable] g++ pwn 본문

War Game/HackCTF

[HackCTF/Pwnable] g++ pwn

tmxk4221 2020. 2. 22. 00:17

1. 문제확인

 

nc ctf.j0n9hyun.xyz 3011

 

1) 접속

입력을받고 출력한 뒤 프로그램이 종료됨

 

2) IDA를 통해 확인

총 4개의 함수를 볼 수 있음

 

2-1) IDA(Pseudocode)확인 - main()

 

2-2) IDA(Pseudocode)확인 - vuln()

- fgets()를 통해 s변수에 32bytes까지 입력받음
- 다시 s변수에 저장된 값을 input값에 저장
- replace()를 통해 "I"문자열이 저장된 v7과 사용자의 입력 값이 저장된 input과 v4를 인자로 받음
- replace()의 리턴 값으로 v4를 반환하고 input값에 복사해주는 듯 싶다
- 이후에 v1에 input값을 저장하고 strcpy()를 통해 다시 s변수에 v1의 값을 복사시킨 뒤 s변수를 출력

 

2-3) IDA(Pseudocode)확인 - get_flag()

 

3) $checksec를 통해 elf파일에 걸린 메모리 보호기법 확인


2. 접근방법

1) vuln()분석

- replace()함수에서는 사용자의 입력 값 중에 "I"가 있는지 찾아서 어떤 값으로 변환한 뒤 v4변수로 반환

- 확인 결과 "I"의 개수만큼 "You"로 출력

 

- fgets()에서는 32bytes까지 길이제한이 있어 bof수행하기 어렵지만 strcpy()에서는 길이의 제한을 받지 않음

 

- strcpy()의 인자로 s변수가 사용되는데 s변수는 [ebp-0x3c]부터 시작한다.

 

 

2) 결론

  • s변수가 ebp로부터 60bytes떨어진 곳에 위치하므로 fgets()에서는 32bytes까지 길이제한이 있어 bof가 불가능
  • 하지만, 1byte인 "I"문자를 여러 개 입력하여 replace()를 통해 3bytes인 "You"로 변환되므로 길이 제한이 없는 strcpy()부분에서 bof가 가능
  • 따라서, SFP까지 덮기 위해서 64bytes가 필요하므로 replace()와 strcpy()를 이용하여 bof를 수행하고 ret부분에 get_flag()의 주소를 덮어야 한다.

3. 풀이

1) gdb를 통해 test

- "I"문자 20개와 "A"문자 4개를 input값으로 넣어 s변수에 64bytes까지 증가되는 것을 볼 수 있으며 EBP에 "AAAA"가 들어간 것을 확인할 수 있다.

- 이제, get_flag()의 주소를 찾아 vuln()의 ret주소를 바꿔보자

 

2) get_flag()주소 확인

- get_flag() : 0x8048f0d

 

3) 공격코드 작성

from pwn import *

p = remote("ctf.j0n9hyun.xyz", 3011)

get_flag_addr = 0x8048f0d

payload = "I"*20
payload += "A"*4
payload += p32(get_flag_addr)

p.sendline(payload)
p.interactive()

 

4) 공격 실행

'War Game > HackCTF' 카테고리의 다른 글

[HackCTF/Pwnable] 1996  (0) 2020.02.23
[HackCTF/Pwnable] Poet  (0) 2020.02.22
[HackCTF/Pwnable] RTL_World  (0) 2020.02.22
[HackCTF/Pwnable] Yes or no  (0) 2020.02.22
[HackCTF/Pwnable] BOF_PIE  (0) 2020.01.28
Comments