Chrome: Added basis for decrypting chrome cookies
Not currently functional
This commit is contained in:
parent
d1e434b610
commit
e0eabdb67e
|
@ -5,4 +5,13 @@ set(CMAKE_CXX_STANDARD 17)
|
||||||
|
|
||||||
add_executable(dropout-dl main.cpp)
|
add_executable(dropout-dl main.cpp)
|
||||||
|
|
||||||
|
IF (EXISTS "firefox_profile")
|
||||||
target_link_libraries(dropout-dl curl sqlite3)
|
target_link_libraries(dropout-dl curl sqlite3)
|
||||||
|
add_compile_definitions(DROPOUT_DL_SQLITE)
|
||||||
|
ELSEIF(EXISTS "chrome_profile")
|
||||||
|
target_link_libraries(dropout-dl curl sqlite3 gcrypt)
|
||||||
|
add_compile_definitions(DROPOUT_DL_SQLITE DROPOUT_DL_GCRYPT)
|
||||||
|
ELSE()
|
||||||
|
target_link_libraries(dropout-dl curl)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
|
309
main.cpp
309
main.cpp
|
@ -6,7 +6,13 @@
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
|
|
||||||
|
#ifdef DROPOUT_DL_SQLITE
|
||||||
#include <sqlite3.h>
|
#include <sqlite3.h>
|
||||||
|
#ifdef DROPOUT_DL_GCRYPT
|
||||||
|
#include <gcrypt.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp)
|
static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp)
|
||||||
|
@ -65,8 +71,6 @@ const char* full_character = "▓";
|
||||||
const char* empty_character = "░";
|
const char* empty_character = "░";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int progress_func(void* ptr, double TotalToDownload, double NowDownloaded, double TotalToUpload, double NowUploaded)
|
int progress_func(void* ptr, double TotalToDownload, double NowDownloaded, double TotalToUpload, double NowUploaded)
|
||||||
{
|
{
|
||||||
current_time = time_ms();
|
current_time = time_ms();
|
||||||
|
@ -461,59 +465,30 @@ std::string get_config_page(const std::string& url, bool verbose = false) {
|
||||||
return config_page;
|
return config_page;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string auth_cookie;
|
static int sqlite_write_callback(void* data, int argc, char** argv, char** azColName)
|
||||||
std::string session_cookie;
|
|
||||||
|
|
||||||
static int sqlite_auth_callback(void* data, int argc, char** argv, char** azColName)
|
|
||||||
{
|
{
|
||||||
if (argc < 1) {
|
if (argc < 1) {
|
||||||
std::cerr << "ERROR: sqlite could not find dropout.tv cookie" << std::endl;
|
std::cerr << "ERROR: sqlite could not find dropout.tv cookie" << std::endl;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
auth_cookie = argv[0];
|
*(std::string*)data = argv[0];
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sqlite_session_callback(void*, int argc, char** argv, char**) {
|
#ifdef DROPOUT_DL_SQLITE
|
||||||
if (argc < 1) {
|
std::vector<std::string> get_cookies_from_firefox(bool verbose = false) {
|
||||||
std::cerr << "ERROR: sqlite could not find dropout.tv cookie" << std::endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
session_cookie = argv[0];
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
|
||||||
|
|
||||||
bool verbose = true;
|
|
||||||
std::string quality = "1080p";
|
|
||||||
|
|
||||||
std::string series_name;
|
|
||||||
std::string name;
|
|
||||||
std::string filename;
|
|
||||||
std::string season;
|
|
||||||
std::string episode;
|
|
||||||
|
|
||||||
std::string firefox_profile;
|
|
||||||
|
|
||||||
std::string config_url;
|
|
||||||
std::string embed_url;
|
|
||||||
std::string episode_url;
|
|
||||||
|
|
||||||
std::fstream firefox_profile_file("firefox_profile");
|
std::fstream firefox_profile_file("firefox_profile");
|
||||||
|
std::string firefox_profile;
|
||||||
|
|
||||||
std::fstream auth_cookie_file("auth_cookie");
|
std::string auth_cookie;
|
||||||
|
std::string session_cookie;
|
||||||
|
|
||||||
std::fstream session_cookie_file("session_cookie");
|
std::vector<std::string> out;
|
||||||
|
|
||||||
std::fstream user_auth_file("token");
|
firefox_profile_file >> firefox_profile;
|
||||||
|
|
||||||
if (firefox_profile_file.is_open()) {
|
|
||||||
getline(firefox_profile_file, firefox_profile);
|
|
||||||
|
|
||||||
if (std::filesystem::is_directory(firefox_profile)) {
|
if (std::filesystem::is_directory(firefox_profile)) {
|
||||||
|
|
||||||
|
@ -531,7 +506,7 @@ int main(int argc, char** argv) {
|
||||||
int rc = sqlite3_open("tmp/firefox_cookies.sqlite", &db);
|
int rc = sqlite3_open("tmp/firefox_cookies.sqlite", &db);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
std::cerr << "Can't open database: " << sqlite3_errmsg(db) << '\n';
|
std::cerr << "Can't open database: " << sqlite3_errmsg(db) << '\n';
|
||||||
return 1;
|
exit(1);
|
||||||
} else {
|
} else {
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
std::cout << "Firefox database opened successfully\n";
|
std::cout << "Firefox database opened successfully\n";
|
||||||
|
@ -542,63 +517,267 @@ int main(int argc, char** argv) {
|
||||||
|
|
||||||
std::string sql("SELECT value FROM moz_cookies WHERE host LIKE '%dropout.tv%' AND name='__cf_bm';");
|
std::string sql("SELECT value FROM moz_cookies WHERE host LIKE '%dropout.tv%' AND name='__cf_bm';");
|
||||||
|
|
||||||
rc = sqlite3_exec(db, sql.c_str(), sqlite_auth_callback, nullptr, &err_code);
|
rc = sqlite3_exec(db, sql.c_str(), sqlite_write_callback, &auth_cookie, &err_code);
|
||||||
|
|
||||||
|
out.emplace_back(auth_cookie);
|
||||||
|
|
||||||
if (rc != SQLITE_OK) {
|
if (rc != SQLITE_OK) {
|
||||||
fprintf(stderr, "SQL error: %s\n", err_code);
|
fprintf(stderr, "SQL error: %s\n", err_code);
|
||||||
sqlite3_free(err_code);
|
sqlite3_free(err_code);
|
||||||
sqlite3_close(db);
|
sqlite3_close(db);
|
||||||
return 2;
|
exit(2);
|
||||||
} else if (verbose) {
|
} else if (verbose) {
|
||||||
std::cout << "Got __cf_bm cookie from firefox sqlite db\n";
|
std::cout << "Got __cf_bm cookie from firefox sqlite db\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
sql = "SELECT value FROM moz_cookies WHERE host LIKE '%dropout.tv%' AND name='_session';";
|
sql = "SELECT value FROM moz_cookies WHERE host LIKE '%dropout.tv%' AND name='_session';";
|
||||||
|
|
||||||
rc = sqlite3_exec(db, sql.c_str(), sqlite_session_callback, nullptr, &err_code);
|
rc = sqlite3_exec(db, sql.c_str(), sqlite_write_callback, &session_cookie, &err_code);
|
||||||
|
|
||||||
|
out.emplace_back(session_cookie);
|
||||||
|
|
||||||
if (rc != SQLITE_OK) {
|
if (rc != SQLITE_OK) {
|
||||||
fprintf(stderr, "SQL error: %s\n", err_code);
|
fprintf(stderr, "SQL error: %s\n", err_code);
|
||||||
sqlite3_free(err_code);
|
sqlite3_free(err_code);
|
||||||
sqlite3_close(db);
|
sqlite3_close(db);
|
||||||
return 3;
|
exit(3);
|
||||||
} else if (verbose) {
|
} else if (verbose) {
|
||||||
std::cout << "Got _session cookie from firefox sqlite db\n";
|
std::cout << "Got _session cookie from firefox sqlite db\n";
|
||||||
}
|
}
|
||||||
sqlite3_close(db);
|
sqlite3_close(db);
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DROPOUT_DL_GCRYPT
|
||||||
|
std::vector<std::string> get_cookies_from_chrome(bool verbose = false) {
|
||||||
|
|
||||||
|
std::fstream chrome_profile_file("chrome_profile");
|
||||||
|
std::string chrome_profile;
|
||||||
|
|
||||||
|
std::string auth_cookie;
|
||||||
|
int auth_cookie_length;
|
||||||
|
std::string session_cookie;
|
||||||
|
int session_cookie_length;
|
||||||
|
|
||||||
|
std::vector<std::string> out;
|
||||||
|
|
||||||
|
getline(chrome_profile_file, chrome_profile);
|
||||||
|
|
||||||
|
if (std::filesystem::is_directory(chrome_profile)) {
|
||||||
|
|
||||||
|
sqlite3 *db;
|
||||||
|
|
||||||
|
if (verbose) {
|
||||||
|
std::cout << "Getting chrome cookies from chrome sqlite db\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
int rc = sqlite3_open((chrome_profile + "/Cookies").c_str(), &db);
|
||||||
|
if (rc) {
|
||||||
|
std::cerr << "Can't open database: " << sqlite3_errmsg(db) << '\n';
|
||||||
|
exit(1);
|
||||||
|
} else {
|
||||||
|
if (verbose) {
|
||||||
|
std::cout << "Chrome database opened successfully\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char *err_code = nullptr;
|
||||||
|
|
||||||
|
std::string len;
|
||||||
|
|
||||||
|
std::string sql = "SELECT length(encrypted_value) FROM cookies WHERE host_key LIKE '%dropout.tv%' AND name='__cf_bm';";
|
||||||
|
|
||||||
|
sqlite3_exec(db, sql.c_str(), sqlite_write_callback, &len, &err_code);
|
||||||
|
|
||||||
|
auth_cookie_length = std::stoi(len);
|
||||||
|
|
||||||
|
sql = "SELECT encrypted_value FROM cookies WHERE host_key LIKE '%dropout.tv%' AND name='__cf_bm';";
|
||||||
|
|
||||||
|
rc = sqlite3_exec(db, sql.c_str(), sqlite_write_callback, &auth_cookie, &err_code);
|
||||||
|
|
||||||
|
if (rc != SQLITE_OK) {
|
||||||
|
fprintf(stderr, "SQL error: %s\n", err_code);
|
||||||
|
sqlite3_free(err_code);
|
||||||
|
sqlite3_close(db);
|
||||||
|
exit(2);
|
||||||
|
} else if (verbose) {
|
||||||
|
std::cout << "Got __cf_bm cookie from chrome sqlite db\n" << auth_cookie << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
sql = "SELECT length(encrypted_value) FROM cookies WHERE host_key LIKE '%dropout.tv%' AND name='_session';";
|
||||||
|
|
||||||
|
sqlite3_exec(db, sql.c_str(), sqlite_write_callback, &len, &err_code);
|
||||||
|
|
||||||
|
session_cookie_length = std::stoi(len);
|
||||||
|
|
||||||
|
sql = "SELECT encrypted_value FROM cookies WHERE host_key LIKE '%dropout.tv%' AND name='_session';";
|
||||||
|
|
||||||
|
rc = sqlite3_exec(db, sql.c_str(), sqlite_write_callback, &session_cookie, &err_code);
|
||||||
|
|
||||||
|
if (rc != SQLITE_OK) {
|
||||||
|
fprintf(stderr, "SQL error: %s\n", err_code);
|
||||||
|
sqlite3_free(err_code);
|
||||||
|
sqlite3_close(db);
|
||||||
|
exit(3);
|
||||||
|
} else if (verbose) {
|
||||||
|
std::cout << "Got _session cookie from chrome sqlite db\n";
|
||||||
|
}
|
||||||
|
sqlite3_close(db);
|
||||||
|
|
||||||
// system(("echo \"SELECT value FROM moz_cookies WHERE originAttributes LIKE '%dropout.tv%';\" | sqlite3 " + firefox_profile + "/cookies.sqlite > cookie").c_str());
|
// system(("echo \"SELECT value FROM moz_cookies WHERE originAttributes LIKE '%dropout.tv%';\" | sqlite3 " + firefox_profile + "/cookies.sqlite > cookie").c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For mac os this is your keychain password
|
||||||
|
// For linux leave as "peanuts"
|
||||||
|
std::string password = "peanuts";
|
||||||
|
std::string salt = "saltysalt";
|
||||||
|
int length = 16;
|
||||||
|
int iterations = 1;
|
||||||
|
|
||||||
|
uint8_t key[32];
|
||||||
|
|
||||||
|
char output[2048];
|
||||||
|
|
||||||
|
char iv[16];
|
||||||
|
|
||||||
|
for (char& c : iv) {
|
||||||
|
c = ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auth_cookie.empty()) {
|
for (char& c : output) {
|
||||||
if (auth_cookie_file.is_open() && !auth_cookie_file.eof()) {
|
c = 0;
|
||||||
getline(auth_cookie_file, auth_cookie);
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < auth_cookie_length; i++) {
|
||||||
|
std::cout << std::hex << (0xFF & (int)auth_cookie[i]) << ' ';
|
||||||
|
}
|
||||||
|
std::cout << '\n';
|
||||||
|
|
||||||
|
gcry_kdf_derive(password.c_str(), password.size(), GCRY_KDF_PBKDF2, GCRY_KDF_ARGON2ID, salt.c_str(), salt.size(), iterations, length, key);
|
||||||
|
|
||||||
|
gcry_cipher_hd_t handle;
|
||||||
|
|
||||||
|
gcry_cipher_open(&handle, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CBC, 0);
|
||||||
|
|
||||||
|
gcry_cipher_setkey(handle, (const void*) &key, length);
|
||||||
|
|
||||||
|
gcry_cipher_setiv(handle, (const void*)&iv, 16);
|
||||||
|
|
||||||
|
unsigned long err = gcry_cipher_decrypt(handle, (unsigned char*)output, 2048, auth_cookie.c_str() + 3, auth_cookie_length - 3);
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
std::cout << gcry_strerror(err) << std::endl;
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (char& c : output) {
|
||||||
|
if (c == '\017') {
|
||||||
|
c = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out.emplace_back(output);
|
||||||
|
|
||||||
|
gcry_cipher_setiv(handle, (const void*)&iv, 16);
|
||||||
|
|
||||||
|
gcry_cipher_decrypt(handle, (unsigned char*)output, 2048, session_cookie.c_str() + 3, session_cookie_length - 3);
|
||||||
|
|
||||||
|
out.emplace_back(output);
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::vector<std::string> get_cookies_from_files(bool verbose = false) {
|
||||||
|
std::fstream auth_cookie_file("auth_cookie");
|
||||||
|
std::fstream session_cookie_file("session_cookie");
|
||||||
|
|
||||||
|
std::string auth_cookie;
|
||||||
|
std::string session_cookie;
|
||||||
|
|
||||||
|
std::vector<std::string> out;
|
||||||
|
|
||||||
|
auth_cookie_file >> auth_cookie;
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
std::cout << "Got __cf_bm cookie from auth_cookie file db\n";
|
std::cout << "Got __cf_bm cookie from auth_cookie file db\n";
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (auth_cookie.empty()) {
|
out.emplace_back(auth_cookie);
|
||||||
std::cerr << "ERROR: dropout.tv auth cookie could not be found" << std::endl;
|
|
||||||
return 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (session_cookie.empty()) {
|
session_cookie_file >> session_cookie;
|
||||||
if (session_cookie_file.is_open() && !session_cookie_file.eof()) {
|
|
||||||
getline(session_cookie_file, session_cookie);
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
std::cout << "Got _session cookie from session_cookie file db\n";
|
std::cout << "Got _session cookie from auth_cookie file db\n";
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session_cookie.empty()) {
|
out.emplace_back(session_cookie);
|
||||||
std::cerr << "ERROR: dropout.tv session cookie could not be found" << std::endl;
|
|
||||||
return 5;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DROPOUT_DL_GCRYPT
|
||||||
|
std::vector<std::string> get_cookies(bool verbose = false) {
|
||||||
|
|
||||||
|
if (std::filesystem::is_regular_file("firefox_profile_")) {
|
||||||
|
return get_cookies_from_firefox(verbose);
|
||||||
|
} else if (std::filesystem::is_regular_file("chrome_profile")) {
|
||||||
|
return get_cookies_from_chrome(verbose);
|
||||||
|
}
|
||||||
|
else if (std::filesystem::is_regular_file("auth_cookie") && std::filesystem::is_regular_file("session_cookie")){
|
||||||
|
return get_cookies_from_files(verbose);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::cerr << "ERROR: dropout.tv cookies could not be found" << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#elif defined(DROPOUT_DL_SQLITE)
|
||||||
|
std::vector<std::string> get_cookies(bool verbose = false) {
|
||||||
|
|
||||||
|
if (std::filesystem::is_character_file("firefox_profile")) {
|
||||||
|
return get_cookies_from_firefox(verbose);
|
||||||
|
}
|
||||||
|
else if (std::filesystem::is_character_file("auth_cookie") && std::filesystem::is_character_file("session_cookie")){
|
||||||
|
return get_cookies_from_files(verbose);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::cerr << "ERROR: dropout.tv cookies could not be found" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
std::vector<std::string> get_cookies(bool verbose = false) {
|
||||||
|
if (std::filesystem::is_character_file("auth_cookie") && std::filesystem::is_character_file("session_cookie")){
|
||||||
|
return get_cookies_from_files(verbose);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::cerr << "ERROR: dropout.tv cookies could not be found" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
|
||||||
|
bool verbose = true;
|
||||||
|
std::string quality = "1080p";
|
||||||
|
|
||||||
|
std::string series_name;
|
||||||
|
std::string name;
|
||||||
|
std::string filename;
|
||||||
|
std::string season;
|
||||||
|
std::string episode;
|
||||||
|
|
||||||
|
std::string firefox_profile;
|
||||||
|
std::string chrome_profile;
|
||||||
|
|
||||||
|
std::string config_url;
|
||||||
|
std::string embed_url;
|
||||||
|
std::string episode_url;
|
||||||
|
|
||||||
|
std::vector<std::string> cookies = get_cookies(verbose);
|
||||||
|
|
||||||
CURL *curl;
|
CURL *curl;
|
||||||
CURLcode res;
|
CURLcode res;
|
||||||
std::string episode_data;
|
std::string episode_data;
|
||||||
|
@ -620,7 +799,7 @@ int main(int argc, char** argv) {
|
||||||
curl = curl_easy_init();
|
curl = curl_easy_init();
|
||||||
if(curl) {
|
if(curl) {
|
||||||
|
|
||||||
episode_data = get_episode_page(episode_url, auth_cookie, session_cookie);
|
episode_data = get_episode_page(episode_url, cookies[0], cookies[1]);
|
||||||
|
|
||||||
name = get_episode_name(episode_data);
|
name = get_episode_name(episode_data);
|
||||||
|
|
||||||
|
@ -671,7 +850,7 @@ int main(int argc, char** argv) {
|
||||||
|
|
||||||
curl = curl_easy_init();
|
curl = curl_easy_init();
|
||||||
if (curl) {
|
if (curl) {
|
||||||
embedded_data = get_embedded_page(embed_url, auth_cookie);
|
embedded_data = get_embedded_page(embed_url, cookies[0]);
|
||||||
|
|
||||||
if (embedded_data.find("you are not authorized") != std::string::npos) {
|
if (embedded_data.find("you are not authorized") != std::string::npos) {
|
||||||
std::cerr << "ERROR: Could not access video. Try refreshing cookies.\n";
|
std::cerr << "ERROR: Could not access video. Try refreshing cookies.\n";
|
||||||
|
|
Loading…
Reference in New Issue