/binja-covfefe.py Secret
Last active
September 24, 2017 21:18
Star
You must be signed in to star a gist
flareon2017 lvl11
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
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() |
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
#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; | |
} |
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
#!/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