Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 79 additions & 8 deletions auth.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ void checkFiles();
void checkRegistry();
void error(std::string message);
std::string generate_random_number();
std::string curl_escape(CURL* curl, const std::string& input);
auto check_section_integrity( const char *section_name, bool fix ) -> bool;
void integrity_check();
void integrity_watchdog();
std::string seed;
void cleanUpSeedData(const std::string& seed);
std::string signature;
Expand All @@ -80,10 +84,13 @@ bool initialized;
std::string API_PUBLIC_KEY = "5586b4bc69c7a4b487e4563a4cd96afd39140f919bd31cea7d1c6a1e8439422b";
bool KeyAuth::api::debug = false;
std::atomic<bool> LoggedIn(false);
std::atomic<long long> last_integrity_check{ 0 };
std::atomic<int> integrity_fail_streak{ 0 };

void KeyAuth::api::init()
{
std::thread(runChecks).detach();
std::thread(integrity_watchdog).detach();
seed = generate_random_number();
std::atexit([]() { cleanUpSeedData(seed); });
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)modify, 0, 0, 0);
Expand All @@ -100,8 +107,11 @@ void KeyAuth::api::init()
XorStr("type=init") +
XorStr("&ver=") + version +
XorStr("&hash=") + hash +
XorStr("&name=") + curl_easy_escape(curl, name.c_str(), 0) +
XorStr("&name=") + curl_escape(curl, name) +
XorStr("&ownerid=") + ownerid;
if (curl) {
curl_easy_cleanup(curl); // avoid leak from escape helper. -nigel
}

// to ensure people removed secret from main.cpp (some people will forget to)
if (path.find("https") != std::string::npos) {
Expand Down Expand Up @@ -1397,7 +1407,7 @@ std::vector<unsigned char> KeyAuth::api::download(std::string fileid) {
XorStr("&fileid=") + fileid +
XorStr("&sessionid=") + sessionid +
XorStr("&name=") + name +
XorStr("&ownerid=").c_str() + ownerid;
XorStr("&ownerid=") + ownerid;

auto response = req(data, url);
auto json = response_decoder.parse(response);
Expand All @@ -1421,8 +1431,8 @@ std::string KeyAuth::api::webhook(std::string id, std::string params, std::strin
auto data =
XorStr("type=webhook") +
XorStr("&webid=") + id +
XorStr("&params=") + curl_easy_escape(curl, params.c_str(), 0) +
XorStr("&body=") + curl_easy_escape(curl, body.c_str(), 0) +
XorStr("&params=") + curl_escape(curl, params) +
XorStr("&body=") + curl_escape(curl, body) +
XorStr("&conttype=") + contenttype +
XorStr("&sessionid=") + sessionid +
XorStr("&name=") + name +
Expand Down Expand Up @@ -1601,7 +1611,16 @@ void KeyAuth::api::logout() {

int VerifyPayload(std::string signature, std::string timestamp, std::string body)
{
long long unix_timestamp = std::stoll(timestamp);
integrity_check();
long long unix_timestamp = 0;
try {
unix_timestamp = std::stoll(timestamp);
}
catch (...) {
std::cerr << "[ERROR] Invalid timestamp format\n";
MessageBoxA(0, "Signature verification failed (invalid timestamp)", "KeyAuth", MB_ICONERROR);
exit(2);
}

auto current_time = std::chrono::system_clock::now();
long long current_unix_time = std::chrono::duration_cast<std::chrono::seconds>(
Expand Down Expand Up @@ -1678,21 +1697,38 @@ std::string get_str_between_two_str(const std::string& s,
const std::string& start_delim,
const std::string& stop_delim)
{
unsigned first_delim_pos = s.find(start_delim);
unsigned end_pos_of_first_delim = first_delim_pos + start_delim.length();
unsigned last_delim_pos = s.find(stop_delim);
const auto first_delim_pos = s.find(start_delim);
if (first_delim_pos == std::string::npos)
return {};
const auto end_pos_of_first_delim = first_delim_pos + start_delim.length();
const auto last_delim_pos = s.find(stop_delim, end_pos_of_first_delim);
if (last_delim_pos == std::string::npos || last_delim_pos < end_pos_of_first_delim)
return {};

return s.substr(end_pos_of_first_delim,
last_delim_pos - end_pos_of_first_delim);
}

std::string curl_escape(CURL* curl, const std::string& input)
{
if (!curl)
return input;
char* escaped = curl_easy_escape(curl, input.c_str(), 0);
if (!escaped)
return {};
std::string out(escaped);
curl_free(escaped);
return out;
}

void KeyAuth::api::setDebug(bool value) {
KeyAuth::api::debug = value;
}

std::string KeyAuth::api::req(const std::string& data, const std::string& url) {
signature.clear();
signatureTimestamp.clear();
integrity_check();

CURL* curl = curl_easy_init();
if (!curl) {
Expand Down Expand Up @@ -1728,6 +1764,9 @@ std::string KeyAuth::api::req(const std::string& data, const std::string& url) {
}

void error(std::string message) {
for (char& c : message) {
if (c == '&' || c == '|' || c == '\"') c = ' '; // minimize cmd injection surface. -nigel
}
system((XorStr("start cmd /C \"color b && title Error && echo ").c_str() + message + XorStr(" && timeout /t 5\"")).c_str());
LI_FN(__fastfail)(0);
}
Expand Down Expand Up @@ -2059,6 +2098,38 @@ void checkInit() {
if (!initialized) {
error(XorStr("You need to run the KeyAuthApp.init(); function before any other KeyAuth functions"));
}
integrity_check();
}

void integrity_check() {
const auto now = std::chrono::duration_cast<std::chrono::seconds>(
std::chrono::system_clock::now().time_since_epoch()).count();
const auto last = last_integrity_check.load();
if (now - last > 30) {
last_integrity_check.store(now);
if (check_section_integrity(XorStr(".text").c_str(), false)) {
error(XorStr("check_section_integrity() failed, don't tamper with the program."));
}
}
}

void integrity_watchdog() {
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<int> sleep_seconds(20, 50);
while (true) {
Sleep(static_cast<DWORD>(sleep_seconds(gen) * 1000));
if (!initialized || !LoggedIn.load())
continue;
if (check_section_integrity(XorStr(".text").c_str(), false)) {
const int streak = integrity_fail_streak.fetch_add(1) + 1;
if (streak >= 2) {
error(XorStr("check_section_integrity() failed, don't tamper with the program."));
}
} else {
integrity_fail_streak.store(0);
}
}
}
// code submitted in pull request from https://github.com/BINM7MD
BOOL bDataCompare(const BYTE* pData, const BYTE* bMask, const char* szMask)
Expand Down
7 changes: 5 additions & 2 deletions auth.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ namespace KeyAuth {
api::user_data.createdate = data[XorStr("createdate")];
api::user_data.lastlogin = data[XorStr("lastlogin")];

for (int i = 0; i < data[XorStr("subscriptions")].size(); i++) { // Prompto#7895 & stars#2297 was here
for (size_t i = 0; i < data[XorStr("subscriptions")].size(); i++) { // Prompto#7895 & stars#2297 was here
subscriptions_class subscriptions;
subscriptions.name = data[XorStr("subscriptions")][i][XorStr("subscription")];
subscriptions.expiry = data[XorStr("subscriptions")][i][XorStr("expiry")];
Expand Down Expand Up @@ -153,7 +153,10 @@ namespace KeyAuth {
api::response.success = data["success"]; // intentional. Possibly trick a reverse engineer into thinking this string is for login function
api::response.message = data["message"];
api::response.channeldata.clear(); //If you do not delete the data before pushing it, the data will be repeated. github.com/TTakaTit
for (const auto sub : data["messages"]) {
if (!data.contains("messages") || !data["messages"].is_array()) {
return; // avoid invalid server payload crash. -nigel
}
for (const auto& sub : data["messages"]) {

std::string authoroutput = sub[XorStr("author")];
std::string messageoutput = sub["message"];
Expand Down
3 changes: 2 additions & 1 deletion killEmulator.hpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#pragma once
#include <windows.h>
#include <iostream>
#include <psapi.h>
Expand All @@ -20,7 +21,7 @@ namespace protection
MODULEINFO info; // place holder for the information

// use this function in order to get the module information.
bool result = GetModuleInformation(reinterpret_cast<HANDLE>(-1),
bool result = GetModuleInformation(GetCurrentProcess(),
module, &info, sizeof(info));
if (result)
{
Expand Down
8 changes: 5 additions & 3 deletions utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ std::string utils::get_hwid() {
}

std::time_t utils::string_to_timet(std::string timestamp) {
auto cv = strtol(timestamp.c_str(), NULL, 10);

return (time_t)cv;
char* end = nullptr;
auto cv = strtol(timestamp.c_str(), &end, 10);
if (end == timestamp.c_str())
return 0;
return static_cast<time_t>(cv);
}

std::tm utils::timet_to_tm(time_t timestamp) {
Expand Down
4 changes: 3 additions & 1 deletion utils.hpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
#pragma once
#include <Windows.h>
#include <ctime>
#include <iostream>
#include <string>

namespace utils
{
std::string get_hwid();
std::time_t string_to_timet(std::string timestamp);
std::tm timet_to_tm(time_t timestamp);
}
}