Skip to content

Instantly share code, notes, and snippets.

@bruce30262
Created September 25, 2018 15:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bruce30262/315e63315f460f9c4b57d0d42e796e96 to your computer and use it in GitHub Desktop.
Save bruce30262/315e63315f460f9c4b57d0d42e796e96 to your computer and use it in GitHub Desktop.
[flareon2018 level12] tracer with taint engine for subleq VM
// python is too slow, re-implement in C
// shitty code alert
// ref: https://0xec.blogspot.com/2017/10/flare-on-challenge-2017-writeup.html
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
int addr = 0x223;
char *Data;
char *msg;
int taint[0x8400];
short max = -1;
int cnt = 0;
short u16(char *data)
{
short ret = 0;
ret |= (data[1] << 8) & 0xff00 ;
ret |= (char)(data[0])&0xff;
return ret&0xffff;
}
void patch_word(int index, short d)
{
char d1 = d&0xff;
char d2 = (d>>8)&0xff;
Data[index] = d1;
Data[index+1] = d2;
}
int check_range(int addr, int min, int max)
{
if (addr >= min && addr <= max) return 1;
else return 0;
}
int track[6] = {0x223, 0x1203, 0x120b, 0x11ff, 0x1211};
int check_in(int addr)
{
int i = 0;
for(i = 0 ; i < 6 ; i++)
{
if (addr== track[i]) return 1;
}
return 0;
}
short Word(int index)
{
return u16(Data+index);
}
int fuck(short now, short f1, short f2, short f3)
{
short bx=0, ax=0, dx=0;
int in = 0;
bx = (f1 << 1)&0xffff;
ax = Word(addr+bx);
int idx1 = addr+bx;
bx = (f2 << 1)&0xffff;
dx = Word(addr+bx);
int idx2 = addr+bx;
// taint tracking
int pc = ((now<<1)+0x223)&0xffff;
if(dx==ax && taint[idx2]) taint[idx2] = 0;
else if(taint[idx1] || taint[idx2])
{
taint[idx2] = 1;
puts("taint");
in = 1;
}
if (in) printf("cnt:%d\ncmp:%p:%p %p:%p\n", cnt,idx2, dx, idx1, ax);
if (in) printf("patch byte: %p %p\n\n", addr+bx, (dx-ax)&0xffff);
dx = (dx - ax)&0xffff;
bx = (f2 << 1)&0xffff;
patch_word(addr+bx, dx);
ax = f3&0xffff;
if (ax != 0)
{
if (dx <= 0) return 1;
}
return 0;
}
void print_char()
{
char ch = Word(addr+4)&0xff;
putchar(ch);
strcat(msg, &ch);
fflush(stdout);
patch_word(addr+4, 0);
patch_word(addr+8, 0);
if(strstr(msg, "harder."))
{
printf("\nmax:%p\n", max);
exit(0);
}
}
void set_password(char *password)
{
int i = 0, idx = 0;
int start1 = 0x142b;
int start2 = 0x5e70;
int len = strlen(password);
for(i = start1 ; i <= 0x1469 ; i += 2)
{
if (idx >= len) Data[i] = 0;
else Data[i] = password[idx];
Data[i+1] = 0;
taint[i] = 1;
idx++;
}
idx = 0;
for(i = start2 ; i <= 0x5eaf ; i++)
{
if (idx >= len) Data[i] = 0;
else Data[i] = password[idx];
idx++;
taint[i] = 1;
}
}
int main(int argc, char *argv[])
{
memset(taint, 0, sizeof(taint));
Data = calloc(0x8500, 1);
msg = calloc(0x1000, 1);
int fd = open("./dump1", 0);
int sz = read(fd, Data, 0x8400);
if(argc != 2)
{
printf("Usage: %s <password>\n", argv[0]);
exit(1);
}
else
{
set_password(argv[1]);
}
short now = 5;
short f1=0, f2=0, f3=0;
while (now+3 <= 0x2dad)
{
cnt += 1;
short bx = (now<<1)&0xffff;
f1 = Word(addr+bx);
f2 = Word(addr+bx+2);
f3 = Word(addr+bx+4);
if (fuck(now, f1, f2, f3) == 0)
{
now += 3;
if(Word(addr+8) != 0) print_char();
}
else
{
bx = (((now+2)&0xffff)<<1)&0xffff;
short tmp = Word(addr+bx);
if(tmp == 0xffff)
{
puts("Done");
break;
}
else
{
now = tmp;
}
if(Word(addr+8) != 0) print_char();
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment