March 18, 2014

RuCTF: Admin 400 (Compile)

The task is simple: just compile the given source code.
All includes can be fixed just by searching all undeclared functions in Google.
I've faced an error with signbit undefined, so I've replaced it with a dirty macro (it just works and that's fine). Also, I've found that variable "bay" somehow gets corrupted before mtprngSeed, so I've replaced it with its value :) One of the libraries was not available in repositories (zopfli), so I've used it with "*.c" (I've renamed main in zopfli_bin.c to avoid double redeclaration).

Commandline looks like:
g++ '/asdasd/source.cpp' /asdasd/zopfli/*.c -I/usr/include/botan-1.10/ -I/usr/include/hangul-1.0 -I'/asdasd/blitz/include' -I/usr/include/nspr -lhangul -lbotan-1.10 -lmozjs185 -lbeecrypt -lsnappy -lmhash -fpermissive

The source looks like:
#include <random/chisquare.h>
#include <blitz/numinquire.h>
#include <time.h>
#include <iostream>
#include <iomanip>
#include <math.h>
#define signbit(x) (x<0?-1:1)

#include <stdlib.h>
#include <cstring>
#include <iostream>
#include <cstdio>
#include <mhash.h>
#include "js/jscntxt.h"
#include "js/jsapi.h"
#include "botan/botan.h"
#include "beecrypt/mtprng.h"
#include "hangul.h"
#include "zopfli.h"
#include "snappy.h"

unsigned char key[] = "aaaa";
int keylen = 4;

char together[10000] = {0};
int pos = 0;

int checkhash(unsigned char *data, size_t datalen, char *checkhash) {
char keyword[100];

memcpy(together + pos, data, datalen);
pos += datalen;

mhash_keygen((keygenid)0, (hashid)10, 10, keyword, 100, (void *)"aaaa", 3, key, keylen);

MHASH hash = mhash_hmac_init((hashid)10, keyword, 100, mhash_get_hash_pblock((hashid)10));

mhash(hash, data, datalen);
void *mac = mhash_hmac_end(hash);

char hash_printed[1000] = "0x";
for (int j = 0; j < mhash_get_block_size((hashid)10); j++) {
unsigned char *m = (unsigned char *)mac;
char r[3];
snprintf(r, 3, "%.2x", m[j]);
strcat(hash_printed, r);

printf("%s\n", hash_printed);

return strcmp(hash_printed, checkhash) == 0;

void reportError(JSContext *cx, const char *message, JSErrorReport *report) {
fprintf(stderr, "%s:%u:%s\n",
report->filename ? report->filename : "[no filename]",
(unsigned int) report->lineno,

int main() {
std::string a = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbccccccccccccaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
std::string output;

ZopfliOptions options;

snappy::Compress(, a.size(), &output);

if(!checkhash((unsigned char *), output.size(), (char *)"0x5a8f06cf6817a74bc75c3c8290196928acb04c189ecdd192a93eb3c3")) {
std::cout<<"Something wrong\n";

unsigned char b[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbccccccccccccaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
unsigned char *out = NULL;
size_t outsize = 0;

ZopfliCompress(&options, ZOPFLI_FORMAT_GZIP, b, a.size(), &out, &outsize);

if(!checkhash(out, outsize, (char *)"0x0f66ce213d2d27067ff9ffa8bbde2dd06d7f3e687549fad846169e16")) {
std::cout<<"Something wrong\n";

HangulInputContext* ic;
const char* p = "dekde";
const ucschar* commit;

ic = hangul_ic_new("2y");

while (*p != '\0') {
hangul_ic_process(ic, *p);

commit = hangul_ic_get_commit_string(ic);

int len = wcslen((const wchar_t*)commit);

if(!checkhash((unsigned char*)commit, len * sizeof(const wchar_t), (char *)"0xc9bf9374fbc9f4989afd0af7ac9824a4dcc768b33bfa3bb38e42617b")) {
std::cout<<"Something wrong\n";

static JSClass global_class = { "global",
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub,
JSRuntime *rt = JS_NewRuntime(8 * 1024 * 1024);
JSContext *cx = JS_NewContext(rt, 8192);
JS_SetErrorReporter(cx, reportError);

JSObject *global = JS_NewCompartmentAndGlobalObject(cx, &global_class, NULL);

JS_SetGlobalObject(cx, global);

if (!JS_InitStandardClasses(cx, global)) {
return 1;
char source[] = "Math.random()";

jsval rval;

cx->rngSeed = 31337;

JS_EvaluateScript(cx, global, source, strlen(source),
"none", 10, &rval);

double nums[2];
nums[0] = JSVAL_TO_DOUBLE(rval);
JS_EvaluateScript(cx, global, source, strlen(source),
"none", 10, &rval);
nums[1] = JSVAL_TO_DOUBLE(rval);

if(!checkhash((unsigned char*)nums, 2 * sizeof(double), (char *)"0x61b35e8d466f24ee1ea502350ec6f5d1134fe6ec543c17845fa62f8a")) {
std::cout<<"Something wrong\n";


mtprngParam mt;

byte bay[] = "qqqqqqqqqqqqqqqq";
byte result[100];

for(int i=0; i< 100; i++) {
result[i] = 0;

mtprngSeed(&mt, "qqqqqqqqqqqqqqqq", 16);

mtprngNext(&mt, result, 100);
if(!checkhash((unsigned char*)&result, 100, (char *)"0x7754dfd27fe6fa00551861ff41e4f48315bd89bef6da652f182ce2d6")) {
std::cout<<"Something wrong\n";

ranlib::ChiSquare<double> gen(4);

double f[16];

for(int i = 0; i<16; i++) {
f[i] = gen.random();

if(!checkhash((unsigned char*)&f, 16 * sizeof(double), (char *)"0xd19d0c167fe93b11004c0167c226d2e92c17dfa36ffb243f39824098")) {
std::cout<<"Something wrong\n";

Botan::byte pass[] = "aaaabbbb";

Botan::PBKDF* pbkdf = Botan::get_pbkdf("PBKDF2(SHA-256)");
Botan::OctetString aes_key = pbkdf->derive_key(32, "pass1337", pass, 8, 31337);

std::string aa = aes_key.as_string();

if(!checkhash((unsigned char*)aa.c_str(), aa.size(), (char *)"0x0c33d122ed50848a676539ae48eb84db0dcbf69e9ee857094755f2d7")) {
std::cout<<"Something wrong\n";

std::cout<<"Answer is RUCTF_";
checkhash((unsigned char*)together, pos, (char *)"");

return 0;
The output of this program is:
Answer is RUCTF_0xc9a7c966dff1549b77cf18723cee2ffe5fb4127b9ba75b446990d330

No comments:

Post a Comment