SlideShare uma empresa Scribd logo
1 de 56
REVERSING[6] Reverse Engineering
목차
• Code injection //리버싱 핵심 원리 3부 + 2부
• 원격 쓰레드를 이용
• 고급 언어로 프로그래밍 //27장
• 어셈블리어를 이용 //28장
• 인라인 패치 //20장
• 부록
• 참고 사이트
CODE INJECTION • 원격 쓰레드 이용
• 인라인 패치
코드 인젠션이란?
• 실행중인 대상 프로세스에 코드를 삽입한 후 실행하는 기법
• 일반적으로 CreateRemoteThread API를 이용하기 때문에Thread 인젝션이라고도 함
• 코드는 쓰레드 프로시저(쓰레드를 만들 때 인자로 넣는 함수, 쓰레드 메인)으로 넣고, 인자는 쓰
레드의 파라미터로 전달한다.
• 코드와 데이터를 각각 인젝션 해주는 것
<injector> <대상
프로그램>
필요한 문자열
함수 포인터
내가 만든 코드
이용
inject!
DLL INJECTION VS CODE INJECTION
• DLL injection은 DLL 자체를 프로세스에 올린다.
• DLL의 코드에서 사용하는 모든 데이터는 DLL의 데이터 영역에 있다.
• Ex) 문자열 등...
• -> 따로 데이터를 injection할 필요가 없다.
• Code injection은 코드 뿐만 아니라 코드에서 이용하는 데이터도 같이 인젝션 해 주어야 한다.
• 코드 인젝션을 사용하는 이유
• 메모리를 조금만 차지한다.
• DLL 인젝션보다 작은 공간을 차지한다.
• 흔적을 찾기 어렵다
• DLL 인젝션은 해당 프로세스 메모리에 흔적을 남기기 때문에 간단히 인젝션 여부를 알 수 있다.
• 코드 인젝션은 쉽게 흔적을 남기지 않는다. (알아내는 방법이 있긴 하다)
• 기타
• 코드 인젝션은 DLL 파일이 필요하지 않다. 인젝션하는 프로그램만 필요하다(injector)
• DLL injecton은 규모가 크고 복잡한 일을 수행할 때, Code injection은 규모가 작고 간단한 일을 수행할 때 사용한다.
CODE INJECTION – 원격 쓰레드를 이용 – 고급 언어로 프로그래
밍
• 쓰레드 인자로 넣을 구조체의 형식이다.
• 이 구조체 모양대로 내용을 써서 대상 프로그
램의 메모리에 써 둘 것이다.
• 쓰레드를 만들 때, 이 구조체를 저장해 둔 대상
프로그램의 가상메모리 주소를 인자로 준다.
• 대상 프로그램은 자신의 가상 메모리에 저장된 데이터를
이용하여 일을 할 수 있다.
• 함수 포인터를 이용하기 쉽도록 재정의하는 코드
이다.
CODE INJECTION – 원격 쓰레드를 이용 – 고급 언어로 프로그래
밍
• 위에 있는 두 줄은 함수 선언이다.
• 아래는 메인 함수이다.
• 인자로 PID를 입력 받는다.
CODE INJECTION – 원격 쓰레드를 이용 – 고급 언어로 프로그래
밍
• 인젝션할 코드이다.
• 인자로 받은 주소를 캐스팅한다.
• 미리 저장해 둔 함수 포인터(LoadLibraryA와 GetProcAddress)
와 문자열(user32.dll, MessageBoxA) 이용하여
user32.dll(MessageBoxA API가 저장된 DLL)을 열고,
MessageBoxA 함수 주소를 얻는다.
• 미리 저장해 둔 문자열을 이용하여 MessageBoxA함수에 인
자를 넣고 함수를 호출한다.
• kernel32.dll은 대부분의 프로그램이 이용하고, kenel32.dll과
같은 시스템 라이브러리는 모든 프로세스가 같은 가상메모
리에 매핑하기 때문에 injector에서 주소를 구해 넣어도 괜찮
았다.
• kernel32.dll을 이용하지 않는 dll도 있으니 code injection하기 전에
확인해야 한다.
CODE INJECTION – 원격 쓰레드를 이용 – 고급 언어로 프로그래
밍
• 본격적으로 코드를 인젝션하는 함수이다.
• 일단 대상 프로세스에 넣을 구조체(쓰레드 인자로 이용될)
에 내용을 적는다.
• 아래 구조체 모양을 참고해 보자.
• pFunc은 함수 포인터(주소)가 들어갈 공간이다.
• LoadLibraryA함수와 GetProcAddress함수의 주소를 구
해 넣었다.
• 이들은 MessageBoxA를 호출하기 위해서 구한 것이
다.
• szBuf는 문자열들이 들어갈 공간이다.
• 이들은 LoadLibraryA의 인자로 줄 DLL 이름과
GetProcAddress의 인자로 줄 함수 이름, 그리고
MessageBoxA를 호출할 때 인자로 줄 문자열들의 이
름이다.
• 다른 API를 이용하고 싶다면 그 API가 속한 DLL과 함수
CODE INJECTION – 원격 쓰레드를 이용 – 고급 언어로 프로그래
밍
• 프로세스를 열고 방금 내용을 채워 넣은 구조체를 그대로 써 준
다.
CODE INJECTION – 원격 쓰레드를 이용 – 고급 언어로 프로그래
밍
• 그 다음 인젝션할 코드(함수)의 크기를 구하고, 그 크기만큼 메모
리를 확보하여 내용을 쓴다.
• 인젝션할 코드는 이 함수 바로 다음에 올 것이다.
CODE INJECTION – 원격 쓰레드를 이용 – 고급 언어로 프로그래
밍
• 방금 넣은 코드의 주소는 pRemoteBuf[1]이고, 저장한 구조체의 주소는 pRemoteBuf[0]이
다.
• 이들을 인자로 넣어 CreateRemoteThread함수를 호출한다.
CODE INJECTION – 원격 쓰레드를 이용 – 고급 언어로 프로그래
밍
•주의!
• 컴파일은 반드시 Release mode로 한다.
• Debug모드로 하면 추가적으로 생성되
는 코드가 있다.(추가적으로 불리는 함
수가 있다)
• 따라서 Debug모드로 컴파일한 코드
를 인젝션하면 대상 프로그램에는 없
는 함수를 호출하기 때문에 에러가 나
고, 프로그램이 종료된다.
CODE INJECTION – 원격 쓰레드를 이용 – 고급 언어로 프로그래
밍
CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이
용
• 어셈블리어를 이용하여 인젝션할 코드를
생성하면 조금 더 자유로운 형태로 이용
가능하다.
• 문자열(데이터)과 코드를 함께 넣을 수 있다.
• 올리디버거로 간편하게 만들 수 있다.
• 아무 EXE나 열고 빈 칸에 옆과 같은 내용을 쓰자
• 단, call 주소는 상황에 맞게 쓴다.
• 또는 인라인 어셈블리를 이용해도 됨
CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이
용
• 함수 프롤로그
CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이
용
• 인자로 받은 struct 주소를 가져온다.
• 이번에는 struct에 함수 주소(LoadLibraryA와
GetProcAddress)만 넣었다.
• 이 주소를 하드코딩 하지 않는 이유는
ASLR이라는 기법 때문이다.
• ASLR : Address Space Layout
Randomization.
• 시스템 DLL은 모든 프로그램이 같은
주소의 가상메모리에 올라온다. 하지만
재부팅하면 그 ‘같은 주소’가 될 주소가
바뀐다. 따라서 함수 주소는 매번 구해서
넣는다.
• ESI에는 LoadLibraryA, ESI+4에는
CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이
용
• LoadLibraryA함수를 호출하는 코드이다.
• 사용할 dll 문자열은 user32.dll이다.
CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이
용
• user32.dll 문자열을 스택에 저장한다.
• 리틀 엔디안으로
• 문자열 뒷부분부터 거꾸로
• 맨 마지막에 push esp를 해서 문자열의 맨
처음 부분이 저장된 주소를 스택에
넣는다.
CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이
용
• 순서와 리틀 엔디안에 주의한다.
• 문자열 맨 끝에 null (0)이 들어가는 것에
주의한다.
CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이
용
• ESI(인자로 받은 주소)에 저장된 구조체의 첫
번째 멤버인 LoadLibraryA 함수 주소를
이용하여 함수를 호출한다.
CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이
용
• GetProcAddress함수를 호출하는 코드이다.
• 사용할 함수 이름 문자열은 MessageBoxA이다.
• GetProcAddress함수는 WINAPI 함수 호출
규약을 이용한다.
• WINAPI 함수 규약은 stdcall 함수 호출
규약이다.
• -> 함수 인자를 역순으로 push한다
CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이
용
• 조금 전과 같은 방법으로, MessageBoxA
문자열을 스택에 저장하고, 주소를 넘긴다.
CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이
용
• LoadLibraryA함수의 반환 값인 user32.dll의
핸들을 push한다.
CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이
용
• ESI+4에 저장된, 구조체의 두 번째 값인
GetProcAddress함수를 호출한다.
CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이
용
• 이제 MessageBoxA를 호출할 것이다.
• 문자열은 2, 3번째 인자이다.
• 단순한 push방법을 이용하기엔 골치
아프다.
• push방법 말고 다른 방법을 이용해본다.
CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이
용
• 먼저 uType에 해당하는 인자를 push한다.
CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이
용
• 만드는 중에는 일단 call 00400000(뒤에 아무
숫자, 짧지 않은 길이의)를 입력해 둔다.
• call을 하면 함수 call 바로 아래 주소(다음에
실행할 코드 주소)를 스택에 push한 뒤
점프한다.
• 사실 여기서 사용하는 주소는 상대
주소이다.
• 기계어에는 자신으로부터 얼마나 떨어진
곳으로 점프하라 라는 정보가 있다.
• 올리 디버거가 알아서 상대 주소로 계산해서
기계어를 만들어 준다.
• 어셈블리어로는 그냥 주소를 써 줘도
된다.
CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이
용
• 상대 주소
계산법
JMP 100
EIP : 50
(EIP는 다음에 실행할 코드 주소를
가리킨다.)
100
<어셈블리어
표현>
E9 B0 00 00 00
EIP : 50
(EIP는 다음에 실행할 코드 주소를
가리킨다.)
100
<기계어 표현>
시작주소 45 시작주소 45
• 00000050 + 000000Bo = 100
• 리틀엔디안으로 B0000000
• 주의 : 작은 바이트를 이용하는
short jmp라는 명령어도 있다.
일단은 그냥 점프를 이용하기
위해 4바이트의 주소를 넣자.
CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이
용
• 상대 주소
계산법
EIP : 105
(EIP는 다음에 실행할 코드 주소를
가리킨다.)
JMP 45
<어셈블리어
표현>
<기계어 표현>
시작주소 100, 코드 크기 5바이트
시작주소 45
EIP : 105
(EIP는 다음에 실행할 코드 주소를
가리킨다.)
E9 40 FF FF FF
시작주소 100, 코드 크기 5바이트
시작주소 45
• 105 – c0 = 45
• -c0 = 4바이트로 FFFFFF40
• 00000105 + FFFFFF40 = 45
• 리틀 엔디안으로 40FFFFFF
CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이
용
• 수정하려는 줄을 클릭한 후 오른쪽키-binary-
edit으로 출력하고자 하는 문자열을 입력한다.
• 뒤에서 두 번째 인자인 메시지 박스 제목을
입력한다.
CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이
용
• 맨 끝 null을 입력하는 것을 잊지 말자
CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이
용
• 위의 call 목적지가 문자열 바로 다음을
가리키도록 수정한다.
CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이
용
• 똑같은 방식으로, 인쇄하고자 하는 문자열을
넣는다.
CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이
용
• hWnd 인자로 0을 넣는다.
CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이
용
• MessageBoxA함수를 호출한다.
CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이
용
• 함수 에필로그이다.
CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이
용
• 파일을 저장하고 헥사 에디터로 연다.
• 기계어를 얻기 위함이다.
CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이
용
• 기계어를 복사해서 배열에 넣을 형태로 수정한다.
• 메모장으로 노가다하든 에디터를 쓰든...
• NotePad++같이 매크로를 이용할 수 있는 프로그램을 추천함
• 이것이 쉘코드 제작의 기본이다.
CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이
용
• 이번 구조체에는 함수 주소만을 넣는다.
• ThreadProc함수 대신 쉘코드를 넣는다.
CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이
용
• 메인 함수이다.
CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이
용
• 쓰레드 인자로 줄 구조체를 넣는
것은 똑같다.
• 문자열은 더이상 넣지
않는다.
CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이
용
• 함수 주소를 이용하여 사이즈를 구하던 것과는 달리, 단순히 쉘코드 배열의 사이즈를 구해 넣는다.
• 쉘코드를 프로세스에 쓰고 쓰레드를 생성한다.
CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이
용
• 성공!
CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이
용
• 쉘코드를 0xFF 식의 char 배열로 만들기보다는
위와 같이 스트링으로 쓰는게 더 정석적이다.
• 코드상에서 char 배열 초기화를 제외한
부분은 달라진 것이 없다.
• 취향 따라 쓴다..
TIP
• jmp를 다른 방식으로 표현한다면?
• jmp 401000를 아래와 같이 표현할 수 있다.
• push 401000
• ret
• Call을 다른 방식으로 표현한다면?
• push 다음 주소
• jmp 함수 주소
• 이렇게 같은 코드를 다른 방식으로 쓸 수도 있다.
인라인 패치
• 인라인 코드 패치, 인라인 패치
• 원하는 코드를 직접 수정하기 어려울 때 코드 케이브(Code cave)라고 하는 패치 코드를 삽입한 후 실행해 프
로그램을 패치시키는 기법
• 패킹 혹은 암호화 때문에 파일을 직접 수정하기 어려운 경우 많이 사용되는 기법
• 혹은 수정한 코드가 아래 코드를 침범하여 끼워 넣기 애매한 경우에도 이용할 수 있다.
• 매번 프로세스 메모리의 코드를 패치하기 때문에 인라인 코드 패치라고 부른다.
• 파일 자체에서 코드를 수정하는 것이 아니라 파일을 실행한 후 수정하는 것
• 복호화가 끝난 후 가는 OEP를 조작하여 끼워 넣은 코드로 이동하게 한다. 끼워 넣은 코드는 복호화 된 기존 코드에서 수정하고 싶은 부분을 수
정한다.
• 파일 수정을 이용한 Code injection, 그리고 이를 이용한 기존 코드 패치 방법이다.
인라인 패치
인라인 패치
일반적인 코드 패치 인라인 패치
대상 파일 파일 & 메모리
횟수 1번 파일에는 1번만
메모리는 실행될 때마다
방법 Direct
(원하는 위치에 직접 패치)
Indirect
(코드 케이브를 미리 설치한 후
메모리에서 원하는 영역이 복
호화 되었을 때 패치)
인라인 패치
• 패치할 프로그램이다.
• result가 3이 아닌 값을 출력하도록 해보자.
• 패치의 효과를 체험할 수 있도록 UPX 패킹을
적용하자.
인라인 패치
• UPX의 디코딩 루틴을 지나 OEP로 점프하는 코드를 찾았다.
• 이 주소는 앞으로 임의로 넣은 코드의 주소로 바꿀 것
• 임의로 넣은 코드는 디코딩 되어 메모리에 올라온 코드를 수정(패치)하는 일
을 한다.
인라인 패치
• 메인문이다.
• printf를 호출하기 전을 수정하고자 한다.
• 끼워 넣을 코드는 맨 밑 코드영역의 null padding 자리에 넣을 것이다.
• 드래그한 코드는 jmp 코드로 수정할 것이다.
• 정상 작동하기 위해서는 이 코드도 필요하므로 복사해 둔다
• 임의의 코드를 실행하면 드래그한 코드가 jmp 406AA0로 수정될 것(406AA0에는 printf 결과를 조작하기 위한 코드를 끼워
넣을 것)
인라인 패치
• 디코딩 루틴 이후 OEP로 점프하는 코드를 아래 추가한 코드로 점프하도록 변경
• 이 점프로 인해 실행되는 코드 : 기존 main 함수의 printf 전 코드를 jmp 코드로 변경하는 코드
• 바뀐 코드로 인해 아래쪽에 추가한 코드가 실행된다.
• jmp코드로 수정하기 위해 지워진 코드를 넣어 정상적으로 작동하도록 한다.
• 추가 하고싶은 코드를 넣어 임의로 변경한다 (이 경우, printf 인자를 조작하는 일)
• 다시 기존 코드로 점프하여 실행을 이어간다.
인라인 패치
• 성공!
• OEP를 수정할 때, 그 점프하는 코드마저 패킹이나 암호화가 적용
되어 있다면, 그 알고리즘을 알아내야 한다.
• 그래야 패킹/암호화를 풀었을 때 제대로 점프할 수 있다.
• 일부러 약간 돌아서 코드를 실행하게 했다.
• 여건이 된다면 다시 아래로 jmp하지 않고 바로 코드만 수정해도Ok.
부록 • 참고 사이트
참고 사이트
• JMP 상대주소
• https://ko.wikipedia.org/wiki/JMP_(x86_%EB%AA%85%EB%A0%B9%EC%96%B4)
• http://jyj850714.tistory.com/337
• 인라인 패치
• https://asecurity.so/2017/01/hooking-%ED%9B%84%ED%82%B9-code-path-inline-patch-%EC%BD%94%EB%93%9C-
%ED%8C%A8%EC%B9%98-%EC%9D%B8%EB%9D%BC%EC%9D%B8-%ED%8C%A8%EC%B9%98/

Mais conteúdo relacionado

Mais procurados

Pwnable study basic_3
Pwnable study basic_3Pwnable study basic_3
Pwnable study basic_3Jinkyoung Kim
 
Windows reversing study_basic_1
Windows reversing study_basic_1Windows reversing study_basic_1
Windows reversing study_basic_1Jinkyoung Kim
 
Windows reversing study_basic_5
Windows reversing study_basic_5Windows reversing study_basic_5
Windows reversing study_basic_5Jinkyoung Kim
 
Pwnable study basic_1
Pwnable study basic_1Pwnable study basic_1
Pwnable study basic_1Jinkyoung Kim
 
Windows reversing study_basic_6
Windows reversing study_basic_6Windows reversing study_basic_6
Windows reversing study_basic_6Jinkyoung Kim
 
Windows reversing study_basic_4
Windows reversing study_basic_4Windows reversing study_basic_4
Windows reversing study_basic_4Jinkyoung Kim
 
Linux reversing study_basic_3
Linux reversing study_basic_3Linux reversing study_basic_3
Linux reversing study_basic_3Jinkyoung Kim
 
Assembly 스터디 2
Assembly 스터디 2Assembly 스터디 2
Assembly 스터디 2Jinkyoung Kim
 
Windows reversing study_basic_2
Windows reversing study_basic_2Windows reversing study_basic_2
Windows reversing study_basic_2Jinkyoung Kim
 
Pwnable study basic_2
Pwnable study basic_2Pwnable study basic_2
Pwnable study basic_2Jinkyoung Kim
 
Linux reversing study_basic_2
Linux reversing study_basic_2Linux reversing study_basic_2
Linux reversing study_basic_2Jinkyoung Kim
 
Web hacking introduction
Web hacking introductionWeb hacking introduction
Web hacking introductionJinkyoung Kim
 
Linux reversing study_basic_1
Linux reversing study_basic_1Linux reversing study_basic_1
Linux reversing study_basic_1Jinkyoung Kim
 
[Kerference] 시작! 리버싱 - 김종범(KERT)
[Kerference] 시작! 리버싱 - 김종범(KERT)[Kerference] 시작! 리버싱 - 김종범(KERT)
[Kerference] 시작! 리버싱 - 김종범(KERT)NAVER D2
 
2016317 파이썬기초_파이썬_다중설치부터_Jupyter를이용한프로그래밍_이태영
2016317 파이썬기초_파이썬_다중설치부터_Jupyter를이용한프로그래밍_이태영2016317 파이썬기초_파이썬_다중설치부터_Jupyter를이용한프로그래밍_이태영
2016317 파이썬기초_파이썬_다중설치부터_Jupyter를이용한프로그래밍_이태영Tae Young Lee
 
잘 알려지지 않은 숨은 진주, Winsock API - WSAPoll, Fast Loopback
잘 알려지지 않은 숨은 진주, Winsock API - WSAPoll, Fast Loopback잘 알려지지 않은 숨은 진주, Winsock API - WSAPoll, Fast Loopback
잘 알려지지 않은 숨은 진주, Winsock API - WSAPoll, Fast Loopback흥배 최
 

Mais procurados (20)

Pwnable study basic_3
Pwnable study basic_3Pwnable study basic_3
Pwnable study basic_3
 
Windows reversing study_basic_1
Windows reversing study_basic_1Windows reversing study_basic_1
Windows reversing study_basic_1
 
Windows reversing study_basic_5
Windows reversing study_basic_5Windows reversing study_basic_5
Windows reversing study_basic_5
 
Pwnable study basic_1
Pwnable study basic_1Pwnable study basic_1
Pwnable study basic_1
 
Windows reversing study_basic_6
Windows reversing study_basic_6Windows reversing study_basic_6
Windows reversing study_basic_6
 
Windows reversing study_basic_4
Windows reversing study_basic_4Windows reversing study_basic_4
Windows reversing study_basic_4
 
System+os study 3
System+os study 3System+os study 3
System+os study 3
 
Linux reversing study_basic_3
Linux reversing study_basic_3Linux reversing study_basic_3
Linux reversing study_basic_3
 
Python
PythonPython
Python
 
Assembly 스터디 2
Assembly 스터디 2Assembly 스터디 2
Assembly 스터디 2
 
Windows reversing study_basic_2
Windows reversing study_basic_2Windows reversing study_basic_2
Windows reversing study_basic_2
 
Pwnable study basic_2
Pwnable study basic_2Pwnable study basic_2
Pwnable study basic_2
 
System+os study 5
System+os study 5System+os study 5
System+os study 5
 
Linux reversing study_basic_2
Linux reversing study_basic_2Linux reversing study_basic_2
Linux reversing study_basic_2
 
Web hacking introduction
Web hacking introductionWeb hacking introduction
Web hacking introduction
 
Linux reversing study_basic_1
Linux reversing study_basic_1Linux reversing study_basic_1
Linux reversing study_basic_1
 
[Kerference] 시작! 리버싱 - 김종범(KERT)
[Kerference] 시작! 리버싱 - 김종범(KERT)[Kerference] 시작! 리버싱 - 김종범(KERT)
[Kerference] 시작! 리버싱 - 김종범(KERT)
 
System+os study 6
System+os study 6System+os study 6
System+os study 6
 
2016317 파이썬기초_파이썬_다중설치부터_Jupyter를이용한프로그래밍_이태영
2016317 파이썬기초_파이썬_다중설치부터_Jupyter를이용한프로그래밍_이태영2016317 파이썬기초_파이썬_다중설치부터_Jupyter를이용한프로그래밍_이태영
2016317 파이썬기초_파이썬_다중설치부터_Jupyter를이용한프로그래밍_이태영
 
잘 알려지지 않은 숨은 진주, Winsock API - WSAPoll, Fast Loopback
잘 알려지지 않은 숨은 진주, Winsock API - WSAPoll, Fast Loopback잘 알려지지 않은 숨은 진주, Winsock API - WSAPoll, Fast Loopback
잘 알려지지 않은 숨은 진주, Winsock API - WSAPoll, Fast Loopback
 

Semelhante a Windows reversing study_basic_7

당신의 디버깅에 니코니코니
당신의 디버깅에 니코니코니당신의 디버깅에 니코니코니
당신의 디버깅에 니코니코니Lusain Kim
 
해커가 되고 싶은 자는 나에게... 정보보안 입문과 길 찾기
해커가 되고 싶은 자는 나에게... 정보보안 입문과 길 찾기해커가 되고 싶은 자는 나에게... 정보보안 입문과 길 찾기
해커가 되고 싶은 자는 나에게... 정보보안 입문과 길 찾기Jinkyoung Kim
 
ant로 안드로이드 앱을 자동으로 빌드하자
ant로 안드로이드 앱을 자동으로 빌드하자ant로 안드로이드 앱을 자동으로 빌드하자
ant로 안드로이드 앱을 자동으로 빌드하자Sewon Ann
 
병렬 프로그래밍
병렬 프로그래밍병렬 프로그래밍
병렬 프로그래밍준혁 이
 
2006 03 15_pe & api hook
2006 03 15_pe & api hook2006 03 15_pe & api hook
2006 03 15_pe & api hook용환 노
 
I os push: 세상에서 가장 간단한 날씨, 대기환경 엡
I os push:  세상에서 가장 간단한  날씨, 대기환경 엡I os push:  세상에서 가장 간단한  날씨, 대기환경 엡
I os push: 세상에서 가장 간단한 날씨, 대기환경 엡HannaSungKim
 
[2007 CodeEngn Conference 01] 김기오 - NASM 어셈블러 사용법과 Calling Convention
[2007 CodeEngn Conference 01] 김기오 - NASM 어셈블러 사용법과 Calling Convention[2007 CodeEngn Conference 01] 김기오 - NASM 어셈블러 사용법과 Calling Convention
[2007 CodeEngn Conference 01] 김기오 - NASM 어셈블러 사용법과 Calling ConventionGangSeok Lee
 
Go로 새 프로젝트 시작하기
Go로 새 프로젝트 시작하기Go로 새 프로젝트 시작하기
Go로 새 프로젝트 시작하기Joonsung Lee
 
가상화된 코드를 분석해보자
가상화된 코드를 분석해보자가상화된 코드를 분석해보자
가상화된 코드를 분석해보자dkswognsdi
 
6. code level reversing
6. code level reversing6. code level reversing
6. code level reversingYoungjun Chang
 
[16]Obfuscation 101 : 난독화, 프로가드, R8, 트랜스포머 API
[16]Obfuscation 101 : 난독화, 프로가드, R8, 트랜스포머 API[16]Obfuscation 101 : 난독화, 프로가드, R8, 트랜스포머 API
[16]Obfuscation 101 : 난독화, 프로가드, R8, 트랜스포머 APINAVER Engineering
 
카사 공개세미나1회 W.E.L.C.
카사 공개세미나1회  W.E.L.C.카사 공개세미나1회  W.E.L.C.
카사 공개세미나1회 W.E.L.C.Ryan Park
 
아이폰에 포팅해보기
아이폰에 포팅해보기아이폰에 포팅해보기
아이폰에 포팅해보기changehee lee
 
20150306 파이썬기초 IPython을이용한프로그래밍_이태영
20150306 파이썬기초 IPython을이용한프로그래밍_이태영20150306 파이썬기초 IPython을이용한프로그래밍_이태영
20150306 파이썬기초 IPython을이용한프로그래밍_이태영Tae Young Lee
 
C#을 사용한 빠른 툴 개발
C#을 사용한 빠른 툴 개발C#을 사용한 빠른 툴 개발
C#을 사용한 빠른 툴 개발흥배 최
 
[NDC2015] 언제 어디서나 프로파일링 가능한 코드네임 JYP 작성기 - 라이브 게임 배포 후에도 프로파일링 하기
[NDC2015] 언제 어디서나 프로파일링 가능한 코드네임 JYP 작성기 - 라이브 게임 배포 후에도 프로파일링 하기[NDC2015] 언제 어디서나 프로파일링 가능한 코드네임 JYP 작성기 - 라이브 게임 배포 후에도 프로파일링 하기
[NDC2015] 언제 어디서나 프로파일링 가능한 코드네임 JYP 작성기 - 라이브 게임 배포 후에도 프로파일링 하기Jaeseung Ha
 
ASP.NET MVC Framework 개발자를 위한 Razor Syntax.pdf
ASP.NET MVC Framework 개발자를 위한 Razor Syntax.pdfASP.NET MVC Framework 개발자를 위한 Razor Syntax.pdf
ASP.NET MVC Framework 개발자를 위한 Razor Syntax.pdfSangHoon Han
 
ModelSim 기초 매뉴얼
ModelSim 기초 매뉴얼ModelSim 기초 매뉴얼
ModelSim 기초 매뉴얼Jihyun Lee
 
2013 C++ Study For Students #1
2013 C++ Study For Students #12013 C++ Study For Students #1
2013 C++ Study For Students #1Chris Ohk
 

Semelhante a Windows reversing study_basic_7 (20)

당신의 디버깅에 니코니코니
당신의 디버깅에 니코니코니당신의 디버깅에 니코니코니
당신의 디버깅에 니코니코니
 
해커가 되고 싶은 자는 나에게... 정보보안 입문과 길 찾기
해커가 되고 싶은 자는 나에게... 정보보안 입문과 길 찾기해커가 되고 싶은 자는 나에게... 정보보안 입문과 길 찾기
해커가 되고 싶은 자는 나에게... 정보보안 입문과 길 찾기
 
ant로 안드로이드 앱을 자동으로 빌드하자
ant로 안드로이드 앱을 자동으로 빌드하자ant로 안드로이드 앱을 자동으로 빌드하자
ant로 안드로이드 앱을 자동으로 빌드하자
 
병렬 프로그래밍
병렬 프로그래밍병렬 프로그래밍
병렬 프로그래밍
 
Ch09
Ch09Ch09
Ch09
 
2006 03 15_pe & api hook
2006 03 15_pe & api hook2006 03 15_pe & api hook
2006 03 15_pe & api hook
 
I os push: 세상에서 가장 간단한 날씨, 대기환경 엡
I os push:  세상에서 가장 간단한  날씨, 대기환경 엡I os push:  세상에서 가장 간단한  날씨, 대기환경 엡
I os push: 세상에서 가장 간단한 날씨, 대기환경 엡
 
[2007 CodeEngn Conference 01] 김기오 - NASM 어셈블러 사용법과 Calling Convention
[2007 CodeEngn Conference 01] 김기오 - NASM 어셈블러 사용법과 Calling Convention[2007 CodeEngn Conference 01] 김기오 - NASM 어셈블러 사용법과 Calling Convention
[2007 CodeEngn Conference 01] 김기오 - NASM 어셈블러 사용법과 Calling Convention
 
Go로 새 프로젝트 시작하기
Go로 새 프로젝트 시작하기Go로 새 프로젝트 시작하기
Go로 새 프로젝트 시작하기
 
가상화된 코드를 분석해보자
가상화된 코드를 분석해보자가상화된 코드를 분석해보자
가상화된 코드를 분석해보자
 
6. code level reversing
6. code level reversing6. code level reversing
6. code level reversing
 
[16]Obfuscation 101 : 난독화, 프로가드, R8, 트랜스포머 API
[16]Obfuscation 101 : 난독화, 프로가드, R8, 트랜스포머 API[16]Obfuscation 101 : 난독화, 프로가드, R8, 트랜스포머 API
[16]Obfuscation 101 : 난독화, 프로가드, R8, 트랜스포머 API
 
카사 공개세미나1회 W.E.L.C.
카사 공개세미나1회  W.E.L.C.카사 공개세미나1회  W.E.L.C.
카사 공개세미나1회 W.E.L.C.
 
아이폰에 포팅해보기
아이폰에 포팅해보기아이폰에 포팅해보기
아이폰에 포팅해보기
 
20150306 파이썬기초 IPython을이용한프로그래밍_이태영
20150306 파이썬기초 IPython을이용한프로그래밍_이태영20150306 파이썬기초 IPython을이용한프로그래밍_이태영
20150306 파이썬기초 IPython을이용한프로그래밍_이태영
 
C#을 사용한 빠른 툴 개발
C#을 사용한 빠른 툴 개발C#을 사용한 빠른 툴 개발
C#을 사용한 빠른 툴 개발
 
[NDC2015] 언제 어디서나 프로파일링 가능한 코드네임 JYP 작성기 - 라이브 게임 배포 후에도 프로파일링 하기
[NDC2015] 언제 어디서나 프로파일링 가능한 코드네임 JYP 작성기 - 라이브 게임 배포 후에도 프로파일링 하기[NDC2015] 언제 어디서나 프로파일링 가능한 코드네임 JYP 작성기 - 라이브 게임 배포 후에도 프로파일링 하기
[NDC2015] 언제 어디서나 프로파일링 가능한 코드네임 JYP 작성기 - 라이브 게임 배포 후에도 프로파일링 하기
 
ASP.NET MVC Framework 개발자를 위한 Razor Syntax.pdf
ASP.NET MVC Framework 개발자를 위한 Razor Syntax.pdfASP.NET MVC Framework 개발자를 위한 Razor Syntax.pdf
ASP.NET MVC Framework 개발자를 위한 Razor Syntax.pdf
 
ModelSim 기초 매뉴얼
ModelSim 기초 매뉴얼ModelSim 기초 매뉴얼
ModelSim 기초 매뉴얼
 
2013 C++ Study For Students #1
2013 C++ Study For Students #12013 C++ Study For Students #1
2013 C++ Study For Students #1
 

Windows reversing study_basic_7

  • 2. 목차 • Code injection //리버싱 핵심 원리 3부 + 2부 • 원격 쓰레드를 이용 • 고급 언어로 프로그래밍 //27장 • 어셈블리어를 이용 //28장 • 인라인 패치 //20장 • 부록 • 참고 사이트
  • 3. CODE INJECTION • 원격 쓰레드 이용 • 인라인 패치
  • 4. 코드 인젠션이란? • 실행중인 대상 프로세스에 코드를 삽입한 후 실행하는 기법 • 일반적으로 CreateRemoteThread API를 이용하기 때문에Thread 인젝션이라고도 함 • 코드는 쓰레드 프로시저(쓰레드를 만들 때 인자로 넣는 함수, 쓰레드 메인)으로 넣고, 인자는 쓰 레드의 파라미터로 전달한다. • 코드와 데이터를 각각 인젝션 해주는 것 <injector> <대상 프로그램> 필요한 문자열 함수 포인터 내가 만든 코드 이용 inject!
  • 5. DLL INJECTION VS CODE INJECTION • DLL injection은 DLL 자체를 프로세스에 올린다. • DLL의 코드에서 사용하는 모든 데이터는 DLL의 데이터 영역에 있다. • Ex) 문자열 등... • -> 따로 데이터를 injection할 필요가 없다. • Code injection은 코드 뿐만 아니라 코드에서 이용하는 데이터도 같이 인젝션 해 주어야 한다. • 코드 인젝션을 사용하는 이유 • 메모리를 조금만 차지한다. • DLL 인젝션보다 작은 공간을 차지한다. • 흔적을 찾기 어렵다 • DLL 인젝션은 해당 프로세스 메모리에 흔적을 남기기 때문에 간단히 인젝션 여부를 알 수 있다. • 코드 인젝션은 쉽게 흔적을 남기지 않는다. (알아내는 방법이 있긴 하다) • 기타 • 코드 인젝션은 DLL 파일이 필요하지 않다. 인젝션하는 프로그램만 필요하다(injector) • DLL injecton은 규모가 크고 복잡한 일을 수행할 때, Code injection은 규모가 작고 간단한 일을 수행할 때 사용한다.
  • 6. CODE INJECTION – 원격 쓰레드를 이용 – 고급 언어로 프로그래 밍 • 쓰레드 인자로 넣을 구조체의 형식이다. • 이 구조체 모양대로 내용을 써서 대상 프로그 램의 메모리에 써 둘 것이다. • 쓰레드를 만들 때, 이 구조체를 저장해 둔 대상 프로그램의 가상메모리 주소를 인자로 준다. • 대상 프로그램은 자신의 가상 메모리에 저장된 데이터를 이용하여 일을 할 수 있다.
  • 7. • 함수 포인터를 이용하기 쉽도록 재정의하는 코드 이다. CODE INJECTION – 원격 쓰레드를 이용 – 고급 언어로 프로그래 밍
  • 8. • 위에 있는 두 줄은 함수 선언이다. • 아래는 메인 함수이다. • 인자로 PID를 입력 받는다. CODE INJECTION – 원격 쓰레드를 이용 – 고급 언어로 프로그래 밍
  • 9. • 인젝션할 코드이다. • 인자로 받은 주소를 캐스팅한다. • 미리 저장해 둔 함수 포인터(LoadLibraryA와 GetProcAddress) 와 문자열(user32.dll, MessageBoxA) 이용하여 user32.dll(MessageBoxA API가 저장된 DLL)을 열고, MessageBoxA 함수 주소를 얻는다. • 미리 저장해 둔 문자열을 이용하여 MessageBoxA함수에 인 자를 넣고 함수를 호출한다. • kernel32.dll은 대부분의 프로그램이 이용하고, kenel32.dll과 같은 시스템 라이브러리는 모든 프로세스가 같은 가상메모 리에 매핑하기 때문에 injector에서 주소를 구해 넣어도 괜찮 았다. • kernel32.dll을 이용하지 않는 dll도 있으니 code injection하기 전에 확인해야 한다. CODE INJECTION – 원격 쓰레드를 이용 – 고급 언어로 프로그래 밍
  • 10. • 본격적으로 코드를 인젝션하는 함수이다. • 일단 대상 프로세스에 넣을 구조체(쓰레드 인자로 이용될) 에 내용을 적는다. • 아래 구조체 모양을 참고해 보자. • pFunc은 함수 포인터(주소)가 들어갈 공간이다. • LoadLibraryA함수와 GetProcAddress함수의 주소를 구 해 넣었다. • 이들은 MessageBoxA를 호출하기 위해서 구한 것이 다. • szBuf는 문자열들이 들어갈 공간이다. • 이들은 LoadLibraryA의 인자로 줄 DLL 이름과 GetProcAddress의 인자로 줄 함수 이름, 그리고 MessageBoxA를 호출할 때 인자로 줄 문자열들의 이 름이다. • 다른 API를 이용하고 싶다면 그 API가 속한 DLL과 함수 CODE INJECTION – 원격 쓰레드를 이용 – 고급 언어로 프로그래 밍
  • 11. • 프로세스를 열고 방금 내용을 채워 넣은 구조체를 그대로 써 준 다. CODE INJECTION – 원격 쓰레드를 이용 – 고급 언어로 프로그래 밍
  • 12. • 그 다음 인젝션할 코드(함수)의 크기를 구하고, 그 크기만큼 메모 리를 확보하여 내용을 쓴다. • 인젝션할 코드는 이 함수 바로 다음에 올 것이다. CODE INJECTION – 원격 쓰레드를 이용 – 고급 언어로 프로그래 밍
  • 13. • 방금 넣은 코드의 주소는 pRemoteBuf[1]이고, 저장한 구조체의 주소는 pRemoteBuf[0]이 다. • 이들을 인자로 넣어 CreateRemoteThread함수를 호출한다. CODE INJECTION – 원격 쓰레드를 이용 – 고급 언어로 프로그래 밍
  • 14. •주의! • 컴파일은 반드시 Release mode로 한다. • Debug모드로 하면 추가적으로 생성되 는 코드가 있다.(추가적으로 불리는 함 수가 있다) • 따라서 Debug모드로 컴파일한 코드 를 인젝션하면 대상 프로그램에는 없 는 함수를 호출하기 때문에 에러가 나 고, 프로그램이 종료된다. CODE INJECTION – 원격 쓰레드를 이용 – 고급 언어로 프로그래 밍
  • 15. CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이 용 • 어셈블리어를 이용하여 인젝션할 코드를 생성하면 조금 더 자유로운 형태로 이용 가능하다. • 문자열(데이터)과 코드를 함께 넣을 수 있다. • 올리디버거로 간편하게 만들 수 있다. • 아무 EXE나 열고 빈 칸에 옆과 같은 내용을 쓰자 • 단, call 주소는 상황에 맞게 쓴다. • 또는 인라인 어셈블리를 이용해도 됨
  • 16. CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이 용 • 함수 프롤로그
  • 17. CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이 용 • 인자로 받은 struct 주소를 가져온다. • 이번에는 struct에 함수 주소(LoadLibraryA와 GetProcAddress)만 넣었다. • 이 주소를 하드코딩 하지 않는 이유는 ASLR이라는 기법 때문이다. • ASLR : Address Space Layout Randomization. • 시스템 DLL은 모든 프로그램이 같은 주소의 가상메모리에 올라온다. 하지만 재부팅하면 그 ‘같은 주소’가 될 주소가 바뀐다. 따라서 함수 주소는 매번 구해서 넣는다. • ESI에는 LoadLibraryA, ESI+4에는
  • 18. CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이 용 • LoadLibraryA함수를 호출하는 코드이다. • 사용할 dll 문자열은 user32.dll이다.
  • 19. CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이 용 • user32.dll 문자열을 스택에 저장한다. • 리틀 엔디안으로 • 문자열 뒷부분부터 거꾸로 • 맨 마지막에 push esp를 해서 문자열의 맨 처음 부분이 저장된 주소를 스택에 넣는다.
  • 20. CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이 용 • 순서와 리틀 엔디안에 주의한다. • 문자열 맨 끝에 null (0)이 들어가는 것에 주의한다.
  • 21. CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이 용 • ESI(인자로 받은 주소)에 저장된 구조체의 첫 번째 멤버인 LoadLibraryA 함수 주소를 이용하여 함수를 호출한다.
  • 22. CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이 용 • GetProcAddress함수를 호출하는 코드이다. • 사용할 함수 이름 문자열은 MessageBoxA이다. • GetProcAddress함수는 WINAPI 함수 호출 규약을 이용한다. • WINAPI 함수 규약은 stdcall 함수 호출 규약이다. • -> 함수 인자를 역순으로 push한다
  • 23. CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이 용 • 조금 전과 같은 방법으로, MessageBoxA 문자열을 스택에 저장하고, 주소를 넘긴다.
  • 24. CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이 용 • LoadLibraryA함수의 반환 값인 user32.dll의 핸들을 push한다.
  • 25. CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이 용 • ESI+4에 저장된, 구조체의 두 번째 값인 GetProcAddress함수를 호출한다.
  • 26. CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이 용 • 이제 MessageBoxA를 호출할 것이다. • 문자열은 2, 3번째 인자이다. • 단순한 push방법을 이용하기엔 골치 아프다. • push방법 말고 다른 방법을 이용해본다.
  • 27. CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이 용 • 먼저 uType에 해당하는 인자를 push한다.
  • 28. CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이 용 • 만드는 중에는 일단 call 00400000(뒤에 아무 숫자, 짧지 않은 길이의)를 입력해 둔다. • call을 하면 함수 call 바로 아래 주소(다음에 실행할 코드 주소)를 스택에 push한 뒤 점프한다. • 사실 여기서 사용하는 주소는 상대 주소이다. • 기계어에는 자신으로부터 얼마나 떨어진 곳으로 점프하라 라는 정보가 있다. • 올리 디버거가 알아서 상대 주소로 계산해서 기계어를 만들어 준다. • 어셈블리어로는 그냥 주소를 써 줘도 된다.
  • 29. CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이 용 • 상대 주소 계산법 JMP 100 EIP : 50 (EIP는 다음에 실행할 코드 주소를 가리킨다.) 100 <어셈블리어 표현> E9 B0 00 00 00 EIP : 50 (EIP는 다음에 실행할 코드 주소를 가리킨다.) 100 <기계어 표현> 시작주소 45 시작주소 45 • 00000050 + 000000Bo = 100 • 리틀엔디안으로 B0000000 • 주의 : 작은 바이트를 이용하는 short jmp라는 명령어도 있다. 일단은 그냥 점프를 이용하기 위해 4바이트의 주소를 넣자.
  • 30. CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이 용 • 상대 주소 계산법 EIP : 105 (EIP는 다음에 실행할 코드 주소를 가리킨다.) JMP 45 <어셈블리어 표현> <기계어 표현> 시작주소 100, 코드 크기 5바이트 시작주소 45 EIP : 105 (EIP는 다음에 실행할 코드 주소를 가리킨다.) E9 40 FF FF FF 시작주소 100, 코드 크기 5바이트 시작주소 45 • 105 – c0 = 45 • -c0 = 4바이트로 FFFFFF40 • 00000105 + FFFFFF40 = 45 • 리틀 엔디안으로 40FFFFFF
  • 31. CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이 용 • 수정하려는 줄을 클릭한 후 오른쪽키-binary- edit으로 출력하고자 하는 문자열을 입력한다. • 뒤에서 두 번째 인자인 메시지 박스 제목을 입력한다.
  • 32. CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이 용 • 맨 끝 null을 입력하는 것을 잊지 말자
  • 33. CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이 용 • 위의 call 목적지가 문자열 바로 다음을 가리키도록 수정한다.
  • 34. CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이 용 • 똑같은 방식으로, 인쇄하고자 하는 문자열을 넣는다.
  • 35. CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이 용 • hWnd 인자로 0을 넣는다.
  • 36. CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이 용 • MessageBoxA함수를 호출한다.
  • 37. CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이 용 • 함수 에필로그이다.
  • 38. CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이 용 • 파일을 저장하고 헥사 에디터로 연다. • 기계어를 얻기 위함이다.
  • 39. CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이 용 • 기계어를 복사해서 배열에 넣을 형태로 수정한다. • 메모장으로 노가다하든 에디터를 쓰든... • NotePad++같이 매크로를 이용할 수 있는 프로그램을 추천함 • 이것이 쉘코드 제작의 기본이다.
  • 40. CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이 용 • 이번 구조체에는 함수 주소만을 넣는다. • ThreadProc함수 대신 쉘코드를 넣는다.
  • 41. CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이 용 • 메인 함수이다.
  • 42. CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이 용 • 쓰레드 인자로 줄 구조체를 넣는 것은 똑같다. • 문자열은 더이상 넣지 않는다.
  • 43. CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이 용 • 함수 주소를 이용하여 사이즈를 구하던 것과는 달리, 단순히 쉘코드 배열의 사이즈를 구해 넣는다. • 쉘코드를 프로세스에 쓰고 쓰레드를 생성한다.
  • 44. CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이 용 • 성공!
  • 45. CODE INJECTION – 원격 쓰레드를 이용 – 어셈블리어를 이 용 • 쉘코드를 0xFF 식의 char 배열로 만들기보다는 위와 같이 스트링으로 쓰는게 더 정석적이다. • 코드상에서 char 배열 초기화를 제외한 부분은 달라진 것이 없다. • 취향 따라 쓴다..
  • 46. TIP • jmp를 다른 방식으로 표현한다면? • jmp 401000를 아래와 같이 표현할 수 있다. • push 401000 • ret • Call을 다른 방식으로 표현한다면? • push 다음 주소 • jmp 함수 주소 • 이렇게 같은 코드를 다른 방식으로 쓸 수도 있다.
  • 47. 인라인 패치 • 인라인 코드 패치, 인라인 패치 • 원하는 코드를 직접 수정하기 어려울 때 코드 케이브(Code cave)라고 하는 패치 코드를 삽입한 후 실행해 프 로그램을 패치시키는 기법 • 패킹 혹은 암호화 때문에 파일을 직접 수정하기 어려운 경우 많이 사용되는 기법 • 혹은 수정한 코드가 아래 코드를 침범하여 끼워 넣기 애매한 경우에도 이용할 수 있다. • 매번 프로세스 메모리의 코드를 패치하기 때문에 인라인 코드 패치라고 부른다. • 파일 자체에서 코드를 수정하는 것이 아니라 파일을 실행한 후 수정하는 것 • 복호화가 끝난 후 가는 OEP를 조작하여 끼워 넣은 코드로 이동하게 한다. 끼워 넣은 코드는 복호화 된 기존 코드에서 수정하고 싶은 부분을 수 정한다. • 파일 수정을 이용한 Code injection, 그리고 이를 이용한 기존 코드 패치 방법이다.
  • 49. 인라인 패치 일반적인 코드 패치 인라인 패치 대상 파일 파일 & 메모리 횟수 1번 파일에는 1번만 메모리는 실행될 때마다 방법 Direct (원하는 위치에 직접 패치) Indirect (코드 케이브를 미리 설치한 후 메모리에서 원하는 영역이 복 호화 되었을 때 패치)
  • 50. 인라인 패치 • 패치할 프로그램이다. • result가 3이 아닌 값을 출력하도록 해보자. • 패치의 효과를 체험할 수 있도록 UPX 패킹을 적용하자.
  • 51. 인라인 패치 • UPX의 디코딩 루틴을 지나 OEP로 점프하는 코드를 찾았다. • 이 주소는 앞으로 임의로 넣은 코드의 주소로 바꿀 것 • 임의로 넣은 코드는 디코딩 되어 메모리에 올라온 코드를 수정(패치)하는 일 을 한다.
  • 52. 인라인 패치 • 메인문이다. • printf를 호출하기 전을 수정하고자 한다. • 끼워 넣을 코드는 맨 밑 코드영역의 null padding 자리에 넣을 것이다. • 드래그한 코드는 jmp 코드로 수정할 것이다. • 정상 작동하기 위해서는 이 코드도 필요하므로 복사해 둔다 • 임의의 코드를 실행하면 드래그한 코드가 jmp 406AA0로 수정될 것(406AA0에는 printf 결과를 조작하기 위한 코드를 끼워 넣을 것)
  • 53. 인라인 패치 • 디코딩 루틴 이후 OEP로 점프하는 코드를 아래 추가한 코드로 점프하도록 변경 • 이 점프로 인해 실행되는 코드 : 기존 main 함수의 printf 전 코드를 jmp 코드로 변경하는 코드 • 바뀐 코드로 인해 아래쪽에 추가한 코드가 실행된다. • jmp코드로 수정하기 위해 지워진 코드를 넣어 정상적으로 작동하도록 한다. • 추가 하고싶은 코드를 넣어 임의로 변경한다 (이 경우, printf 인자를 조작하는 일) • 다시 기존 코드로 점프하여 실행을 이어간다.
  • 54. 인라인 패치 • 성공! • OEP를 수정할 때, 그 점프하는 코드마저 패킹이나 암호화가 적용 되어 있다면, 그 알고리즘을 알아내야 한다. • 그래야 패킹/암호화를 풀었을 때 제대로 점프할 수 있다. • 일부러 약간 돌아서 코드를 실행하게 했다. • 여건이 된다면 다시 아래로 jmp하지 않고 바로 코드만 수정해도Ok.
  • 55. 부록 • 참고 사이트
  • 56. 참고 사이트 • JMP 상대주소 • https://ko.wikipedia.org/wiki/JMP_(x86_%EB%AA%85%EB%A0%B9%EC%96%B4) • http://jyj850714.tistory.com/337 • 인라인 패치 • https://asecurity.so/2017/01/hooking-%ED%9B%84%ED%82%B9-code-path-inline-patch-%EC%BD%94%EB%93%9C- %ED%8C%A8%EC%B9%98-%EC%9D%B8%EB%9D%BC%EC%9D%B8-%ED%8C%A8%EC%B9%98/