본문으로 바로가기

[D+7] 쉘 코드 제작

category 해킹&보안/시스템해킹&보안 2017. 4. 11. 23:38
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

5. 쉘 코드 제작


1) 쉘코드


▣ 쉘코드란(Shellcode)?

- 명령어 해석기 또는 모든 특정 명령어를 실행하기 위한 기계어의 나열들.

- 시스템의 특정명령을 실행할 수 있는 기계어 코드.

- 소프트웨어 취약점 이용을 위한 내용부에 사용.


2) 쉘코드 제작


▣ 제작 방법론

1. c언어로 프로그램 작성.

2. 어셈블리어로 살펴본 후 필요한 함수 추출.

3. 기계어로 다시 추출.


(1) C언어 작성

- /tmp/write.c로 저장

컴파일 : #gcc -o write write.c

#include <stdio.h>

int main() {
	printf("i2sec\n");
	return 0;
}


(2) 시스템 콜 분석 (strace)

- strace : 시스템 콜 호출을 추적할 수 있는 프로그램. (리눅스 기본 내장 프로그램)

☞ 시스템 콜 함수 : 커널과 직접 명령을 주고 받을 수 있는 인터페이스(함수)

- 실행시 어떤 시스템 콜을 호출해서 쓰는지 볼 때 사용.


- write 함수 원형 보기

# man 2 write

☞ 2 : 시스템 콜 함수 쳅터

☞ fd : 파일 서술자 ( 0 : STDIN, 1 : STDOUT, 2 : STDERR)


(3) 시스템 콜을 사용하여 다시 C언어 작성

- /tmp/syswrite.c로 저장

- 컴파일 : #gcc -o syswrite syswrite.c -static

☞ -static : 정적으로 컴파일. 컴파일 시 필요한 내용들 같이 묶어서.. 분석이 쉬워짐.

#include <stdio.h>

int main() {
	write(1, "i2sec\n", 6);
	return 0;
}


(4) GDB로 write() 분석

- GDB : 유닉스 기반의 GNU 디버거

- 레지스터는 무조건 앞에 $[레지스터]의 모양으로 참조가능.

 명령어

 설명

 gdb [프로그램]

 gdb 프로그램 실행

 set disassembly-flavor [intel] 또는 [att]

 어셈블리어 문법 선택

 disassemble [함수] 또는 [주소]

 디스어셈블 출력

 break *[offset] 또는 *[주소]

 중단점 설정

 info breakpoints

 설정되어 있는 중단점 목록 보기

 del [번호] 또는 미 기재시 모두 삭제

 중단점 삭제

 info registers

 레지스터 정보보기

 run

 실행(중단점이 있는 경우 중단점 있는 곳까지 실행)

 continue

 다음 중단점까지 진행

 si

 현재 명령줄 실행, 함수 호출 시 내부 진입O (step into)

 ni

 현재 명령줄 실행, 함수 호출 시 내부 진입X (next into)

 [p or x]/[개수][출력형식]

 변수 및 레지스터 값 출력
 p : 변수 참조시 / x : 주소값 참조시

 출력형식 x : 16진수 / s : 문자열 / d : 10진수 / b : byte / i : instruction


- int : interrupt(끼워 넣다)

int 0x80 : 시스템 콜을 호출!

- 대부분 보통 함수의 인자 순서대로 eax ~ edx 까지 들어감. 

☞ 이 때 eax에 4가 들어간 것은 시스템 콜 함수 넘버임. (write의 번호)

시스템 콜 함수 넘버는 아래 명령어로 확인가능함.

# vi /usr/include/asm/unistd.h


(5) 어셈블리어로 제작

- /tmp/syswrite.asm으로 작성

global _start

_start:
    jmp short message

start:
    pop ecx
    mov eax, 4
    mov ebx, 1
    mov edx, 6
    int 0x80

message:
    call start
    db "i2sec", 0x0a, 0x0d     //0x0a0d : '\n'

- 목적파일 생성과 바이너리 생성

# nasm -f elf syswrite.asm

# ld -o syswrite syswrite.o


- syswrite 실행하면 무한루프 발생...

☞ 순차적 실행으로 인해 start 라벨에서 다시 message라벨로 내려가기때문..

☞ 종료 코드를 삽입해야함. (exit(0);)

- exit(0);코드 추가

☞ exit 함수는 시스템 콜 함수로 넘버는 1임.

☞ exit(0); 은 차례대로 exit : EAX, 0 : EBX 임을 직감.

global _start

_start:
    jmp short message

start:
    pop ecx
    mov eax, 4
    mov ebx, 1
    mov edx, 6
    int 0x80

    mov eax, 1
    mov ebx, 0
    int 0x80

message:
    call start
    db "i2sec", 0x0a, 0x0d     //0x0a0d : '\n'

- i2sec을 한번만 출력하고 정상적으로 종료됨.


(6) 쉘코드 추출

- objdump -d -M intel [프로그램] : 기계어로 보여줌. 

- 기계어만 추출하기 위해 쉘 스크립트를 사용하자. (기계어를 한줄로 나열해야함)

# for i in $(objdump -d syswrite | grep "^ " | cut -f 2);do echo -n \\x$i;done

☞ grep "^ " : 한 줄 기준으로 자름. (라벨이름 줄을 없앰.)

☞ cut -f 2 : 두번째 열만 가져옴.

☞ -n : 개행을 안함.

- 그런데!! BOF 공격은 문자열 입력에 우리가 짠 쉘코드를 주입할것인데 string으로 따지면 0x00은 널바이트이며 중간에 끊김이 발생.

- NULL 바이트를 제거해주자.

1. 크기를 줄여줌.

☞ jmp -> short jmp : short jmp는 2바이트만 사용.

ex) jmp i2sec          ->  E9 1E 00 00 00

ex) short jmp i2sec     ->  E9 1E

☞ 레지스터 너비 수정. (8비트, 16비트 레지스터 사용)

ex) EAX : 32비트 / AX : 16비트 / AL : 8비트

2. 0 값 삽입

☞ XOR : 자기 자신을 XOR 연산하여 0 삽입

ex) XOR EAX, EAX

global _start

_start:
        jmp short message

start:
        xor eax, eax
        xor ebx, ebx
        xor edx, edx

        pop ecx
        mov al, 0x04
        mov bl, 0x01
        mov dl, 0x06
        int 0x80

        mov al, 0x01
        xor ebx, ebx
        int 0x80
message:
        call start
        db "i2sec", 0x0a, 0x0d

- start: 밑의 3줄의 xor은 작은 레지스터들을 사용하기 전에는 원래 무슨값이 들어있는지 모르니까 초기화 해주는 것임.



- 다시 쉘코드를 추출해준다!

\xeb\x15\x31\xc0\x31\xdb\x31\xd2\x59\xb0\x04\xb3\x01\xb2\x06\xcd\x80

\xb0\x01\x31\xdb\xcd\x80\xe8\xe6\xff\xff\xff\x69\x32\x73\x65\x63\x0a\x0d



[정리]

1. C언어로 구현

2. GDB로 역어셈블링하여 필요한 부분만 찾음.

3. 시스템 콜에 필요한 필수 부분만으로 다시 구현.

4. 컴파일 후 objdump로 기계어를 출력.

5. null바이트 존재시 null값을 제거.

6. 기계어코드들을 하나의 문장으로 완성!







i2sec 대구지점 23기 수료생.

'해킹&보안 > 시스템해킹&보안' 카테고리의 다른 글

[D+9] 메모리 보호 기법  (0) 2017.04.12
[D+8] 쉘 코드 제작 (심화)  (0) 2017.04.12
쉘 프로그래밍  (0) 2017.03.16
[D+5] Backdoor (백도어) (2)  (0) 2017.03.08
[D+4] Backdoor (백도어) (1)  (0) 2017.03.07