wp
[羊城杯 2020]loginhttps://files.nssctf.cn/93d508d3ed81455ca644b2d34de40978?response-content-disposition=attachment;filename=login.zip
解压后拖入ida,shift+f12,可分析出此程序由pyinstaller打包而来,因此用pyinstxtractor解包

在gituhb里搜索,将pyinstxtractor.py放在exe文件同一目录中,然后在当前目录打开终端,输入python pyinstxtractor.py login.exe运行,然后会多出extracted文件夹,找到login.pyc文件,再当前目录终端输入uncompyle6 login.pyc > login.py,即可得到py文件,运行分析解密:Z3 通过约束求解直接推导出满足所有方程的code数组值,再逆向还原原始输入,代码如下
from z3 import Solver, Int, And, sat
import hashlib
# 1. 定义Z3整数变量:code[0]到code[13]
code = [Int(f"code_{i}") for i in range(14)]
# 2. 按照题目中的变量重排规则,定义a1-a14
a1 = code[2]
a2 = code[1]
a3 = code[0]
a4 = code[3]
a5 = code[4]
a6 = code[5]
a7 = code[6]
a8 = code[7]
a9 = code[9]
a10 = code[8]
a11 = code[10]
a12 = code[11]
a13 = code[12]
a14 = code[13]
# 3. 创建Z3求解器并添加约束
s = Solver()
# 添加code数组的取值范围约束:0-127(ASCII字符异或的结果范围)
for c in code:
s.add(And(c >= 0, c <= 127))
# 添加14组线性方程约束(严格复刻题目中的公式)
# 注意:a8 << 7 等价于 a8 * 128
s.add(a1 * 88 + a2 * 67 + a3 * 65 - a4 * 5 + a5 * 43 + a6 * 89 + a7 * 25 + a8 * 13 - a9 * 36 + a10 * 15 + a11 * 11 + a12 * 47 - a13 * 60 + a14 * 29 == 22748)
s.add(a1 * 89 + a2 * 7 + a3 * 12 - a4 * 25 + a5 * 41 + a6 * 23 + a7 * 20 - a8 * 66 + a9 * 31 + a10 * 8 + a11 * 2 - a12 * 41 - a13 * 39 + a14 * 17 == 7258)
s.add(a1 * 28 + a2 * 35 + a3 * 16 - a4 * 65 + a5 * 53 + a6 * 39 + a7 * 27 + a8 * 15 - a9 * 33 + a10 * 13 + a11 * 101 + a12 * 90 - a13 * 34 + a14 * 23 == 26190)
s.add(a1 * 23 + a2 * 34 + a3 * 35 - a4 * 59 + a5 * 49 + a6 * 81 + a7 * 25 + (a8 * 128) - a9 * 32 + a10 * 75 + a11 * 81 + a12 * 47 - a13 * 60 + a14 * 29 == 37136)
s.add(a1 * 38 + a2 * 97 + a3 * 35 - a4 * 52 + a5 * 42 + a6 * 79 + a7 * 90 + a8 * 23 - a9 * 36 + a10 * 57 + a11 * 81 + a12 * 42 - a13 * 62 - a14 * 11 == 27915)
s.add(a1 * 22 + a2 * 27 + a3 * 35 - a4 * 45 + a5 * 47 + a6 * 49 + a7 * 29 + a8 * 18 - a9 * 26 + a10 * 35 + a11 * 41 + a12 * 40 - a13 * 61 + a14 * 28 == 17298)
s.add(a1 * 12 + a2 * 45 + a3 * 35 - a4 * 9 - a5 * 42 + a6 * 86 + a7 * 23 + a8 * 85 - a9 * 47 + a10 * 34 + a11 * 76 + a12 * 43 - a13 * 44 + a14 * 65 == 19875)
s.add(a1 * 79 + a2 * 62 + a3 * 35 - a4 * 85 + a5 * 33 + a6 * 79 + a7 * 86 + a8 * 14 - a9 * 30 + a10 * 25 + a11 * 11 + a12 * 57 - a13 * 50 - a14 * 9 == 22784)
s.add(a1 * 8 + a2 * 6 + a3 * 64 - a4 * 85 + a5 * 73 + a6 * 29 + a7 * 2 + a8 * 23 - a9 * 36 + a10 * 5 + a11 * 2 + a12 * 47 - a13 * 64 + a14 * 27 == 9710)
s.add(a1 * 67 - a2 * 68 + a3 * 68 - a4 * 51 - a5 * 43 + a6 * 81 + a7 * 22 - a8 * 12 - a9 * 38 + a10 * 75 + a11 * 41 + a12 * 27 - a13 * 52 + a14 * 31 == 13376)
s.add(a1 * 85 + a2 * 63 + a3 * 5 - a4 * 51 + a5 * 44 + a6 * 36 + a7 * 28 + a8 * 15 - a9 * 6 + a10 * 45 + a11 * 31 + a12 * 7 - a13 * 67 + a14 * 78 == 24065)
s.add(a1 * 47 + a2 * 64 + a3 * 66 - a4 * 5 + a5 * 43 + a6 * 112 + a7 * 25 + a8 * 13 - a9 * 35 + a10 * 95 + a11 * 21 + a12 * 43 - a13 * 61 + a14 * 20 == 27687)
s.add(a1 * 89 + a2 * 67 + a3 * 85 - a4 * 25 + a5 * 49 + a6 * 89 + a7 * 23 + a8 * 56 - a9 * 92 + a10 * 14 + a11 * 89 + a12 * 47 - a13 * 61 - a14 * 29 == 29250)
s.add(a1 * 95 + a2 * 34 + a3 * 62 - a4 * 9 - a5 * 43 + a6 * 83 + a7 * 25 + a8 * 12 - a9 * 36 + a10 * 16 + a11 * 51 + a12 * 47 - a13 * 60 - a14 * 24 == 15317)
# 4. 求解约束
if s.check() == sat:
print("找到符合条件的解!")
model = s.model()
# 提取code数组的具体值(转换为整数)
code_val = [model[c].as_long() for c in code]
print("code数组的值:", code_val)
# 5. 逆向异或还原原始14位输入
def code_to_input(code):
"""从code数组还原原始输入字符串"""
# code[13] = ord(input1[13])
input_ords = [0] * 14
input_ords[13] = code[13]
# 逆向异或:code[i] = ord(input1[i]) ^ ord(input1[i+1]) → ord(input1[i]) = code[i] ^ ord(input1[i+1])
for i in range(12, -1, -1):
input_ords[i] = code[i] ^ input_ords[i+1]
# 转换为字符(过滤不可见字符,若有)
try:
input_str = ''.join([chr(o) for o in input_ords])
# 验证还原的正确性
verify_code = []
for i in range(13):
verify_code.append(ord(input_str[i]) ^ ord(input_str[i+1]))
verify_code.append(ord(input_str[13]))
if verify_code == code:
return input_str
else:
return None
except:
return None
# 还原原始输入
original_input = code_to_input(code_val)
if original_input:
print("解密得到的原始输入:", original_input)
# 6. 生成题目要求的flag(MD5哈希后拼接)
md5_hash = hashlib.md5(original_input.encode('utf-8')).hexdigest()
flag = f"GWHT{{{md5_hash}}}"
print("最终的flag:", flag)
else:
print("还原输入时出错!")
else:
print("未找到符合条件的解,请检查约束条件是否正确!")

[BJDCTF 2020]Easyhttps://files.nssctf.cn/9394259e8c6c4758bb464b78bc220c00?response-content-disposition=attachment;filename=easy.exe
mai函数无特殊消息,而上方的-ques函数里有可疑信息(毕竟ques就是问题的简写嘛!我是这样想的),f5查看伪汇编代码可得主要逻辑为:初始化一组预定义整数(v3~v12),通过 5 次循环,将整数数据逐位转换为二进制位,存储到内存 v19,遍历二进制位,将 1 映射为 *、0 映射为空格,并按 “5 字符 + 空格” 的格式输出,最终形成类似 “字符画” 的结果。所以我们的flag应该是通过字符画的结果显现出来,所以我们的目的是使得这个函数被执行,打开x32动态调试,修改eip地址为ques函数地址,然后无脑f9运行,可出


补充:eip:寄存器包含下一条要执行指令的地址;ecx:计数器(字符串和循环操作);ebp:存储函数栈底地址(基址);esp:指向栈顶;edx:数据寄存器
mov a,b 将数据从b移动到a ;sub a,b 在a基础上减b ;jmp love 无条件跳转到love位置 ;call love 直接调用love
push 进栈,pop出栈
除此之外还做了一些题,感触最深为此二
应用
朋友在网上刷到爱心代码,必须安排,可她并没有什么python环境,无法运行,总不可能在我的电脑上运行拍照发之,于是可以将py文件打包成exe文件直接运行(做那个解包题的延申),爱心代码如下
import random
import math
import tkinter as tk
from math import sin, cos, pi, log
import time
# 画布设置
CANVAS_WIDTH = 840
CANVAS_HEIGHT = 680
CANVAS_CENTER_X = CANVAS_WIDTH / 2
CANVAS_CENTER_Y = CANVAS_HEIGHT / 2
IMAGE_ENLARGE = 13 # 增大爱心尺寸
HEART_COLOR = "#FF69B4" # 改为更鲜艳的粉色
TEXT_COLOR = "#FFFFFF"
class DynamicHeart:
def __init__(self):
self.root = tk.Tk()
self.root.title('鲁冰菁我爱你 - 动态爱心')
self.root.configure(bg='black')
self.canvas = tk.Canvas(self.root, width=CANVAS_WIDTH, height=CANVAS_HEIGHT, bg='black')
self.canvas.pack()
self.heart_points = []
self.particles = []
self.animation_phase = 0
self.beat_direction = 1
self.beat_scale = 1.0
self.setup_heart()
self.animate()
def heart_function(self, t, shrink_ratio=IMAGE_ENLARGE):
"""爱心函数生成器"""
# 改进的爱心函数,更平滑
x = 16 * (sin(t) ** 3)
y = -(13 * cos(t) - 5 * cos(2 * t) - 2 * cos(3 * t) - cos(4 * t))
x *= shrink_ratio * self.beat_scale
y *= shrink_ratio * self.beat_scale
x += CANVAS_CENTER_X
y += CANVAS_CENTER_Y
return int(x), int(y)
def scatter_inside_heart(self, x, y, beta=0.15):
"""在爱心内部生成随机点"""
ratio_x = -beta * math.log(random.random())
ratio_y = -beta * math.log(random.random())
dx = ratio_x * (x - CANVAS_CENTER_X)
dy = ratio_y * (y - CANVAS_CENTER_Y)
return x - dx, y - dy
def setup_heart(self):
"""初始化爱心点阵"""
self.heart_points = []
for t in range(0, 628, 1): # 更密集的点
t_val = t / 100
x, y = self.heart_function(t_val)
self.heart_points.append((x, y))
def create_particles(self):
"""创建动态粒子"""
for _ in range(50): # 减少粒子数量以提高性能
t = random.uniform(0, 2 * pi)
x, y = self.heart_function(t)
x, y = self.scatter_inside_heart(x, y)
particle = {
'x': x, 'y': y,
'size': random.randint(1, 3),
'speed': random.uniform(0.5, 2),
'direction': random.uniform(0, 2 * pi),
'alpha': random.uniform(0.3, 1.0)
}
self.particles.append(particle)
def update_particles(self):
"""更新粒子位置"""
for particle in self.particles:
# 粒子移动
particle['x'] += cos(particle['direction']) * particle['speed']
particle['y'] += sin(particle['direction']) * particle['speed']
# 边界检查,让粒子在爱心范围内
if (particle['x'] < 0 or particle['x'] > CANVAS_WIDTH or
particle['y'] < 0 or particle['y'] > CANVAS_HEIGHT):
# 重置粒子位置
t = random.uniform(0, 2 * pi)
x, y = self.heart_function(t)
particle['x'], particle['y'] = self.scatter_inside_heart(x, y)
def draw(self):
"""绘制爱心和粒子"""
self.canvas.delete("all")
# 绘制爱心轮廓(动态缩放)
for x, y in self.heart_points:
scaled_x = CANVAS_CENTER_X + (x - CANVAS_CENTER_X) * self.beat_scale
scaled_y = CANVAS_CENTER_Y + (y - CANVAS_CENTER_Y) * self.beat_scale
self.canvas.create_oval(scaled_x, scaled_y, scaled_x+2, scaled_y+2,
fill=HEART_COLOR, outline=HEART_COLOR)
# 绘制动态粒子
for particle in self.particles:
color = self.get_color_with_alpha(HEART_COLOR, particle['alpha'])
self.canvas.create_oval(particle['x'], particle['y'],
particle['x']+particle['size'],
particle['y']+particle['size'],
fill=color, outline=color)
# 添加文字"鲁冰菁我爱你"(调小字体)
self.canvas.create_text(CANVAS_CENTER_X, CANVAS_CENTER_Y,
text="鲁冰菁\n我爱你",
fill=TEXT_COLOR,
font=("微软雅黑", 18, "bold"), # 调小字体
justify='center')
# 添加装饰文字
self.canvas.create_text(CANVAS_CENTER_X, CANVAS_HEIGHT - 30,
text="❤️ 永恒的爱 ❤️",
fill="#FFD700",
font=("楷体", 12, "italic"))
def get_color_with_alpha(self, color, alpha):
"""带透明度的颜色"""
return color
def animate(self):
"""动画循环"""
# 心跳效果
self.animation_phase += 0.1
beat_intensity = 0.1 * sin(self.animation_phase)
self.beat_scale = 1.0 + beat_intensity * self.beat_direction
if abs(beat_intensity) < 0.01:
self.beat_direction *= -1
self.update_particles()
self.draw()
self.root.after(50, self.animate) # 控制动画速度
def run(self):
"""运行程序"""
self.create_particles()
self.root.mainloop()
if __name__ == "__main__":
heart = DynamicHeart()
heart.run()
运行结果如下(动态的)

使用pip命令下载pyinstaller,将爱心代码保存为py文件,来到此py文件目录打开终端输入Pyinstaller -F -w 你的文件.py,等待出现INFO: Build complete! The results are available in: ……\dist,来到dist文件夹,里面就有你的文件.exe
0 条评论