[ftz] level 15: guess what
15_루틴 분기 키값의 이해(2)
√ 문제 분석
- lev14와 다른 점: check 포인터가 0xdeadbeef 문자열을 가리켜야 한다.
- lev14: 단순히 check 정수 변수에 0xdeadbeef 값만 입력 해주는 것
- lev15: check 포인터 변수에 있는 값이 가리키는 메모리 주소에 0xdeadbeef를 넣어주는 것
√ gdb로 소스코드 분석
- 함수 프롤로그 부분
- main+3> stack에 공간 56byte 만듦
: crap[4], *check[4], buf[20], dummy[28]
>> fgets(ebp-56, 0x2d, 0x8049664)
= fgets(buf, 45, stdin)
- ebp-16(*check)와 0xdeadbeef 비교: check 포인터가 0xdeadbeef 문자열을 가리키는지 확인
같지 않으면, main+77로 JMP
>> setreuid(3096, 3096)
>> system("/bin/sh")
buf[20] |
dummy[20] |
*check[4] |
crap[4] |
dummy[8] |
SFP[4] |
RET[4] |
* 변수 할당 공간 확인
- lev14와 동일 구조
- check 포인터 변수가 가리키는 메모리 주소 안의 값이 0xdeadbeef여야 한다!!
√ 공격
* 방법 1)
buf에 0xdeadbeef 문자열을 10번 반복하여 40byte를 채운 다음,
check가 buf를 가리키도록 buf 주소값을 입력하면 되지 않을까?
>> print "\xef\xbe\xad\xde"*10 + "buf의 주소값(=0xdeadbeef가 있는 곳 주소)"
: 총 44byte 입력하여 BOF 발생시켜 check가 가리키는 주소값을 변조할 수 있다.
buf 주소값 찾기
- 0xdeadbeef를 비교하는 부분에 bp를 걸고 실행한 후 ABCD를 입력하여
buf의 시작 주소값을 찾는다
buf의 주소값: 0xbfffde20
- 위를 토대로 crack을 시도해보면, 한 번이 아니라 여러 번 시도를 해야 성공을 하는 것을 확인할 수 있다.
>> 프로그램이 실행될 때마다 stack 주소가 조금씩 변하기 때문!
: gdb에서 run을 여러 번 하면서 그때마다 $esp의 값을 확인해보면
그 주소값이 계속 변하지만 반복되는 것이 있다는 것을 확인할 수 있을 것
- 이 방법은 여러 번 시도해야 하며, 한 번에 성공하기 어렵고 성공을 보장할 수도 없다.
>> 계속해서 바뀌는 stack 주소가 아닌, 주소가 바뀌지 않으며
0xdeadbeef 문자열을 가지고 있는 어떤 문자열을 사용할 수 있을까?
* 방법 2)
어셈블리 코드에 있는 deadbeef 문자열의 주소를 알아내어 이를 이용해 crack 하는 방법
check 포인터가 그 문자열의 주소를 가리키게 하자.
0xdeadbeef을 비교하는 곳에 bp를 걸어두고 프로그램을 실행한 후 $eip을 조사했다.
다음에 실행할 어셈블리 코드를 16진수로 읽어보았다.
>> deadbeef 문자열 주소: 0x80484b2
** 페이로드
NOP[40] + 0x80484b2
Level 16 Password = about to cause mass
* 방법 3)
환경변수를 이용한 크랙방법
0xdeadbeef 문자열을 환경변수로 등록하고, check가 이 환경변수를 가리키도록 하자.
- main() 안의 세번째 줄은 프로그램 길이의 오차를 수정하는 부분이다.
- 환경변수를 등록한 후,
- 위 소스코드를 실행시켜 환경변수 BEEF의 주소를 알아낸다.
'write-up > pwnable' 카테고리의 다른 글
[ftz] level 17: king poetic (0) | 2019.08.26 |
---|---|
[ftz] level 16: about to cause mass (0) | 2019.08.24 |
[ftz] level 14: what that nigga want? (0) | 2019.08.23 |
[ftz] level 13: have no clue (0) | 2019.08.23 |
[ftz] level 12: it is like this (0) | 2019.08.21 |
댓글