Это выдает ошибку сегментации (ядро сброшено) - PullRequest
0 голосов
/ 22 сентября 2019

Так что я сейчас работаю над ctf, что в основном заставляет меня что-то делать на C. Это базовая программа, которая проверяет, равен ли вывод функции check_password хэш-коду.Я решил перебить это, поэтому написал код.Вероятно, есть какой-то более простой способ сделать это, я хочу немного проверить свои навыки кодирования и, возможно, узнать немного больше о Си по пути.Поэтому я написал этот код, который увеличивает аргумент, переданный функции check_password, каждый цикл равен 1, а затем сравнивает вывод с хеш-кодом.Когда я запускаю эту программу, она выдает ошибку «Ошибка сегментации (ядро выгружено)».

Я уже пытался найти проблему в поиске, но, похоже, я не понимал, в чем конкретно заключалась ошибка в моем коде.Вот мой код:

#include <stdio.h>
#include <stdbool.h>
unsigned long hashcode = 0x21DD09EC;
unsigned long check_password(const char* p){
        int* ip = (int*)p;
        int i;
        int res=0;
        for(i=0; i<5; i++){
                res += ip[i];
        }
        return res;
}

int main()
{
    const char* i = 0;
    long current_guess;
    bool found = false;
    while(!found) {
        current_guess = check_password(i);
        if(current_guess == hashcode) {
            printf(i);
            found = true;
            break;
        }
        else {
            i++;
            continue;
        }
    }

    return 0;
}

Так что он должен пройти через все параметры и распечатать его, как только это будет сделано, за исключением того, что выдает ошибку.Помощь была бы признательна.

Вот код программы, которую я пытаюсь получить пароль слишком кстати между прочим

#include <stdio.h>
#include <string.h>
unsigned long hashcode = 0x21DD09EC;
unsigned long check_password(const char* p){
        int* ip = (int*)p;
        int i;
        int res=0;
        for(i=0; i<5; i++){
                res += ip[i];
        }
        return res;
}

int main(int argc, char* argv[]){
        if(argc<2){
                printf("usage : %s [passcode]\n", argv[0]);
                return 0;
        }
        if(strlen(argv[1]) != 20){
                printf("passcode length should be 20 bytes\n");
                return 0;
        }

        if(hashcode == check_password( argv[1] )){
                system("/bin/cat flag");
                return 0;
        }
        else
                printf("wrong passcode.\n");
        return 0;
}

Ответы [ 3 ]

0 голосов
/ 22 сентября 2019

Это потому, что вы передаете i как указатель, а затем разыменовываете его.Таким образом, вы будете разыменовывать 0x1, адрес, к которому у вас нет прав доступа, и получите SIGSEGV.

Плюс, вы точно не уверены, что вы пытаетесь сделать с этой программой.Функция проверки пароля пытается получить доступ к int как массиву, что не имеет смысла.

Редактировать: с полным кодом это имеет гораздо больше смысла.Программа выполняет следующее: принимает первый аргумент (argv [1]), если его длина равна 20 (иначе говоря, если аргумент представляет собой строку из 20 символов), то он будет передан функции check_password.Теперь вам нужно довольно хорошее знание C, чтобы понять, что происходит.

Указатель на вашу строку, char const *, теперь приводится как указатель на int.Символ всегда один байт.Int обычно 4 байта.Ваша строка символов теперь будет читаться как массив int.

Давайте возьмем строку «test».Он кодируется в памяти следующим образом: 0x74(t) 0x73(s) 0x65(e) 0x74(t) Вы заметите, что он перевернут.Это связано с тем, что большинство компьютеров в настоящее время имеют порядок байтов (то есть самый большой бит читается первым).Когда эта строка преобразуется как int и access, она будет читаться как int со значением 0x74736574, иначе 1953719668.

Контрольный пароль повторяется в этом массиве int 5 раз.Он добавит первые 5 целых чисел, которые он читает, что означает, что если мы возьмем следующий пароль: abcdefghijklmnopqrst, результат будет следующим:

first loop:
res = 0x64636261
second loop:
res += 0x68676665
third loop:
res += 0x72717069
fourth loop:
res += 0x76757473
last loop:
res += 0x7a797877

Ваша цель - достичь значения 0x21DD09EC с паролем,Один из многих возможных ответов будет: 0fwzzzgzabafgccczc9c

0 голосов
/ 22 сентября 2019

Не уверен, что вы пытаетесь достичь, но

const char* i = 0;

i - это точка указателя на адрес 0, которая может быть причиной ошибки сегментации.Вы можете попробовать назначить указатель на ваш ввод, прежде чем использовать указатель.

const char input[10];

i = input;
0 голосов
/ 22 сентября 2019

ОК, мой первоначальный ответ был не тем, который вы хотели.Теперь, когда вы пояснили:

Функция check_password делает что-то "немного непослушное" при приведении указателя const char* к указателю int*, но это нормально.Для него требуется не менее 20 символов, поэтому строку можно «интерпретировать» как массив из 5 целых чисел.

Когда вы вызываете эту функцию, вам необходимо передать ей строку символов (не менее 20 символов),В приведенном выше примере main эта строка равна argv[1], что является первым параметром, заданным программе после ее имени;Итак, если вы запустите программу с «checkpw ABCD1234WXYZ5678aaaa», то строка ABC ... будет данными, передаваемыми в функцию.

Помогает ли это?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...