본문 바로가기
Reversing/리버싱 핵심 원리

[리버싱 핵심 원리] 27장, Code 인젝션

by Y06 2021. 12. 2.

Code Injection

Code Injection이란 상대방 프로세스에 독립 실행 코드를 삽입한 후 실행하는 기법이다. 일반적으로 CreateRemoteThread() API를 이용하여 원격 스레드 형태로 실행하므로 Thread 인젝션이라고도 얘기한다. 

Code 인젝션

인젝션 대상이 되는 target.exe 프로세스에 코드와 데이터를 삽입한다. 이때 코드의 형식은 스레드 프로시저(Thread Procedure) 형식으로 해주고, 코드에서 사용되는 데이터는 스레드의 파라미터로 전달한다. 즉 코드와 데이터를 각각 인젝션해주는 것이다. 이와 같이 개념은 간단하지만 구현에 있어서 주의해야 할 내용이 있다. Code 인젝션 구현의 주의사항에 대하서는 DLL 인젝션과 비교하여 설명할 수 있다.

 

DLL 인젝션 vs Code 인젝션

DWORD WINAPI ThreadProc(LPVOID lParam)
{
            MessageBoxA(NULL, "www.reversecore.com", "ReverseCore", MB_OK);
            
            return 0;
}

위의 코드의 내용은 Window 메시지 박스를 출력하는 것이다. DLL 인젝션 기법이라면 위 코드를 DLL 파일 형태로 만든 후 다른 프로세스에 인젝션하면 된다.

DLL의 코드에서 사용되는 모든 데이터는 DLL의 데이터영역에 위치한다. 따라서 DLL 인젝션 기법으로 DLL을 통째로 상대방 프로세스 메모리에 삽입시키면, 코드와 데이터가 같이 메모리에 존재하기 때문에 코드는 정상적으로 실행될 수 있다. Code 인젝션은 필요한 코드를 인젝션하는 것이다. 하지만 코드에서 사용되는 데이터도 같이 인젝션해야 정상적으로 코드의 실행이 가능해진다. 이러한 이유 때문에 DLL 인젝션 기법보다 고려할 사항이 좀 더 많다.

 

코드 인젝션을 사용하는 이유

코드 인젝션은 DLL 인젝션과 비교하여 기능은 비슷하면서 고려해야 할 사항은 더 많기 때문에 사용하기 불편하게 느껴질 수 있다.

 

[코드 인젝션 장점]

 

1) 메모리를 조금만 차지한다.

아주 작은 크기의 코드와 데이터를 인젝션할 때는 DLL로 만들어서 인젝션할 필요가 없다. 간단히 Code 인젝션으로 구현하면 DLL 인젝션과 같은 기능을 제공하면서 메모리를 훨씬 덜 차지한다.

 

2) 흔적을 찾기 어렵다.

DLL 인젝션은 해당 프로세스 메모리에 흔적을 남기기 때문에 간단히 인젝션 여부를 알 수 있다. 하지만 Code 인젝션은 쉽게 흔적을 남기지 않는다.

 

3) 기타

별도의 DLL 파일 없이 'Code Injection 프로그램'만 있으면 된다. 또한 처음에는 생소하지만 일단 익숙해지며 아주 쉽고 편리하게 구현할 수 있다. 간단히 정리하면 DLL 인젝션은 규모가 크고 복잡한 일을 수행할 때 사용하고, Code 인젝션은 규모가 작고 간단한 일을 수행할 때 사용한다.

 

실습 예제

Code Injection의 코드

dwSize = (DWORD)abs((int)dwSize);를 넣어준다.

notepad.exe의 PID 확인

notepad.exe를 실행한 후 Process Explorer를 이용하여 notepad.exe 프로세스의 PID를 확인한다.

노란색으로 밑줄 친 부분이 제 테스트 환경에서의 notepad.exe의 PID 입니다.

첨부된 CodeInjection.exe 파일을 실행시킨다. 이때 실행 파라미터로 앞에서 구한 notepad.exe의 PID 값을 입력한다. 실행을 하게 되면 위와 같이 메시지창이 뜨게 된다.

만약 The token does not have the specified privilege라는 문구가 나타나면 위에 주석처리된 부분을 똑같이 주석처리 해주면 된다. 관리자 권한으로 실행하면 되지만 이런 방식을 이용하여 우회할 수도 있다.