Hackpack2023-2023/4/15
https://ctf2023.hackpack.club/challenges
做了2题出来,其实是一题,第一题是手动逆向,第二题是脚本自动逆向
主要是学习到了nclib包使用
使用说明
https://nclib.readthedocs.io/en/latest/netcat.html
Speed-Rev
题目是在3分钟逆向6题
第一题是直接找字符串,第二题和第三题是把字符串拆开变成一堆判断,
第四五六也是判断,不过给的是字与字关系
自动化脚本主要是要找到这些静态数据,自己写的时候是通过一些比较特殊的代码段所对应的数据来作为线索寻找
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反编译
标签:tmp,Hackpack,题解,rc,Re,ls,ans,print,data From: https://www.cnblogs.com/Joooook/p/17357718.html