관리 메뉴

IT창고

System 쉘 코드 본문

보안/System

System 쉘 코드

방구석여포 2018. 2. 3. 01:39

쉘 코드(ShellCode)에 대해 알아보겠습니다.

쉘코드는 시스템의 특정 명령을 수행하는 크기가 작은 코드로 주로 기계어로 구성되어있습니다.


쉘코드를 만들어 타겟 프로세스 메모리에 실행하고자 하는 명령들을 올려놓고 실행할수있습니다.

조건이 있습니다.

1. 기계어로 작성되어 있어야만 합니다.


objdump -d옵션을 사용해서 해당 소스의 기계어를 확인해볼수있습니다.


2. 데이터 세그먼트는 사용할수 없습니다.

세그먼트를 사용하게 되면 push주소가 고정값이 되는데 타겟프로그램에 해당 문자가 있을 확률은 거의 없기 때문입니다.

call도 시스템함수가 있을 보장이 없기 때문에 주소를 없애서 코드를 작성해야만 합니다.


간단한 소스를 만들어보겠습니다.

C언어로 system("/bin/sh"); 인 쉘를 사용하는 코드입니다.


어셈블리어로 코드를 작성해야하는데 어셈블리어로 코드를 작성하는 이유는 직접 메모리를 제어할수있고 불필요한 세그먼트없이 코드를 작성할수있기 때문입니다. call명령어는 쓸수없으므로 시스템콜을 사용하여 호출하겠습니다. 시스템콜을 사용한다면 주소가 없이 다른 프로세스에서 사용이 가능합니다.



이번에는 data, bss 세그먼트를 없애고 쉘 코드를 작성해보았습니다. 기계어를 확인하면 00(NULL)이 많이 보이는데 00(NULL)은 우회기법도 없는 입력할수없는 숫자(Bad-character)입니다. push값을 0 대신에 레지스터로 받으면 해결할수있습니다!


이번에는 기계어에 00(NULL)값이 없고 주소를 사용하지않는 코드를 뽑아냈습니다. NULL byte가 제거된 모습을 확인할수있습니다.

이제 뽑아낸 코드로 타켓 프로세스에 적용할수있습니다.

이런 공격방법을 명령어 삽입공격이라 하며 임의의 코드를 실행하는 방법은 오버플로우밖에 없습니다. 만약 코드가 없다면 위와 같은 과정으로 코드를 만들어쓰면 됩니다.


NULL값을 제거한 코드를 사용하기 위해서는 문자열 이스케이프로 바꿔줘야만 합니다.

"\x31\xd2\x31\xc0\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x50\x8d\x5c\x24\x04\x53\xb0\x0b\x8b\x1c\x24\x89\xe1\xcd\x80"


이제 뽑아낸 코드를 문자열 이스케이프로 바꿔주었는데 이코드가 확실한지 검증을 해봐야합니다. 

C언어로 함수포인터를 이용해서 쉘코드를 검증해보겠습니다.



정상적으로 실행되는 모습을 확인할수있습니다. 이 코드가 확실한걸 알수있습니다.


쉘 코드를 작성했다면 타겟 프로그램의 메모리를 살펴봅니다. eip레지스터에 들어갈 자리를 확인합니다.

$(python -c 'print "\x31\xd2\x31\xc0\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x50\x8d\x5c\x24\x04\x53\xb0\x0b\x8b\x1c\x24\x89\xe1\xcd\x80" + "A"* 53 + "\xcb\xfa\xff\xbf" ')

디버거에서 확인한 프로세스의 메모리와 실제 메모리는 차이가 있습니다. 정확한 주소를 확인하는건 불가능하지만 옛날에 해커가 16바이트 단위로 주소를 위아래로 보정해보면서 정확한 주소를 찾아야만 합니다.

illegar instruction 에러가 나온다면 16byte단위로 찾아봅니다.

'보안 > System' 카테고리의 다른 글

System BufferOverFlow2 (윈도우XP)  (0) 2018.03.06
System RTL 공격기법  (0) 2018.02.18
System BufferOverFlow  (0) 2018.01.30
System 디버거(de-bugger)  (0) 2018.01.25
System main함수의 인자와 시스템콜  (0) 2018.01.23
Comments