【总结】逻辑运算在Z3中运用+CTF习题

news/2024/11/15 11:51:03/文章来源:https://www.cnblogs.com/hetianlab/p/18308521

国际赛IrisCTF在前几天举办,遇到了一道有意思的题目,特来总结。

题目

附件如下:📎babyrevjohnson.tar

解题过程

关键main函数分析如下:


int __fastcall main(int argc, const char **argv, const char **envp){ int v4; // [rsp+4h] [rbp-7Ch] int v5; // [rsp+4h] [rbp-7Ch] int v6; // [rsp+8h] [rbp-78h] int v7; // [rsp+Ch] [rbp-74h] char input[104]; // [rsp+10h] [rbp-70h] BYREF unsigned __int64 v9; // [rsp+78h] [rbp-8h] v9 = __readfsqword(0x28u); puts("Welcome to the Johnson's family!"); puts("You have gotten to know each person decently well, so let's see if you remember all of the facts."); puts("(Remember that each of the members like different things from each other.)"); v4 = 0; while ( v4 <= 3 ) // 在提供的颜色中,选择4种{ printf("Please choose %s's favorite color: ", (&names)[v4]);// 4个人 __isoc99_scanf("%99s", input); if ( !strcmp(input, colors) ){ v6 = 1; // red goto LABEL_11;} if ( !strcmp(input, s2) ){ v6 = 2; // blue goto LABEL_11;} if ( !strcmp(input, off_4050) ){ v6 = 3; // green goto LABEL_11;} if ( !strcmp(input, off_4058) ){ v6 = 4; // yellow LABEL_11: if ( v6 == chosenColors[0] || v6 == dword_4094 || v6 == dword_4098 || v6 == dword_409C )// 选择4个颜色,然后顺序不能一样 puts("That option was already chosen!"); else chosenColors[v4++] = v6; // 存储选择的颜色(已经转换成了数字)} else{ puts("Invalid color!");}} v5 = 0; while ( v5 <= 3 ){ printf("Please choose %s's favorite food: ", (&names)[v5]);// 4个人最喜欢的食物 __isoc99_scanf("%99s", input); if ( !strcmp(input, foods) ){ v7 = 1; // pizza goto LABEL_28;} if ( !strcmp(input, off_4068) ){ v7 = 2; // pasta goto LABEL_28;} if ( !strcmp(input, off_4070) ){ v7 = 3; // steak goto LABEL_28;} if ( !strcmp(input, off_4078) ){ v7 = 4; // chicken LABEL_28: if ( v7 == chosenFoods[0] || v7 == dword_40A4 || v7 == dword_40A8 || v7 == dword_40AC ) puts("That option was already chosen!"); else chosenFoods[v5++] = v7;} else{ puts("Invalid food!");}} check(); // 开始check,检测我们输入的颜色和食物是否正确 return 0;
​} -----------------------------------------------------------------------

将check提取出来,我们方便分析

其实到这里已经可以得到结果了,国外的题目确实很讲究趣味性,用颜色和食物作为导向,引导一步一步分析

笔者使用静态分析的方法,一步一步跟踪


C++

 int check(){ bool v0; // dl _BOOL4 v1; // eax _BOOL4 v2; // edx v0 = dword_40A8 != 2 && dword_40AC != 2;  v1 = v0 && dword_4094 != 1; v2 = chosenColors[0] != 3 && dword_4094 != 3; if ( !v2 || !v1 || chosenFoods[0] != 4 || dword_40AC == 3 || dword_4098 == 4 || dword_409C != 2 ) return puts("Incorrect."); puts("Correct!"); return system("cat flag.txt"); // 执行cat flag的命令
​} -----------------------------------------------------------------------

对应的输入值地址如下:

我们将颜色color数组用x系列表示,将食物用food数组y系列表示

化简如下:


 C++ v0 = y3 != 2 && y4 != 2;  v1 = v0 && x2 != 1; v2 = x1 != 3 && x2 != 3; if ( !v2 || !v1 || y1 != 4 || y4 == 3 || x3 == 4 || x4 != 2){ //错误} else{ //成功
​} -----------------------------------------------------------------------

思路1:简单粗暴的爆破,但不是学习的目的,因此并不采用

思路2:锻炼写脚本能力,使用z3解题可以锻炼写脚本的能力,因此采用


Python

  from z3 import *  # 创建变量 x1, x2, x3, x4 = Ints('x1 x2 x3 x4') y1, y2, y3, y4 = Ints('y1 y2 y3 y4')  # 创建约束条件 v0 = And(y3 != 2, y4 != 2) v1 = And(v0, x2 != 1) v2 = And(x1 != 3, x2 != 3)  # 创建条件语句 cond = Or(Not(v2), Not(v1), y1 != 4, y4 == 3, x3 == 4, x4 != 2) cond1 = Not(cond) #正常来说,cond的值要为false的,但是z3的add添加的条件必须为1才行,因此要进行取反操作 # 创建求解器 solver = Solver()  # 添加约束条件和条件语句到求解器 solver.add(cond1)#这里添加的条件必须为true,所以最后使用了 not 进行取反操作  # 求解 if solver.check() == sat: # 如果有解,则获取解 model = solver.model()  # 打印解 print("成功:") print("x1 =", model[x1]) print("x2 =", model[x2]) print("x3 =", model[x3]) print("x4 =", model[x4]) print("y1 =", model[y1]) print("y2 =", model[y2]) print("y3 =", model[y3]) print("y4 =", model[y4]) else:
​ print("无解") ---------------------------------------------------------------------------------------

得到结果


Python

  成功: x1 = 4 x2 = 0 x3 = 5 x4 = 2 y1 = 4 y2 = None y3 = 3
​ y4 = 0 -----------------------------------------------------------------------

其实有经验的师傅发现了,这是有多解的,因为没有为约束变量添加范围约束

【----帮助网安学习,以下所有学习资料免费领!加vx:dctintin,备注 “博客园” 获取!】

 ① 网安学习成长路径思维导图
 ② 60+网安经典常用工具包
 ③ 100+SRC漏洞分析报告
 ④ 150+网安攻防实战技术电子书
 ⑤ 最权威CISSP 认证考试指南+题库
 ⑥ 超1800页CTF实战技巧手册
 ⑦ 最新网安大厂面试题合集(含答案)
 ⑧ APP客户端安全检测指南(安卓+IOS)

改进之后的代码如下:


Python

  from z3 import *  # 创建变量 x1, x2, x3, x4 = Ints('x1 x2 x3 x4') y1, y2, y3, y4 = Ints('y1 y2 y3 y4')  # 创建约束条件 v0 = And(y3 != 2, y4 != 2) v1 = And(v0, x2 != 1) v2 = And(x1 != 3, x2 != 3) range_constraint = And(x1 >= 1, x1 <= 4, x2 >= 1, x2 <= 4, x3 >= 1, x3 <= 4, x4 >= 1, x4 <= 4, y1 >= 1, y1 <= 4, y2 >= 1, y2 <= 4, y3 >= 1, y3 <= 4, y4 >= 1, y4 <= 4) # 创建条件语句 cond = Or(Not(v2), Not(v1), y1 != 4, y4 == 3, x3 == 4, x4 != 2) cond1 = Not(cond) #正常来说,cond的值要为false的,但是z3的add添加的条件必须为1才行,因此要进行取反操作 # 创建求解器 solver = Solver()  # 添加约束条件和条件语句到求解器 solver.add(cond1)#这里添加的条件必须为true,所以最后使用了 not 进行取反操作 solver.add(range_constraint) # 求解 if solver.check() == sat: # 如果有解,则获取解 model = solver.model()  # 打印解 print("成功:") print("x1 =", model[x1]) print("x2 =", model[x2]) print("x3 =", model[x3]) print("x4 =", model[x4]) print("y1 =", model[y1]) print("y2 =", model[y2]) print("y3 =", model[y3]) print("y4 =", model[y4]) else:
​ print("无解") ---------------------------------------------------------------------------------------
​
---------------------------------------------------------------------------------------
​
得到结果:
​
-----------------------------------------------------------------------
​ Python 成功: x1 = 1 x2 = 4 x3 = 1 x4 = 2 y1 = 4 y2 = 1 y3 = 3
​ y4 = 4 -----------------------------------------------------------------------

发现x1和x3重复了,因此还要添加值不重复约束


 Python from z3 import *  # 创建变量 x1, x2, x3, x4 = Ints('x1 x2 x3 x4') y1, y2, y3, y4 = Ints('y1 y2 y3 y4')  # 创建约束条件 v0 = And(y3 != 2, y4 != 2) v1 = And(v0, x2 != 1) v2 = And(x1 != 3, x2 != 3) #值范围约束 range_constraint = And(x1 >= 1, x1 <= 4, x2 >= 1, x2 <= 4, x3 >= 1, x3 <= 4, x4 >= 1, x4 <= 4, y1 >= 1, y1 <= 4, y2 >= 1, y2 <= 4, y3 >= 1, y3 <= 4, y4 >= 1, y4 <= 4) #非重复值约束 distinct_x=Distinct(x1,x2,x3,x4) distinct_y=Distinct(y1,y2,y3,y4)  # 创建条件语句 cond = Or(Not(v2), Not(v1), y1 != 4, y4 == 3, x3 == 4, x4 != 2) cond1 = Not(cond) #正常来说,cond的值要为false的,但是z3的add添加的条件必须为1才行,因此要进行取反操作 # 创建求解器 solver = Solver()  # 添加约束条件和条件语句到求解器 solver.add(cond1)#这里添加的条件必须为true,所以最后使用了 not 进行取反操作 solver.add(range_constraint) solver.add(distinct_y) solver.add(distinct_x) # 求解 if solver.check() == sat: # 如果有解,则获取解 model = solver.model()  # 打印解 print("成功:") print("x1 =", model[x1]) print("x2 =", model[x2]) print("x3 =", model[x3]) print("x4 =", model[x4]) print("y1 =", model[y1]) print("y2 =", model[y2]) print("y3 =", model[y3]) print("y4 =", model[y4]) else:
​ print("无解") ---------------------------------------------------------------------------------------

最终得到正确的结果


Python 成功: x1 = 1 x2 = 4 x3 = 3 x4 = 2 y1 = 4 y2 = 2 y3 = 3

y4 = 1


x1-x4= 1 4 3 2

y1-y4= 4 2 3 1

按照这样的顺序输入即可:

得到了flag

irisctf{m0r3_th4n_0n3_l0g1c_puzzl3_h3r3}

总结

题目并不是很难,没有复杂的ollvm混淆也没有复杂的加密。但是却一步一步引导我们去学习和总结。z3解题的过程中,会有很多误解,然后经过自己的思考总结,发现了漏掉的东西,再进行补充,最终写出正确的脚本。

国外的题还是很值得学习的,不单单为了出题而出题。这就是逻辑运算在z3的运用以及如何增加约束,让z3求解出我们需要的key。

更多网安技能的在线实操练习,请点击这里>>

  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/745507.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在Python中使用SWCNN去除水印

在Python中使用SWCNN去除水印 说明首次发表日期:2024-07-17 SWCNN Github官方仓库: https://github.com/hellloxiaotian/SWCNN SWCNN 论文链接: https://arxiv.org/abs/2403.05807准备 运行环境 首先创建一个conda环境,安装SWCNN官方建议的库: conda create -n py39torch …

Xilinx NVMe AXI4主机控制器,AXI4接口高性能版本介绍

NVMe AXI4 Host Controller IP可以连接高速存储PCIe SSD,无需CPU,自动加速处理所有的NVMe协议命令,具备独立的数据写入和读取AXI4接口,不但适用高性能、顺序访问的应用,也适用于随机访问的应用,同时结合外部存储器(比如DDR),使得Host端的数据访问管理更加灵活。NVMe A…

请问如何将带有斜纹水印pdf的转成Excel呢?

大家好,我是Python进阶者。 一、前言 前几天在Python最强王者交流群【wen】问了一个Python自动化办公的问题,问题如下:请问如何将带有斜纹水印pdf的转成Excel呢?目前我把pdf转成图片,根据水印的颜色进行清除,但是在脱网环境下无法将图片转成Excel。 二、实现过程 后来【隔…

并发问题的三大根源是什么?

本文探讨了在多线程环境下,CPU缓存、线程切换以及编译优化如何影响数据的可见性、原子性和有序性,并提出了相应的解决方案。在单核CPU时代,所有线程共享同一缓存,确保了数据的一致性。然而,多核CPU下,各核心拥有独立缓存,可能导致线程间数据更新不可见。1.前言 从进程与…

判断语句

判断语句 猜猜心里数字:n=6 if int(input("第一次输入数字"))==n:print("猜对了") elif int(input("第二次输入数字"))==n:print("第二次猜对了") elif int(input("第三次输入数字"))==n:print("第三次对了") el…

nacos RCE

1.漏洞原理 漏洞的核心在于 Nacos 的某些接口没有严格的权限控制,攻击者可以通过通过特定的 JSON 数据结构,远程执行恶意代码。以利用该漏洞读取敏感文件、执行系统命令。 条件:需要登录后才能利用漏洞 2.影响版本 nacos 2.3.2 nacos 2.4.0 3.环境搭建 https://github.com/a…

DataFountain-个贷违约预测实战

赛题来源:Datafountain 个贷违约预测 竞赛 - DataFountain 参考优秀选手方法单模走天下:公布一个单模型精度达0.9014(B榜第8)的算法 数据科学社区-DataFountain并加入自己理解整理如下:赛题理解 题目给出了train_internet.csv、train_public.csv、test_public.csv、submit_e…

数据仓库建模工具之一——Hive学习第三天

1、Hive的基本操作 1.1 Hive库操作 1.1.1 创建数据库1)创建一个数据库,数据库在HDFS上的默认存储路径是/hive/warehouse/*.db。create database testdb;2)避免要创建的数据库已经存在错误,增加if not exists判断。(标准写法)-- 中括号表示可以省略的内容 create database…

Datawhale AI 夏令营——电力需求挑战赛——Task2学习笔记

一、实先准备import numpy as np import pandas as pd import lightgbm as lgb from sklearn.metrics import mean_squared_log_error, mean_absolute_error, mean_squared_error import tqdm import sys import os import gc import argparse import warnings warnings.filter…

美团VS饿了么,到底谁更胜一筹?

美团大战饿了么,到底谁会更胜一筹最近啊,收到一个粉丝的投稿,我发现他在美团和饿了么都去面试过。 这俩企业大家应该都经常用吧,咱点外卖的时候,我有时候就琢磨,到底他俩谁更厉害点。 今天咱们就瞅瞅,在面试这块儿谁更难一些。 (目前都只有一面的情况,要是想要后续的,…

系统状态方程的离散化

A=[0 1 0; 0 0 1; -6 -11 -6]; B=[1 0; 2 -1; 0 2]; C=[1 -1 0; 2 1 -1]; D=[0 0; 0 0]; sysG=ss(A,B,C,D); %获取系统的模拟传递函数 step(sysG) %模拟系统的阶跃响应,如图1 T=0.1; sysGd=c2d(sysG,T); %获取系统的数字传递…