├── todos.txt ├── requirements.txt ├── install.sh ├── table.py ├── defaults.py ├── vulns.py ├── checkfile.py ├── func.py ├── main.py └── README.md /todos.txt: -------------------------------------------------------------------------------- 1 | Check magic byte of ELF 2 | Display specific function 3 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | pwntools==4.6.0 2 | r2pipe==0.9.7 3 | termcolor==1.1.0 4 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if [[ $EUID -ne 0 ]]; then 3 | echo "Running this script as : $USER" 4 | echo "********************************************************************************" 5 | fi 6 | sudo apt install python3 python3-pip checksec binutils git 7 | echo "********************************************************************************" 8 | if [ -d "$HOME/radare2/" ] 9 | then 10 | echo "Directory $HOME/radare2/ exists." 11 | exit 1 12 | else 13 | echo "Directory $HOME/radare2/ does not exists." 14 | cd $HOME 15 | git clone https://github.com/radareorg/radare2 16 | $HOME/radare2/sys/install.sh 17 | r2pm update 18 | r2pm -ci r2ghidra 19 | fi 20 | echo "SUCCESS !!" 21 | -------------------------------------------------------------------------------- /table.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | from termcolor import cprint 3 | 4 | printb_red=lambda x : cprint(x,'red',attrs=['bold']) 5 | print_cyan=lambda x : cprint(x,'cyan') 6 | 7 | 8 | def get_got(filename): 9 | e = ELF(filename,checksec=False) 10 | data=e.got 11 | printb_red("\n> GOT TABLE : \n") 12 | for x in data: 13 | print("\t"+x.ljust(35)+" : "+str(hex(data[x])).rjust(10)) 14 | print_cyan("\n"+"*"*75) 15 | 16 | 17 | def get_plt(filename): 18 | e = ELF(filename,checksec=False) 19 | data=e.plt 20 | printb_red("\n> PLT TABLE : \n") 21 | for x in data: 22 | print("\t"+x.ljust(35)+" : "+str(hex(data[x])).rjust(10)) 23 | print_cyan("\n"+"*"*75) 24 | 25 | 26 | def get_funcs(filename): 27 | e = ELF(filename,checksec=False) 28 | data=e.functions 29 | printb_red("\n> FUNCTION TABLE : \n") 30 | for x in data: 31 | print("\t"+x.ljust(35)+" : "+str(data[x])[9:-1].split(",")[1][9:].rjust(10)) 32 | print_cyan("\n"+"*"*75) 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /defaults.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | from termcolor import cprint 3 | 4 | printb_red=lambda x : cprint(x,'red',attrs=['bold']) 5 | print_yellow=lambda x : cprint(x,'yellow') 6 | print_cyan=lambda x : cprint(x,'cyan') 7 | 8 | def entrypoint(filename): 9 | e = ELF(filename,checksec=False) 10 | data=e.functions 11 | printb_red("\n> ELF ENTRY POINT : \n") 12 | print("\tThe entry point of the ELF is at ",end="") 13 | print_yellow(str(hex(e.entrypoint))+"\n") 14 | print_cyan("*"*75) 15 | 16 | def headers(filename): 17 | p = subprocess.Popen(["readelf -l %s | sed -n '/Program Headers:/,/Section to Segment mapping:/p'"%(filename)], stdout=subprocess.PIPE, shell=True) 18 | data=p.stdout.read() 19 | data=data.decode('utf-8') 20 | printb_red("\n> HEADER MEMORY MAP : \n") 21 | print(data[17:-30]) 22 | print_cyan("*"*75) 23 | 24 | def get_gadgets(filename): 25 | e = ELF(filename,checksec=False) 26 | r=ROP(e) 27 | g=r.gadgets 28 | g=g.values() 29 | printb_red("\n> ROP GADGETS : \n") 30 | for x in g: 31 | y=str(x).replace("Gadget","") 32 | y_tuple=eval(y) 33 | print_yellow("\t"+str(hex(y_tuple[0])).ljust(10)+" : "+";".join(list(y_tuple[1]))) 34 | print_cyan("\n"+"*"*75) -------------------------------------------------------------------------------- /vulns.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | from termcolor import cprint 3 | 4 | print_red=lambda x : cprint(x,'red') 5 | printb_red=lambda x : cprint(x,'red',attrs=['bold']) 6 | print_yellow=lambda x : cprint(x,'yellow') 7 | print_green=lambda x : cprint(x,'green') 8 | printb_green=lambda x : cprint(x,'green',attrs=['bold']) 9 | print_cyan=lambda x : cprint(x,'cyan') 10 | 11 | frmstr=['fprintf','fscanf','printf','scanf','sprintf','sscanf'] 12 | cmdexec=['system','execl','execle','execlp','execv','execve','execvp','popen'] 13 | bof=['calloc','malloc','realloc','fscanf','gets','scanf','sprintf','sscanf','strcat','strcpy','strncat','strncmp','strncpy','memchr','memcmp','memcpy','memmove','memset','scanf','gets','fwscan','sscanf'] 14 | 15 | def got_funcs(filename): 16 | e = ELF(filename,checksec=False) 17 | data=e.got 18 | funcs=[] 19 | for x in data: 20 | funcs.append(x) 21 | return funcs 22 | 23 | 24 | def check_vuln(filename,funcs): 25 | printb_red("\n> VULNERABLE FUNCTIONS : \n") 26 | for x in funcs: 27 | if x in frmstr: 28 | data=get_vuln_asm_inst(filename,x) 29 | if(len(data)>5): 30 | print("\tPossible vulnerability locations - ",end="") 31 | printb_green("Format String\n") 32 | print_yellow(data) 33 | if x in bof: 34 | data=get_vuln_asm_inst(filename,x) 35 | if(len(data)>5): 36 | print("\tPossible vulnerability locations - ",end="") 37 | printb_green("Buffer Overflow\n") 38 | print_yellow(data) 39 | if x in cmdexec: 40 | data=get_vuln_asm_inst(filename,x) 41 | if(len(data)>5): 42 | print("\tPossible vulnerability locations - ",end="") 43 | printb_green("Command Execution\n") 44 | print_yellow(data) 45 | print_cyan("\n"+"*"*75) 46 | 47 | def get_vuln_asm_inst(filename,fname): 48 | p = subprocess.Popen(["cat /tmp/elfxtract_inst | grep %s"%(fname)], stdout=subprocess.PIPE, shell=True) 49 | data=p.stdout.read() 50 | data=data.decode('utf-8').replace("│ "," ") 51 | return(data) 52 | 53 | -------------------------------------------------------------------------------- /checkfile.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | import os 3 | from termcolor import cprint 4 | 5 | printb_red=lambda x : cprint(x,'red',attrs=['bold']) 6 | print_yellow=lambda x : cprint(x,'yellow') 7 | print_green=lambda x : cprint(x,'green') 8 | print_blue=lambda x : cprint(x,'blue') 9 | print_cyan=lambda x : cprint(x,'cyan') 10 | 11 | def file_details(filename): 12 | p = subprocess.Popen(["file %s"%(filename)], stdout=subprocess.PIPE, shell=True) 13 | data=p.stdout.read() 14 | data=data.decode('utf-8') 15 | file_data=data.split(",") 16 | printb_red("\n> FILE INFO : \n") 17 | print("\tELF Name".ljust(15)+" : "+file_data[0].split(":")[0]) 18 | print("\tELF Type".ljust(15)+" : "+file_data[0].split(":")[1]) 19 | print("\tELF Arch".ljust(15)+" : "+file_data[1]) 20 | print("\tELF SHA1 Hash".ljust(15)+" : "+file_data[5]) 21 | print("\n\tThis binary is",end="") 22 | print_yellow("%s &%s"%(file_data[3],file_data[7])) 23 | print_cyan("*"*75) 24 | 25 | 26 | def elf_checksec(filename): 27 | p = subprocess.Popen(["/usr/bin/checksec --format=csv --file=%s"%(filename)], stdout=subprocess.PIPE, shell=True) 28 | data=p.stdout.read() 29 | data=data.decode('utf-8').split(",") 30 | printb_red("\n> ELF SECURITY MITIGATIONS : \n") 31 | print("\tRELRO".ljust(15)+" : "+data[0]) 32 | print("\tSTACK CANARY".ljust(15)+" : "+data[1]) 33 | print("\tNX BIT".ljust(15)+" : "+data[2]) 34 | print("\tPIE".ljust(15)+" : "+data[3]) 35 | print("\tRPATH".ljust(15)+" : "+data[4]) 36 | print("\tRUNPATH".ljust(15)+" : "+data[5]+"\n") 37 | print_cyan("*"*75) 38 | 39 | 40 | def sharedobj_details(filename): 41 | p = subprocess.Popen(["ldd %s"%(filename)], stdout=subprocess.PIPE, shell=True) 42 | data=p.stdout.read() 43 | data=data.decode('utf-8').split("\n") 44 | printb_red("\n> SHARED OBJECT DEPENDENCY : \n") 45 | for x in data: 46 | print(x) 47 | print_cyan("*"*75) 48 | 49 | 50 | def check_strings(filename): 51 | p = subprocess.Popen(["rabin2 -z %s"%(filename)], stdout=subprocess.PIPE, shell=True) 52 | data=p.stdout.read() 53 | data=data.decode('utf-8').split("\n") 54 | printb_red("\n> POSSIBLE STRINGS : \n") 55 | print_blue("\t"+data[1]) 56 | for x in data[2:]: 57 | print("\t"+x) 58 | print_cyan("*"*75) 59 | 60 | def hexdump_strings(filename): 61 | p = subprocess.Popen(["readelf -x .rodata %s"%(filename)], stdout=subprocess.PIPE, shell=True) 62 | data=p.stdout.read() 63 | data=data.decode('utf-8').split("\n") 64 | printb_red("\n> RODATA HEXDUMP : \n") 65 | for x in data[2:]: 66 | print_green("\t"+x) 67 | print_cyan("*"*75) -------------------------------------------------------------------------------- /func.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | from pwnlib.term.term import flush 3 | import r2pipe 4 | import time 5 | from termcolor import cprint 6 | 7 | printb_red=lambda x : cprint(x,'red',attrs=['bold']) 8 | print_yellow=lambda x : cprint(x,'yellow') 9 | printb_green=lambda x : cprint(x,'green',attrs=['bold']) 10 | print_cyan=lambda x : cprint(x,'cyan') 11 | 12 | def defined_func(filename): 13 | e = ELF("%s"%(filename),checksec=False) 14 | data=e.functions 15 | functions=[] 16 | userdefined_func=[] 17 | for x in data: 18 | functions.append(x) 19 | inbuilt=['__libc_csu_fini','__libc_csu_init','_start','__stack_chk_fail_local','__x86.get_pc_thunk.bx'] 20 | for x in functions: 21 | if x not in inbuilt: 22 | userdefined_func.append(x) 23 | return userdefined_func 24 | 25 | def list_userdefined_func(filename,funcs): 26 | e = ELF("%s"%(filename),checksec=False) 27 | printb_red("\n> POSSIBLE USER DEFINED FUNCTIONS : \n") 28 | if len(funcs)==0: 29 | print_yellow("Could not find possible user defined functions") 30 | else: 31 | for x in funcs: 32 | print_yellow("\t"+x.ljust(20)+" : "+str(hex(e.symbols[x])).rjust(10)) 33 | print_cyan("\n"+"*"*75) 34 | 35 | 36 | def get_decompile(filename,x): 37 | r = r2pipe.open('%s'%(filename),flags=['-2']) 38 | r.cmd("aaa") 39 | r.cmd("s sym.%s"%(x)) 40 | printb_green("\n[*] DECOMPILED CODE - %s : \n"%(x)) 41 | data=r.cmd('pdg') 42 | print(data) 43 | 44 | def get_asm(filename,f,x): 45 | r = r2pipe.open('%s'%(filename),flags=['-2']) 46 | r.cmd("aaa") 47 | r.cmd("s sym.%s"%(x)) 48 | printb_green("\n[*] ASM - %s : \n"%(x)) 49 | data=r.cmd('pdf') 50 | f.write(data) 51 | print(data) 52 | 53 | 54 | def decompile_func(filename,funcs,time_val): 55 | printb_red("\n> DECOMPILED CODE : \n") 56 | if len(funcs)==0: 57 | print_yellow("Could not find possible user defined functions") 58 | else: 59 | for x in funcs: 60 | get_decompile(filename,x) 61 | print_cyan("\n"+"*"*75) 62 | 63 | def asm_func(filename,funcs,time_val): 64 | printb_red("\n> ASM CODE : \n") 65 | if len(funcs)==0: 66 | print_yellow("Could not find possible user defined functions") 67 | else: 68 | f=open("/tmp/elfxtract_inst","w") 69 | for x in funcs: 70 | get_asm(filename,f,x) 71 | f.close() 72 | print_cyan("\n"+"*"*75) 73 | 74 | def asm_and_decompile(filename,funcs,time_val): 75 | printb_red("\n> ASSEMBLY AND DECOMPILED CODE : \n") 76 | if len(funcs)==0: 77 | print_yellow("Could not find possible user defined functions") 78 | else: 79 | f=open("/tmp/elfxtract_inst","w") 80 | for x in funcs: 81 | get_asm(filename,f,x) 82 | get_decompile(filename,x) 83 | f.close() 84 | print_cyan("\n"+"*"*75) 85 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | from genericpath import exists 4 | from checkfile import check_strings, elf_checksec, file_details, hexdump_strings, sharedobj_details 5 | from table import get_funcs, get_got,get_plt 6 | from defaults import entrypoint, get_gadgets, headers 7 | from func import asm_and_decompile, asm_func, decompile_func, defined_func, list_userdefined_func 8 | from vulns import check_vuln, got_funcs 9 | 10 | from termcolor import cprint 11 | import argparse 12 | import os 13 | 14 | print_red=lambda x : cprint(x,'red') 15 | print_yellow=lambda x : cprint(x,'yellow') 16 | print_green=lambda x : cprint(x,'green') 17 | print_cyan=lambda x : cprint(x,'cyan') 18 | 19 | def banner(): 20 | print_green( 21 | ''' 22 | _____ _ ________ ___ _ 23 | | ___| | | ___\ \ / / | | | 24 | | |__ | | | |_ \ V /| |_ _ __ __ _ ___| |_ 25 | | __|| | | _| / \| __| '__/ _` |/ __| __| 26 | | |___| |____| | / /^\ \ |_| | | (_| | (__| |_ 27 | \____/\_____/\_| \/ \/\__|_| \__,_|\___|\__| 28 | 29 | @aidenpearce369 30 | ''' 31 | ) 32 | print_cyan("*"*75) 33 | 34 | def check_imports(): 35 | try: 36 | import pwn 37 | import r2pipe 38 | except: 39 | print("> Modules are not properly installed, try installing it properly") 40 | print(" - pip install pwntools") 41 | print(" - pip install r2pipe") 42 | exit() 43 | 44 | def check_file(filename): 45 | if os.path.exists(filename): 46 | pass 47 | else: 48 | print_yellow("Could not find a valid ELF named - %s"%(filename)) 49 | exit() 50 | 51 | def basicinfo(filename): 52 | check_file(filename) 53 | file_details(filename) 54 | sharedobj_details(filename) 55 | elf_checksec(filename) 56 | check_strings(filename) 57 | hexdump_strings(filename) 58 | 59 | def mapping(filename): 60 | entrypoint(filename) 61 | headers(filename) 62 | 63 | def gadgetcheck(filename): 64 | get_gadgets(filename) 65 | 66 | def tablecheck(filename): 67 | get_plt(filename) 68 | get_got(filename) 69 | get_funcs(filename) 70 | 71 | def functioncheck(filename,time_val): 72 | funcs=defined_func(filename) 73 | list_userdefined_func(filename,funcs) 74 | asm_and_decompile(filename,funcs,time_val) 75 | got=got_funcs(filename) 76 | check_vuln(filename,got) 77 | 78 | def onlydecompile(filename,time_val): 79 | funcs=defined_func(filename) 80 | decompile_func(filename,funcs,time_val) 81 | 82 | def onlyasm(filename,time_val): 83 | funcs=defined_func(filename) 84 | asm_func(filename,funcs,time_val) 85 | 86 | def specificfunction(fname,filename,time_val): 87 | funcs=defined_func(filename) 88 | if fname in funcs: 89 | asm_func(filename,funcs,time_val) 90 | decompile_func(filename,funcs,time_val) 91 | else: 92 | print("Could not find the given function") 93 | print("Available functions are "+str(funcs)) 94 | exit() 95 | 96 | if __name__ == "__main__": 97 | banner() 98 | check_imports() 99 | parser=argparse.ArgumentParser() 100 | parser.add_argument("-f","--file",required=True,help="Path of the ELF") 101 | parser.add_argument("-a","--all",help="Extract all info",action="store_true") 102 | parser.add_argument("-i","--info",help="Displays basic info",action="store_true") 103 | parser.add_argument("-g","--gadgets",help="Displays gadgets",action="store_true") 104 | parser.add_argument("--user-func",help="Displays the details of user defined functions",action="store_true") 105 | parser.add_argument("--get-func",help="Displays the ASM & decompiled code of the given function") 106 | parser.add_argument("--asm-only",help="Displays the ASM of ELF",action="store_true") 107 | parser.add_argument("--decompiled-only",help="Displays the decompiled C code of ELF",action="store_true") 108 | parser.add_argument("-t","--tables",help="Displays PLT, GOT & Function table",action="store_true") 109 | args=parser.parse_args() 110 | check_file(args.file) 111 | if(args.all): 112 | basicinfo(args.file) 113 | mapping(args.file) 114 | gadgetcheck(args.file) 115 | tablecheck(args.file) 116 | functioncheck(args.file,5) 117 | if((args.all)==False and (args.info)==True): 118 | basicinfo(args.file) 119 | if((args.all)==False and (args.gadgets)==True): 120 | gadgetcheck(args.file) 121 | if((args.all)==False and (args.tables)==True): 122 | tablecheck(args.file) 123 | if((args.all)==False and (args.user_func)==True): 124 | functioncheck(args.file,5) 125 | if((args.all)==False and (args.get_func)!=None): 126 | specificfunction(args.get_func,args.file,5) 127 | if((args.all)==False and (args.decompiled_only)==True): 128 | onlydecompile(args.file,5) 129 | if((args.all)==False and (args.asm_only)==True): 130 | onlyasm(args.file,5) 131 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ELFXtract 2 | 3 | **ELFXtract** is an automated analysis tool used for enumerating ELF binaries 4 | 5 | Powered by [Radare2](https://github.com/radareorg/radare2) and [r2ghidra](https://github.com/radareorg/r2ghidra) 6 | 7 | This is specially developed for PWN challenges and it has many automated features 8 | 9 | It almost displays every details of the ELF and also decompiles its ASM to C code using ```r2ghidra``` 10 | 11 | Decompiling ELFs in Ghidra takes more time, but in **elfxtract** it decompiles and displays in few seconds 12 | 13 | ### Features in ELFXtract 14 | 1. File info 15 | 2. Shared object dependency details 16 | 3. ELF Security Mitigation details / Checksec 17 | 4. String details 18 | 5. Header memory map 19 | 6. ROP gadgets 20 | 7. PLT Table 21 | 8. GOT Table 22 | 9. Function Table 23 | 10. ASM code of functions 24 | 11. Decompiled code of functions 25 | 12. Predicting possible vulnerable functions 26 | 27 | 28 | ### Installation 29 | 30 | ```c 31 | git clone https://github.com/AidenPearce369/elfxtract 32 | cd elfxtract 33 | chmod +x install.sh 34 | ./install.sh 35 | pip install -r requirements.txt 36 | ``` 37 | 38 | ### Working 39 | 40 | You can run **elfxtract** with any ELF along with ```-a``` to list all details from the ELF 41 | 42 | ```c 43 | ra@ubuntu:~/elfxtract$ python3 main.py --file programvuln -a 44 | 45 | _____ _ ________ ___ _ 46 | | ___| | | ___\ \ / / | | | 47 | | |__ | | | |_ \ V /| |_ _ __ __ _ ___| |_ 48 | | __|| | | _| / \| __| '__/ _` |/ __| __| 49 | | |___| |____| | / /^\ \ |_| | | (_| | (__| |_ 50 | \____/\_____/\_| \/ \/\__|_| \__,_|\___|\__| 51 | 52 | @aidenpearce369 53 | 54 | *************************************************************************** 55 | 56 | > FILE INFO : 57 | 58 | ELF Name : programvuln 59 | ELF Type : ELF 64-bit LSB shared object 60 | ELF Arch : x86-64 61 | ELF SHA1 Hash : BuildID[sha1]=cf149d97ad1e895561080b1f5c317bc5bc1e8652 62 | 63 | This binary is dynamically linked & not stripped 64 | 65 | *************************************************************************** 66 | 67 | > SHARED OBJECT DEPENDENCY : 68 | 69 | linux-vdso.so.1 (0x00007ffd525a4000) 70 | libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fd610d93000) 71 | /lib64/ld-linux-x86-64.so.2 (0x00007fd610fa1000) 72 | 73 | *************************************************************************** 74 | 75 | > ELF SECURITY MITIGATIONS : 76 | 77 | RELRO : Full RELRO 78 | STACK CANARY : No Canary found 79 | NX BIT : NX disabled 80 | PIE : PIE enabled 81 | RPATH : No RPATH 82 | RUNPATH : No RUNPATH 83 | 84 | *************************************************************************** 85 | 86 | > POSSIBLE STRINGS : 87 | 88 | nth paddr vaddr len size section type string 89 | ――――――――――――――――――――――――――――――――――――――――――――――――――――――― 90 | 0 0x00002008 0x00002008 31 32 .rodata ascii You have bypassed this function 91 | 1 0x00002028 0x00002028 12 13 .rodata ascii cat flag.txt 92 | 2 0x00002035 0x00002035 15 16 .rodata ascii Enter your name 93 | 3 0x00002045 0x00002045 13 14 .rodata ascii Your name is 94 | 95 | *************************************************************************** 96 | 97 | > RODATA HEXDUMP : 98 | 99 | 0x00002000 01000200 00000000 596f7520 68617665 ........You have 100 | 0x00002010 20627970 61737365 64207468 69732066 bypassed this f 101 | 0x00002020 756e6374 696f6e00 63617420 666c6167 unction.cat flag 102 | 0x00002030 2e747874 00456e74 65722079 6f757220 .txt.Enter your 103 | 0x00002040 6e616d65 00596f75 72206e61 6d652069 name.Your name i 104 | 0x00002050 732000 s . 105 | 106 | 107 | *************************************************************************** 108 | 109 | > ELF ENTRY POINT : 110 | 111 | The entry point of the ELF is at 0x10c0 112 | 113 | *************************************************************************** 114 | 115 | > HEADER MEMORY MAP : 116 | 117 | Type Offset VirtAddr PhysAddr 118 | FileSiz MemSiz Flags Align 119 | PHDR 0x0000000000000040 0x0000000000000040 0x0000000000000040 120 | 0x00000000000002d8 0x00000000000002d8 R 0x8 121 | INTERP 0x0000000000000318 0x0000000000000318 0x0000000000000318 122 | 0x000000000000001c 0x000000000000001c R 0x1 123 | [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2] 124 | LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000 125 | 0x00000000000006a8 0x00000000000006a8 R 0x1000 126 | LOAD 0x0000000000001000 0x0000000000001000 0x0000000000001000 127 | 0x00000000000002b5 0x00000000000002b5 R E 0x1000 128 | LOAD 0x0000000000002000 0x0000000000002000 0x0000000000002000 129 | 0x00000000000001c8 0x00000000000001c8 R 0x1000 130 | LOAD 0x0000000000002da0 0x0000000000003da0 0x0000000000003da0 131 | 0x0000000000000270 0x0000000000000278 RW 0x1000 132 | DYNAMIC 0x0000000000002db0 0x0000000000003db0 0x0000000000003db0 133 | 0x00000000000001f0 0x00000000000001f0 RW 0x8 134 | NOTE 0x0000000000000338 0x0000000000000338 0x0000000000000338 135 | 0x0000000000000020 0x0000000000000020 R 0x8 136 | NOTE 0x0000000000000358 0x0000000000000358 0x0000000000000358 137 | 0x0000000000000044 0x0000000000000044 R 0x4 138 | GNU_PROPERTY 0x0000000000000338 0x0000000000000338 0x0000000000000338 139 | 0x0000000000000020 0x0000000000000020 R 0x8 140 | GNU_EH_FRAME 0x0000000000002054 0x0000000000002054 0x0000000000002054 141 | 0x000000000000004c 0x000000000000004c R 0x4 142 | GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000 143 | 0x0000000000000000 0x0000000000000000 RWE 0x10 144 | GNU_RELRO 0x0000000000002da0 0x0000000000003da0 0x0000000000003da0 145 | 0x0000000000000260 0x0000000000000260 R 0x1 146 | 147 | *************************************************************************** 148 | [*] Loaded 14 cached gadgets for 'programvuln' 149 | 150 | > ROP GADGETS : 151 | 152 | 0x1017 : add esp, 8;ret 153 | 0x1016 : add rsp, 8;ret 154 | 0x1221 : leave;ret 155 | 0x128c : pop r12;pop r13;pop r14;pop r15;ret 156 | 0x128e : pop r13;pop r14;pop r15;ret 157 | 0x1290 : pop r14;pop r15;ret 158 | 0x1292 : pop r15;ret 159 | 0x128b : pop rbp;pop r12;pop r13;pop r14;pop r15;ret 160 | 0x128f : pop rbp;pop r14;pop r15;ret 161 | 0x1193 : pop rbp;ret 162 | 0x1293 : pop rdi;ret 163 | 0x1291 : pop rsi;pop r15;ret 164 | 0x128d : pop rsp;pop r13;pop r14;pop r15;ret 165 | 0x101a : ret 166 | 167 | *************************************************************************** 168 | 169 | > PLT TABLE : 170 | 171 | __cxa_finalize : 0x1074 172 | puts : 0x1084 173 | system : 0x1094 174 | printf : 0x10a4 175 | gets : 0x10b4 176 | 177 | *************************************************************************** 178 | 179 | > GOT TABLE : 180 | 181 | _ITM_deregisterTMCloneTable : 0x3fd8 182 | __libc_start_main : 0x3fe0 183 | __gmon_start__ : 0x3fe8 184 | _ITM_registerTMCloneTable : 0x3ff0 185 | __cxa_finalize : 0x3ff8 186 | puts : 0x3fb8 187 | system : 0x3fc0 188 | printf : 0x3fc8 189 | gets : 0x3fd0 190 | 191 | *************************************************************************** 192 | 193 | > FUNCTION TABLE : 194 | 195 | __libc_csu_fini : 0x12a0 196 | __libc_csu_init : 0x1230 197 | win : 0x11a9 198 | _start : 0x10c0 199 | main : 0x11d6 200 | 201 | *************************************************************************** 202 | 203 | > POSSIBLE USER DEFINED FUNCTIONS : 204 | 205 | win : 0x11a9 206 | main : 0x11d6 207 | 208 | *************************************************************************** 209 | 210 | > ASSEMBLY AND DECOMPILED CODE : 211 | 212 | 213 | [*] ASM - win : 214 | 215 | ┌ 45: sym.win (); 216 | │ 0x000011a9 f30f1efa endbr64 217 | │ 0x000011ad 55 push rbp 218 | │ 0x000011ae 4889e5 mov rbp, rsp 219 | │ 0x000011b1 488d3d500e00. lea rdi, str.You_have_bypassed_this_function ; 0x2008 ; "You have bypassed this function" ; const char *format 220 | │ 0x000011b8 b800000000 mov eax, 0 221 | │ 0x000011bd e8defeffff call sym.imp.printf ; int printf(const char *format) 222 | │ 0x000011c2 488d3d5f0e00. lea rdi, str.cat_flag.txt ; 0x2028 ; "cat flag.txt" ; const char *string 223 | │ 0x000011c9 b800000000 mov eax, 0 224 | │ 0x000011ce e8bdfeffff call sym.imp.system ; int system(const char *string) 225 | │ 0x000011d3 90 nop 226 | │ 0x000011d4 5d pop rbp 227 | └ 0x000011d5 c3 ret 228 | 229 | [*] DECOMPILED CODE - win : 230 | 231 | void sym.win(void) 232 | 233 | { 234 | sym.imp.printf("You have bypassed this function"); 235 | sym.imp.system("cat flag.txt"); 236 | return; 237 | } 238 | 239 | [*] ASM - main : 240 | 241 | ; DATA XREF from entry0 @ 0x10e1 242 | ┌ 77: int main (int argc, char **argv, char **envp); 243 | │ ; var char *s @ rbp-0x40 244 | │ 0x000011d6 f30f1efa endbr64 245 | │ 0x000011da 55 push rbp 246 | │ 0x000011db 4889e5 mov rbp, rsp 247 | │ 0x000011de 4883ec40 sub rsp, 0x40 248 | │ 0x000011e2 488d3d4c0e00. lea rdi, str.Enter_your_name ; 0x2035 ; "Enter your name" ; const char *s 249 | │ 0x000011e9 e892feffff call sym.imp.puts ; int puts(const char *s) 250 | │ 0x000011ee 488d45c0 lea rax, [s] 251 | │ 0x000011f2 4889c7 mov rdi, rax ; char *s 252 | │ 0x000011f5 b800000000 mov eax, 0 253 | │ 0x000011fa e8b1feffff call sym.imp.gets ; char *gets(char *s) 254 | │ 0x000011ff 488d3d3f0e00. lea rdi, str.Your_name_is_ ; 0x2045 ; "Your name is " ; const char *format 255 | │ 0x00001206 b800000000 mov eax, 0 256 | │ 0x0000120b e890feffff call sym.imp.printf ; int printf(const char *format) 257 | │ 0x00001210 488d45c0 lea rax, [s] 258 | │ 0x00001214 4889c7 mov rdi, rax ; const char *s 259 | │ 0x00001217 e864feffff call sym.imp.puts ; int puts(const char *s) 260 | │ 0x0000121c b800000000 mov eax, 0 261 | │ 0x00001221 c9 leave 262 | └ 0x00001222 c3 ret 263 | 264 | [*] DECOMPILED CODE - main : 265 | 266 | // WARNING: [r2ghidra] Failed to match type char * for variable s to Decompiler type: 267 | 268 | undefined8 main(void) 269 | 270 | { 271 | undefined8 s; 272 | 273 | sym.imp.puts("Enter your name"); 274 | sym.imp.gets(&s); 275 | sym.imp.printf("Your name is "); 276 | sym.imp.puts(&s); 277 | return 0; 278 | } 279 | 280 | *************************************************************************** 281 | 282 | > VULNERABLE FUNCTIONS : 283 | 284 | Possible vulnerability locations - Command Execution 285 | 286 | 0x000011ce e8bdfeffff call sym.imp.system ; int system(const char *string) 287 | 288 | Possible vulnerability locations - Format String 289 | 290 | 0x000011bd e8defeffff call sym.imp.printf ; int printf(const char *format) 291 | 0x0000120b e890feffff call sym.imp.printf ; int printf(const char *format) 292 | 293 | Possible vulnerability locations - Buffer Overflow 294 | 295 | 0x000011fa e8b1feffff call sym.imp.gets ; char *gets(char *s) 296 | 297 | 298 | *************************************************************************** 299 | ``` 300 | 301 | You can also pass arguments and get the info based on your needs, 302 | 303 | ```c 304 | ra@ubuntu:~/elfxtract$ python3 main.py -h 305 | 306 | _____ _ ________ ___ _ 307 | | ___| | | ___\ \ / / | | | 308 | | |__ | | | |_ \ V /| |_ _ __ __ _ ___| |_ 309 | | __|| | | _| / \| __| '__/ _` |/ __| __| 310 | | |___| |____| | / /^\ \ |_| | | (_| | (__| |_ 311 | \____/\_____/\_| \/ \/\__|_| \__,_|\___|\__| 312 | 313 | @aidenpearce369 314 | 315 | *************************************************************************** 316 | usage: main.py [-h] -f FILE [-a] [-i] [-g] [--user-func] [--get-func GET_FUNC] [--asm-only] 317 | [--decompiled-only] [-t] 318 | 319 | optional arguments: 320 | -h, --help show this help message and exit 321 | -f FILE, --file FILE Path of the ELF 322 | -a, --all Extract all info 323 | -i, --info Displays basic info 324 | -g, --gadgets Displays gadgets 325 | --user-func Displays the details of user defined functions 326 | --get-func GET_FUNC Displays the ASM & decompiled code of the given function 327 | --asm-only Displays the ASM of ELF 328 | --decompiled-only Displays the decompiled C code of ELF 329 | -t, --tables Displays PLT, GOT & Function table 330 | ``` 331 | 332 | ### Updates 333 | 334 | **elfxtract** is fully developed for parsing PWN binaries, 335 | 336 | Soon, it will be added with new features to analyse system binaries 337 | 338 | And also, auto-BOF and auto-ret2 exploit features will be added 339 | 340 | --------------------------------------------------------------------------------