hint를 확인한다.
C소스에서 fgets가 사용되는 것을 보니
이 문제도 BOF문제인 듯 하다.
우선 위의 소스코드를 확인해보겠다.
fgets의 용도 : 스트림에서 문자열( num-1 개의 문자 )를 입력받고 str에 저장한다.
Null 문자는 자동적으로 마지막으로 입력받은 문자 뒤에 붙는다.
scanf와 달리 띄어쓰기가 있는 문자열도 입력 받을 수 있다.
[ fgets의 인자 ]
첫번째 인자 : 읽어들인 문자열을 저장할 배열
두번째 인자 : 마지막 Null문자를 포함하여 읽어들일 최대 문자 수
ex. 10이라면 최대 9문자를 입력받음
세번째 인자 : 문자를 읽어들일 스트림의 File 객체를 가리키는 포인터
-> 표준 입력에서 입력을 받으려면 stdin 사용
입력은 44개의 문자를 입력받으며,
if문에서 check가 0xdeadbeef와 같다면
3095의 권한으로 shell이 실행된다고 되어있다.
그럼 tmp 폴더로 옮겨서 GDB를 실행하여 확인해보겠다.
우선 메모리 구조를 보게되면 0x38의 공간을 확보한다고 나와있다.
0x38은 56byte이다.
그렇다면 메모리 구조는 crap이 4byte이고
check가 4byte, buf[20]이 20byte이고 나머지 28byte인 dummy가 각 변수 사이에
끼어있을 것이다.
cmpl을 이용하여 두개의 레지스터를 비교하고
jne를 이용하여 비교값이 다를 때는 main+75로 넘어간다고 되어있다.
이 때 비교하는 %ebp의 주소가 check가 될 것이다.
main+17을 보게되면 %eax를 %ebp에 넣고 push한 다음
gets함수를 이용하여 문자를 입력받는 것을 알 수 있다.
그렇다면 buf의 위치는 0xffffffc8이라는 것도 알게 된다.
그다음 main+29dptj 비교할 때 check의 위치도 알게 되므로
check의 위치는 0xfffffff0이라는 것을 알게 된다.
따라서 buf와 check 사이의 공간은 40byte이므로
buf 20byte와 dummy 20byte 후에 check 4byte가 있다는 것도 알게된다.
따라서 40개의 NOP를 입력한 후에
0xdeadbeef를 입력하면 cmpl을 하였을때 맞지 않을까란 생각을 해보았다.
'코딩 문제 > 해커스쿨' 카테고리의 다른 글
FTZ : level16 (0) | 2019.07.14 |
---|---|
FTZ : level15 (0) | 2019.07.13 |
FTZ : level13 (0) | 2019.07.08 |
FTZ : level12 (0) | 2019.07.07 |
FTZ : level11 (0) | 2019.06.29 |