ASLR( Address Space Layout Randomization )이란

: 힙(heap), 스택(stack), 공유 라이브러리(libc)등이 주소공간에 mapping될 때 그 위치를 프로그램 실행시 마다 랜덤하게 변경하는 메모리 보호 기법으로 해커들이 공격시 주로 필요로하는 주소공간을 랜덤하게하여 공격을 대비할 수 있습니다

'시스템 해킹' 카테고리의 다른 글

CANARY  (0) 2020.11.10
ASCII Armor  (0) 2020.11.10
RTL ( Return to Libc )  (0) 2020.11.06
DEP (Data Execution Prevention)  (0) 2020.11.06
Stack Buffer Overflow (스택 버퍼 오버플로우)  (0) 2020.11.06

RTL ( Return to Libc )

: DEP 메모리 보호 기법을 우회하는 공격 기법으로 실행 권한이 있는 공유 라이브러리를 통해 공격하는 기법이다

- shellcode의 호출이 필요없다

- RTL은 LIBC에 함수 호출을 하고 함수의 인자 값을 전달해야 한다

 

RTL ( Return to Libc ) 순서

1. root 권한으로 setuid가 설정된 파일 작성

2. 일반 계정으로 환경변수 주소 구하는 코드 작성

3. root 권한을 얻고 쉘을 실행시키는 코드 작성

4. 언어팩 세팅

5. 작성 코드 환경 변수 등록 후 주소 확인

6. 취약한 함수가 쓰인 프로그램을 gdb로 확인하여 변수의 시작 부분에서 EBP까지의 거리를 확인

7. 스택 구조 알기

8. 사용할 함수 주소 구하기

9. 일반 계정으로 root 권한 파일 실행 및 root 권한 획득

 

1. root 권한으로 setuid가 설정된 파일 작성

 

취얌적 함수가 들어가 있는 파일을 루트 권한으로 작성해준다 /tmp/bof.c

 

컴파일 후 setuid 비트를 걸어준다

 

2. 일반 계정으로 환경변수 주소 구하는 코드 작성과  쉘코드 획득

 

일반 계정으로 환경변수를 입력하면 주소값을 돌려주는 코드를 작성한다 /tmp/env.c

 

컴파일을 해주는데 경고표시가 뜨지만 실행을하면 잘 작동되는걸 볼수있다 

 

3. root 권한을 얻고 쉘을 실행시키는 코드 작성

 

setuid 함수로 0번의 아이디를 얻고 system함수로 쉘을 실행 시키는 코드 작성한다 //tmp/sh

 

sh.c 파일을 컴파일 해주고 실행시킨뒤 잘 동작되는지 확인해본다

4. 언어팩 세팅

- 다른 환경변수를 등록하기 전에 언어팩 세팅을 제일 먼저 해줘야 다른 환경 변수의 주소가 바뀌지 않는다

- 기본 세팅인 영문은 1바이트로 동작하기 때문에 2바이트인 한글로 언어팩을 변경해준다 ( 로그아웃시 초기화 )

 

언어팩을 한글로 변경해주고 확인해본다


5. 작성 코드 환경 변수 등록 후 주소 확인

 

작성한 /tmp/sh 파일을 환경 변수에 등록한 후 env를 이용해 주소를 구한다

 

6. 취약한 함수가 쓰인 프로그램을 gdb로 확인하여 변수의 시작 부분에서 EBP까지의 거리를 확인

- root 권한으로 작성된 파일을 바로 gdb로 열게되면 동작이 제대로되지 않기 때문에 이름의 글자수를 똑같이하여 복사를 해준뒤 gdb로 열어서 확인한다

 

이름 변경후 gdb열기

 

RET까지의 거리는 10진수 520인 것을 확인할 수 있다

 

7. 스택 구조 알기

- 앞서했던 Buffer Overflow를 막기위한 보호기법 DEP를 우회하기 위해 RET 자리에 실행 권한이 있는 Shared Libc의 함수 execl 의 주소를 넣어 준다

 

RET 자리에 system 함수가 들어갈 수 있게해준다

 

함수의 정상 동작인 부분을 보면 RET에 system 함수를 넣었을 때 함수의 호출 부분 뒤로 4bytes 뒤부터 순서대로 인자를 받고 있는걸 볼 수 있다

 

8. 사용할 함수 주소 구하기

 

사용할 함수를 gdb에 들어가서 break를 아무데나 걸고 run을 시킨뒤 print로 주소를 구해온다

 

9. 일반 계정으로 root 권한 파일 실행 및 root 권한 획득

공격코드

buffer ~ EBP전 EBP RET 함수의 RET 인자
520bytes 4bytes execl 함수 주소 4bytes 4bytes

./bof "`perl -e 'print "A"x524, "[ 호출 함수 주소 ]", "A"x4, "[ 환경 변수 등록 공격 코드 주소]"x3'`"

 

( execl의 함수 원형은 인자를 최소 3개 이상을 받기 때문에 3을 곱해준다 )

 

취약한 실팽 파일 뒤에 인자로 공격 코드를 넣어주면 쉘이 실행되고 root 권한을 획든한걸 확인할 수 있다

'시스템 해킹' 카테고리의 다른 글

ASCII Armor  (0) 2020.11.10
ASLR ( Address Space Layout Randomization )  (0) 2020.11.10
DEP (Data Execution Prevention)  (0) 2020.11.06
Stack Buffer Overflow (스택 버퍼 오버플로우)  (0) 2020.11.06
Shellcode(쉘코드) 제작  (1) 2020.11.04

DEP (Data Execution Prevention)
: 데이터 실행 방지로 스택이나 힙에서의 쉘 코드 실행을 막아주는 메모리 보호 기법으로 Buffer Overflow를 막을 수 있다

종류
- HardWare DEP : 가상 메모리 페이지 단위로 해당 메모리에서 코드를 실행할 수 없음을 나타낸다
- SoftWare DEP : seh overwrite같이 특정 유형의 악의적인 코드 공격을 막아준다

'시스템 해킹' 카테고리의 다른 글

ASCII Armor  (0) 2020.11.10
ASLR ( Address Space Layout Randomization )  (0) 2020.11.10
RTL ( Return to Libc )  (0) 2020.11.06
Stack Buffer Overflow (스택 버퍼 오버플로우)  (0) 2020.11.06
Shellcode(쉘코드) 제작  (1) 2020.11.04

Stack Buffer Overflow (스택 버퍼 오버플로우)

: 할당된 버퍼 보다 많은 데이터가 삽입되었을 때 인접 메모리를 덮어 쓰게 되는 취약점이다

 

Buffer Overflow에 취약한 함수 목록

- strcpy, strcat, gets, fscanf, scanf, sprintf, sscanf, vfscanf, vsprintf, vscanf, vsscanf, streadd, strecpy, strtrns

 

Buffer Overflow의 취약점 원인

- 문자열 처리함수에서 입력값에 대한 길이 체크를 하지 않음으로 취약점 발생

 

Buffer Overflow 대응 방안

- 근본적인 대응 방안은 안전한 함수 사용 및 입력값 길이 체크

 

Buffer Overflow 순서

1. root 권한으로 setuid가 설정된 파일 작성

2. 일반 계정으로 환경변수 주소 구하는 코드 작성과 쉘코드 획득

3. 언어팩 세팅

4. 쉘코드 환경 변수 등록

5. 취약한 함수가 쓰인 프로그램을 gdb로 확인하여 변수의 시작 부분에서 EBP까지의 거리를 확인

6. 스택 구조 알기

7. 일반 계정으로 root 권한 파일 실행 및 root 권한 획득

 

1. root 권한으로 setuid가 설정된 파일 작성

 

취얌적 함수가 들어가 있는 파일을 루트 권한으로 작성해준다 /tmp/bof.c

 

컴파일 후 setuid 비트를 걸어준다 

 

2. 일반 계정으로 환경변수 주소 구하는 코드 작성과  쉘코드 획득

 

일반 계정으로 환경변수를 입력하면 주소값을 돌려주는 코드를 작성한다 /tmp/env.c

 

컴파일을 해주는데 경고표시가 뜨지만 실행을하면 잘 작동되는걸 볼수있다 

권한 상승 후 쉘 실행 시키는 쉘코드:

\x31\xc0\x89\xc3\xb0\x17\xcd\x80\xeb\x0f\x5e\x31\xc0\x50\x89\xe2\x56\x89\xe1\x89\xf3\xb0\x0b\xcd\x80\xe8\xec\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68

 

3. 언어팩 세팅

- 다른 환경변수를 등록하기 전에 언어팩 세팅을 제일 먼저 해줘야 다른 환경 변수의 주소가 바뀌지 않는다

- 기본 세팅인 영문은 1바이트로 동작하기 때문에 2바이트인 한글로 언어팩을 변경해준다 ( 로그아웃시 초기화 )

 

언어팩을 한글로 변경해주고 확인해본다

 

4. 쉘코드 환경 변수 등록 및 주소 구하기

 

쉘 코드를 perl 스크립트를 이용해 환경 변수에 등록해주고 주소를 구해준다

 

5. 취약한 함수가 쓰인 프로그램을 gdb로 확인하여 변수의 시작 부분에서 EBP까지의 거리를 확인

- root 권한으로 작성된 파일을 바로 gdb로 열게되면 동작이 제대로되지 않기 때문에 이름의 글자수를 똑같이하여 복사를 해준뒤 gdb로 열어서 확인한다

 

이름 변경후 gdb열기

 

ret까지의 거리는 10진수 520인 것을 확인할 수 있다

 

6. 스택 구조 알기

EBP - 스택의 하단부

ESP - 스택이 쌓이는 상단부

RET - 프로그램이 시작될 때 끝나고 돌아갈 주소를 저장해 놓은 곳

 

 

- 스택은 높은 주소에서 낮은 주소로 쌓이고 데이터는 낮은 주소에서 높은 주소로 쌓인다

- EBP 기준으로 -520 인 위치가 buffer의 시작 주소이다

- buffer에 데이터를 작성할 때 520 바이트를 작성하면 EBP전까지 작성한 데이터로 가득 채울 수 있다

- EBP전까지 데이터를 가득 채운뒤 4바이트를 더 작성하게되면 RET전까지인 EBP까지 가득 채울 수 있게된다

- EBP까지 데이터를 가득 채웠으면 환경변수에 저장해둔 쉘코드를 RET에 채워 넣으면 프로그램이 끝나고 공격코드가 실행되게 된다 

 

7. 일반 계정으로 root 권한 파일 실행 및 root 권한 획득

공격코드

buffer ~ EBP전 EBP RET
520bytes 4bytes 쉘코드 환경 변수 주소

./bof `perl -e 'print "A"x[거리], "[쉘 코드 환경 변수 주소]"'`

 

perl 스크립트를 이용해 취약한 프로그램을 실행하면서 공격 코드를 인자로 넘겨주면 root 권한의 쉘이 실행이된다

'시스템 해킹' 카테고리의 다른 글

ASCII Armor  (0) 2020.11.10
ASLR ( Address Space Layout Randomization )  (0) 2020.11.10
RTL ( Return to Libc )  (0) 2020.11.06
DEP (Data Execution Prevention)  (0) 2020.11.06
Shellcode(쉘코드) 제작  (1) 2020.11.04

 

Shellcode(쉘코드) 정의

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

- 아래에서 제작한 Shellcode는 쉘을 떨어뜨리기 위한 쉘코드이다

 

Shellcode(쉘코드) 제작 순서

  1. c언어로 구현

  2. gdb로 역 어셈블링하여 필요한 부분 찾기

  3. 시스템 콜에 필요한 필수 부분만으로 어셈블리어 구현

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

  5. null이 존재할 시 null값을 변환 처리하여 없앤다

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

 

1. c언어로 구현

 

vi를 사용하여 shellcode.c라는 파일로 쉘을 떨어뜨리기 위한 위 코드를 작성해준다                 #execve(const char *path, char*const argv[], char envp[]);
static 옵션을 꼭 사용하여 컴파일을 해준다

 

2. gdb로 역 어셈블링하여 필요한 부분 찾기

 

gdb를 이용하여 execve함수의 동작 내용을 확인하고 int 0x80 부분에 브레이크를 걸어준다

 

run으로 프로그램을 시작한뒤 명령어로 변수의 값들을 확인해준다

eax ebx ecx edx
execve(11번)
16진수 - 0b
/bin/sh 배열의 시작 주소
(/bin/sh의 주소)
0
함수 호출 번호 첫 번째 인자 자리  두 번째 인자 자리  세 번째 인자 자리

 

3. 시스템 콜에 필요한 필수 부분만으로 어셈블리어 구현

 

shellcode.asm 파일로 필수요소만 어셈블리어로 작성해준다

 

컴파일을하고 잘 실행이되나 한번 실행시켜 본다

 

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

 

objdump로 열어서 기계어 코드에 null 값이 있나 확인해준다

 

5. null이 존재할 시 null값을 변환 처리하여 없앤다

null 값 이후에 값들을 복사하지않아 정상적으로 동작하지 않는다는 문제점이 있기 때문에 null값을 다 지워준다

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

ex) 32bit : eax, 16bit : ax, 8bit : al 

- XOR ( 자기 자신을 XOR하여 0삽입)

ex) xor eax, eax 

 

위에서 작성 shellcode.asm 코드를 오른쪽과 같이 수정하고 다시 한번 컴파일해준다

 

컴파일 후 다시 objdump로 shellcode를 열어보면 null 값이 사라진걸 확인할 수 있다

 

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

추출 명령어

for i in $(objdump -d ./shellcode | grep "^ "|cut -f2);do echo -n \\x$i;done

 

명령어를 사용하여 objdump 안에서 기계어 코드만 \x를 붙여서 뽑아낸다

 

7. 6번에서 추출해낸 기계어 코드를 테스트해 본다

 

위에 code 배열 안에 추출한 기계어 코드를 넣어주고 test.c로 저장후 컴파일해준다

 

test 파일을 실행해보면 쉘코드가 잘 작동하는걸 확인할 수 있다

 

 

'시스템 해킹' 카테고리의 다른 글

ASCII Armor  (0) 2020.11.10
ASLR ( Address Space Layout Randomization )  (0) 2020.11.10
RTL ( Return to Libc )  (0) 2020.11.06
DEP (Data Execution Prevention)  (0) 2020.11.06
Stack Buffer Overflow (스택 버퍼 오버플로우)  (0) 2020.11.06

+ Recent posts