Я изучаю этический взлом, и мне дали это в качестве упражнения. Я застрял на нем уже два дня.
Мы пишем программу, которая преднамеренно уязвима к «переполнению буфера».
#include <stdio.h>
void badf(int n, char c, char* buffer)
{
char mycode[] = {
0xeb, 0x0f, 0xb8, 0x0b,
0x00, 0x00, 0x00, 0x8b,
0x1c, 0x24, 0x8d, 0x0c,
0x24, 0x31, 0xd2, 0xcd,
0x80, 0xe8, 0xec, 0xff,
0xff, 0xff, 0x2f, 0x62,
0x69, 0x6e, 0x2f, 0x6c,
0x73, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00
}; // 37 bytes
int i;
// Copy mycode array into buffer array
for (i=0; i<n; i++)
{
buffer[i]=mycode[i];
}
// Overwrite Base Pointer
buffer[37] = 0x00;
buffer[38] = 0x00;
buffer[39] = 0x00;
buffer[40] = 0x00;
// Overwrite Instruction Pointer
buffer[41] = 0x90;
buffer[42] = 0x83;
buffer[43] = 0x04;
buffer[44] = 0x08;
}
void f(int n, char c)
{
char buffer[37];
badf(n,c,buffer);
}
void test()
{
printf("test\n");
}
int main()
{
f(37,0x00);
return 0;
}
Массив mycode
содержит "вредоносный" машинный код (на самом деле он просто вызывает execv
с /bin/ls
). badf
— «уязвимая» функция. На данный момент вы можете видеть, что я перезаписываю базовый указатель на 0x00s и указатель инструкций на 0x08048390, который является адресом функции test()
. Это работает, «тест» печатается на терминале.
Теперь мое следующее упражнение состоит в том, чтобы «использовать ddd, чтобы найти адрес вашего массива кода и изменить C, чтобы записать этот адрес поверх указателя инструкции, как вы делали на предыдущем шаге».
Чего я не понимаю, так это того, как я могу использовать ddd, чтобы найти адрес моего массива кода. Я легко нахожу адрес, по которому массив перемещается в БП:
0x08048260 <badf+12>: movb $0xeb,-0x29(%ebp)
0x08048264 <badf+16>: movb $0xf,-0x28(%ebp)
0x08048268 <badf+20>: movb $0xb8,-0x27(%ebp)
.....
Или куда он копируется в буферный массив:
0x080482f4 <badf+160>: movl $0x0,-0x4(%ebp)
0x080482fb <badf+167>: jmp 0x8048316 <badf+194>
0x080482fd <badf+169>: mov -0x4(%ebp),%edx
0x08048300 <badf+172>: mov 0x10(%ebp),%eax
.....
Но, конечно, это не то, что мы ищем.
Как найти адрес указателя инструкций для выполнения загруженного машинного кода, записав его в массив буферов таким образом?
edit: ddd — это отладчик, который мы используем, также обратите внимание, что мы работаем с 32-битной версией Linux. Код компилируется с флагом -fno-stack-operator
, отключающим автоматические проверки компилятором на переполнение буфера.
badf+12
и сбросить адресebp-0x29
- person Michael M.   schedule 18.11.2013