보통 버전이 높은 리눅스에서는 일반적으로 배열에 쉘코드를 넣어서 실행하는게 제대로 되지 않는다.
일반적인 쉘코드 실행 검사 프로그램이다.
#include <stdio.h> #include <string.h> char shell[]="\x31\xc0\x31\xd2\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xb0\x0b\xcd\x80"; int main() { printf("shell len = %d\n",strlen(shell)); (*(void (*)()) shell)(); }
쉘코드는 맞지만 조금 높은 버전의 리눅스에서는 스택이나 힙에 실행권한이 없어져 프로그램이 실행이 되지 않는다.
그러나 mprotect라는걸로 실행 권한을 추가해 주면 해당 영역에서 코드 실행이 가능하다.
#include <stdio.h> #include <string.h> #include <unistd.h> #include <sys/mman.h> void allow_execution(const void *addr) { long pagesize = (int)sysconf(_SC_PAGESIZE); char *p = (char *)((long)addr & ~(pagesize - 1L)); mprotect(p,pagesize * 10L, PROT_READ|PROT_WRITE|PROT_EXEC); } char shell[]="\x31\xc0\x31\xd2\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xb0\x0b\xcd\x80"; int main() { allow_execution(shell); printf("shell len = %d\n",strlen(shell)); (*(void (*)()) shell)(); }
처럼 코딩해보면 mprotect라는걸로 해당 영역의 권한을 바꿔 버리기 때문에 쉘코드가 실행되는걸 확인할수 있다.
파이썬으로 제작
from ctypes import * libc = CDLL('libc.so.6') mprotect = libc.mprotect getpagesize = libc.getpagesize PROT_READ = 0x1 PROT_WRITE = 0x2 PROT_EXEC = 0x4 codes = (c_ubyte * 32)( 0x31,0xc0,0x31,0xd2,0x50,0x68,0x2f,0x2f,0x73,0x68,0x68,0x2f,0x62,0x69,0x6e,0x89,0xe3,0x52,0x53,0x89,0xe1,0xb0,0x0b,0xcd,0x80 ) p = addressof(codes) & ~(getpagesize() - 1) mprotect(p, getpagesize(), PROT_READ | PROT_WRITE | PROT_EXEC) add_func = CFUNCTYPE(c_int, c_int, c_int)(addressof(codes)) print "add(99, 1) = %d" % add_func(99, 1)
어떻게든 자료를 가져다가 되게끔 하긴 했지만 파이썬에서는 어떻게 돌아가는지 솔직히 잘 모르겠다. 연구가 필요하다....
'systemhacking > background' 카테고리의 다른 글
aslr, dep, ascii_armor (0) | 2015.02.15 |
---|---|
/proc/<pid>/maps 메모리 권한, 로드중인 라이브러리 확인 (0) | 2015.02.11 |
linux background 2 (binary hacks) (0) | 2015.02.08 |
linux background 1 (binary hacks) (0) | 2015.02.06 |
system 기본 용어들 (0) | 2015.02.04 |