当前位置: 首页 > news >正文

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

国际赛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] BYREFunsigned __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 seeif you remember all of the facts.");puts("(Remember that each of the members like different things fromeach 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; // redgoto LABEL_11;}if ( !strcmp(input, s2) ){v6 = 2; // bluegoto LABEL_11;}if ( !strcmp(input, off_4050) ){v6 = 3; // greengoto LABEL_11;}if ( !strcmp(input, off_4058) ){v6 = 4; // yellowLABEL_11:if ( v6 == chosenColors[0] || v6 == dword_4094 || v6 ==dword_4098 || v6 == dword_409C )// 选择4个颜色,然后顺序不能一样puts("That option was already chosen!");elsechosenColors[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; // pizzagoto LABEL_28;}if ( !strcmp(input, off_4068) ){v7 = 2; // pastagoto LABEL_28;}if ( !strcmp(input, off_4070) ){v7 = 3; // steakgoto LABEL_28;}if ( !strcmp(input, off_4078) ){v7 = 4; // chickenLABEL_28:if ( v7 == chosenFoods[0] || v7 == dword_40A4 || v7 == dword_40A8|| v7 == dword_40AC )puts("That option was already chosen!");elsechosenFoods[v5++] = v7;}else{puts("Invalid food!");}}check(); // 开始check,检测我们输入的颜色和食物是否正确return 0;}-----------------------------------------------------------------------

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

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

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


C++

 int check(){bool v0; // dl_BOOL4 v1; // eax_BOOL4 v2; // edxv0 = 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 = 4x2 = 0x3 = 5x4 = 2y1 = 4y2 = Noney3 = 3y4 = 0-----------------------------------------------------------------------

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

帮助网安学习,全套资料S信免费领取:
① 网安学习成长路径思维导图
② 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 = 1x2 = 4x3 = 1x4 = 2y1 = 4y2 = 1y3 = 3y4 = 4-----------------------------------------------------------------------

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


 Pythonfrom 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

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • C#实现数据采集系统-查询报文处理和响应报文分析处理
  • 【C++】C++类和对象详解(上)
  • Docker核心技术:容器技术要解决哪些问题
  • Python爬虫-淘宝搜索热词数据
  • 《0基础》学习Python——第二十二讲__网络爬虫/<5>爬取豆瓣电影封面图
  • uniapp封装请求拦截器,封装请求拦截和响应拦截的方法
  • c# 一个自定义日志类
  • 【JAVA 常用API】数据库字段存储JSON格式数据,JAVA中如何将List<Entity>或者对象实体转换为字符串
  • Linux shell编程学习笔记65: nice命令 显示和调整进程优先级
  • linux文本查看命令
  • 概率论原理精解【1】
  • 基于YOLO8的目标检测系统:开启智能视觉识别之旅
  • 【Linux】Linux的基本使用
  • 开源防病毒工具--ClamAV
  • linux 报错:bash: /etc/profile: 行 32: 语法错误:未预期的文件结束符
  • C语言笔记(第一章:C语言编程)
  • nodejs实现webservice问题总结
  • React系列之 Redux 架构模式
  • uva 10370 Above Average
  • 浮现式设计
  • 模仿 Go Sort 排序接口实现的自定义排序
  • 使用阿里云发布分布式网站,开发时候应该注意什么?
  • 吴恩达Deep Learning课程练习题参考答案——R语言版
  • 再谈express与koa的对比
  • 移动端高清、多屏适配方案
  • ​比特币大跌的 2 个原因
  • ‌‌雅诗兰黛、‌‌兰蔻等美妆大品牌的营销策略是什么?
  • $.proxy和$.extend
  • (ZT)北大教授朱青生给学生的一封信:大学,更是一个科学的保证
  • (带教程)商业版SEO关键词按天计费系统:关键词排名优化、代理服务、手机自适应及搭建教程
  • (详细版)Vary: Scaling up the Vision Vocabulary for Large Vision-Language Models
  • (一)项目实践-利用Appdesigner制作目标跟踪仿真软件
  • .NET CLR基本术语
  • .net core 外观者设计模式 实现,多种支付选择
  • .NET MAUI Sqlite数据库操作(二)异步初始化方法
  • .NET/C#⾯试题汇总系列:⾯向对象
  • @LoadBalanced 和 @RefreshScope 同时使用,负载均衡失效分析
  • @RequestBody详解:用于获取请求体中的Json格式参数
  • @开发者,一文搞懂什么是 C# 计时器!
  • [000-01-022].第03节:RabbitMQ环境搭建
  • [ABC275A] Find Takahashi 题解
  • [BZOJ1053][HAOI2007]反素数ant
  • [BZOJ3757] 苹果树
  • [Effective C++读书笔记]0012_复制对象时勿忘其每一部分
  • [Everyday Mathematics]20150130
  • [Firefly-Linux] RK3568 pca9555芯片驱动详解
  • [Flex] PopUpButton系列 —— 控制弹出菜单的透明度、可用、可选择状态
  • [LeetCode] 596:超过5名学生的课
  • [leetcode]swap-nodes-in-pairs
  • [Luogu P3527BZOJ 2527][Poi2011]Meteors(整体二分+BIT)
  • [nohup, ] Linux后台进程运行
  • [oeasy]python0004_游乐场_和python一起玩耍_python解释器_数学运算
  • [one_demo_14]一个简单的easyui的demo
  • [UEFI]ROM镜像的备份与还原
  • [uni-app] uni.showToast 一闪而过问题/设定时间无效/1秒即逝