2016-04-19 3 views
-3

Я окончил университет, чтобы найти работу в ближайшее время, но у меня есть вопрос о безопасности кода.Как хакер может использовать массив или указатели

В Java нет массивов вне границ и нет указателей, которые предполагают, что Java более безопасна, чем C. В C эти массивы вне пределов могут вызывать повреждение стека или переполнение буфера и оборванные указатели. В интервью мне может быть предложено «как хакер может воспользоваться преимуществами этого?»

Как мне ответить на это?

Примеры приветствуются.

+1

https://xkcd.com/1354/ – immibis

+0

Я думаю, вы ошибаетесь здесь. Многие из этих проблем могут возникнуть в результате плохого дизайна, не говоря уже о хакерах; Java просто обеспечивает изоляционный слой. Позвольте мне проиллюстрировать: у вас достаточно денег, чтобы заплатить за 1 пункт, и вы просите 10, которые предоставляются по запросу. Вы ожидаете заплатить за остальных 9, верно? C заставляет вас закодировать это самостоятельно, тогда как JVM просто убивает ваше приложение из-за неперехваченного исключения. Кроме того: тот факт, что Heartbleed является ошибкой в ​​широко развернутой криптографической библиотеке, является единственной причиной, по которой это было так много, но это было связано с плохим дизайном, а не с C. –

ответ

1

Ну, вы могли бы поговорить конкретно о Heartbleed (там есть тонна документации).

В принципе, существует АНИ вызов, который может быть сделано через сеть, где ваш код будет запросить сообщение поддержания активности, которая, как правило, выглядит следующим образом:

You: send me "potato", which is 6 chars. 
Response: potato 

Однако, не было никакой проверки, что текст просил, а длина текста отправленного в выравнивали, так что вы можете сделать это:

You: send me "potato", which is 512 chars. 
Response potato&&&&#8388325099#((#(#)%#(((#%)password:1234#(%()#%((#%#(#%)(#)(%)(##()JFJFEOIJF#)J(JF)(#J)(#J#)(J#))J#.... 

Где реагирующий компьютер будет посылать картофель, плюс 506 байт, что, по существу, стек вокруг этой локальной переменной, который может содержать почти все, включая pa sswords и т. д.

Это достаточно хороший пример?

0

Если ваша работа не связана с безопасностью, я не думаю, что вас попросят об этом. Идентификация уязвимостей относительно проста, но использовать их сложно, и я думаю, что большинство работодателей были бы счастливы, зная, что вы знаете, что вам нужно проверить свои границы.

billjamesdev explains раскрытие информации через переполнение, и это в основном то, о чем шла речь в Heartbleed. Тем не менее, есть намного худшие возможные результаты, самые известные из которых являются произвольными, удаленное выполнение кода: в основном, кто-то еще запускает любой код, который им нравится в вашей программе из-за уязвимости программного обеспечения. Переполнение буфера на основе стека легче использовать для получения RCE, но буферы на основе кучи также могут быть использованы в некоторой степени.

В этой маленькой функции:

int foo() { 
    char bar[4]; 
} 

Массив bar живет в стеке. Еще одна интересная вещь, которая живет в стеке, является адресом возврата функции. Если вы перепишете этот адрес, когда функция вернется, он переместится в выбранное вами место, а не там, где разработчик решил, что он вернется. Скажите, что у вас есть эти две функции:

int main() { 
    char bar[4]; 
    scanf("Enter no more than 4 characters: %s\n", bar); 
} 

int bar() { 
    system("sh"); // starts a shell on Linux 
} 

и предположить, что bar живет в адресном 0x41414141 (что весьма маловероятно, но это делает демонстрацию легче, потому что 0x41 является кодом ASCII для «A»). Если запустить эту программу на Linux и ввода этого:

Enter no more than 4 characters: 00001111AAAA 

На x86, это будет заполнить буфер символов с ASCII нулями, перезаписать специальное значение, называемое указателем базового кадра родителя (это очень важно для вашей программы но хакерам обычно не нужно заботиться об этом) с помощью ASCII и перезаписывать обратный адрес 0x41414141.Когда main вернется, вместо прекращения программы он запустит оболочку.

Существует множество вариантов атак, но основная идея заключается в том, что переполнение буфера может позволить хакерам захватить поток выполнения вашей программы.

0

Это хороший пример того, что я видел недавно. Это немного надуманно, но это довольно легко понять.

У нас есть таблица рассылки с некоторыми функциями в ней, и из-за ошибки мы можем вызвать неправильную функцию.

#include <assert.h> 
#include <float.h> 
#include <math.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

#define SETBIT(X,Y)  X|=(1ULL<<(Y)) 

typedef void (*method)(void); 

void unsafe(); 
void safe(); 

void safe(void) { 
    printf("anyone can call this\n"); 
} 
void unsafe(void) { 
    fprintf(stderr, "wtf, how did this get called\n"); 
    abort(); 
} 
static method dispatch_table[2] = {0}; 

typedef struct node { 
    union container { 
    float fdata; 
    int idata; 
    } data; 
    uint32_t func; 
} Node; 

int main(void) { 
    size_t nsize1 = sizeof(Node); 
    assert(nsize1 == 8); 
    assert(sizeof(int) == 4); 
    assert(sizeof(float) == 4); 
    assert(sizeof(double) == 8); 

    dispatch_table[0] = &safe; 
    dispatch_table[1] = &unsafe; 
    Node n = {.data.fdata = 10.0}; 
    n.func = 0; 

    //The problem starts here 
    void *bad = (void*)&n; 
    uint64_t *badder = (uint64_t*)bad; 
    SETBIT(*badder, 32);// Off by one error 
    printf("%d\n", n.func); 
    dispatch_table[n.func](); 
    return 0; 
} 
Смежные вопросы