Волан-де-Морт спрятал свою расколотую душу в семи крестражах.
Найдите все крестражи и РАЗДЕЛАЙТЕ их!
автор: jiwon choi

ssh [email protected] -p2222 (pw: гость)

Хоркруксы - это 32-битный двоичный файл ELF, который инициализирует в памяти 7 хоркруксов Волан-де-Морта. У Horcuxes есть случайные константы, которые нам нужно вывести, чтобы победить Волан-де-Морта.

horcruxes@prowl:~$ ./horcruxes 
Voldemort concealed his splitted soul inside 7 horcruxes.
Find all horcruxes, and destroy it!
Select Menu:222
How many EXP did you earned? : 2222
You'd better get more experience to kill Voldemort

Давайте посмотрим, что такое EXP и как мы можем предсказать, что он убьет Волдеморта. Это основная подпрограмма:

gdb-peda$ disassemble main 
Dump of assembler code for function main:
   0x0809ff24 <+0>:     lea    ecx,[esp+0x4]
   0x0809ff28 <+4>:     and    esp,0xfffffff0
   0x0809ff2b <+7>:     push   DWORD PTR [ecx-0x4]
   0x0809ff2e <+10>:    push   ebp
   0x0809ff2f <+11>:    mov    ebp,esp
   0x0809ff31 <+13>:    push   ecx
   0x0809ff32 <+14>:    sub    esp,0x14
   0x0809ff35 <+17>:    mov    eax,ds:0x80a2064
   0x0809ff3a <+22>:    push   0x0
   0x0809ff3c <+24>:    push   0x2
   0x0809ff3e <+26>:    push   0x0
   0x0809ff40 <+28>:    push   eax
   0x0809ff41 <+29>:    call   0x809fcf0 <setvbuf@plt>
   0x0809ff46 <+34>:    add    esp,0x10
   0x0809ff49 <+37>:    mov    eax,ds:0x80a2060
   0x0809ff4e <+42>:    push   0x0
   0x0809ff50 <+44>:    push   0x2
   0x0809ff52 <+46>:    push   0x0
   0x0809ff54 <+48>:    push   eax
   0x0809ff55 <+49>:    call   0x809fcf0 <setvbuf@plt>
   0x0809ff5a <+54>:    add    esp,0x10
   0x0809ff5d <+57>:    sub    esp,0xc
   0x0809ff60 <+60>:    push   0x3c
   0x0809ff62 <+62>:    call   0x809fc90 <alarm@plt>
   0x0809ff67 <+67>:    add    esp,0x10
   0x0809ff6a <+70>:    call   0x80a0324 <hint>
   0x0809ff6f <+75>:    call   0x80a0177 <init_ABCDEFG>
   0x0809ff74 <+80>:    sub    esp,0xc
   0x0809ff77 <+83>:    push   0x0
   0x0809ff79 <+85>:    call   0x809fc20 <seccomp_init@plt>
   0x0809ff7e <+90>:    add    esp,0x10
   0x0809ff81 <+93>:    mov    DWORD PTR [ebp-0xc],eax
   0x0809ff84 <+96>:    push   0x0
   0x0809ff86 <+98>:    push   0xad
   0x0809ff8b <+103>:   push   0x7fff0000
   0x0809ff90 <+108>:   push   DWORD PTR [ebp-0xc]
   0x0809ff93 <+111>:   call   0x809fc60 <seccomp_rule_add@plt>
   0x0809ff98 <+116>:   add    esp,0x10
   0x0809ff9b <+119>:   push   0x0
   0x0809ff9d <+121>:   push   0x5
   0x0809ff9f <+123>:   push   0x7fff0000
   0x0809ffa4 <+128>:   push   DWORD PTR [ebp-0xc]
   0x0809ffa7 <+131>:   call   0x809fc60 <seccomp_rule_add@plt>
   0x0809ffac <+136>:   add    esp,0x10
   0x0809ffaf <+139>:   push   0x0
   0x0809ffb1 <+141>:   push   0x3
   0x0809ffb3 <+143>:   push   0x7fff0000
   0x0809ffb8 <+148>:   push   DWORD PTR [ebp-0xc]
   0x0809ffbb <+151>:   call   0x809fc60 <seccomp_rule_add@plt>
   0x0809ffc0 <+156>:   add    esp,0x10
   0x0809ffc3 <+159>:   push   0x0
   0x0809ffc5 <+161>:   push   0x4
   0x0809ffc7 <+163>:   push   0x7fff0000
   0x0809ffcc <+168>:   push   DWORD PTR [ebp-0xc]
   0x0809ffcf <+171>:   call   0x809fc60 <seccomp_rule_add@plt>
   0x0809ffd4 <+176>:   add    esp,0x10
   0x0809ffd7 <+179>:   push   0x0
   0x0809ffd9 <+181>:   push   0xfc
   0x0809ffde <+186>:   push   0x7fff0000
   0x0809ffe3 <+191>:   push   DWORD PTR [ebp-0xc]
   0x0809ffe6 <+194>:   call   0x809fc60 <seccomp_rule_add@plt>
   0x0809ffeb <+199>:   add    esp,0x10
   0x0809ffee <+202>:   sub    esp,0xc
   0x0809fff1 <+205>:   push   DWORD PTR [ebp-0xc]
   0x0809fff4 <+208>:   call   0x809fc80 <seccomp_load@plt>
   0x0809fff9 <+213>:   add    esp,0x10
   0x0809fffc <+216>:   call   0x80a0009 <ropme>
   0x080a0001 <+221>:   mov    ecx,DWORD PTR [ebp-0x4]
   0x080a0004 <+224>:   leave  
   0x080a0005 <+225>:   lea    esp,[ecx-0x4]
   0x080a0008 <+228>:   ret    
End of assembler dump.
gdb-peda$ 
[main_tmux<g-off.tower-research.com[adogra]

init_ABCDEFG инициализирует 7 наших крестражей в памяти.

gdb-peda$ disassemble init_ABCDEFG
Dump of assembler code for function init_ABCDEFG:
   0x080a0177 <+0>:     push   ebp
   0x080a0178 <+1>:     mov    ebp,esp
   0x080a017a <+3>:     sub    esp,0x18
   0x080a017d <+6>:     sub    esp,0x8
   0x080a0180 <+9>:     push   0x0
   0x080a0182 <+11>:    push   0x80a0577
   0x080a0187 <+16>:    call   0x809fcc0 <open@plt>
   0x080a018c <+21>:    add    esp,0x10
   0x080a018f <+24>:    mov    DWORD PTR [ebp-0xc],eax
   0x080a0192 <+27>:    sub    esp,0x4
   0x080a0195 <+30>:    push   0x4
   0x080a0197 <+32>:    lea    eax,[ebp-0x10]
   0x080a019a <+35>:    push   eax
   0x080a019b <+36>:    push   DWORD PTR [ebp-0xc]
   0x080a019e <+39>:    call   0x809fc30 <read@plt>
   0x080a01a3 <+44>:    add    esp,0x10
   0x080a01a6 <+47>:    cmp    eax,0x4
   0x080a01a9 <+50>:    je     0x80a01c5 <init_ABCDEFG+78>
   0x080a01ab <+52>:    sub    esp,0xc
   0x080a01ae <+55>:    push   0x80a0584
   0x080a01b3 <+60>:    call   0x809fca0 <puts@plt>
   0x080a01b8 <+65>:    add    esp,0x10
   0x080a01bb <+68>:    sub    esp,0xc
   0x080a01be <+71>:    push   0x0
   0x080a01c0 <+73>:    call   0x809fcb0 <exit@plt>
   .
   .
   0x080a01df <+104>:   add    esp,0x10
   0x080a01e2 <+107>:   call   0x809fd00 <rand@plt>
   0x080a01e7 <+112>:   imul   edx,eax,0xdeadbeef
   0x080a01ed <+118>:   cmp    edx,0xcafebabe
   0x080a01f3 <+124>:   setae  al
   0x080a01f6 <+127>:   movzx  eax,al
   0x080a01f9 <+130>:   imul   eax,eax,0xcafebabe
   0x080a01ff <+136>:   sub    edx,eax
   0x080a0201 <+138>:   mov    eax,edx
   0x080a0203 <+140>:   mov    ds:0x80a2088,eax
   0x080a0208 <+145>:   call   0x809fd00 <rand@plt>
   0x080a020d <+150>:   imul   edx,eax,0xdeadbeef
   0x080a0213 <+156>:   cmp    edx,0xcafebabe
   0x080a0219 <+162>:   setae  al
   0x080a021c <+165>:   movzx  eax,al
   0x080a021f <+168>:   imul   eax,eax,0xcafebabe
   0x080a0225 <+174>:   sub    edx,eax
   0x080a0227 <+176>:   mov    eax,edx
   0x080a0229 <+178>:   mov    ds:0x80a2070,eax
   0x080a022e <+183>:   call   0x809fd00 <rand@plt>
   0x080a0233 <+188>:   imul   edx,eax,0xdeadbeef
   0x080a0239 <+194>:   cmp    edx,0xcafebabe
   0x080a023f <+200>:   setae  al
   0x080a0242 <+203>:   movzx  eax,al
   0x080a0245 <+206>:   imul   eax,eax,0xcafebab
   .
   0x080a02c1 <+330>:   mov    ds:0x80a2074,eax
   0x080a02c6 <+335>:   call   0x809fd00 <rand@plt>
   0x080a02cb <+340>:   imul   edx,eax,0xdeadbeef
   0x080a02d1 <+346>:   cmp    edx,0xcafebabe
   0x080a02d7 <+352>:   setae  al
   0x080a02da <+355>:   movzx  eax,al
   0x080a02dd <+358>:   imul   eax,eax,0xcafebabe
   0x080a02e3 <+364>:   sub    edx,eax
   0x080a02e5 <+366>:   mov    eax,edx
   0x080a02e7 <+368>:   mov    ds:0x80a207c,eax
   0x080a02ec <+373>:   mov    edx,DWORD PTR ds:0x80a2088
   0x080a02f2 <+379>:   mov    eax,ds:0x80a2070
   0x080a02f7 <+384>:   add    edx,eax
   0x080a02f9 <+386>:   mov    eax,ds:0x80a2084
   0x080a02fe <+391>:   add    edx,eax
   0x080a0300 <+393>:   mov    eax,ds:0x80a206c
   0x080a0305 <+398>:   add    edx,eax
   0x080a0307 <+400>:   mov    eax,ds:0x80a2080
   0x080a030c <+405>:   add    edx,eax
   0x080a030e <+407>:   mov    eax,ds:0x80a2074
   0x080a0313 <+412>:   add    edx,eax
   0x080a0315 <+414>:   mov    eax,ds:0x80a207c
   0x080a031a <+419>:   add    eax,edx
   0x080a031c <+421>:   mov    ds:0x80a2078,eax
   0x080a0321 <+426>:   nop
   0x080a0322 <+427>:   leave  
   0x080a0323 <+428>:   ret

Функция init считывает некоторые байты из / dev / urandom, а затем выполняет арифметические операции и устанавливает константы в памяти. В конце концов, он суммирует эти константы и сохраняет их в ds: 0x80a2078.

После инициализации и настройки профилей seccomp. ropme называется следующим.

gdb-peda$ disassemble ropme
Dump of assembler code for function ropme:
   0x080a0009 <+0>:     push   ebp
   0x080a000a <+1>:     mov    ebp,esp
   0x080a000c <+3>:     sub    esp,0x78
   0x080a000f <+6>:     sub    esp,0xc
   0x080a0012 <+9>:     push   0x80a050c
   0x080a0017 <+14>:    call   0x809fc40 <printf@plt>
   0x080a001c <+19>:    add    esp,0x10
   0x080a001f <+22>:    sub    esp,0x8
   0x080a0022 <+25>:    lea    eax,[ebp-0x10]
   0x080a0025 <+28>:    push   eax
   0x080a0026 <+29>:    push   0x80a0519
   0x080a002b <+34>:    call   0x809fd10 <__isoc99_scanf@plt>
   0x080a0030 <+39>:    add    esp,0x10
   0x080a0033 <+42>:    call   0x809fc70 <getchar@plt>
   0x080a0038 <+47>:    mov    edx,DWORD PTR [ebp-0x10]
   0x080a003b <+50>:    mov    eax,ds:0x80a2088
   0x080a0040 <+55>:    cmp    edx,eax
   0x080a0042 <+57>:    jne    0x80a004e <ropme+69>
   0x080a0044 <+59>:    call   0x809fe4b <A>
   0x080a0049 <+64>:    jmp    0x80a0170 <ropme+359>
   0x080a004e <+69>:    mov    edx,DWORD PTR [ebp-0x10]
   0x080a0051 <+72>:    mov    eax,ds:0x80a2070
   0x080a0056 <+77>:    cmp    edx,eax
   0x080a0058 <+79>:    jne    0x80a0064 <ropme+91>
   0x080a005a <+81>:    call   0x809fe6a <B>
   0x080a005f <+86>:    jmp    0x80a0170 <ropme+359>
   0x080a0064 <+91>:    mov    edx,DWORD PTR [ebp-0x10]
   0x080a0067 <+94>:    mov    eax,ds:0x80a2084
   0x080a006c <+99>:    cmp    edx,eax
   0x080a006e <+101>:   jne    0x80a007a <ropme+113>
   0x080a0070 <+103>:   call   0x809fe89 <C>
   .
   .
   .
   0x080a00da <+209>:   call   0x809fc40 <printf@plt>
   0x080a00df <+214>:   add    esp,0x10
   0x080a00e2 <+217>:   sub    esp,0xc
   0x080a00e5 <+220>:   lea    eax,[ebp-0x74]
   0x080a00e8 <+223>:   push   eax
   0x080a00e9 <+224>:   call   0x809fc50 <gets@plt>
   0x080a00ee <+229>:   add    esp,0x10
   0x080a00f1 <+232>:   sub    esp,0xc
   0x080a00f4 <+235>:   lea    eax,[ebp-0x74]
   0x080a00f7 <+238>:   push   eax
   0x080a00f8 <+239>:   call   0x809fd20 <atoi@plt>
   0x080a00fd <+244>:   add    esp,0x10
   0x080a0100 <+247>:   mov    edx,eax
   0x080a0102 <+249>:   mov    eax,ds:0x80a2078
   0x080a0107 <+254>:   cmp    edx,eax
   0x080a0109 <+256>:   jne    0x80a0160 <ropme+343>
   0x080a010b <+258>:   sub    esp,0x8
   0x080a010e <+261>:   push   0x0
   0x080a0110 <+263>:   push   0x80a053c
   0x080a0115 <+268>:   call   0x809fcc0 <open@plt>
   0x080a011a <+273>:   add    esp,0x10
   0x080a011d <+276>:   mov    DWORD PTR [ebp-0xc],eax
   0x080a0120 <+279>:   sub    esp,0x4
   0x080a0123 <+282>:   push   0x64
   0x080a0125 <+284>:   lea    eax,[ebp-0x74]
   0x080a0128 <+287>:   push   eax
   0x080a0129 <+288>:   push   DWORD PTR [ebp-0xc]
   0x080a012c <+291>:   call   0x809fc30 <read@plt>
   0x080a0131 <+296>:   add    esp,0x10
   0x080a0134 <+299>:   mov    BYTE PTR [ebp+eax*1-0x74],0x0
   0x080a0139 <+304>:   sub    esp,0xc
   0x080a013c <+307>:   lea    eax,[ebp-0x74]
   0x080a013f <+310>:   push   eax
   0x080a0140 <+311>:   call   0x809fca0 <puts@plt>
   0x080a0145 <+316>:   add    esp,0x10
   0x080a0148 <+319>:   sub    esp,0xc
   0x080a014b <+322>:   push   DWORD PTR [ebp-0xc]
   0x080a014e <+325>:   call   0x809fd30 <close@plt>
   0x080a0153 <+330>:   add    esp,0x10
   0x080a0156 <+333>:   sub    esp,0xc
   0x080a0159 <+336>:   push   0x0
   0x080a015b <+338>:   call   0x809fcb0 <exit@plt>
   0x080a0160 <+343>:   sub    esp,0xc
   0x080a0163 <+346>:   push   0x80a0544
   0x080a0168 <+351>:   call   0x809fca0 <puts@plt>
   0x080a016d <+356>:   add    esp,0x10
   0x080a0170 <+359>:   mov    eax,0x0
   0x080a0175 <+364>:   leave  
   0x080a0176 <+365>:   ret

Целое число, которое мы указываем в приглашении меню, сравнивается с константами, которые мы видели ранее. Если мы предоставим правильное целое число, оно вызовет функцию (A, B, C,…), которая содержит крестраж.

В конце функции есть вызов gets (уязвимый !!), который спрашивает нас, сколько опыта мы получили. Затем EXP сравнивается с константой 0x80a2078, которая является просто суммой наших констант. Если сумма, которую мы предоставляем, верна, программа открывает нам флаг.

Давайте посмотрим, как разобрать эти функции (A, B, C,…):

gdb-peda$ disassemble A
Dump of assembler code for function A:
   0x0809fe4b <+0>:     push   ebp
   0x0809fe4c <+1>:     mov    ebp,esp
   0x0809fe4e <+3>:     sub    esp,0x8
   0x0809fe51 <+6>:     mov    eax,ds:0x80a2088
   0x0809fe56 <+11>:    sub    esp,0x8
   0x0809fe59 <+14>:    push   eax
   0x0809fe5a <+15>:    push   0x80a03d0
   0x0809fe5f <+20>:    call   0x809fc40 <printf@plt>
   0x0809fe64 <+25>:    add    esp,0x10
   0x0809fe67 <+28>:    nop
   0x0809fe68 <+29>:    leave  
   0x0809fe69 <+30>:    ret    
End of assembler dump.
gdb-peda$ x/1s 0x80a03d0
0x80a03d0:      "You found \"Tom Riddle's Diary\" (EXP +%d)\n"
gdb-peda$

Хорошо, он выплевывает константу и распечатывает, что мы нашли крестраж. Теперь задача ясна, нам нужно использовать переполнение в конце функции. Управляйте потоком выполнения и распечатывайте все крестражи один за другим.

Сначала я подумал, почему бы просто не перейти к той части кода, которая выдаёт флаг, нам не нужно будет утечка каких-либо констант. Интересно, что автор, наверное, уже думал об этом, если проверить адреса ropme. Адреса начинаются с 0x080a, 0xa - это символ новой строки, и после этого он перестанет получать наш ввод.

Мы можем легко вычислить адреса каждой из подпрограмм крестража. Просто взглянув на разборку. Все, что нам нужно сделать, это управлять EIP после вызова get, чтобы передать поток в A, B, C… G, а затем снова выполнить операцию и, наконец, ввести сумму утекших констант, чтобы получить флаг.

Вот и наш последний подвиг. Давайте посмотрим на это в действии:

Итак, мы идем! Я больше не ем бутылочку для малышей: D