๊ณต๊ณต๋ถ๋ฌธ 2๋ฑ์ผ๋ก ๋ง๋ฌด๋ฆฌํ CCE ํ๊ธฐ
Jeopardy 2086
์ + Live Fire 2010
์ ์ผ๋ก 2**12
์ ์ ๋ฌ์ฑํ๋ฉฐ ๊ณต๊ณต 2์ ์ด 6์๋ฅผ ๊ธฐ๋กํ๋ค.
๋๋ Live Fire ์ 01 ๋ฒ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ์๋ค. 01๋ฒ์ด ์๊ฐ๋ณด๋ค ๋ฆ์ด์ง๋ฉด์ ๋ค๋ฅธ ๋ฌธ์ ๋ฅผ ์ ๋๋ก ๋ชป๋ดค๋๋ฐ ๋ํ ์๊ฐ์ด ์งง๋ค๊ณ ๋๊ปด์ก๋ค. ๋ฌธ์ ๋ ๋ค ์ฌ๋ฐ์ด๋ณด์๋๋ฐ ๐ฅ
์ฐ๋ฆฌ ํ NOOP
์ ์๊ฐํ์๋ฉด ์ก๊ตฐ ์ฌ์ด๋ฒ์์ ์ผํฐ
์์ ๊ทผ๋ฌดํ๋ ๋ณ์ฌ 2๋ช
๊ณผ ๊ฐ๋ถ 2๋ช
์ผ๋ก ์ด๋ฃจ์ด์ ธ ์๋ค
๋ณ์ฌ๋ ๋์ ์ฌ์ด๋ฒ์์ ๋ณ ์๋๊ธฐ์ธ ์ ์
์ด, ๊ทธ๋ฆฌ๊ณ ๊น์ข
๋ฏผ ์๋ น๋, ์ด๋์ ๋์๋๊น์ง.
์ธ์์์ ์๋ง ํ๋๋ฟ์ผ ๊ณต๊ณต ๋ถ๋ฌธ ์ถ์ ์ด์ด์ 1๋ฑ์ ๊ธฐ๋ํ์ง๋ง ์จ์ด์๋ ์ฌ๊ตญ 2๋ถ๊ป 1๋ฑ ์๋ฆฌ๋ ๋์ด๊ฐ๋ค.
Live Fire
๋ ๋ชจ๋ ํ์๊ฒ 2500 ์ ์ ๋ํ ์์ํ ๋ ๋ถ์ฌํ๊ณ , ๊ฐ ํ๋ง๋ค ์ฃผ์ด์ง ์๋ฒ์ 20๋ถ๋ง๋ค 5๊ฐ ์ทจ์ฝ์ ์ ๊ณต๊ฒฉ์ด ์ด๋ฃจ์ด์ก๋ค. ๊ฐ ์ทจ์ฝ์ ๋น 10์ ์ฉ ์ฐจ๊ฐ๋๋ฉฐ ์ ์์ ์ธ ๊ธฐ๋ฅ์ด ๊ณ ์ฅ๋ ์ ๊ทธ๋ฅ 50์ ์ด ๊น์ด๋ ๋ฐฉ์์ด๋ค. 2022๋
CCE ๋๋ ๋ฐ์ด๋๋ฆฌ๋ง ์ฃผ์ด์ง๊ณ ์ด์
ํจ์น๋ฅผ ํตํด ์
๋ก๋ํด์ผ ํ๋๋ฐ ์ด๋ฒ์๋ ์๋ฒ ๋ด์ ssh ์ ์ํ์ฌ ์ง์ ์์ค์ฝ๋๋ฅผ ์์ ํ ๋น๋ํ๋ ๋ฐฉ์์ผ๋ก ํจ์น๊ฐ ์งํ๋์๋ค. ๊ทธ๋ ๋น์ Live Fire ์ ๋ํธ๋์ด ์๊ฐ๋ณด๋ค ์ปธ๊ณ (๋ํ ์๊ฐ์ด ๋ ๊ธธ์๊ธฐ์) ์ด๋ฒ์๋ Live Fire๊ฐ ์ค์ํ ๊ฒ ๊ฐ์ Live Fire ๋ถํฐ ํ์ธํ๋ค.
๊ณ์ฐํด๋ณด๋ฉด 1200์ ์ด ์ต์ ์ ์์ด๋ค. 150์ ์ฉ 9์๊ฐ๋ง๋ค ๊ฐ์๋๊ณ ๋ง์ง๋ง ํ๋ฒ์ ์๋๋ 2500์ ์์ 1300์ ์ด ๊น์ฌ 1200์ ์ด ์ต์ ์ ์.
2019๋
๋ถํฐ ๋งค๋
๋ํ๋ฅผ ์ฌ๊ธฐ์ ๊ธฐ ๋ค๋๋ฉด์ ์ฒ์ ๊ฒช๋ ์ํฉ์ด ์ผ์ด๋ฌ๋ค.
๋ํ์ฅ ์
์ฅํ๋ ์ค์ด ๋ญ์ด๋ฆฌ ๊ธธ์ง ์์ํ๋๋ฐ ์ ๋์ ์ก๊ตฐ ๋ณธ์ฒญ๊ณผ ๊ณตํญ์์ ๋ณผ ์ ์๋ ๊ฒ์๋๊ฐ ์์๋ค. ์๋ด์ฌํญ์ผ๋ก๋ ๊ฒ์๋ ํต์ ์๊ฐ์ ์ง๋ ๊ฒฝ์ฐ ์
์ฅ์ด ํ๋ค ์ ์๋ค๋ ์๋ฏธ์ฌ์ฅํ ๋ฌธ์๊ฐ ์์๋ค. ์ํผ ์ค ์๋ค๋ณด๋ ๊ฒฝ์ฐฐ๋ถ๋ค๊ณผ ์ ์ฅ์
์ ๋ถ๋ค์ด ์์งํ ๊ฒ์ฌ ๋ฐ ๋ชธ ์ค์บ์ ํ๋๋ฐ ์์ด๋ด๊น ์ถ์๋ค.
์ค๋ง์ค๋ง ํ๋๋ฐ ๋ํต๋ น์ด ์ง์ ์ค์ จ๋ค. ๐ต CCE ํ์ฌ ์์ APEX ? ๋ญ ํ์ฌ๋ ๊ฐ์ด ํ๋๋ผ ์ธ๊ตญ์ธ๋ค๋ ๋ง์ด ์๊ณ ๋ฐ์๋ ๋ณด์ ๊ด๋ จ ํ์ฌ๋ค ๋ถ์ค๊ฐ ์์๋๋ฐ ์ค์ 11์์ ๋ํต๋ น์ ๊ธฐ๋ ์ดฌ์์์ด ์์๋ค. ๊ทธ๋ ๊ฒ ์ด๋ณ ๋ถํฐ ๋ณ์ฅ, ํ์ฌ๋ถํฐ ์ค์, ์์๋ถํฐ 5์คํ๊น์ง ๋ชจ๋ ๋๊ฐ์ ๋ฑ๋ก๋์๋ค.๐
๊ฐ์ฅ ๋จผ์ ๋ก๊ทธ์ธ ์ฝ๋๊ฐ ๋์ ๋์๋ค.
bool Server::Authentication::initAccount() {
char *err;
const char *statement = "DROP TABLE IF EXISTS Account;"
"CREATE TABLE Account(Id TEXT, Password TEXT);"
"INSERT INTO Account VALUES('admin', 'CCE2024LIVEFIRE');";
Check(sqlite3_open(":memory:", &m_db) == SQLITE_OK);
Check(sqlite3_exec(m_db, statement, 0, 0, &err) == SQLITE_OK);
return true;
}
int callback(void *ptr, int argc, char **argv, char **azColName) {
auto me = (Server::Authentication *)ptr;
for (int i = 0; i < argc; i++) {
if (!strcmp(argv[i], me->userPW())) {
me->setAdmin(true);
me->setAuthorized(true);
break;
}
}
return 0;
}
bool Server::Authentication::doAuthorize(const char *requestID, const char *password) {
char *err;
m_userID = (char *)requestID;
m_userPW = (char *)password;
if (strncmp("admin", requestID, 5)) {
std::cout << "Log in as guest" << std::endl;
m_authorized = true;
return true;
}
const char *statement = "SELECT Password FROM Account WHERE Id = '%s'";
if (res != SQLITE_DONE) {
std::cerr << "Execution failed: " << sqlite3_errmsg(m_db) << std::endl;
}
auto statementBuffer = alloca(strlen(statement) + strlen(requestID));
memset(statementBuffer, 0, strlen(statement) + strlen(requestID));
snprintf((char *)statementBuffer, strlen(statement) + strlen(requestID), statement, requestID);
std::cout << "Query: " << (char *)statementBuffer << std::endl;
Check(sqlite3_exec(m_db, (const char *)statementBuffer, callback, (void *)this, &err) == SQLITE_OK);
return false;
}
๋ฌผ๊ตฌ๋๋ฌด ์์ ๋ด๋ ๋ฌธ์ ์ธ '%s'
๊ฐ ๋ณด์ธ๋ค. ๊ฒ๋ค๊ฐ id ๋น๊ต ๋ํ strncmp
๋ก ์ 5๋ฐ์ดํธ๋ง admin
์ธ์ง ํ์ธํ๊ธฐ ๋๋ฌธ์ admin' or 1=1 --
์ฒ๋ผ sqli
๊ฐ ๊ฐ๋ฅํด๋ณด์ธ๋ค. ์๋ํด๋ณด๋ฉด ์ ๋๋ค.
bool Server::Authentication::doAuthorize(const char *requestID, const char *password) {
char *err;
sqlite3_stmt *stmt;
m_userID = (char *)requestID;
m_userPW = (char *)password;
if (strncmp("admin", requestID, 5)) {
std::cout << "Log in as guest" << std::endl;
m_authorized = true;
return true;
}
const char *statement = "SELECT Password FROM Account WHERE Id = ?";
std::cout << "doAuthorize" << std::endl;
if (sqlite3_prepare_v2(m_db, statement, -1, &stmt, nullptr) != SQLITE_OK) {
std::cerr << "Failed to prepare statement: " << sqlite3_errmsg(m_db) << std::endl;
sqlite3_close(m_db);
return 1;
}
if (sqlite3_bind_text(stmt, 1, requestID, -1, SQLITE_STATIC) != SQLITE_OK) {
std::cerr << "Failed to bind text: " << sqlite3_errmsg(m_db) << std::endl;
}
int res = sqlite3_step(stmt);
if (res == SQLITE_ROW) {
const char *_password = (const char*)sqlite3_column_text(stmt, 0);
std::cout << _password << std::endl;
if (!strncmp(_password, password, strlen(_password))) {
std::cout << "Login Success" << std::endl;
sqlite3_finalize(stmt);
this->setAdmin(true);
this->setAuthorized(true);
return true;
}
} else if (res != SQLITE_DONE) {
std::cerr << "Execution failed: " << sqlite3_errmsg(m_db) << std::endl;
}
sqlite3_finalize(stmt);
std::cout << "Login Failed" << std::endl;
return false;
}
์ ์ฝ๋์ฒ๋ผ '%s'
๋ฅผ ?
๋ก ๋์ฒดํ๊ณ prepare
- bind
- step
์์ผ๋ก ํธ์ถํ๋ฉฐ ํ๋ผ๋ฏธํฐ ๋ฐ์ธ๋ฉ์ ํด์ค๋ค.
์ฝ๊ฐ ํค๋งค๋ค ๋ก๊ทธ์ธ ๊ธฐ๋ฅ์ด ์๋์ํด์ ๋ ํ์? ๋ ๋ ค๋จน์์ง๋ง 10์์ ์ฑ๊ณต์ ์ผ๋ก ํจ์นํ๋ค.
๋จ์ 8์๊ฐ => 10 point * 3 / 1hour => 240 ์ ๋ฐฉ์ด
bool CommandServer::CommandServer::runcmd(const httplib::Request &request, std::string &result) {
std::ostringstream tmp;
auto cmd = request.get_param_value("command");
Check(!cmd.empty());
auto runCommand = Check(filter(cmd.c_str()));
std::cout << "Running command: " << runCommand << std::endl;
auto ret = exec(runCommand);
auto rdbuf = ret.rdbuf();
tmp << cmd;
tmp << "\n";
tmp << rdbuf;
result.append(tmp.str());
return true;
}
char *CommandServer::CommandServer::filter(const char *cmd) {
for (auto &allowedCmd : sCommandList) {
if (!strncmp(allowedCmd, cmd, strlen(allowedCmd))) {
auto streambuf = std::string(cmd);
if (streambuf.contains(' ')) {
auto buffer = (char *)Check(malloc(strlen(cmd) + 0x100));
bzero(buffer, strlen(cmd) + 0x100);
auto splited = split(streambuf, ' ');
Check(splited.size() == 2);
snprintf(buffer, strlen(cmd) + 0x100, "%s '%s'", splited[0].c_str(), res.c_str());
std::cout << buffer << std::endl;
return buffer;
}
return (char *)cmd;
}
}
return nullptr;
}
๋ณด๋ค์ํผ ์ฌ๊ธฐ๋ %s '%s'
๋ก sprintf
ํด์ฃผ๊ณ ์๋ค. ๐ ๋ง command ์ฝ์
ํด๋ฒ๋ฆฌ๊ณ ์ถ์ ๋ง์์ด ๋ค๊ณ ๊ทธ๋ด ๊ฒ์ด๋ค. ์ญ์๋ echo ';ls;'
ํด๋ณธ ๊ฒฐ๊ณผ ์ ์คํ๋๋ค. ์ด๋ป๊ฒ ํจ์นํ ๊น ํ๋ค๊ฐ ๊ทธ๋ฅ quote escape ์ฒ๋ฆฌ ํ๋ค. + ` ์ฒ๋ฆฌ๊น์ง.
std::string escapeSpecialChars(const std::string& input) {
std::string result;
for (char c : input) {
if (c == '\'') {
result += "'\\''";
} else if (c == '`') {
result += "\\`";
} else {
result += c;
}
}
return result;
}
char *CommandServer::CommandServer::filter(const char *cmd) {
for (auto &allowedCmd : sCommandList) {
if (!strncmp(allowedCmd, cmd, strlen(allowedCmd))) {
auto streambuf = std::string(cmd);
// echo ';ls;'
if (streambuf.contains(' ')) {
auto buffer = (char *)Check(malloc(strlen(cmd) + 0x100));
bzero(buffer, strlen(cmd) + 0x100);
auto splited = split(streambuf, ' ');
Check(splited.size() == 2);
std::string res = escapeSpecialChars(splited[1]);
snprintf(buffer, strlen(cmd) + 0x100, "%s '%s'", splited[0].c_str(), res.c_str());
std::cout << buffer << std::endl;
return buffer;
}
return (char *)cmd;
}
}
return nullptr;
}
๋ฐฉ์ด ์ฑ๊ณต ~
(์์ธ์ง ๋ชจ๋ฅด๊ฒ 3๊ฐ๊ฐ ๋ฐฉ์ด๋์ด์ ๋ญ๊ฐ ์ถ์๋ค)
๋จ์ 7์๊ฐ => 10p * 3/1h => 210p ๋ฐฉ์ด ~
๊ฐ์๊ธฐ ๋ง 50์ ์ฉ ๊น์ด๊ธฐ ์์ํ๋ ์ ์๋ฅผ ๋ณด๊ณ ๋นํฉ์ค๋ฌ์ ๋ค. ํ ๋์ด ์ฐจ๋ก ์ดํผ์ปท ๋ง๊ณ ๋ณด๋ ์๋ฒ๋ฅผ ์๋ชป ๋๋ฆฌ๊ณ ์์๋ค. ๋ฐฑ๊ทธ๋ผ์ด๋์์ ๋์๊ฐ๋ run.sh
๊ฐ ์๋์ค ๋ชจ๋ฅด๊ณ ๋ฐ๋ก ๋๋ฆฌ๊ณ ์์๋๋ฐ, ์ด๋์ด ํจํท์ ๋๋ ๋จน์ผ๋ฉด์ ๋น์ ์์ ์ธ ๊ฒฐ๊ณผ๋ก ์ด์ด์ง๊ฒ ๋ ๊ฒ์ด๋ค. ๐ญ
?! ๋ฐ๋ก ํ์ธํด๋ณด์
bool Server::Server::prepareTLEs() {
std::ifstream file;
file.open("/home/user/Livefire2024/src/Resource/tles.txt", std::ifstream::in);
Check(file.is_open());
std::string line, temp;
while (std::getline(file, line)) {
line.append("\n");
Check(line.length() == 70);
if (line.at(0) == '\x32') {
std::string TLE;
TLE.append("XXXX \n");
TLE.append(temp);
TLE.append(line);
Check(TLE.length() == 70 * 3);
auto number = Satellite::satellite_number(TLE);
auto it = m_satellites.find(number);
if (it != m_satellites.end()) { continue; }
auto object = std::unique_ptr<Satellite::Satellite>(new Satellite::Satellite(std::to_string(number), TLE));
m_satellites.insert(std::make_pair(number, std::move(object)));
m_numTLEs++;
} else {
temp = line;
}
}
return true;
}
..
m_server.Post("/register", [&](const httplib::Request &request, httplib::Response &response) {
m_mutex.lock();
SCOPE_EXIT({ m_mutex.unlock(); });
DEBUG_DUMP_REQUEST;
if (!m_authenticator.isAuthorized()) {
response.set_redirect("/");
}
auto content = std::make_unique<uint8_t[]>(0x1000);
bzero(content.get(), 0x1000);
auto name = request.get_param_value("name");
CheckVoid(!name.empty());
auto TLE = request.get_param_value("TLE");
auto pos = TLE.find("\n");
CheckVoid(pos != std::string::npos);
auto substr = TLE.substr(pos + 1);
auto number = Satellite::satellite_number(substr);
auto it = m_satellites.find(number);
if (it == m_satellites.end()) {
auto object = std::unique_ptr<Satellite::Satellite>(new Satellite::Satellite(name, TLE));
m_satellites.insert(std::make_pair(number, std::move(object)));
m_numTLEs++;
snprintf((char *)content.get(), 0x1000, "Success to register, Total TLEs: %d", m_numTLEs);
response.set_content((char *)content.get(), "text/plain");
} else {
snprintf((char *)content.get(), 0x1000, "Failed to register, Total TLEs: %d", m_numTLEs);
response.set_content((char *)content.get(), "text/plain");
}
});
m_server.Post("/unregister", [&](const httplib::Request &request, httplib::Response &response) {
m_mutex.lock();
SCOPE_EXIT({ m_mutex.unlock(); });
DEBUG_DUMP_REQUEST;
if (!m_authenticator.isAuthorized()) {
response.set_redirect("/");
}
auto numberAsStr = request.get_param_value("number");
CheckVoid(!numberAsStr.empty());
auto number = stoi(numberAsStr);
auto it = m_satellites.find(number);
if (it != m_satellites.end()) {
auto object = it->second.get();
m_satellites.erase(it);
response.set_content(object->dumpInfo(), "text/plain");
}
});
prepareTLEs
์์ ์ฌ์ ์ ์ ์๋ ์ธ๊ณต์์ฑ ์ ๋ณด๋ค์ std::map<int, std::unique_ptr<Satellite::Satellite>> m_satellites
์ ์ ์ฅํ๋ค. ๋ register
๊ธฐ๋ฅ์์๋ ์ถ๊ฐ์ ์ธ TLE
๋ฅผ ๋ฑ๋กํ ์ ์๋ค. ์ด๋ ๋๋ค m_numTLEs
๋ฅผ 1 ์ฆ๊ฐ์ํค๋๋ฐ, unregister
์๋ ๊ฐ์์ํค๋ ์ฝ๋๊ฐ ์๊ธธ๋ m_numTLEs--
๋ฅผ ์ถ๊ฐํด์ฃผ์๋ค. ๊ทธ๋ฆฌ๊ณ m_satellites.erase(it)
ํ object->dumpInfo()
๋ฅผ ์คํํ๋๋ฐ UAF๋ก ์ธํ Segfault๊ฐ ๋จ๋ ๊ฒ ๊ฐ์์ erase
์ ์ ๋ฏธ๋ฆฌ dumpInfo
๋ฅผ ์ ์ฅํ๊ณ ๋ฆฌํดํ๋ ์์ผ๋ก ๋ฐ๊ฟ์คฌ๋ค.
m_server.Post("/unregister", [&](const httplib::Request &request, httplib::Response &response) {
m_mutex.lock();
SCOPE_EXIT({ m_mutex.unlock(); });
DEBUG_DUMP_REQUEST;
if (!m_authenticator.isAuthorized()) {
response.set_redirect("/");
}
auto numberAsStr = request.get_param_value("number");
CheckVoid(!numberAsStr.empty());
auto number = stoi(numberAsStr);
auto it = m_satellites.find(number);
if (it != m_satellites.end()) {
auto object = it->second.get();
std::string res = object->dumpInfo();
m_numTLEs--;
m_satellites.erase(it);
response.set_content(res, "text/plain");
}
});
๋จ์ 6์๊ฐ => 10p * 3/1h => 180 ์ ๋ฐฉ์ด
m_server.Get("/statistic", [&](const httplib::Request &request, httplib::Response &response) {
std::string content;
m_mutex.lock();
SCOPE_EXIT({ m_mutex.unlock(); });
DEBUG_DUMP_REQUEST;
if (!m_authenticator.isAuthorized()) {
response.set_redirect("/");
}
for (auto const&it : m_satellites) {
auto satellite = it.second.get();
content.append(satellite->dumpInfo());
content.append("\n");
}
response.set_content(content, "text/plain");
});
์ ์ฅ๋ ๋ชจ๋ ์ธ๊ณต์์ฑ๋ค์ ์ ๋ณด๋ฅผ ์ถ๋ ฅํด์ฃผ๋ ๊ธฐ๋ฅ์ด ์๋ค.
ํ
์คํธ ํด๋ดค๋๋ฐ ์ด๊ฒ ๋ญ๋ ๋ชจ๋ ๊ฐ์ ์ ๋ณด๋ฅผ ๋ฑ๊ณ ์๋ค. ํน์ง์ด๋ผ๋ฉด ๋ง์ง๋ง์ผ๋ก ๋ฑ๋ก๋์๋ 41866 ์ธ๊ณต์์ฑ์ ์ ๋ณด์ด๋ค. ๋๊ฐ ์ด๋ฐ ๊ฒฝ์ฐ๋ ์์ ์ธ๊ณต์์ฑ๋ค์ ์ ๋ณด๋ฅผ ๊ฐ์ง๋ m_TLE
๋ฌธ์์ด์ด ๋ชจ๋ 41866 ์ธ๊ณต์์ฑ์ m_TLE
๋ก ๋ฎ์ด์ง ์ํ์ด๋ค. ํ์ธํด๋ณธ ๊ฒฐ๊ณผ ์ ์ฌ์ง์ฒ๋ผ ๋๊ฐ์ ๋ฌธ์์ด์ ๊ฐ์ง๊ณ ์์๋ค.
// Server.cc
bool Server::Server::prepareTLEs() {
std::ifstream file;
file.open("/home/user/Livefire2024/src/Resource/tles.txt", std::ifstream::in);
Check(file.is_open());
std::string line, temp;
while (std::getline(file, line)) {
line.append("\n");
Check(line.length() == 70);
if (line.at(0) == '\x32') {
std::string TLE;
TLE.append("XXXX \n");
TLE.append(temp);
TLE.append(line);
Check(TLE.length() == 70 * 3);
auto number = Satellite::satellite_number(TLE);
auto it = m_satellites.find(number);
if (it != m_satellites.end()) { continue; }
auto object = std::unique_ptr<Satellite::Satellite>(new Satellite::Satellite(std::to_string(number), TLE));
m_satellites.insert(std::make_pair(number, std::move(object)));
m_numTLEs++;
} else {
temp = line;
}
}
return true;
}
//Satellite.h
class Satellite {
public:
Satellite(std::string_view name, std::string_view TLE) {
std::random_device rd;
m_name = (char *)malloc(name.length());
memcpy(m_name, name.data(), name.length());
m_TLE = std::move(TLE);
std::cout << "Adding new satellite " << name << std::endl;
std::mt19937 gen(rd());
std::normal_distribution<float> generator(0, 1);
m_location = std::make_pair(generator(gen) * 160 - 80, generator(gen) * 360 - 180);
}
๊ฐ์ฒด๋ง๋ค์ m_TLE ๊ฐ ๋ง์ง๋ง์ TLE ๋ฅผ ๊ฐ๋ฆฌํจ๋ค๋ ๊ฒ์ prepareTLEs
๋ด์ TLE ๋ฅผ ๊ฐ๋ฆฌํจ๋ค๋ ๊ฒ์์ ์ ์ ์๋ค
๊ฐ์ฒด๋ง๋ค ๋ค๋ฅธ string ์ ๊ฐ๋ฆฌํค๋๋ก ๋์ถฉ ๋๋นตํด์คฌ๋ค ใ
ใ
;
if (line.at(0) == '\x32') {
std::string* TLE = new std::string();
TLE->append("XXXX \n");
TLE->append(temp);
TLE->append(line);
Check((*TLE).length() == 70 * 3);
auto number = Satellite::satellite_number(*TLE);
auto it = m_satellites.find(number);
if (it != m_satellites.end()) { continue; }
auto object = std::unique_ptr<Satellite::Satellite>(new Satellite::Satellite(std::to_string(number), *TLE));
m_satellites.insert(std::make_pair(number, std::move(object)));
m_numTLEs++;
}
๋จ์ 6์๊ฐ => 180์ ๋ฐฉ์ด
์ต์ ์ ์ 1200 ์ ์์ ๋ฐฉ์ด ์ฑ๊ณตํ 240 + 210 + 180 + 180 = 810 ์ ์ ๋ํ์ฌ ์ฐ๋ฆฌ ํ์ 2010
์ Live Fire ์ ์๋ฅผ ๊ธฐ๋กํ์๋ค.
๋ฌธ์ ์ ์ 2086 ์ ๊ณผ ๋ํ๋ฉด 4096์ , ์ต์ข ์ ์๊ฐ ๋์จ๋ค.
arm PE ํ์ผ๊ณผ ์ํธํ๋ ํ์ผ์ด ์ฃผ์ด์ง๋ค.
์ํธํ ๊ณผ์ ์ ๋ถ์ํ์ฌ ๋ณตํธํํด์ผํ๋ ๋ฌธ์ ์ผ ๊ฒ์ด๋ค.
IDA๋ก ์ฅ ๋ณด๋ฉด ๋ฐ๋ก WinCrypt
๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก ๊ฐ๋จํ๊ฒ ์ํธํ ์งํํ๋ ๊ฒ์ ๋ณผ ์ ์๊ณ , ๊ธ๋ฐฉ ํ๋ฆด ๊ฑฐ๋ผ ์์ํ๋ค.
AES 256๋นํธ ํค๋ฅผ ์์ฑํ ํ ํ์ผ์ ์ํธํํ๋ค. AES ํค๋ฅผ RSA ๊ณต๊ฐํค๋ก ์ํธํํ์ฌ ์ํธํ ํ์ผ ์๋ถ๋ถ์ ์ ์ฅํ๋๋ฐ, RSA ๊ณต๊ฐํค๋ ๋ฐ์ด๋๋ฆฌ ๋ด์ ์งฑ๋ฐํ์๋ค.
์ v9
์ ์ ์ฅ๋๋ ๊ฐ์ ๋ฝ์๋ณด๋ฉด
์ ๊ฐ์๋ฐ ์ด๋ PUBLICKEYBLOB
๊ตฌ์กฐ์ฒด ํ์์ด๋ค. CryptExportKey
ํ ๋ PUBLICKEYBLOB
ํ์์ผ๋ก ๋ด๋ณด๋ธ ๊ฒฐ๊ณผ์ ๊ฐ์๋ฐ ๊ตฌ์กฐ์ฒด๋ ๋ค์๊ณผ ๊ฐ๋ค.
๊ทธ๋ ๊ฒ 2049๋นํธ์ง๋ฆฌ N ์ ์ถ์ถํด๋ณด๋ฉด(Little Endian ์ผ๋ก ์ ์ฅ๋จ)
N = 0x10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004c5d341864e53fc1f46aed6e24a13f6a1a4a3795ff787068cdcfc892d40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005b1de37580ed5eeec2c6e5b7506de185673f8b93a478b3a9740d2cd012bb8d06e47d849e646eeabf83bd075a46879584072282b588825dd8d4b
๋ณด๋ฉด ์ค๊ฐ์ 00์ด ์์ฒญ ๋ง๋ค. ๋ฑ ๋ด๋ ์์ํด๋ณด์ด๊ธธ๋ ์์ ์์ ์ ์
์ด์๊ฒ ๋ณด์ฌ์คฌ๋ค.
ํผ์ ์ฅ์ฅ ํ๋๋ ๋
ธํธ์ ์ด๊ฑธ ์ ์ด์ ๋ณด์ฌ์คฌ๋ค.
N = (2^1024 + a) * (2^1024 + b) = 2^2048 + 2^1024(a + b) + ab
WOW ๐ฎ ์ ์์ด๋ฉด ์ ๋นต๊พธ ๋ซ๋ฆฐ N ์ ์ค๋ช
ํ ์ ์์๋ค. ์ต์์์ 1์ด 1 << 2048
์ด๊ณ , ์ค๊ฐ์ 4c5d341...2d4
๋ 2^1024(a+b)
, 5b1d..8d4b
๋ ab
์ธ ๊ฒ์ด๋ค.
a+b
์ ab
๋ฅผ ์๊ธฐ ๋๋ฌธ์ a
์ b
๋ฅผ ์ ์ ์๊ณ , ๊ทธ ๊ฐ์
from z3 import *
n = 0x10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004c5d341864e53fc1f46aed6e24a13f6a1a4a3795ff787068cdcfc892d40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005b1de37580ed5eeec2c6e5b7506de185673f8b93a478b3a9740d2cd012bb8d06e47d849e646eeabf83bd075a46879584072282b588825dd8d4b
5b1de37580ed5eeec2c6e5b7506de185673f8b93a478b3a9740d2cd012bb8d06e47d849e646eeabf83bd075a46879584072282b588825dd8d4b
pab = 0x4c5d341864e53fc1f46aed6e24a13f6a1a4a3795ff787068cdcfc892d4
ab = 0x5b1de37580ed5eeec2c6e5b7506de185673f8b93a478b3a9740d2cd012bb8d06e47d849e646eeabf83bd075a46879584072282b588825dd8d4b
a = Int('a')
b = Int('b')
s = Solver()
s.add(a > 0)
s.add(b > 0)
s.add(a * b == ab)
s.add(a + b == pab)
'''
s.check()
m = s.model()
[b = 1029385710293857012310298374019823740519823750198237501982375019825445,
a = 1029385710293857012310298374019823740519823750198237501982375019825583]
'''
์์ ๊ฐ๋ค.
๊ทธ๋ฌ๋ฉด p
์ q
๋ ๊ฐ๊ฐ ((1 << 1024) + a)
, ((1 << 1024) + b)
๊ฐ ๋๊ณ RSA ๊ฐ์ธํค๋ฅผ ๊ตฌํ ์ ์๊ฒ ๋์๋ค.
q = 1029385710293857012310298374019823740519823750198237501982375019825445
p = 1029385710293857012310298374019823740519823750198237501982375019825583
p, q = ((1 << 1024) + p), ((1 << 1024) + q)
assert p * q == n
e = 0x10001
phi = (p-1) * (q-1)
d = pow(e, -1, phi)
๊ทธ๋ฆฌ๊ณ ์ฝ์ง์ ์๊ฐ์ด ์ด์ด์ก๋๋ฐ, WinCrypt
๊ฐ aes key ๋ฅผ RSA ๋ก CryptExportKey
ํ ๋ PKCS ํจ๋ฉ์ ํ๋ ๊ฒ ๊ฐ์๋ฐ, python ์ผ๋ก decrypt ํ ๋ ์๊พธ ๋ป๋ฌ๋ค. n ์ด 2049 ๋นํธ์ธ๋ฐ ์ํธํ๋ ๋ฐ์ดํฐ๋ 257 ๋ฐ์ดํธ, ์ด ๋๊ฐ๊ฐ PKCS์ RSA ์ฌ์ด์์ ์ถฉ๋? ์ด ์ผ์ด๋ ๊ฒ ๊ฐ์๋ค. ๊ทธ๋์ CryptExportKey
๋ก ๊ฐ์ธํค๋ฅผ PRIVATEKEYBLOB
๊ตฌ์กฐ์ฒด๋ก ์ถ๋ ฅํ blob ์ ์ง์ ๋ง๋ค์ด์ cpp ์ฝ๋์์ CryptImportKey
ํ ๋ด์ CryptDecrypt
ํ๋ ๊ฝค ๋ฉ์ฒญํ ๋ฐฉ๋ฒ์ผ๋ก aes key ๋ฅผ ๋ณต๊ตฌํ๋ค. ks
๋์ ์๋ฒ๋ฅผ ๋ณด๋ aes_key = long_to_bytes(pow(int.from_bytes(aes_key, 'little'), d, n))[::-1][:32][::-1]
์ ๊ฐ์ด ๋ณต๊ตฌํ ์ ์์๋ค. ์๋๋ฅผ ํด๋ดค๋ ๊ฑด๋ฐ little
์๋์์ผ๋ก ์ฝ๊ณ ๋ค์ง๊ณ 32๋ฐ์ดํธ ๊ฐ์ ธ์ค๊ณ ๋ค์ ๋ค์ง๋ ๊ตฌ์กฐ๋ฅผ ์์ ๋ชฐ๋๋ค ใ
ใ
;
์ถ์ ์๋ถ ์๋ฒ ๋ณด๋ฉด ์๋์ ๊ฐ์๋ฐ(๋๋ ์ ๊ฑธ ๋ฐ๋๋ค.)
rsakey = RSA.construct((n, e, d))
cipher = PKCS1_v1_5.new(rsakey)
aes_key = cipher.decrypt(aes_key[::-1], None)
PKCS1_v1_5 ์ 256๋ฐ์ดํธ๋ฅผ ๋์ค์ผ ๋๋ค. ๊น๋ํ๊ฒ
#include <windows.h>
#include <wincrypt.h>
#include <stdio.h>
HCRYPTKEY* ImportRSAKey(HCRYPTPROV hProv) {
BYTE aa[] = {0x4B, 0x8D, 0xDD, 0x25, 0x88, 0x58, 0x2B, 0x28, 0x72, 0x40, 0x58, 0x79, 0x68, 0xA4, 0x75, 0xD0, 0x3B, 0xF8, 0xAB, 0xEE, 0x46, 0xE6, 0x49, 0xD8, 0x47, 0x6E, 0xD0, 0xB8, 0x2B, 0x01, 0xCD, 0xD2, 0x40, 0x97, 0x3A, 0x8B, 0x47, 0x3A, 0xB9, 0xF8, 0x73, 0x56, 0x18, 0xDE, 0x06, 0x75, 0x5B, 0x6E, 0x2C, 0xEC, 0xEE, 0xD5, 0x0E, 0x58, 0x37, 0xDE, 0xB1, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD4, 0x92, 0xC8, 0xCF, 0xCD, 0x68, 0x70, 0x78, 0xFF, 0x95, 0x37, 0x4A, 0x1A, 0x6A, 0x3F, 0xA1, 0x24, 0x6E, 0xED, 0x6A, 0xF4, 0xC1, 0x3F, 0xE5, 0x64, 0x18, 0x34, 0x5D, 0x4C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xAF, 0x49, 0xE4, 0xE7, 0x66, 0x34, 0x38, 0xBC, 0xFF, 0xCA, 0x1B, 0x25, 0x0D, 0xB5, 0x9F, 0x50, 0x12, 0xB7, 0x76, 0x35, 0xFA, 0xE0, 0x9F, 0x72, 0x32, 0x0C, 0x9A, 0x2E, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x25, 0x49, 0xE4, 0xE7, 0x66, 0x34, 0x38, 0xBC, 0xFF, 0xCA, 0x1B, 0x25, 0x0D, 0xB5, 0x9F, 0x50, 0x12, 0xB7, 0x76, 0x35, 0xFA, 0xE0, 0x9F, 0x72, 0x32, 0x0C, 0x9A, 0x2E, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x69, 0xF8, 0xF4, 0x6B, 0x2D, 0xD0, 0x1F, 0x22, 0x1D, 0xD0, 0x59, 0xFC, 0x0E, 0x93, 0xAA, 0xCE, 0x09, 0x64, 0xA4, 0x4F, 0x64, 0x12, 0x69, 0x33, 0xE8, 0xB6, 0x79, 0x36, 0xB8, 0x91, 0xBA, 0x4E, 0x25, 0x71, 0x9C, 0xDF, 0x6C, 0x94, 0x70, 0xC8, 0xD2, 0xAA, 0xF2, 0xE6, 0x2E, 0x20, 0x83, 0xC0, 0x60, 0xAF, 0x4C, 0xF0, 0xA5, 0x80, 0xD8, 0xE9, 0x01, 0x51, 0x5F, 0xB3, 0xA0, 0x4C, 0x5F, 0xB3, 0xA0, 0x4C, 0x5F, 0xB3, 0xA0, 0x4C, 0x5F, 0xB3, 0xA0, 0x4C, 0x5F, 0xB3, 0xA0, 0x4C, 0x5F, 0xB3, 0xA0, 0x4C, 0x5F, 0xB3, 0xA0, 0x4C, 0x5F, 0xB3, 0xA0, 0x4C, 0x5F, 0xB3, 0xA0, 0x4C, 0x5F, 0xB3, 0xA0, 0x4C, 0x5F, 0xB3, 0xA0, 0x4C, 0x5F, 0xB3, 0xA0, 0x4C, 0x5F, 0xB3, 0xA0, 0x4C, 0x5F, 0xB3, 0xA0, 0x4C, 0x5F, 0xB3, 0xA0, 0x4C, 0x5F, 0xB3, 0xA0, 0x4C, 0x5F, 0xB3, 0xA0, 0x4C, 0x5F, 0xB3, 0xD6, 0x44, 0x6C, 0x8A, 0x28, 0xF7, 0xC1, 0xE4, 0xFB, 0xB4, 0x25, 0xA9, 0xFC, 0x8C, 0x7A, 0xFB, 0x74, 0xBA, 0x67, 0xDE, 0x30, 0x3F, 0xD7, 0xD8, 0x24, 0x08, 0xBA, 0x7F, 0x58, 0x3B, 0xE2, 0xC4, 0x1D, 0x3B, 0xE2, 0xC4, 0x1D, 0x3B, 0xE2, 0xC4, 0x1D, 0x3B, 0xE2, 0xC4, 0x1D, 0x3B, 0xE2, 0xC4, 0x1D, 0x3B, 0xE2, 0xC4, 0x1D, 0x3B, 0xE2, 0xC4, 0x1D, 0x3B, 0xE2, 0xC4, 0x1D, 0x3B, 0xE2, 0xC4, 0x1D, 0x3B, 0xE2, 0xC4, 0x1D, 0x3B, 0xE2, 0xC4, 0x1D, 0x3B, 0xE2, 0xC4, 0x1D, 0x3B, 0xE2, 0xC4, 0x1D, 0x3B, 0xE2, 0xC4, 0x1D, 0x3B, 0xE2, 0xC4, 0x1D, 0x3B, 0xE2, 0xC4, 0x1D, 0x3B, 0xE2, 0xC4, 0x1D, 0x3B, 0xE2, 0xC4, 0x1D, 0x3B, 0xE2, 0xC4, 0x1D, 0x3B, 0xE2, 0xC4, 0x1D, 0x3B, 0xE2, 0xC4, 0x1D, 0x3B, 0xE2, 0xC4, 0x1D, 0x3B, 0xE2, 0xC4, 0x1D, 0x3B, 0xE2, 0xC4, 0x1D, 0x3B, 0xE2, 0xC4, 0xCD, 0x8A, 0x46, 0x94, 0x53, 0xE6, 0x5C, 0xDB, 0x38, 0x79, 0xC4, 0xCC, 0xC7, 0x3F, 0x85, 0x4A, 0xA9, 0x86, 0xEC, 0xD1, 0x8B, 0x2A, 0xFC, 0x02, 0xD0, 0x72, 0x1A, 0xCD, 0xF0, 0xB2, 0x1A, 0x4D, 0xE5, 0xB2, 0x1A, 0x4D, 0xE5, 0xB2, 0x1A, 0x4D, 0xE5, 0xB2, 0x1A, 0x4D, 0xE5, 0xB2, 0x1A, 0x4D, 0xE5, 0xB2, 0x1A, 0x4D, 0xE5, 0xB2, 0x1A, 0x4D, 0xE5, 0xB2, 0x1A, 0x4D, 0xE5, 0xB2, 0x1A, 0x4D, 0xE5, 0xB2, 0x1A, 0x4D, 0xE5, 0xB2, 0x1A, 0x4D, 0xE5, 0xB2, 0x1A, 0x4D, 0xE5, 0xB2, 0x1A, 0x4D, 0xE5, 0xB2, 0x1A, 0x4D, 0xE5, 0xB2, 0x1A, 0x4D, 0xE5, 0xB2, 0x1A, 0x4D, 0xE5, 0xB2, 0x1A, 0x4D, 0xE5, 0xB2, 0x1A, 0x4D, 0xE5, 0xB2, 0x1A, 0x4D, 0xE5, 0xB2, 0x1A, 0x4D, 0xE5, 0xB2, 0x1A, 0x4D, 0xE5, 0xB2, 0x1A, 0x4D, 0xE5, 0xB2, 0x1A, 0x4D, 0xE5, 0xB2, 0x1A, 0x4D, 0xE5, 0xB2, 0x1A, 0x4D, 0x83, 0x73, 0xA4, 0x38, 0xFC, 0x0B, 0x61, 0x11, 0x32, 0xD0, 0x22, 0x82, 0x19, 0x48, 0xA4, 0xD3, 0xB0, 0x23, 0x25, 0xF2, 0xF3, 0x5A, 0x31, 0xF6, 0xBE, 0x5E, 0xC5, 0x9A, 0xDF, 0xD4, 0x26, 0x2B, 0xD9, 0xD4, 0x26, 0x2B, 0xD9, 0xD4, 0x26, 0x2B, 0xD9, 0xD4, 0x26, 0x2B, 0xD9, 0xD4, 0x26, 0x2B, 0xD9, 0xD4, 0x26, 0x2B, 0xD9, 0xD4, 0x26, 0x2B, 0xD9, 0xD4, 0x26, 0x2B, 0xD9, 0xD4, 0x26, 0x2B, 0xD9, 0xD4, 0x26, 0x2B, 0xD9, 0xD4, 0x26, 0x2B, 0xD9, 0xD4, 0x26, 0x2B, 0xD9, 0xD4, 0x26, 0x2B, 0xD9, 0xD4, 0x26, 0x2B, 0xD9, 0xD4, 0x26, 0x2B, 0xD9, 0xD4, 0x26, 0x2B, 0xD9, 0xD4, 0x26, 0x2B, 0xD9, 0xD4, 0x26, 0x2B, 0xD9, 0xD4, 0x26, 0x2B, 0xD9, 0xD4, 0x26, 0x2B, 0xD9, 0xD4, 0x26, 0x2B, 0xD9, 0xD4, 0x26, 0x2B, 0xD9, 0xD4, 0x26, 0x2B, 0xD9, 0xD4, 0x26, 0x2B, 0xD9, 0xD4, 0x26, 0x2B, 0x27, 0x2C, 0x8C, 0x7C, 0x6C, 0x91, 0x05, 0xDD, 0xB3, 0xDD, 0x66, 0x39, 0x66, 0x94, 0x3A, 0xA1, 0x5C, 0x50, 0xFC, 0x34, 0x3F, 0x57, 0x3E, 0xF9, 0x9B, 0x90, 0xE3, 0x66, 0xD7, 0xB5, 0x03, 0x73, 0xED, 0xC0, 0x5C, 0x3B, 0x30, 0xD7, 0x0E, 0xCC, 0xB5, 0x03, 0x73, 0xED, 0xC0, 0x5C, 0x3B, 0x30, 0xD7, 0x0E, 0xCC, 0xB5, 0x03, 0x73, 0xED, 0xC0, 0x5C, 0x3B, 0x30, 0xD7, 0x0E, 0xCC, 0xB5, 0x03, 0x73, 0xED, 0xC0, 0x5C, 0x3B, 0x30, 0xD7, 0x0E, 0xCC, 0xB5, 0x03, 0x73, 0xED, 0xC0, 0x5C, 0x3B, 0x30, 0xD7, 0x0E, 0xCC, 0xB5, 0x03, 0x73, 0xED, 0xC0, 0x5C, 0x3B, 0x30, 0xD7, 0x0E, 0xCC, 0xB5, 0x03, 0x73, 0xED, 0xC0, 0x5C, 0x3B, 0x30, 0xD7, 0x0E, 0xCC, 0xB5, 0x03, 0x73, 0xED, 0xC0, 0x5C, 0x3B, 0x30, 0xD7, 0x0E, 0xCC, 0xB5, 0x03, 0x73, 0xED, 0xC0, 0x5C, 0x3B, 0x30, 0xD7, 0x0E, 0x4C};
DWORD bitlen = 2049;
BLOBHEADER blobHeader;
blobHeader.bType = PRIVATEKEYBLOB;
blobHeader.bVersion = 0x02;
blobHeader.reserved = 0;
blobHeader.aiKeyAlg = CALG_RSA_KEYX;
RSAPUBKEY rsaPubKey;
rsaPubKey.magic = 0x32415352;
rsaPubKey.bitlen = bitlen;
rsaPubKey.pubexp = 65537;
DWORD blobSize = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
bitlen / 8 * 7;
BYTE *keyBlob = (BYTE*)malloc(blobSize);
BYTE *ptr = keyBlob;
memcpy(ptr, &blobHeader, sizeof(BLOBHEADER));
ptr += sizeof(BLOBHEADER);
memcpy(ptr, &rsaPubKey, sizeof(RSAPUBKEY));
ptr += sizeof(RSAPUBKEY);
memcpy(ptr, aa, sizeof(aa));
ptr += sizeof(aa);
HCRYPTKEY* hKey = (HCRYPTKEY*) malloc(sizeof(HCRYPTKEY));
if (!CryptImportKey(hProv, keyBlob, blobSize, 0, 0, hKey)) {
printf("CryptImportKey failed: %d\n", GetLastError());
} else {
printf("Key imported successfully\n");
}
free(keyBlob);
return hKey;
}
BOOL DecryptAESKey(HCRYPTKEY hPrivateKey, const BYTE* pbEncryptedAESKey, DWORD dwEncryptedAESKeyLen, BYTE** ppDecryptedAESKey, DWORD* pdwDecryptedAESKeyLen) {
*pdwDecryptedAESKeyLen = dwEncryptedAESKeyLen;
*ppDecryptedAESKey = (BYTE*)malloc(*pdwDecryptedAESKeyLen);
if (*ppDecryptedAESKey == NULL) {
printf("Memory allocation failed\n");
return FALSE;
}
memcpy(*ppDecryptedAESKey, pbEncryptedAESKey, dwEncryptedAESKeyLen);
if (!CryptDecrypt(hPrivateKey, 0, TRUE, 0, *ppDecryptedAESKey, pdwDecryptedAESKeyLen)) {
printf("CryptDecrypt failed: %d\n", GetLastError());
free(*ppDecryptedAESKey);
return FALSE;
}
return TRUE;
}
int main() {
HCRYPTPROV hProv;
if (!CryptAcquireContext(&hProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
printf("CryptAcquireContext failed: %d\n", GetLastError());
return 1;
}
BYTE encryptedAESKey[] = { 0xB5, 0x14, 0x9D, 0x1F, 0x12, 0x0B, 0x68, 0xF8, 0xF0, 0x9B, 0xD0, 0x53, 0xFB, 0x04, 0x60, 0xDF, 0xE8, 0xEB, 0x70, 0x8D, 0x28, 0xEA, 0x51, 0xAE, 0xCB, 0xBC, 0x0C, 0x40, 0xFD, 0x8B, 0x72, 0x89, 0xE9, 0x52, 0x5E, 0x32, 0xCF, 0x93, 0x72, 0x0C, 0x83, 0x62, 0xC5, 0xC3, 0xCF, 0xFD, 0xBB, 0x03, 0x3A, 0x19, 0xA0, 0x49, 0x33, 0x0B, 0x29, 0x2B, 0x19, 0x13, 0xB2, 0x1C, 0xD4, 0x83, 0x41, 0x82, 0xF2, 0xEC, 0xD5, 0x3C, 0xAD, 0x66, 0xD7, 0xDA, 0x83, 0x31, 0x8D, 0x0F, 0x01, 0xE3, 0x25, 0xBE, 0x50, 0x52, 0xBE, 0x1C, 0x7A, 0x0D, 0x12, 0x4F, 0x82, 0x7C, 0x48, 0x15, 0x32, 0xF1, 0xD5, 0x76, 0x42, 0x77, 0x02, 0x2F, 0x39, 0x3D, 0x14, 0x21, 0x7F, 0x24, 0x80, 0x51, 0x6B, 0xE2, 0xCA, 0xDF, 0xEB, 0xC5, 0x76, 0x17, 0x0F, 0x3E, 0x57, 0xB3, 0x27, 0x7A, 0x59, 0xAC, 0x12, 0x08, 0x9D, 0x0C, 0xAE, 0x9F, 0x65, 0xDB, 0xBE, 0x60, 0x31, 0x9D, 0xA1, 0xD6, 0x2D, 0xEF, 0x91, 0x66, 0x2C, 0x24, 0x21, 0xC2, 0xF5, 0x82, 0x4B, 0xA7, 0xE1, 0x79, 0x23, 0x68, 0x7C, 0xBE, 0x59, 0xF0, 0x55, 0xB8, 0x1B, 0xB9, 0xF6, 0x3A, 0xDB, 0x24, 0xED, 0x9D, 0x5A, 0xAC, 0xB2, 0x43, 0x1C, 0xF2, 0x31, 0xB3, 0x82, 0x35, 0x36, 0xD4, 0xDC, 0xE0, 0xB8, 0xB8, 0x4B, 0xCB, 0xAE, 0xFE, 0xE7, 0x0B, 0x85, 0x37, 0x13, 0xFC, 0x26, 0xBF, 0x49, 0x20, 0xC3, 0xCC, 0x22, 0x5D, 0xA6, 0x1F, 0x1F, 0xE8, 0x07, 0xE2, 0x96, 0xE5, 0x4B, 0x73, 0x61, 0xD1, 0x82, 0x67, 0x7C, 0x4F, 0xFC, 0xF0, 0x97, 0x49, 0x11, 0x88, 0x7C, 0x27, 0x65, 0x8C, 0x73, 0x4D, 0x36, 0x56, 0xC7, 0x10, 0x36, 0x90, 0x0E, 0xD6, 0xA9, 0xC1, 0xEB, 0x61, 0x09, 0xC5, 0x93, 0x54, 0x0F, 0xAB, 0xAD, 0xBF, 0x7A, 0x2F, 0x5C, 0x3E, 0x9B, 0x4B, 0x00 };
DWORD encryptedAESKeyLen = sizeof(encryptedAESKey);
HCRYPTKEY* hPrivateKey = ImportRSAKey(hProv);
BYTE* decryptedAESKey = NULL;
DWORD decryptedAESKeyLen = 0;
if (DecryptAESKey(*hPrivateKey, encryptedAESKey, encryptedAESKeyLen, &decryptedAESKey, &decryptedAESKeyLen)) {
printf("Decrypted AES Key: ");
for (DWORD i = 0; i < decryptedAESKeyLen; i++) {
printf("%02X", decryptedAESKey[i]);
}
printf("\n");
free(decryptedAESKey);
} else {
printf("Failed to decrypt AES key\n");
}
CryptReleaseContext(hProv, 0);
return 0;
}
GPT ๊ฐ ์ง์ค ์ฝ๋๋ฅผ ์คํํด๋ณด๋ฉด
๐๐๐
aes_key = bytes.fromhex('68D71403FA7BBC9E7437A13709CFBCE0B0DE984FADD5F729384DCE682A6ACD42')
print(f'Decrypted aes key : ', len(aes_key), aes_key.hex())
i = 4 + size
cipher = AES.new(aes_key, AES.MODE_CBC)
out = b''
while i < len(enc):
data = enc[i:i+1024]
out += cipher.decrypt(data)
i += 1024
open('./important.pdf', 'wb').write(out)
IV ๋์ ๋งจ ์ 16๋ฐ์ดํธ๊ฐ ๊นจ์ง๋ค.
์ ์ pdf ํ์ผ ์๋ถ๋ถ์ผ๋ก ๋ฐ๊ฟ์น๊ธฐ
๋ณต๊ตฌ ์๋ฃ~