Целью атаки является программа на языке C, использующая двусвязный список:
Код: Выделить всё
#include
#include
#include
typedef struct node {
struct node *prev;
struct node *next;
char data[32];
} Node;
Node *list_insert(Node *after)
{
Node *node = calloc(1, sizeof(struct node));
if (after) {
node->prev = after;
if (after->next) {
node->next = after->next;
node->next->prev = node;
}
after->next = node;
}
return node;
}
void list_delete(Node *node)
{
if (node->prev) {
node->prev->next = node->next;
}
if (node->next) {
node->next->prev = node->prev;
}
}
int _main(int argc, char *argv[])
{
if (argc != 4) {
fprintf(stderr, "Error: Need three command-line arguments\n");
return 1;
}
Node *a = list_insert(0);
Node *b = list_insert(a);
Node *c = list_insert(b);
strcpy(a->data, argv[1]);
strcpy(b->data, argv[2]);
strcpy(c->data, argv[3]);
list_delete(c);
list_delete(b);
list_delete(a);
return 0;
}
Код: Выделить всё
OS = Linux
ISA = x86_32
addr_of_a = 0x080002e0
addr_of_b = 0x08000320
addr_of_c = 0x08000350
ret = 0xfffe8764 # the return address of the list_delete function (returns to _main)
Очевидно, уязвимостью является буфер данных char[32] внутри каждого узла связанного списка, который может быть переполнен . Мой текущий план:
- Переполнить b->данные, пока они не достигнут c, а затем перезаписать c->prev с помощью ret-0x4 и перезаписать c->next адресом c->data (это делает c->next указателем на область данных, которую я хотите внедрить шеллкод).
- вызывается, затем выполняется строка node->prev->next = node->next. Учитывая настройку на шаге 1, эта строка будет вставлять адрес c->data вместо обратного адреса list_delete.
Код: Выделить всё
list_delete(c) - Это на этом этапе я застрял: код в следующем операторе if node->next->prev = node->prev выполняется, и первое слово в моем шеллкоде перезаписывается с помощью node- >предыдущая(значение null, потому что мне нужно установить node->next на указатель на данные, чтобы перезаписать возвращаемый результат. адрес в стеке. Я понял, что с помощью этого метода, какой бы адрес я ни установил c->next, содержимое, на которое он указывает, всегда будет получать свои первые 4 байта, всегда будет перезаписано.
Код: Выделить всё
value = ret-4). Я не могу избежать этого, установив для node->next
Я потратил так много часов на это домашнее задание и в настоящее время застрял. Если бы кто-нибудь мог мне помочь, я был бы очень признателен!
Подробнее здесь: https://stackoverflow.com/questions/790 ... king-and-b