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

SHADOW
В описании к заданию написано:
«Ollydbg не спасет Вас, исследователи! Игра будет вестись в темных уголках ядра операционной системы. Хватит ли Вам смелости узнать потаенные места виртуальной реальности? Shadow ждет вас, найдите его!»
Намек ясен. Делаем пару прогонов анализаторами нашего образца:

Убрано под спойлер


Оке, все чисто. Cмотрим импорт:

Убрано под спойлер


На данном этапе, не копая дизасм листинг (он кст небольшой, см смещение 00402310), можно понять логику работы приложения:

  1. Подгружается драйвер (CreateService)
  2. Ему передаются некие параметры (DeviceIoControl)
  3. Драйвер что-то делает
  4. ???

Очевидно, нам необходимо выцепить драйвер. Загружаем r3 отладчик архетипа «Оля», ставим бряк на CreateServiceA, DeviceIoControl и клацаем F9 (антиотладка отсутствует). Сразу же срабатывает точка останова на CreateServiceA, вот так выглядит стек:

Убрано под спойлер


Замечаем путь к нашему драйверу, копируем его куда-нибудь. Клацаем F9, ловим еще одну остановку на этой же функции:

Убрано под спойлер


Вам может показаться, что это один и тот же драйвер, однако присмотритесь внимательнее: названия чуть-чуть отличаются. Его тоже сохраним. Клацаем F9, перед нами появляется консолька с просьбой ввести некие данные:

Убрано под спойлер


Вводим рандом, отправляем. Сразу же срабатывает бряк на DeviceIoControl:

Убрано под спойлер


Здесь мы можем лицезреть нашу связку меил : сериал, которая передается третьим и пятым параметром соответственно. Четвертый и шестой аргумент — размер буферов (с учетом нуля). Трассируем в отладчике до ret, затем еще до одного. В результате увидим такую картину:

Убрано под спойлер


Иными словами, если DeviceIoControl вернул ненулевое значение — крякми решен. Что ж, перейдем к изучению первого драйвера. DriverEntry:

Убрано под спойлер


Обработчик DeviceIoControl:

Убрано под спойлер


Заветная Validate:

Убрано под спойлер


Обратить эту функцию не составит труда. Однако давайте вспомним, что у нас существует и второй драйвер, про который мы пока ничего не знаем. Его DriverEntry:

Убрано под спойлер


Интересное кино! Выглядит как самый настоящий драйвер-фильтр. Глянем обработчик:

Убрано под спойлер


Что мы здесь видим:

  1. Функция ValidateStr отвечает за дополнительную валидацию наших первичных данных: допускаются только символы A..Z + a..z + 0..9 + '.' + '@'. Я бы оторвал руки человеку, который добавил такую проверку — лично мой меил не проходит ее, в нем содержится символ '-'
  2. Функция ModifyMail изменяет наш меил следующим образом:

    Убрано под спойлер

  3. IofCallDriver передает управление основному драйверу с уже измененными данными

Таким образом, учтя все проверки, можно набросать что-то типа этого:

Убрано под спойлер
#include "main.h"

char mail[257];
char hashes[32][33];

void main()
{
	for (;;)
	{
		printf_s("Enter your name (1 chars min and 256 chars max, only A..Z + a..z + '.' + '@'):\n");
		fgets(mail, 257, stdin);

		int ln = strlen(mail) - 1;
		if (mail[ln] == '\n')
			mail[ln] = '\x00';
		else ln++;

		if (ln < 1)
			continue;

		for (int i = 0; i < ln; i++)
		{
			if ((mail[i] < '0' || mail[i] > '9') && mail[i] != '.' && mail[i] != '@')
			{
				if (i & 1)
					mail[i] &= 0xDF;
				else
					mail[i] |= 0x20;
			}
		} //change chars case

		GetMD5(mail, ln, mail);

		for (int i = 0; i < 32; i++)
		{
			if (mail[i] < '0' || mail[i] > '9')
			{
				mail[i] &= 0xDF;
				GetMD5(mail, 32, hashes[i]);
				mail[i] |= 0x20;
			}
			else
				GetMD5(mail, 32, hashes[i]);
		}

		for (int i = 0; i < 32; i++)
			mail[i] = hashes[i][i];

		printf("%s\n", mail);	
	}
}


Функция GetMD5 самая стандартная, взятая отсюда. Компилируем, запускаем:

Убрано под спойлер


Solved. На этом прощаюсь.

Комментарии (5)


  1. potan
    25.12.2017 08:43

    А пробовали ломать что-нибудь, написанное на Haskell? Он такой код создает, что ни один человек на ассемблере руками не напишет.


    1. unc1e Автор
      26.12.2017 18:10

      Нет, не пробовал. Проблема зачастую не в коде, а в его количестве. Сколько метров (наверняка именно в этих единицах) весит хелловорлд?


      1. potan
        26.12.2017 19:21

        Функция main из helloworld:
        .data
        .align 8
        .align 1
        .globl __stginit_Main
        __stginit_Main:
        .data
        .align 8
        .align 1
        sK5_closure:
        .quad sK5_info
        .quad 0
        .quad 0
        .quad 0
        .section .rodata
        .align 8
        .align 1
        cKc_str:
        .byte 72
        .byte 101
        .byte 108
        .byte 108
        .byte 111
        .byte 44
        .byte 32
        .byte 87
        .byte 111
        .byte 114
        .byte 108
        .byte 100
        .byte 0
        .text
        .align 8
        .long SKg_srt-(sK5_info)+0
        .long 0
        .quad 0
        .quad 4294967318
        sK5_info:
        .LcKd:
        leaq -16(%rbp),%rax
        cmpq %r15,%rax
        jb .LcKe
        .LcKf:
        movq %r13,%rcx
        movq %rbx,%rdx
        subq $8,%rsp
        subq $32,%rsp
        xorl %eax,%eax
        call newCAF
        addq $40,%rsp
        testq %rax,%rax
        je .LcKb
        .LcKa:
        movq $stg_bh_upd_frame_info,-16(%rbp)
        movq %rax,-8(%rbp)
        movl $cKc_str,%r14d
        movl $ghczmprim_GHCziCString_unpackCStringzh_closure,%ebx
        addq $-16,%rbp
        jmp stg_ap_n_fast
        .LcKb:
        jmp *(%rbx)
        .LcKe:
        jmp *-16(%r13)
        .data
        .align 8
        .align 1
        sK4_closure:
        .quad sK4_info
        .quad 0
        .quad 0
        .quad 0
        .text
        .align 8
        .long SKg_srt-(sK4_info)+8
        .long 0
        .quad 0
        .quad 12884901910
        sK4_info:
        .LcKt:
        leaq -16(%rbp),%rax
        cmpq %r15,%rax
        jb .LcKu
        .LcKv:
        movq %r13,%rcx
        movq %rbx,%rdx
        subq $8,%rsp
        subq $32,%rsp
        xorl %eax,%eax
        call newCAF
        addq $40,%rsp
        testq %rax,%rax
        je .LcKs
        .LcKr:
        movq $stg_bh_upd_frame_info,-16(%rbp)
        movq %rax,-8(%rbp)
        movl $base_GHCziShow_zdfShowChar_closure,%r14d
        movl $base_GHCziShow_zdfShowZMZN_closure,%ebx
        addq $-16,%rbp
        jmp stg_ap_p_fast
        .LcKs:
        jmp *(%rbx)
        .LcKu:
        jmp *-16(%r13)
        .data
        .align 8
        .align 1
        .globl Main_main_closure
        Main_main_closure:
        .quad Main_main_info
        .quad 0
        .quad 0
        .quad 0
        .text
        .align 8
        .long SKg_srt-(Main_main_info)+24
        .long 0
        .quad 0
        .quad 30064771094
        .globl Main_main_info
        Main_main_info:
        .LcKH:
        leaq -16(%rbp),%rax
        cmpq %r15,%rax
        jb .LcKI
        .LcKJ:
        movq %r13,%rcx
        movq %rbx,%rdx
        subq $8,%rsp
        subq $32,%rsp
        xorl %eax,%eax
        call newCAF
        addq $40,%rsp
        testq %rax,%rax
        je .LcKG
        .LcKF:
        movq $stg_bh_upd_frame_info,-16(%rbp)
        movq %rax,-8(%rbp)
        movl $sK5_closure,%esi
        movl $sK4_closure,%r14d
        movl $base_SystemziIO_print_closure,%ebx
        addq $-16,%rbp
        jmp stg_ap_pp_fast
        .LcKG:
        jmp *(%rbx)
        .LcKI:
        jmp *-16(%r13)
        .data
        .align 8
        .align 1
        .globl ZCMain_main_closure
        ZCMain_main_closure:
        .quad ZCMain_main_info
        .quad 0
        .quad 0
        .quad 0
        .text
        .align 8
        .long SKg_srt-(ZCMain_main_info)+48
        .long 0
        .quad 0
        .quad 12884901910
        .globl ZCMain_main_info
        ZCMain_main_info:
        .LcKV:
        leaq -16(%rbp),%rax
        cmpq %r15,%rax
        jb .LcKW
        .LcKX:
        movq %r13,%rcx
        movq %rbx,%rdx
        subq $8,%rsp
        subq $32,%rsp
        xorl %eax,%eax
        call newCAF
        addq $40,%rsp
        testq %rax,%rax
        je .LcKU
        .LcKT:
        movq $stg_bh_upd_frame_info,-16(%rbp)
        movq %rax,-8(%rbp)
        movl $Main_main_closure,%r14d
        movl $base_GHCziTopHandler_runMainIO_closure,%ebx
        addq $-16,%rbp
        jmp stg_ap_p_fast
        .LcKU:
        jmp *(%rbx)
        .LcKW:
        jmp *-16(%r13)
        .section .data
        .align 8
        .align 1
        SKg_srt:
        .quad ghczmprim_GHCziCString_unpackCStringzh_closure
        .quad base_GHCziShow_zdfShowZMZN_closure
        .quad base_GHCziShow_zdfShowChar_closure
        .quad base_SystemziIO_print_closure
        .quad sK4_closure
        .quad sK5_closure
        .quad base_GHCziTopHandler_runMainIO_closure
        .quad Main_main_closure
        .ident «GHC 7.10.3»


        1. ReakTiVe-007
          27.12.2017 18:24

          image


        1. unc1e Автор
          28.12.2017 01:29

          Это довольно цивильный код)) Правда, неинтеловский формат режет глаза + оверхед директив