Hackpack 2023 逆向Re部分题解

Hackpack2023-2023/4/15

image

https://ctf2023.hackpack.club/challenges

做了2题出来,其实是一题,第一题是手动逆向,第二题是脚本自动逆向

主要是学习到了nclib包使用

使用说明

https://nclib.readthedocs.io/en/latest/netcat.html

Speed-Rev

题目是在3分钟逆向6题

第一题是直接找字符串,第二题和第三题是把字符串拆开变成一堆判断,

image

第四五六也是判断,不过给的是字与字关系

image

自动化脚本主要是要找到这些静态数据,自己写的时候是通过一些比较特殊的代码段所对应的数据来作为线索寻找

import nclib
import base64
import string
if __name__ == '__main__':
    TO=2
    obj=nclib.Netcat(('cha.hackpack.club',41702))
    
    rc=obj.recv_all(timeout=TO).decode()
    data=rc[rc.find('b\'')+2:-20].encode()
    ans=base64.decodebytes(data)[8196:8212]#固定位置
    print(ans.decode())
    obj.send(ans+b'\n')

    rc = obj.recv_all(timeout=TO).decode()
    data = base64.decodebytes(rc[rc.find('b\'') + 2:-20].encode())
    ls=data[4436:8212].split(b'<')
    ans=b''
    for i in range(1,17):
        ans+=ls[i][:1]
    print(ans.decode())
    obj.send(ans+b'\n')

    rc = obj.recv_all(timeout=TO).decode()
    data = base64.decodebytes(rc[rc.find('b\'') + 2:-20].encode())
    ls = data[4436:8212].split(b'<')
    ans = b''
    for i in range(1, 17):
        ans += ls[i][:1]
    print(ans.decode())
    obj.send(ans + b'\n')
    
    #像456题都是可能出现多种符合情况的flag,就生成一个可能的列表,筛选其中仅含字母数字的就行
    rc = obj.recv_all(timeout=TO).decode()#4
    data = base64.decodebytes(rc[rc.find('b\'') + 2:-20].encode())
    out=open('4','wb')
    out.write(data)
    ls = data[4448:5204].split(b't')#这里的t就是比较特殊的代码段
    tmp=[]
    for i in ls:
        if i[-1]==0 and i[-5]==ord('='):
            tmp.append(i[-4])
        else:
            if i[-1]!=233:
                tmp.append(i[-1])
    print(tmp)
    ans=[]
    for i in string.ascii_letters+string.digits:
        c = [i]
        mark=1
        for i in range(15):
            if tmp[i] - ord(c[i])>0:
                c.append(chr(tmp[i] - ord(c[i])))
            else:
                c.append('\\')
        if mark==1:
            ans.append(''.join(c))
    for i in ans:
        mark=1
        for j in i:
            if j not in string.ascii_letters+string.digits:
                mark=0
                break
        if mark==1:
            print(i)
            obj.send(i.encode()+b'\n')
            break

    rc = obj.recv_all(timeout=TO).decode()  # 5
    data = base64.decodebytes(rc[rc.find('b\'') + 2:-20].encode())
    out = open('5', 'wb')
    out.write(data)
    ls = data[4418:5204].split(b't')
    tmp = []
    for i in ls:
        h=[]
        if i:
            if len(i)>5 and i[-1] == 0 and i[-5] == ord('='):
                h=[i[-4],1]
                tmp.append(h)
            else:
                if i[-1]!=233:
                    h=[i[-1],0]
                    tmp.append(h)
    tmp=tmp[:15]
    print(tmp)
    ls=[]
    for i in string.ascii_letters+string.digits:
        h=tmp+[[ord(i),0]]
        h.reverse()
        ans=''
        for i in h:
            if i[1]==0:
                ans=chr(i[0])+ans
            elif i[1]==1:
                ans = chr(i[0]-ord(ans[0])) + ans
        ls.append(ans)
    print(ls)
    for i in ls:
        mark = 1
        for j in i:
            if j not in string.ascii_letters + string.digits:
                mark = 0
                break
        if mark == 1:
            print(i)
            obj.send(i.encode() + b'\n')
            break




    rc = obj.recv_all(timeout=TO).decode()  # 6
    data = base64.decodebytes(rc[rc.find('b\'') + 2:-20].encode())
    out.write(data)
    ls = data[4418:5204].split(b't')
    tmp = []
    for i in ls:
        h=[]
        if i:
            if len(i)>5 and i[-1] == 0 and i[-5] == ord('='):
                h=[i[-4],1]
                tmp.append(h)
            else:
                if i[-1]!=233:
                    h=[i[-1],0]
                    tmp.append(h)
    tmp=tmp[:15]
    print(tmp)
    ls=[]
    for i in string.ascii_letters+string.digits:
        h=tmp+[[ord(i),0]]
        h.reverse()
        ans=''
        for i in h:
            if i[1]==0:
                ans=chr(i[0])+ans
            elif i[1]==1:
                ans = chr(i[0]-ord(ans[0])) + ans
        ls.append(ans)
    print(ls)
    for i in ls:
        mark = 1
        for j in i:
            if j not in string.ascii_letters + string.digits:
                mark = 0
                break
        if mark == 1:
            print(i)
            obj.send(i.encode() + b'\n')
            break
    rc = obj.recv_all(timeout=TO).decode()  # 6
    print(rc)

群里大佬给的脚本,主要看solve,angr是一个基于python的二进制漏洞分析框架

https://blog.csdn.net/weixin_42016744/article/details/118517814

#!/usr/bin/env python3
from angr import Project, SimState, SimulationManager
from claripy import *
from pwn import *
from base64 import b64decode

def recv(p: tube, n: int=1, echo: bool=True) -> bytes:
    data = b''
    for _ in range(n):
        line = p.recvline(keepends=True)
        if echo:
            print('\033[1;30m%s\033[0m' % line.decode('utf-8'), end='')
        data += line
    return data

def recvp(p: tube, n: int, echo: bool=True) -> bytes:
    data = p.recv(n)
    if echo:
        print('\033[1;30m%s\033[0m' % data.decode('utf-8'), end='')
    return data

def send(p: tube, text: str | int | bytes) -> None:
    if isinstance(text, int):
        text = str(text)
    if isinstance(text, str):
        data = text.encode('utf-8')
        echo = text
    elif isinstance(text, bytes):
        data = text
        echo = repr(text)
    else:
        raise ValueError('invalid argument: %r' % text)
    p.sendline(data)
    print('\033[32m%s\033[0m' % echo)

def solve(filename: str) -> bytes:
    proj = Project(filename, auto_load_libs=False, main_opts={'base_addr': 0})#新建工程

    func = proj.loader.main_object.get_symbol('validate')#找到关键函数
    assert func.is_function
    addr = func.linked_addr

    flag = BVS('flag', 128)
    state: SimState = proj.factory.call_state(addr, flag)
    for i in range(16):
        state.solver.add(Or(
            And(flag.get_byte(i) >= ord('A'), flag.get_byte(i) <= ord('Z')),
            And(flag.get_byte(i) >= ord('a'), flag.get_byte(i) <= ord('z')),
            And(flag.get_byte(i) >= ord('0'), flag.get_byte(i) <= ord('9')),
        ))
    state.memory.store(state.regs.rsp, flag)
    state.regs.rdi = state.regs.rsp
    state.stack_push(0)
    state.stack_push(0)
    simgr = proj.factory.simulation_manager(state)
    def function_returns(simgr: SimulationManager) -> bool:
        if len(simgr.active) == 0:
            return True
        simgr.move('active', 'deadended', lambda state: state.addr == 0)
    simgr.run(until=function_returns)

    answer = b'1' * 16
    for state in simgr.deadended:
        state.solver.add(state.regs.eax == 0)
        if state.satisfiable():
            answer = state.solver.eval(flag, cast_to=bytes)
            # print(answer)
    return answer

def main() -> None:
    context.clear(arch = 'amd64')
    p = remote('cha.hackpack.club', 41702)
    recv(p, 2)

    for i in range(6):
        while True:
            data = recv(p, echo=False)
            if data.startswith(b'b\''):
                break
        assert data.endswith(b'\'\n')
        data = b64decode(data[2:-2])
        recv(p)
        filename = f'binary{i+1}'
        open(filename, 'wb').write(data)
        send(p, solve(filename))
        if recv(p) == b'Wrong!\n': break
    else: recv(p)

if __name__ == '__main__':
    main()

WASM-safe

web assembbly反编译

用jeb或者按照下面的方式

https://www.52pojie.cn/thread-962068-1-1.html

虽然没解出来,但是接触到新的wasm反编译

posted @ 2023-04-26 23:22  Joooook  阅读(88)  评论(0)    收藏  举报