2011-12-17 5 views
8

안녕 모두,쉘 코드를 char [] 배열로 선언 할 때와 char *를 선언 할 때의 차이점은 무엇입니까?

나는 기본적인 쉘 코딩을 배우려고 노력하고 있고, 나는 누군가가 나에게 설명 할 수 있기를 바란다는 궁금증에 빠져있다. 다음 코드를 두 가지 방법으로 컴파일했습니다 : 쉘 코드를 배열 및 char *로 선언하십시오. 쉘 코드를 배열로 선언하면 linux가 데이터를 실행하려고한다는 것을 감지하고 첫 번째 명령에서 segfault를 얻습니다. 그러나 쉘 코드를 char *로 선언하면 모든 쉘 코드가 실행되고 "Hello world!"가 표시됩니다. 컴파일러는 어떻게이 두 선언을 다르게 취급합니까? 그리고 보호되지 않는 메모리에있는 쉘 코드로 끝나는 이유는 무엇입니까? 미리 감사드립니다. 당신이 char[]로 선언하면

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

/* This declaration ends in a segfault */ 
//char shellcode[] = 

/* This declaration ends in successful execution */ 
char* shellcode = 

/* Shellcode prints "Hello world!" and exits */  
"\xeb\x1f\x48\x31\xc0\x48\x31\xdb\x48\x31\xc9\x48\x31\xd2\xb0\x04\xb3\x01\x59\xb2\x0c\xcd\x80\x48\x31\xc0\xb0\x01\x48\x31\xdb\xcd\x80\xe8\xdc\xff\xff\xff\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64\x21"; 

int main() 
{ 
    void (*f)(); 
    f = (void (*)())shellcode; 
    (void)(*f)(); 
} 

답변

8

은 메모리 스택에 있습니다. char*으로 선언하고 문자열 리터럴을 지정하면 메모리는 실행 가능 이미지 자체에 있습니다. 리눅스는 스택에서 코드를 실행하는 것을 좋아하지 않지만 실행 가능한 이미지의 해당 부분에서 메모리를 실행하는 것이 좋습니다. 그 이유는 사람들이 임의의 명령어로 스택을 오버플로 한 다음 실행할 수있는 특정 유형의 스택 오버플로 공격을 피하려고하기 때문입니다.

Linux의 mprotect을 사용하면 Windows에서 메모리 영역 또는 VirtualProtectEx의 사용 권한을 설정할 수 있습니다. 이렇게하면 메모리의 사용 권한을 명시 적으로 설정할 수 있습니다. 첫 번째 경우

3

는 :

char shellcode[] = 

이 로컬 배열로 스택에 문자열 리터럴을 넣습니다. 스택 및 힙 메모리는 일반적으로 보안의 명백한 이유로 실행 권한이 없습니다. 두 번째 경우

:

char* shellcode = 

문자열은 정적 메모리에 살고 - 실행 가능 - 일반적으로 프로그램 바이너리의 나머지와 같은 지역.