ctf/angr/examples/b01lersctf2020_little_engine wsl2 kali

wsl2 kali linux 默认是4g内存,1g swap,运行b01lersctf2020_little_engine内存不足被杀。修改配置增加3g,成功运行。
1.打开Windows资源管理器,地址栏输入 %UserProfile% 回车,在该目录下创建一个文件, 名字为 .wslconfig ,写入内容示例如下 (我电脑8GB内存,分给WSL内存2GB,另外设置交换分区6GB)

[wsl2]
memory=2GB
swap=6GB
localhostForwarding=true

cmd执行 wsl --shutdown 关闭WSL,再重新打开即可
然后修改wp脚本

#!/usr/bin/env python
# coding: utf-8
import angr
import claripy
import time
import logging
import psutil
import os
import sys

#compiled on ubuntu 18.04 system:
#https://github.com/b01lers/b01lers-ctf-2020/tree/master/rev/100_little_engine

def main():
    #setup of addresses used in program
    #addresses assume base address of
    base_addr = 0x100000

    #length of desired input is 75 as found from reversing the binary in ghidra,
    #need to add 4 times this size, since the actual array is 4 times the size。实际上经过测试,这个长度并不对,如果改成222,而不是301,运行时间反而缩短了。222的最终输入:x.posix.dumps(0) b'??p?c?t?f?{?t?h?3?_?m?0?d?3?r?n?_?s?t?3?4?m?_?3?n?g?1?n?3?_?w?4?5?_?1?n?v030n0t030d0_010n0_010609080_0b0u0T0_0t0h030_0b030s0t0_000n030_0i0n0_010904000}00000000000000000000000000000000000000000000000000000000000000000000000\n'。实际长度应该是1+75*2
    #1 extra byte for first input
    input_len = 1+75*4

    #seting up the angr project
    # auto_load_libs can't be disabled as the test fails.
    p = angr.Project('./engine', main_opts={'base_addr': base_addr}, auto_load_libs=True)

    #looking at the code/binary, we can tell the input string is expected to fill 22 bytes,
    # thus the 8 byte symbolic size. Hopefully we can find the constraints the binary
    # expects during symbolic execution
    flag_chars = [claripy.BVS('flag_%d' % i, 8) for i in range(input_len)]

    #extra \n for first input, then find the flag!
    flag = claripy.Concat( *flag_chars + [claripy.BVV(b'\n')])

    # enable unicorn engine for fast efficient solving
    st = p.factory.full_init_state(
            args=['./engine'],
            add_options=angr.options.unicorn,
            stdin=flag
           )

    #constrain to non-newline bytes
    #constrain to ascii-only characters
    for k in flag_chars:
        st.solver.add(k < 0x7f)
        st.solver.add(k > 0x20)

    # Construct a SimulationManager to perform symbolic execution.
    # Step until there is nothing left to be stepped.
    sm = p.factory.simulation_manager(st, veritesting=True)
    # sm.run()
    # for i in range(200):
    while sm.active:
    # while len(sm.deadended) <1:
        sm.step()
        print(sm.active)
        print('psutil.virtual_memory(): ', psutil.virtual_memory())
        print('psutil.swap_memory(): ', psutil.swap_memory())
        # print(sys.getsizeof(sm) / 1024 / 1024, 'MB')
        print(u'Process(os.getpid()).memory_info: %.4f GB' % (psutil.Process(os.getpid()).memory_info().rss / 1024 / 1024 / 1024) )
        print('len(sm.deadended): ', len(sm.deadended))

        # if len(sm.deadended)>0:
            # break

    #grab all finished states, that have the win function output in stdout
    y = []
    print('sm.deadended',len(sm.deadended), sm.deadended)
    for x in sm.deadended:
        print('x.posix.dumps(1)',x.posix.dumps(1))
        if b"Chugga" in x.posix.dumps(1):
            y.append(x)

    #grab the first output
    valid = y[0].posix.dumps(0)

    #parse and turn into final flag
    bt = [ chr(valid[i]) for i in range(0,len(valid),2)]
    flag = ''.join(bt)[1:76]
    return flag

def test():
    assert main() == "pctf{th3_m0d3rn_st34m_3ng1n3_w45_1nv3nt3d_1n_1698_buT_th3_b3st_0n3_in_1940}"

if __name__ == "__main__":
    before = time.time()
    # set some debug messages so that we know what's going on
    logging.getLogger('angr.sim_manager').setLevel('DEBUG')
    print(main())
    after = time.time()
    print("Time elapsed: {}".format(after - before))

结果如下

psutil.virtual_memory():  svmem(total=1999572992, available=18796544, percent=99.1, used=1875640320, free=67670016, active=176431104, inactive=1476464640, buffers=626688, cached=55635968, shared=118784, slab=70893568)
psutil.swap_memory():  sswap(total=6442450944, used=3220795392, free=3221655552, percent=50.0, sin=14468882432, sout=14932557824)
Process(os.getpid()).memory_info: 1.5066 GB
sm.deadended 2 [<SimState @ 0xa00098>, <SimState @ 0xa00098>]
x.posix.dumps(1) b"Welcome! We're doing things a little differently here, you're going to tell me a tidbit about trains. Are you ready?\nNow, I hope you're a total trainiac. Give me your best tidbit: Chugga chugga choo choo you're the little engine that CAN!\n"
x.posix.dumps(1) b"Welcome! We're doing things a little differently here, you're going to tell me a tidbit about trains. Are you ready?\nNow, I hope you're a total trainiac. Give me your best tidbit: I guess you don't know anything about trains...go do some TRAINing you non-conductor :(\n"
pctf{th3_m0d3rn_st34m_3ng1n3_w45_1nv3nt3d_1n_1698_buT_th3_b3st_0n3_in_1940}
Time elapsed: 1051.057656288147

另一个脚本解法:

import angr
import claripy
import sys

def Go():
    path_to_binary = "./engine" 
    project = angr.Project(path_to_binary, auto_load_libs=True)

    #length of desired input is 75 as found from reversing the binary in ghidra
    #need to add 4 times this size, since the actual array is 4 times the size
    #1 extra byte for first input
    input_len = 1+75*4
    #looking at the code/binary, we can tell the input string is expected to fill 22 bytes,
    # thus the 8 byte symbolic size. Hopefully we can find the constraints the binary
    # expects during symbolic execution
    flag_chars = [claripy.BVS('flag_%d' % i, 8) for i in range(input_len)]

    #extra \n for first input, then find the flag!
    flag = claripy.Concat( *flag_chars + [claripy.BVV(b'\n')])

    initial_state = project.factory.entry_state(
            add_options=angr.options.unicorn,
            stdin=flag
    )
    #constrain to non-newline bytes
    #constrain to ascii-only characters
    for k in flag_chars:
        initial_state.solver.add(k < 0x7f)
        initial_state.solver.add(k > 0x20)
    simulation = project.factory.simgr(initial_state, veritesting=True)

    def is_successful(state):
        stdout_output = state.posix.dumps(1)
        if b'Chugga' in stdout_output:
            return True
        else: 
            return False

    def should_abort(state):
        stdout_output = state.posix.dumps(1)
        if b'know anything' in  stdout_output:
            return True
            
        else:
            return False

    simulation.explore(find=is_successful, avoid=should_abort)

    if simulation.found:
        for i in simulation.found:
            solution_state = i
            solution = solution_state.posix.dumps(0)
            print("[+] Success! Solution is: {0}".format(solution))
            #print(scanf0_solution, scanf1_solution)
            #grab the first output
            valid = solution_state.posix.dumps(0)

            #parse and turn into final flag
            bt = [ chr(valid[i]) for i in range(0,len(valid),2)]
            flag = ''.join(bt)[1:76]
            print('flag', flag)
    else:
        raise Exception('Could not find the solution')

if __name__ == "__main__":
    Go()

结果:

[+] Success! Solution is: b'??p?c?t?f?{?t?h?3?_?m?0?d?3?r?n?_?s?t?3?4?m?_?3?n?g?1?n?3?_?w?4?5?_?1?n?v030n0t030d0_010n0_010609080_0b0u0T0_0t0h030_0b030s0t0_000n030_0i0n0_010904000}000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\n'
flag pctf{th3_m0d3rn_st34m_3ng1n3_w45_1nv3nt3d_1n_1698_buT_th3_b3st_0n3_in_1940}


gdb

sharti
layout asm or ctrl+x ctrl+a 两个快捷键一起切换asm窗口
n ni
s si
run c 
b __libc_start_main
b __libc_start_call_main
b *__libc_start_call_main+9  这个没有用,进入b __libc_start_call_main
用n 或者s可以进入main
info files可以看到base addr        Entry point: 0x555555555410
   0x5555555552f0    endbr64
? 0x5555555552f4    push   rbp
   0x5555555552f5    sub    rsp, 0x20
   0x5555555552f9    mov    rax, qword ptr fs:[0x28]
   0x555555555302    mov    qword ptr [rsp + 0x18], rax
   0x555555555307    xor    eax, eax
   0x555555555309    mov    rbp, rsp
   0x55555555530c    call   0x5555555556b0                <0x5555555556b0>   ? 0x7ffff7ae3237 <__libc_start_main+119>    mov    rdi, qword ptr [rsp]
   0x7ffff7ae323b <__libc_start_main+123>    mov    rdx, rbx
   0x7ffff7ae323e <__libc_start_main+126>    mov    esi, ebp
   0x7ffff7ae3240 <__libc_start_main+128>    call   __libc_start_call_main                <__libc_start_call_main>
? 0x7ffff7ae3170 <__libc_start_call_main+96>     mov    rax, qword ptr [rip + 0x1aae11]
   0x7ffff7ae3177 <__libc_start_call_main+103>    mov    rsi, qword ptr [rsp + 0x18]
   0x7ffff7ae317c <__libc_start_call_main+108>    mov    edi, dword ptr [rsp + 0x14]
   0x7ffff7ae3180 <__libc_start_call_main+112>    mov    rdx, qword ptr [rax]
   0x7ffff7ae3183 <__libc_start_call_main+115>    mov    rax, qword ptr [rsp + 8]
   0x7ffff7ae3188 <__libc_start_call_main+120>    call   rax

你可能感兴趣的:(python)