Level15 풀이.
pw = 'guess what'
일단 문제 접근을 위해 hint를 본다.
일단 c코드인건 맞는데, 그 전과 다르게 check 변수를 포인터 변수로 선언해줬다는 것이다. 포인터 변수의 가장 중요한 것은 메모리의 주소 값을 가지는 변수라는 것이다. 또 level14와 같이 level14와 같이 fgets이 있는 걸 봐서는 버퍼 오버 플로우가 발생하는 것 같다.
일단 한 줄씩 보자.
int crap; 는 int형 변수인 crap 선언. int *check;은 int 형 포인터 변수 check를 선언, char buf[20] 문자형 buf 변수에 20바이트 크기 할당. fgets(buf,45,stdin) fgets 함수로 45바이트만큼의 입력을 buf 변수로 받음. if(*check==0xdeadbeef) #check 포인터가 0xdeadbeef면 if 문 실행.
setreuid(~~~~)는 다음 레벨의 권한 같다. system(“/bin/sh”) /bin/sh 셀 실행한다.
일단 스타일이 다르니까 생각해보자.
buf[20]에서부터 *check 까지의 거리. 0xdeadbeef 주소 알기.
가장 중요한 *check 포인터 변수에 존재하는 메모리 주소에 0xdeadbeef문 실행.
일단 main+17 lea, eax [ebp-56] buf에서 ebp까지의 거리를 구한다.
buf[20]에서부터 ebp까지의 거리는 56.
main+29 = cmp DWORD PTR[ebp-16], 0xdeadbeef 이 부분은 조건문에서 *check 포인터와 0xdeadbeef 값 비교하는 부분.
즉 *check에서 ebp까지의 거리 = 16. 그렇다면 buf[20]에서 *check 까지의 거리는 (buf –ebp) - (*check – ebp) = 56 – 16 = 40.
main+32 cmp DWORD PTR [eax], 0xdeadbeef 해당 부분이 0xdeadbeef와 *check를 비교하는 부분이다 . 그래서 일단 x/10x 0x080484b0으로 해당 주소 40byte를 10byte까지로 보자.
정확하게 0xdeadbeef는 0x080484b2에 있다는 걸 확인.
그러면 이번에도 python 코드 사용. buf[20]에서 *check까지 거리 + check(0xdeadbeef의 주소) 이런 식으로 써야 될 듯.
cf)BOF가 대세인 거 같다. BOF 문제가 반복되는 느낌.