Доброго времени суток. Т.к. по мне лучший способ разбираться с языком на начальных этапах это колупать чужие алгоритмы, нарыл себе в архив с десяток заданий с разных локальных CTF (задания на ревёрс. меня интересовало по большей части то, где нужно было реверсить алгоритм криптографический).
Помогите разобраться не с обратной операцией, а вообще с самим алгоритмом работы
Код:
#include <iostream>
#include <fstream>
#include <vector>
#include <array>
#include <sstream>
#include <string>
const std::string configFileName = "keys.cfg";
const std::string textFileName = "code.cd";
const std::string cryptoFileName = "crypto.cd";
std::array<std::string,6> allowedKey = {"AUTHENTIC",
"CORRECT",
"ACTUAL",
"GENUINE",
"ERITABLE",
"FLAG"};
int isAllowedKey(std::string key)
{
for (int i = 0; i < allowedKey.size(); i++)
{
if (allowedKey.at(i) == key)
return i;
}
return -1;
}
std::vector<std::string> split(const std::string &s, char delim) {
std::stringstream ss(s);
std::string item;
std::vector<std::string> elems;
while (std::getline(ss, item, delim)) {
elems.push_back(item);
}
return elems;
}
void writeCrypto(const std::string& text)
{
std::ofstream file(cryptoFileName, std::ios::out);
file << text;
file.close();
}
std::string getKey()
{
std::vector<std::pair<std::string, std::string>> keys;
char readBuf1[1000];
char readBuf2[1000];
std::ifstream file(configFileName, std::ios::in);
while (!file.eof())
{
file >> readBuf1;
file >> readBuf2;
keys.push_back(std::pair<std::string, std::string>{readBuf1, readBuf2});
}
file.close();
std::string words="";
for (int i = 0; i < keys.size(); i++)
{
std::vector<std::string> vec = split(keys[i].first, '_');
if (isAllowedKey(vec.at(0))!=-1 && i < keys.size() - 1)
{
words.insert(words.length(),split(keys[i + 1].first, '_')[0]);
}
if (isAllowedKey(vec.at(0))==5)
{
keys[i].second.insert(keys[i].second.length()-1,(words+keys[i].first));
words=keys[i].second;
int length=words.length();
int sum = 0;
do {
int tmp = length % 10;
sum+= tmp;
} while (length = length / 10);
sum %= keys.size();
words = keys[sum].second;
break;
}
}
return words;
}
std::string getText()
{
std::ifstream file(textFileName);
std::string str((std::istreambuf_iterator<char>(file)),
std::istreambuf_iterator<char>());
file.close();
return str;// "this is text";
}
std::string getAlf()
{
return "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.,!&- ";
}
std::string code(const std::string& alf, std::string key,const std::string& text)
{
std::string crypto;
int textLength = text.length();
int keyLength = key.length();
for (int i = keyLength; i < textLength; i++)
{
key += key[i%keyLength];
}
int ind1, ind2;
int alfLength = alf.length();
for (int i = 0; i<textLength; i++)
{
ind1 = alf.find(text[i]);
ind2 = alf.find(key[i]);
crypto.insert(i, 1, alf.at((ind1 + ind2) % alfLength));
}
return crypto;
}
int main()
{
const std::string alf = getAlf();
std::string key = getKey();
if (key == "")
return 0;
std::string text = getText();
std::string crypto = code(alf, key, text);
writeCrypto(crypto);
return 0;
}
Также к проге понятное дело прилагается два файла
В вайле Keys:
Код:
AUTHENTIC_KEY FREEMAN'SMIND
THIS_IS_KEY FORDOOMHAMMER!
FALSE_KEY HL3COCONFIRMED
THIS_IS_NOT_THE_KEY CAKEISLIE
CORRECT_KEY LEAVEMEALONE
IS_IT_KEY? AFAKEISAFAKE
FEIGNED_KEY AYBABTU
THE_BIG_KEY GABEISOURGOD
ACTUAL_KEY DRAKEFACE
THE_KEY FORTHEFROZENTHRONE!
WRONG_KEY THISISMYBOOMSTICK
I_AM_THE_KEY 'TISBUTASCRATCH
GENUINE_KEY HEY!LISTEN!
REAL_KEY MTLIFEFORNERZHUL
VERITABLE_KEY PRESSCONTROLALTDELETE
FLAG IBFLAG{}
В другом файле текст который будем шифровать
В чем сабж: я никак не могу понять принцип работы программы. т.е. она очень нестабильна. при попытке изменить файл ключей может как продолжить работу, а может вылететь с ошибкой, некоторые из интересных параметров намертво зашиты в коде.
Какую роль вообще играет последняя строчка в файле KEYS, если для элемента sum она не учитывается...
может это просто кривой код?