Мене попросили зламати програму на співбесіді

TL;DR Мене попросили зламати програму на співбесіді. І я отримав роботу.

Всім привіт,

Я собеседовался на позицію інженера програмної безпеки, вони запитували в основному різні низькорівневі речі. Деякі відповіді я знав, деякі ні.
Потім вони надіслали email з захищеним і зашифрованим бинарником, який потрібно було зламати.
Коли я добрався до будинку, я скачав його і побачив, що він запитує пароль. Вони хотіли, щоб я знайшов цей пароль.
Ось що я побачив при першому запуску:

root@lisa:~# ./CrackTheDoor

*** DOOR CONTROL SYSTEM ***

PASSWORD:
Я надрукував три рази якісь дурні слова, і програма закрилася.
У мене ще є інструменти в запасі для аналізу. Давайте зберемо більше інформації про файл.

root@lisa:~# file CrackTheDoor
CrackTheDoor: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, BuildID[sha1]=0x9927be2fe310bea01d412164103b9c8b2d7567ea, not stripped
root@lisa:~#
Окей, тепер ми знаємо трохи більше про бінарники.

root@lisa:~# ldd CrackTheDoor
linux-gate.so.1 => (0xf777b000)
libc.so.6 => /lib32/libc.so.6 (0xf760c000)
/lib/ld-linux.so.2 (0xf777c000)
root@lisa:~#
Нічого незвичайного. Поясню трохи. linux-gate.so ви можете не знайти у своїй файловій системі. Але ldd показує його як загальну бібліотеку. Це Virtual DSO.

Отже, ви знаєте про linux-gate.so.1.
Можливо, ви також знаєте, що libc.so.6 це основна C бібліотека GNU систем.
ld-linux.so це завантажувач динамічних бібліотек в linux.

Запустимо програму в налагоджувач і подивимося що станеться.

root@lisa:~# gdb CrackTheDoor
GNU gdb (GDB) 7.4.1-debian
Copyright © 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL версії 3 or later <gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type «show copying»
and «show warranty» for details.
This GDB was configured as «x86_64-linux-gnu».
For bug reporting instructions, please see:
<www.gnu.org/software/gdb/bugs/>…
Reading symbols from /root/CrackTheDoor...(no debugging symbols found)...done.
(gdb) r
Starting program: /root/CrackTheDoor

Program received signal SIGSEGV, Segmentation fault.
0x080484fb in __do_global_dtors_aux ()
(gdb)
Програма впала. Це означає, що в ній повинні бути якісь антивідладочні трюки. Окей…

Запустимо її знову і подивимося точку входу програми.

root@lisa:~# gdb CrackTheDoor
GNU gdb (GDB) 7.4.1-debian
Copyright © 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL версії 3 or later <gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type «show copying»
and «show warranty» for details.
This GDB was configured as «x86_64-linux-gnu».
For bug reporting instructions, please see:
<www.gnu.org/software/gdb/bugs/>…
Reading symbols from /root/CrackTheDoor...(no debugging symbols found)...done.
(gdb) info file
Symbols from "/root/CrackTheDoor".
Local exec file:
`/root/CrackTheDoor', file type elf32-i386.
Entry point: 0x804762c

...
Поставимо breakpoint на точку входу і почнемо налагодження:

b * 0x804762c


Потім натиснемо «r» для запуску. Опинимося на першої рядку точки входу програми:

gdb) x/30i $pc
=> 0x804762c: pusha
0x804762d: mov $0xaa,%dl
0x804762f: mov $0x8048480,%edi
0x8047634: mov $0x8048cbc,%ecx
0x8047639: mov %edi,0x80476f3
0x804763f: mov %ecx,0x80476f7
0x8047645: sub %edi,%ecx
0x8047647: mov $0x804762f,%esi
0x804764c: push $0x80476c1
0x8047651: pusha
0x8047652: mov $0x55,%al
0x8047654: xor $0x99,%al
0x8047656: mov $0x8047656,%edi
0x804765b: mov $0x80476e5,%ecx
0x8047660: sub $0x8047656,%ecx
0x8047666: repnz scas %es:(%edi),%al
0x8047668: je 0x804770a
0x804766e: mov %edi,0x80476eb
0x8047674: popa
0x8047675: add 0x80476eb,%edx
0x804767b: ret
Має виглядати якось так. Можна вибрати синтаксис між AT&T і Intel версіями. Мені більше подобається Intel.

За адресою 0x8047654, ми присвоюємо 0x55 al регістру, а потім XOR їм його з 0x99 отримуючи 0xCC.
0xCC це дуже важливо, так як це означає зупинку процесу. Коли відладчик хоче перервати виконання програми, він замінює байти на 0xCC в тому місці, де хоче її зупинити.
За адресою 0x8047666, ми бачимо repnz scas; це означає пошук ділянки пам'яті, обмеженого es і edi, на предмет значення в al(0xCC).
Отже, ці рядки просто сканують пам'ять, і якщо там є 0xCC, програма припиняє виконання.
Не хочу витрачати занадто багато часу тут. Запустимо strace:

root@lisa:~# strace ./CrackTheDoor
execve("./CrackTheDoor", ["./CrackTheDoor"], [/* 17 vars */]) = 0
[ Process PID=31085 runs in 32 bit mode. ]
brk(0) = 0x9972000
access("./etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
mmap2 NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xfffffffff7715000
access("./etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("./etc/ld.so.cache", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=35597, ...}) = 0
mmap2 NULL, 35597, PROT_READ, MAP_PRIVATE, 3, 0) = 0xfffffffff770c000
close(3) = 0
access("./etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
open("/lib32/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\300o\1\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1441884, ...}) = 0
mmap2 NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xfffffffff770b000
mmap2 NULL, 1456504, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xfffffffff75a7000
mprotect(0xf7704000, 4096, PROT_NONE) = 0
mmap2(0xf7705000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x15d) = 0xfffffffff7705000
mmap2(0xf7708000, 10616, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xfffffffff7708000
close(3) = 0
mmap2 NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xfffffffff75a6000
set_thread_area(0xffe4d864) = 0
mprotect(0xf7705000, 8192, PROT_READ) = 0
mprotect(0x8049000, 4096, PROT_READ) = 0
mprotect(0xf7733000, 4096, PROT_READ) = 0
munmap(0xf770c000, 35597) = 0
ptrace(PTRACE_TRACEME, 0, 0x1, 0) = -1 EPERM (Operation not permitted)
ptrace(PTRACE_TRACEME, 0, 0x1, 0) = -1 EPERM (Operation not permitted)
Судячи за останніми двома рядками, програма знову впала. З-за системного виклику ptrace.

In Linux, ptrace is an abbreviation for Process Trace». With ptrace, you can control another process, changing its internal state like debuggers.

Ptrace — це абревіатура для «Process Trace». За допомогою ptrace ви можете контролювати інший процес змінюючи його стан, як це роблять відладчики.

Відладчики дуже інтенсивно використовують ptrace. Це їх робота.

Код для такої ділянки може виглядати приблизно так:

int main()
{
if (ptrace(PTRACE_TRACEME, 0, 1, 0) < 0) {
printf("DEBUGGING… Bye\n");
return 1;
}
printf("Hello\n");
return 0;
}
До речі, ви можете зробити ptrace[PTRACE_TRACEMe] тільки один раз, так що якщо відладчик викликав ptrace на нашій програмі до цього, то наш виклик поверне false і ми зрозуміємо, що хтось контролює програму ззовні.
Нам потрібно обійти захист на ptrace щоб програма не думала, що ми намагаємося її налагоджувати.
Ми замінимо результат системного дзвінка.
Ми будемо визначати коли програма викликає ptrace і повертати нуль.
В домашній папці я створив новий .gdbinit файл. Отже, кожен раз коли я запускаю gdb, конфігурація буде завантажуватися автоматично.

~/.gdbinit
set disassembly-flavor intel # Intel syntax is better
set disassemble-next-line on
catch syscall ptrace #Catch the syscall.
commands 1
set ($eax) = 0
continue
end
В eax буде результат системного виклику. І він завжди буде 0, що означає істину в нашому випадку.

Таким чином ми обійшли захист від налагодження і можемо повернутися до gdb.
eren@lisa:~$ gdb ./CrackTheDoor
GNU gdb (GDB) 7.4.1-debian
Copyright © 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL версії 3 or later <gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type «show copying»
and «show warranty» for details.
This GDB was configured as «x86_64-linux-gnu».
For bug reporting instructions, please see:
<www.gnu.org/software/gdb/bugs/>…
Catchpoint 1 (syscall 'ptrace' [26])
Reading symbols from /home/eren/CrackTheDoor...(no debugging symbols found)...done.
(gdb) r
Starting program: /home/eren/CrackTheDoor

Catchpoint 1 (call to syscall ptrace), 0x08047698 in ?? ()
=> 0x08047698: 3d 00 f0 ff ff cmp eax,0xfffff000

Catchpoint 1 (returned from syscall ptrace), 0x08047698 in ?? ()
=> 0x08047698: 3d 00 f0 ff ff cmp eax,0xfffff000

*** DOOR CONTROL SYSTEM ***

PASSWORD:
Я поставив breakpoint на PJeGPC4TIVaKFmmy53DJ

<code>Breakpoint 2, 0x08048534 in PJeGPC4TIVaKFmmy53DJ ()
=> 0x08048534 <PJeGPC4TIVaKFmmy53DJ+0>: 1e push ds
(gdb) x/40i $pc
=> 0x8048534 <PJeGPC4TIVaKFmmy53DJ>: push ds
0x8048535 <PJeGPC4TIVaKFmmy53DJ+1>: mov ebp,esp
0x8048537 <PJeGPC4TIVaKFmmy53DJ+3>: sub esp,0x20
0x804853a <PJeGPC4TIVaKFmmy53DJ+6>: mov BYTE PTR [ebp-0x1],0xe4
0x804853e <PJeGPC4TIVaKFmmy53DJ+10>: mov BYTE PTR [ebp-0x2],0x87
0x8048542 <PJeGPC4TIVaKFmmy53DJ+14>: mov BYTE PTR [ebp-0x3],0xfb
0x8048546 <PJeGPC4TIVaKFmmy53DJ+18>: mov BYTE PTR [ebp-0x4],0xbe
0x804854a <PJeGPC4TIVaKFmmy53DJ+22>: mov BYTE PTR [ebp-0x5],0xc9
0x804854e <PJeGPC4TIVaKFmmy53DJ+26>: mov BYTE PTR [ebp-0x6],0x93
0x8048552 <PJeGPC4TIVaKFmmy53DJ+30>: mov BYTE PTR [ebp-0x7],0x84
0x8048556 <PJeGPC4TIVaKFmmy53DJ+34>: mov BYTE PTR [ebp-0x8],0xfc
0x804855a <PJeGPC4TIVaKFmmy53DJ+38>: mov BYTE PTR [ebp-0x9],0x8d
0x804855e <PJeGPC4TIVaKFmmy53DJ+42>: mov BYTE PTR [ebp-0xa],0xe5
0x8048562 <PJeGPC4TIVaKFmmy53DJ+46>: mov BYTE PTR [ebp-0xb],0xbf
0x8048566 <PJeGPC4TIVaKFmmy53DJ+50>: mov BYTE PTR [ebp-0xc],0x5c
0x804856a <PJeGPC4TIVaKFmmy53DJ+54>: mov BYTE PTR [ebp-0xd],0xe2
0x804856e <PJeGPC4TIVaKFmmy53DJ+58>: mov BYTE PTR [ebp-0xe],0x76
0x8048572 <PJeGPC4TIVaKFmmy53DJ+62>: mov BYTE PTR [ebp-0xf],0x21
0x8048576 <PJeGPC4TIVaKFmmy53DJ+66>: mov BYTE PTR [ebp-0x10],0xb8
0x804857a <PJeGPC4TIVaKFmmy53DJ+70>: mov DWORD PTR [ebp-0x14],0x0
0x8048581 <PJeGPC4TIVaKFmmy53DJ+77>: mov eax,DWORD PTR [ebp-0x14]
0x8048584 <PJeGPC4TIVaKFmmy53DJ+80>: add eax,DWORD PTR [ebp+0x8]
0x8048587 <PJeGPC4TIVaKFmmy53DJ+83>: movzx eax,BYTE PTR [eax]
0x804858a <PJeGPC4TIVaKFmmy53DJ+86>: test al,al
0x804858c <PJeGPC4TIVaKFmmy53DJ+88>: je 0x8048808 <PJeGPC4TIVaKFmmy53DJ+724>
0x8048592 <PJeGPC4TIVaKFmmy53DJ+94>: mov eax,DWORD PTR [ebp-0x14]
0x8048595 <PJeGPC4TIVaKFmmy53DJ+97>: add eax,DWORD PTR [ebp+0x8]
0x8048598 <PJeGPC4TIVaKFmmy53DJ+100>: mov edx,DWORD PTR [ebp-0x14]
0x804859b <PJeGPC4TIVaKFmmy53DJ+103>: add edx,DWORD PTR [ebp+0x8]
0x804859e <PJeGPC4TIVaKFmmy53DJ+106>: movzx edx,BYTE PTR [edx]
0x80485a1 <PJeGPC4TIVaKFmmy53DJ+109>: xor dl,BYTE PTR [ebp-0x1]
0x80485a4 <PJeGPC4TIVaKFmmy53DJ+112>: mov BYTE PTR [eax],dl
0x80485a6 <PJeGPC4TIVaKFmmy53DJ+114>: add DWORD PTR [ebp-0x14],0x1
0x80485aa <PJeGPC4TIVaKFmmy53DJ+118>: mov eax,DWORD PTR [ebp-0x14]
0x80485ad <PJeGPC4TIVaKFmmy53DJ+121>: add eax,DWORD PTR [ebp+0x8]
0x80485b0 <PJeGPC4TIVaKFmmy53DJ+124>: movzx eax,BYTE PTR [eax]
0x80485b3 <PJeGPC4TIVaKFmmy53DJ+127>: test al,al
0x80485b5 <PJeGPC4TIVaKFmmy53DJ+129>: je 0x804880b <PJeGPC4TIVaKFmmy53DJ+727>
0x80485bb <PJeGPC4TIVaKFmmy53DJ+135>: mov eax,DWORD PTR [ebp-0x14]
0x80485be <PJeGPC4TIVaKFmmy53DJ+138>: add eax,DWORD PTR [ebp+0x8]
0x80485c1 <PJeGPC4TIVaKFmmy53DJ+141>: mov edx,DWORD PTR [ebp-0x14]
0x80485c4 <PJeGPC4TIVaKFmmy53DJ+144>: add edx,DWORD PTR [ebp+0x8]
0x80485c7 <PJeGPC4TIVaKFmmy53DJ+147>: movzx edx,BYTE PTR [edx]
0x80485ca <PJeGPC4TIVaKFmmy53DJ+150>: xor dl,BYTE PTR [ebp-0x2]</code>
Ця частина цікава. Я бачу маніпулювання константами і те, що до що подається даними на вхід застосовується XOR констант. Продовжимо…

(gdb) x/30i X1bdrhN8Yk9NZ59Vb7P2
0x8048838 <X1bdrhN8Yk9NZ59Vb7P2>: sbb ecx,DWORD PTR [ecx+0x20ec83e5]
0x804883e <X1bdrhN8Yk9NZ59Vb7P2+6>: mov DWORD PTR [ebp-0x18],0x0
0x8048845 <X1bdrhN8Yk9NZ59Vb7P2+13>: mov BYTE PTR [ebp-0x1],0xd9
0x8048849 <X1bdrhN8Yk9NZ59Vb7P2+17>: mov BYTE PTR [ebp-0x2],0xcd
0x804884d <X1bdrhN8Yk9NZ59Vb7P2+21>: mov BYTE PTR [ebp-0x3],0xc9
0x8048851 <X1bdrhN8Yk9NZ59Vb7P2+25>: mov BYTE PTR [ebp-0x4],0xe5
0x8048855 <X1bdrhN8Yk9NZ59Vb7P2+29>: mov BYTE PTR [ebp-0x5],0x9e
0x8048859 <X1bdrhN8Yk9NZ59Vb7P2+33>: mov BYTE PTR [ebp-0x6],0xd0
0x804885d <X1bdrhN8Yk9NZ59Vb7P2+37>: mov BYTE PTR [ebp-0x7],0xe8
0x8048861 <X1bdrhN8Yk9NZ59Vb7P2+41>: mov BYTE PTR [ebp-0x8],0xa5
0x8048865 <X1bdrhN8Yk9NZ59Vb7P2+45>: mov BYTE PTR [ebp-0x9],0xaf
0x8048869 <X1bdrhN8Yk9NZ59Vb7P2+49>: mov BYTE PTR [ebp-0xa],0x87
0x804886d <X1bdrhN8Yk9NZ59Vb7P2+53>: mov BYTE PTR [ebp-0xb],0xd2
0x8048871 <X1bdrhN8Yk9NZ59Vb7P2+57>: mov BYTE PTR [ebp-0xc],0x79
0x8048875 <X1bdrhN8Yk9NZ59Vb7P2+61>: mov BYTE PTR [ebp-0xd],0xa9
0x8048879 <X1bdrhN8Yk9NZ59Vb7P2+65>: mov BYTE PTR [ebp-0xe],0x5d
0x804887d <X1bdrhN8Yk9NZ59Vb7P2+69>: mov BYTE PTR [ebp-0xf],0x7
0x8048881 <X1bdrhN8Yk9NZ59Vb7P2+73>: mov BYTE PTR [ebp-0x10],0x81
0x8048885 <X1bdrhN8Yk9NZ59Vb7P2+77>: mov DWORD PTR [ebp-0x14],0x0
0x804888c <X1bdrhN8Yk9NZ59Vb7P2+84>: mov eax,DWORD PTR [ebp-0x14]
0x804888f <X1bdrhN8Yk9NZ59Vb7P2+87>: add eax,DWORD PTR [ebp+0x8]
0x8048892 <X1bdrhN8Yk9NZ59Vb7P2+90>: movzx eax,BYTE PTR [eax]
0x8048895 <X1bdrhN8Yk9NZ59Vb7P2+93>: cmp al,BYTE PTR [ebp-0x1]
0x8048898 <X1bdrhN8Yk9NZ59Vb7P2+96>: je 0x80488a2 <X1bdrhN8Yk9NZ59Vb7P2+106>
0x804889a <X1bdrhN8Yk9NZ59Vb7P2+98>: mov eax,DWORD PTR [ebp-0x18]
Ще константи…

Та частина функції:

0x804889d <X1bdrhN8Yk9NZ59Vb7P2+101>: jmp 0x8048a20 <X1bdrhN8Yk9NZ59Vb7P2+488>
0x80488a2 <X1bdrhN8Yk9NZ59Vb7P2+106>: add DWORD PTR [ebp-0x14],0x1
0x80488a6 <X1bdrhN8Yk9NZ59Vb7P2+110>: mov eax,DWORD PTR [ebp-0x14]
0x80488a9 <X1bdrhN8Yk9NZ59Vb7P2+113>: add eax,DWORD PTR [ebp+0x8]
0x80488ac <X1bdrhN8Yk9NZ59Vb7P2+116>: movzx eax,BYTE PTR [eax]
0x80488af <X1bdrhN8Yk9NZ59Vb7P2+119>: cmp al,BYTE PTR [ebp-0x2]
0x80488b2 <X1bdrhN8Yk9NZ59Vb7P2+122>: je 0x80488bc <X1bdrhN8Yk9NZ59Vb7P2+132>
0x80488b4 <X1bdrhN8Yk9NZ59Vb7P2+124>: mov eax,DWORD PTR [ebp-0x18]
0x80488b7 <X1bdrhN8Yk9NZ59Vb7P2+127>: jmp 0x8048a20 <X1bdrhN8Yk9NZ59Vb7P2+488>
0x80488bc <X1bdrhN8Yk9NZ59Vb7P2+132>: add DWORD PTR [ebp-0x14],0x1
0x80488c0 <X1bdrhN8Yk9NZ59Vb7P2+136>: mov eax,DWORD PTR [ebp-0x14]
0x80488c3 <X1bdrhN8Yk9NZ59Vb7P2+139>: add eax,DWORD PTR [ebp+0x8]
0x80488c6 <X1bdrhN8Yk9NZ59Vb7P2+142>: movzx eax,BYTE PTR [eax]
0x80488c9 <X1bdrhN8Yk9NZ59Vb7P2+145>: cmp al,BYTE PTR [ebp-0x3]
0x80488cc <X1bdrhN8Yk9NZ59Vb7P2+148>: je 0x80488d6 <X1bdrhN8Yk9NZ59Vb7P2+158>
0x80488ce <X1bdrhN8Yk9NZ59Vb7P2+150>: mov eax,DWORD PTR [ebp-0x18]
0x80488d1 <X1bdrhN8Yk9NZ59Vb7P2+153>: jmp 0x8048a20 <X1bdrhN8Yk9NZ59Vb7P2+488>
0x80488d6 <X1bdrhN8Yk9NZ59Vb7P2+158>: add DWORD PTR [ebp-0x14],0x1
0x80488da <X1bdrhN8Yk9NZ59Vb7P2+162>: mov eax,DWORD PTR [ebp-0x14]
0x80488dd <X1bdrhN8Yk9NZ59Vb7P2+165>: add eax,DWORD PTR [ebp+0x8]
---Type <return> to continue, or q <return> to quit---
0x80488e0 <X1bdrhN8Yk9NZ59Vb7P2+168>: movzx eax,BYTE PTR [eax]
0x80488e3 <X1bdrhN8Yk9NZ59Vb7P2+171>: cmp al,BYTE PTR [ebp-0x4]
0x80488e6 <X1bdrhN8Yk9NZ59Vb7P2+174>: je 0x80488f0 <X1bdrhN8Yk9NZ59Vb7P2+184>
0x80488e8 <X1bdrhN8Yk9NZ59Vb7P2+176>: mov eax,DWORD PTR [ebp-0x18]
0x80488eb <X1bdrhN8Yk9NZ59Vb7P2+179>: jmp 0x8048a20 <X1bdrhN8Yk9NZ59Vb7P2+488>
0x80488f0 <X1bdrhN8Yk9NZ59Vb7P2+184>: add DWORD PTR [ebp-0x14],0x1
0x80488f4 <X1bdrhN8Yk9NZ59Vb7P2+188>: mov eax,DWORD PTR [ebp-0x14]
0x80488f7 <X1bdrhN8Yk9NZ59Vb7P2+191>: add eax,DWORD PTR [ebp+0x8]
0x80488fa <X1bdrhN8Yk9NZ59Vb7P2+194>: movzx eax,BYTE PTR [eax]
0x80488fd <X1bdrhN8Yk9NZ59Vb7P2+197>: cmp al,BYTE PTR [ebp-0x5]
0x8048900 <X1bdrhN8Yk9NZ59Vb7P2+200>: je 0x804890a <X1bdrhN8Yk9NZ59Vb7P2+210>
0x8048902 <X1bdrhN8Yk9NZ59Vb7P2+202>: mov eax,DWORD PTR [ebp-0x18]
0x8048905 <X1bdrhN8Yk9NZ59Vb7P2+205>: jmp 0x8048a20 <X1bdrhN8Yk9NZ59Vb7P2+488>
0x804890a <X1bdrhN8Yk9NZ59Vb7P2+210>: add DWORD PTR [ebp-0x14],0x1
0x804890e <X1bdrhN8Yk9NZ59Vb7P2+214>: mov eax,DWORD PTR [ebp-0x14]
Чи бачите ви ті ж закономірності, що бачу я? Якщо ні — не біда.
Тут у програмі перевіряється мій введення поксоренный з константами.
Тепер ще раз подивимося на введення, перші байти ксорятся з деякими константами, і потім висновок порівнюється з іншими костантами.
Останні дві функції повинні виглядати якось так:

void PJeGPC4TIVaKFmmy53DJ (int * p)
{
int array[] = {0xe4,0x87,0xfb,0xbe,0xc9,0x93,0x84,0xfc,0x8d,0xe5,0xbf,0x5c,0xe2,0x76,0x21,0xb8}
for(i=0;i<16;i++)
{
p[i] = p[i] ^ array[i]
}
}
int X1bdrhN8Yk9NZ59Vb7P2(int * p)
{
int array = {0xd9,0xcd,0xc9,0xe5,0x9e,0xd0,0xe8,0xa5,0xaf,0x87,0xd2,0x79,0xa9,0x5d,0x7,0x81}
for(i=0;i<16;i++)
{
if(p[i] != array[i])
return false; // fail…
}
return true
}
Я накидав скрипт на Python щоб застосувати XOR до цих констант і знайшов ключ:

#!/usr/bin/python
firstConst = [0xe4,0x87,0xfb,0xbe,0xc9,0x93,0x84,0xfc,0x8d,0xe5,0xbf,0x5c,0xe2,0x76,0x21,0xb8]
secondConst = [0xd9,0xcd,0xc9,0xe5,0x9e,0xd0,0xe8,0xa5,0xaf,0x87,0xd2,0x79,0xa9,0x5d,0x7,0x81]
ret =""
for x in range(16):
ret+=chr(firstConst[x] ^ secondConst[x])
print ret
eren@lisa:~$ ./CrackTheDoor

*** DOOR CONTROL SYSTEM ***

PASSWORD: =J2[WClY«bm%K+&9

*** ACCESS GRANTED ***

*** THE DOOR OPENED ***
Voilà!

Компанія надіслала мені другу частину, так що незабаром я напишу ще одну статтю.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.