-
-
Save Bono-iPad/e8650885d1255f55440a4a467503b2da to your computer and use it in GitHub Desktop.
INS'hAck 2018 GCorp Stage 4 (solved by angr)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
// file: emergency_override.c | |
// date: 2017-08-30 | |
// author: paul.dautry | |
// purpose: | |
// G-Corp Stage 4 - Emergency Override (running on 12042) | |
// license: | |
// GPLv3 | |
// | |
// | |
// _____ _ _ _ _ | |
// / ____| | | (_) | | | | | |
// | | _ _| |__ _ ___ __ _| | __ _ ___| |__ _ __ __ _ | |
// | | | | | | '_ \| |/ __| / _` | |/ _` |/ _ \ '_ \| '__/ _` | | |
// | |___| |_| | |_) | | (__ | (_| | | (_| | __/ |_) | | | (_| | | |
// \_____\__,_|_.__/|_|\___| \__,_|_|\__, |\___|_.__/|_| \__,_| | |
// __/ | | |
// |___/ | |
// | |
// info: partial illustration w/ EO_SZ = 3 below | |
// | |
// T | |
// | | |
// v | |
// ___ ___ ___ | |
// /18_/19_/20_/| | |
// /_9_/10_/11_/|| | |
// /___/___/__ /|/| | |
// | 0 | 1 | 2 | /|| <--------- S | |
// |___|___|___|/|/| | |
// | 3 | 4 | 5 | /|| | |
// |___|___|___|/|/ | |
// | 6 | 7 | 8 | / | |
// |___|___|___|/ | |
// | |
// ^ | |
// | | |
// F | |
// | |
// | |
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
// INCLUDES | |
//------------------------------------------------------------------------------ | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <stdio.h> | |
#include <string.h> | |
#include <errno.h> | |
//------------------------------------------------------------------------------ | |
// CONFIGURATION | |
//------------------------------------------------------------------------------ | |
#define EO_SZ 4 | |
#define EO_KEY_SZ EO_SZ*EO_SZ*EO_SZ | |
#define EO_FACE_SZ EO_SZ*EO_SZ | |
#define EO_RESULT_SZ 3*EO_SZ | |
#define EO_RESULT \ | |
{ \ | |
0x52,0xb4,0x7c,0xca, /* FT */ \ | |
0x54,0xb6,0xfa,0x48, /* FS */ \ | |
0x74,0x8e,0x4e,0xfc, /* TS */ \ | |
} | |
//------------------------------------------------------------------------------ | |
// MACROS | |
//------------------------------------------------------------------------------ | |
#define ERASE(buf, sz) memset(buf, 0x00, sz) | |
//------------------------------------------------------------------------------ | |
// TYPES | |
//------------------------------------------------------------------------------ | |
typedef unsigned char uchar; | |
//------------------------------------------------------------------------------ | |
// GLOBALS | |
//------------------------------------------------------------------------------ | |
static const uchar gRESULT[EO_RESULT_SZ]=EO_RESULT; /* FT + FS + TS */ | |
static uchar gCOMPUT[EO_RESULT_SZ]; /* FT + FS + TS */ | |
static uchar gKEY[EO_KEY_SZ]; | |
static uchar gF[EO_FACE_SZ]; | |
static uchar gS[EO_FACE_SZ]; | |
static uchar gT[EO_FACE_SZ]; | |
//------------------------------------------------------------------------------ | |
// FUNCTIONS | |
//------------------------------------------------------------------------------ | |
void usage(const char *prog) | |
{ | |
printf("usage: %s (compute|check)\n", prog); | |
exit(1); | |
} | |
void compute_F(void) | |
{ | |
int i, j; | |
for(i=0; i<EO_FACE_SZ; i++) { /* iterate over face */ | |
for(j=0; j<EO_SZ; j++) { /* iteratre over layers */ | |
gF[i] += gKEY[i+j*EO_FACE_SZ]; | |
} | |
} | |
} | |
void compute_S(void) | |
{ | |
int i, j; | |
for(i=0; i<EO_FACE_SZ; i++) { /* iterate over face */ | |
for(j=0; j<EO_SZ; j++) { /* iteratre over layers */ | |
gS[i] += gKEY[j+(i%EO_SZ)*EO_FACE_SZ+(i/EO_SZ)*EO_SZ]; | |
} | |
} | |
} | |
void compute_T(void) | |
{ | |
int i, j; | |
for(i=0; i<EO_FACE_SZ; i++) { /* iterate over face */ | |
for(j=0; j<EO_SZ; j++) { /* iteratre over layers */ | |
gT[i] += gKEY[i+j*EO_SZ+(i/EO_SZ)*(EO_FACE_SZ-EO_SZ)]; | |
} | |
} | |
} | |
void compute(void) | |
{ | |
int i, j, idxFT, idxFS; | |
ERASE(gF, EO_FACE_SZ); | |
ERASE(gS, EO_FACE_SZ); | |
ERASE(gT, EO_FACE_SZ); | |
ERASE(gCOMPUT, EO_RESULT_SZ); | |
compute_F(); | |
compute_S(); | |
compute_T(); | |
for(i=0; i<EO_SZ; ++i) { | |
for (j=0; j<EO_SZ; ++j){ | |
idxFT = i+j*EO_SZ; | |
idxFS = i*EO_SZ+j; | |
/* FT */ gCOMPUT[i] += gF[idxFT] + gT[idxFT]; | |
/* FS */ gCOMPUT[i+EO_SZ] += gF[idxFS] + gS[idxFS]; | |
/* TS */ gCOMPUT[i+2*EO_SZ] += gT[idxFS] + gS[idxFT]; | |
} | |
} | |
} | |
void print_result(void) | |
{ | |
int i, j; | |
printf( | |
"#define EO_RESULT \\\n" | |
"{ \\\n"); | |
for(i=0; i<3; i++){ | |
printf(" "); | |
for(j=0; j<EO_SZ; j++){ | |
printf("0x%02x,", gCOMPUT[i*EO_SZ+j]); | |
} | |
switch(i) { | |
case 0: printf(" /* FT */"); break; | |
case 1: printf(" /* FS */"); break; | |
case 2: printf(" /* TS */"); break; | |
} | |
printf(" \\\n"); | |
} | |
printf("}\n"); | |
} | |
void success(void) // for angr | |
{ | |
printf("OK\n"); | |
} | |
void check_result(void) | |
{ | |
if(memcmp(gRESULT, gCOMPUT, EO_RESULT_SZ)==0) { | |
success(); | |
} else { | |
printf("KO\n"); | |
} | |
} | |
//------------------------------------------------------------------------------ | |
// MAIN/ENTRY | |
//------------------------------------------------------------------------------ | |
int main(int argc, char **argv) | |
{/* | |
if(argc!=2) { | |
usage(argv[0]); | |
}*/ | |
ssize_t sz; | |
if((sz=read(STDIN_FILENO, gKEY, EO_KEY_SZ))<0) { | |
perror("failed to read from stdin"); | |
exit(1); | |
} | |
if(sz!=EO_KEY_SZ) { | |
printf("%s expects to read exactly %d bytes from stdin.\n", argv[0], EO_KEY_SZ); | |
exit(1); | |
} | |
compute();check_result();exit(0); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import angr | |
import requests | |
p = angr.Project("./a.out") | |
addr_main = p.loader.main_object.get_symbol('main').rebased_addr | |
addr_s = p.loader.main_object.get_symbol('success').rebased_addr | |
addr_key = p.loader.main_object.get_symbol('gKEY').rebased_addr | |
st = p.factory.blank_state(addr=addr_main) | |
st.memory.store(addr_key,st.se.BVS("flag",8*64)) | |
initial_path = p.factory.path(st) | |
pg = p.factory.path_group(initial_path) | |
e = pg.explore(find=addr_s) | |
if len(e.found) > 0: | |
s = e.found[0].state | |
q = s.se.eval(s.memory.load(addr_key,64),cast_to=str) | |
print repr(q) | |
r = requests.post("https://gcorp-stage-4.ctf.insecurity-insa.fr/",data=q) | |
print r.text |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(angr) $ gcc emergency_override_mod.c | |
(angr) $ python exp.py | |
WARNING | 2018-04-10 01:16:52,112 | angr.analyses.disassembly_utils | Your verison of capstone does not support MIPS instruction groups. | |
WARNING | 2018-04-10 01:16:52,740 | angr.factory | factory.path() is deprecated! Please use factory.entry_state() instead. | |
WARNING | 2018-04-10 01:16:52,740 | angr.factory | factory.path_group() is deprecated! Please use factory.simgr() instead. | |
'$it.\x0cP(F^cg\x1elz?VUhVM^y\x13\x0696r87\x18AN9qQ\x1b9I\t\x10"4OD/\x13\x10;\x08\x0cI(\x10zh\x14\x18P+"\x19>K\x1c' | |
Well done! You've just prevented doomsday... Awesome! | |
888888ba dP dP dP dP .88888. | |
dP dP 88 `8b 88 88 88 88 d8' `8b | |
8888888 a88aaaa8P' 88d888b. .d8888b. 88aaaaa88a 88aaa88 dP. .dP 88 88 88d888b. | |
88 88 88 88' `88 88' `88 88 88 88 `8bd8' 88 88 88' `88 | |
8888888 88 88 88. .88 88 88 88 .d88b. Y8. .8P 88 | |
dP dP dP dP `88888P' dP dP dP dP' `dP `8888P' dP | |
Good job! You must have this flag : INSA{4778b157c376f7a087f4974651c2d8bc66fe2f0ca0883cc93570803a7e067e6f} | |
(angr) $ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment