Skip to content

Instantly share code, notes, and snippets.

@hugsy
Last active September 24, 2017 21:18
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save hugsy/12ffb0aaacbf87db3247ad1a07acb13c to your computer and use it in GitHub Desktop.
flareon2017 lvl11
from binaryninja import *
from binaryninja.enums import *
import struct
BASE_ADDRESS = 0x0403000
bv = BinaryViewType['Raw'].open("/home/hugsy/ctf/flareon_2017/11/dumpmem-00403000-L5000.dmp")
br = BinaryReader(bv)
class Covfefe(Architecture):
name = 'Covfefe'
address_size = 4
default_int_size = 4
max_instr_length = 3 * address_size
regs = {
'r0': RegisterInfo('r0', 4),
'r1': RegisterInfo('r1', 4),
'r2': RegisterInfo('r2', 4),
'r3': RegisterInfo('r3', 4),
'r4': RegisterInfo('r4', 4),
}
def perform_get_instruction_text(self, data, addr):
try:
op1, op2, op3 = struct.unpack('<III', data[:12])
except:
return None, 0
tokens = []
pc = (addr-8) / 4
if not (0x463 <= pc < 0x1100):
return None, 0
tokens.append(InstructionTextToken(InstructionTextTokenType.PossibleAddressToken, "[0x%x] "%(pc,), pc))
tokens.append(InstructionTextToken(InstructionTextTokenType.TextToken , 'sub '))
if op2 not in range(len(Covfefe.regs)):
tokens.append(InstructionTextToken(InstructionTextTokenType.PossibleAddressToken, "{0x%x}"%(op2,), op2*4+8))
else:
tokens.append(InstructionTextToken(InstructionTextTokenType.RegisterToken, 'r%d' % op2))
tokens.append(InstructionTextToken(InstructionTextTokenType.OperandSeparatorToken, ', '))
if op1 not in range(len(Covfefe.regs)):
tokens.append(InstructionTextToken(InstructionTextTokenType.PossibleAddressToken, "{0x%x}"%(op1,), op1*4+8))
else:
tokens.append(InstructionTextToken(InstructionTextTokenType.RegisterToken, 'r%d' % op1))
if op3:
tokens.append(InstructionTextToken(InstructionTextTokenType.TextToken , ' jump='))
tokens.append(InstructionTextToken(InstructionTextTokenType.PossibleAddressToken, "{0x%x}"%(op3,), op3*4+8))
return tokens, 12
def perform_get_instruction_info(self, data, addr):
result = InstructionInfo()
result.length = 0
try:
op1, op2, op3 = struct.unpack('<III', data[:12])
except:
return result
pc = (addr-8) / 4
if not (0x463 <= pc < 0x1100):
return result
result.length = 12
br.seek(op1)
a1 = br.read32()
br.seek(op2)
a2 = br.read32()
if op3:
if op3 == -1:
result.add_branch(BranchType.FunctionReturn)
else:
result.add_branch(BranchType.TrueBranch, op3*4+8)
result.add_branch(BranchType.FalseBranch, addr+12)
return result
def perform_get_instruction_low_level_il(self, data, addr, il):
return
def perform_get_flag_write_low_level_il(self, op, size, write_type, flag, operands, il):
return
def perform_get_flag_condition_low_level_il(self, cond, il):
return
Covfefe.register()
#include <sys/mman.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>
#include <stdio.h>
#define MEM "./dumpmem-00403000-L5000.dmp"
#define VM_START 0x0403000
#define VM_SIZE 0x5000
#define VM_START_OFFSET 0x463
#define VM_MAX_OFFSET 0x1100
int32_t* VM;
int8_t execute_instruction(int32_t *vm, int32_t a1, int32_t a2, int32_t a3)
{
int8_t result = 0;
vm[a2] -= vm[a1];
if ( a3 )
result = (vm[a2] <= 0);
return result;
}
uint8_t run_vm(int32_t *vm, int max_insn, uint32_t pc_start)
{
uint32_t pc;
unsigned char cur_char;
pc = pc_start;
printf("[+] starting vm from pc=%p...\n", (vm+pc_start));
int found = 0;
while ( pc + 3 <= max_insn )
{
printf("[+] pc=0x%x a1=0x%x a2=0x%x a3=0x%x \n", pc, vm[pc], vm[pc + 1], vm[pc + 2]);
printf("[+] vm[a1]=0x%x vm[a2]=0x%x\n", vm[ vm[pc] ], vm[ vm[pc + 1] ]);
printf("--------------------------------------------------------------------------------\n");
int8_t res = execute_instruction(vm,vm[pc], vm[pc + 1], vm[pc + 2]);
printf("[+] vm[0]=0x%x vm[1]=0x%x vm[2]=0x%x vm[3]=0x%x vm[4]=0x%x\n", vm[0], vm[1], vm[2], vm[3], vm[4]);
printf("[+] vm[pc]=0x%x vm[pc+1]=0x%x vm[pc+2]=0x%x\n", vm[pc], vm[pc + 1], vm[pc + 2]);
printf("================================================================================\n");
if (pc==0xa79)
found = 1;
if (found)
getc(stdin);
if ( res )
{
if ( vm[pc + 2] == -1 )
return 1;
pc = vm[pc + 2];
} else {
pc += 3;
}
if ( vm[4] == 1 ){
printf("%c", vm[2]);
fflush(stdout);
vm[4] = 0;
vm[2] = 0;
}
if ( vm[3] == 1 ){
scanf("%c", &cur_char);
vm[1] = cur_char;
vm[3] = 0;
}
//getc(stdin);
}
return 1;
}
int main()
{
int fd = open(MEM, O_RDWR);
assert( fd >= 0 );
printf("[+] using fd=%d\n", fd);
VM = (int32_t *)mmap((void*)VM_START, VM_SIZE, PROT_READ|PROT_WRITE, MAP_FIXED|MAP_PRIVATE, fd,0);
assert(VM != MAP_FAILED);
printf("[+] mmaped to %p\n", VM);
run_vm(VM+2, VM_MAX_OFFSET, VM_START_OFFSET);
return 0;
}
#!/usr/bin/env python2
from pwn import *
import string
context.update(arch="i386", log_level="error", terminal=["tmux", "split-window", "-v", "-p 85"],)
LOCAL, REMOTE, SSH = False, False, False
TARGET=os.path.realpath("./cov-noprint")
def exploit(r, inp):
r.recvuntil("Enter the password:")
r.sendline(inp)
res = r.recvuntil("insn=").splitlines()[:-1]
c1, c2 = res[-2], res[-1]
c1 = int(c1.replace("given vm[0xe98]=", ""), 16)
c2 = int(c2.replace("expects vm[0xe99]=", ""), 16)
res = c1 == c2
# print hex(c1), hex(c2), c1 == c2
r.close()
return res
def run(t):
n = 0
m = {}
for i in string.printable[:-5]:
for j in string.printable[:-5]:
r = process([TARGET, ])
p = t + i + j
if exploit(r, p):
# print "found: %s" % p
return p
return None
if __name__ == "__main__":
t = "" # key="subleq_and_reductio_ad_absurdum"
for i in range(40):
c = run(t)
if not c:
raise Exception("failed")
t = c
print t
sys.exit(0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment