Не удалось получить корневую оболочку при загрузке функции execl()

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

int good(int addr) {
    printf("Address of hmm: %p\n", addr);
}

int hmm() {
    printf("Win.\n");
    execl("/bin/sh", "sh", NULL);
}

extern char **environ;

int main(int argc, char **argv) {

    int i, limit;

    for(i = 0; environ[i] != NULL; i++) 
        memset(environ[i], 0x00, strlen(environ[i]));

    int (*fptr)(int) = good;
    char buf[32];

    if(strlen(argv[1]) <= 40) limit = strlen(argv[1]);

    for(i = 0; i <= limit; i++) {
        buf[i] = argv[1][i];
        if(i < 36) buf[i] = 0x41;
    }

    int (*hmmptr)(int) = hmm;

    (*fptr)((int)hmmptr);

    return 0;

}

Я скомпилировал приведенную выше программу на C от имени пользователя root без какой-либо защиты стека (gcc -fno-stack-protector -o out test.c) и воспользовался ею как обычный пользователь. Мне не удалось получить корневую оболочку.

Это тот же код, который я использовал в 'smashthestack'.


person Adarsh Dinesh    schedule 28.12.2011    source источник
comment
Чтобы напечатать адрес integer, вам нужно сделать &integer_variable, поэтому printf() должно быть printf("Address of hmm: %p\n", &addr);   -  person Sangeeth Saravanaraj    schedule 28.12.2011
comment
Вы знаете, современные операционные системы имеют множество контрмер для предотвращения атак, разрушающих стек... Кстати, какая у вас unix-подобная ОС?   -  person BatchyX    schedule 28.12.2011
comment
Помимо отсутствующего слепка (char*)NULL, в чем проблема?   -  person Daniel Fischer    schedule 28.12.2011
comment
Друзья, (char*)NULL не работает   -  person Adarsh Dinesh    schedule 28.12.2011


Ответы (2)


Все, что вам нужно, это только следующее, чтобы добраться до оболочки с помощью программы c.

#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[]) 
{
    execl("/bin/sh", "sh", NULL);
    return 0;
}

Выполните указанный выше код в корневой оболочке.

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

for(i = 0; environ[i] != NULL; i++) 
    memset(environ[i], 0x00, strlen(environ[i]));

Но чтобы выполнить свой код, вы должны изменить

printf("Address of hmm: %p\n", addr);

to

printf("Address of hmm: %p\n", &addr);

Я не понимаю, почему вы хотите напечатать адрес переменной в этой функции. OTOH, у самой функции нет цели.

person Sangeeth Saravanaraj    schedule 28.12.2011
comment
ОП хочет запустить программу от имени пользователя без полномочий root и получить корневую оболочку (т. Е. Он написал программу, в которой есть недостаток безопасности, и намеревается использовать этот недостаток в качестве академического упражнения. - person ArjunShankar; 28.12.2011

Вы сделали двоичный файл suid?

Работа под root:

# cd /your/working/directory/
# chmod +s ./out

Если все средства защиты от разрушения стека отключены и ваш код правильный, вы получите корневую оболочку. В противном случае (если защита отключена и код правильный) вы получите только пользовательскую оболочку.

person Mischa Arefiev    schedule 28.12.2011