攻防世界逆向刷题

阅读须知:

探索者安全团队技术文章仅供参考,未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作,由于传播、利用本公众号所提供的技术和信息而造成的任何直接或者间接的后果及损失,均由使用者
本人负责,作者不为此承担任何责任,如有侵权烦请告知,我们会立即删除并致歉,创作不易转载请标明出处.感谢!

波克比QWQ师傅

原文出处: https://blog.csdn.net/yjh_fnu_ltn?type=blog

题目

题目地址:polyre

  1. 拿到题目后无壳,直接拖入ida反汇编,从start函数直接跳到main函数:
  2. 明显的虚假控制流平坦化,这里简单讲一下什么是平坦化,平坦化就是将原本嵌套多层的语句,改为只用1个switch加while循环来实现,下面使用python语句来表现一个循环语句平坦化:
#原程序
res=[1,-1,2,-2,3,-3]
for i in range(len(res)):if res[i] < 0:res[i]<<=1res[i]+=10if res[1]&1==1:res[i]*=2else :res[i]^=13res[i]*=4# if res[1]
print(res)res=[1,-1,2,-2,3,-3]
#手动添加平坦换后
i=0
while i<len(res):b=(int(res[i]<0)^1)+1while True:match b:case 0:breakcase 1:res[i]<<=1b=3case 2:res[i]^=13b=4case 3:res[i]+=10b=(res[i]&1)*5case 4:res[i]*=4breakcase 5:res[i]*=2breaki+=1
print(res)


4. 其实现的功能仍然是一样的,只不过将一个循环里的多个语句放在了不同的子模块中,再通过子模块之间的相互控制,来达到原有程序的效果。详细的平坦换请看下面这篇文章:控制流平坦化
5. 知道控制流平坦化后,可以使用符号化执行来简化程序,使程序的可读性增强,便于反汇编,使用deflat.py脚本即可去除平坦化:命令如下
6. -f后是文件名,–addr后是要平坦化的函数首地址,执行后效果如下:汇编视图
7. 这里可以看到,去平坦化后的程序刻度性增强,不过其中还有一些出题人塞进去的虚假指令(恒真/假),永远不会执行。
8. 例如:第一个if语句后面的 ((((_BYTE)dword_603054 - 1) * (_BYTE)dword_603054) & 1) != 0条件就永远为假**(n*(n-1))&1这个结果恒等于0,所以前面的条件恒假,即if语句里面的程序根本不会执行,类似的虚指令后面还有16个,需要清除:
9. 这里使用idapython脚本来快速去除,这里
脚本的逻辑**:将jnz指令的条件跳转修改为直接跳转,因为后面的jmp语句永远不会执行,后面的while循环同理,只会执行一次,因此利用脚本将jnz的条件跳转直接改为jmp进行直接跳转(顺跳),源程序相当于:

st = 0x0000000000400620 #main开始
end = 0x0000000000402144 #main结束def patch_nop(start,end):for i in range(start,end):ida_bytes.patch_byte(i, 0x90)		#修改指定地址处的指令  0x90是最简单的1字节nopdef next_instr(addr):return addr+idc.get_item_size(addr)		#获取指令或数据长度,这个函数的作用就是去往下一条指令addr = st
while(addr<end):next = next_instr(addr)if "ds:dword_603054" in GetDisasm(addr):	#GetDisasm(addr)得到addr的反汇编语句while(True):addr = nextnext = next_instr(addr)if "jnz" in GetDisasm(addr):dest = idc.get_operand_value(addr, 0)		#得到操作数,就是指令后的数ida_bytes.patch_byte(addr, 0xe9)     #0xe9 jmp后面的四个字节是偏移ida_bytes.patch_byte(addr+5, 0x90)   #nop第五个字节offset = dest - (addr + 5)  #调整为正确的偏移地址 也就是相对偏移地址 - 当前指令后的地址ida_bytes.patch_dword(addr + 1, offset) #把地址赋值给jmp后print("patch bcf: 0x%x"%addr)addr = nextbreakelse:addr = next
  1. 利用脚本修改后的汇编指令,反编译程序如下,去除掉后面16个虚指令:
  2. 前期准备结束,正式开始分析函数实现的功能,第一个循环的逻辑是将最后输入的回车符"\n"转化为0,第二个循环:将输入的字符串每8个一组(共64个bit)进行一下处理,大于零则左移1位(乘2),小于零则左移1位后与0xB0004B7679FA26B3异或。这里由于变量v4是64位的有符号数,左移根据其最高位来判定符号,1为负数,0为正数:
  3. 最后,Jami后的字符串与程序给定的数据相比较,因为8个字节一组,所以将程序给定的48个字节分为6组整合到一起:
  4. 最后解密脚本如下,脚本里面使用到的逻辑:原先的正数(最高位的符号位为0)左移1后一定是偶数(左移后低位自动用0补充),而原先的负数(最高位的符号位为1)左移1后(变为偶数)再与0xB0004B7679FA26B3(奇数)异或,结果一定是奇数,也就是说,最后结果(加密一次)里面的偶数原先一定是正数,而结果里面的奇数原先一定是负数,所以根据每次结果奇偶性即可判定上一次该值是否为正或者负,如果是负数则需要给最高位(第64为)补上1(补上因为加密是左移而溢出的1),为正数不用补(加密是左移溢出的是0,相当于没有溢出):
a=[0xBC8FF26D43536296,0x520100780530EE16,0x4DC0B5EA935F08EC,0x342B90AFD853F450,
0x8B250EBCAA2C3681,0x55759F81A2C68AE4]
key=0xB0004B7679FA26B3
for res in a:for j in range(64): #循环64次tmp=res&1if tmp == 1:#判定是否为奇数(为奇数则上轮加密是为负数),在二进制下最低为为1则是奇数res ^= keyres>>=1if tmp==1:res+=0x8000000000000000 #如果该次加密前是负数(),把左移漏掉的最高位1补回来#输出,大小端续转化输出k=0while k<8:print(chr(res&0xff),end="")res>>=8k+=1
#flag{6ff29390-6c20-4c56-ba70-a95758e3d1f8}

总结:控制流平坦换的题需要将程序还原,增强程序的可读性,程序中存在永真(或永假)指令时可以利用idapython将条件跳转(jz,jnz)修改为直接跳转(jmp),进一步增强可读性。

题目 :maze

题目地址 :maze

  1. 查壳无,直接使用ida打开,这应该时一道迷宫的题,打开后如下。在这里插入图片描述
  2. 分析,发现这是一道直线迷宫的题,解这类题目只需要找到该直线迷宫,分析键盘输入对应的移动操作即可,迷宫如下:
  3. 在主循环中分析输入的flag对应的移动操作,可以看到0 后退1=79,前进1=111,后退8=46,前进8=48,由cmp函数可以看见只能停留在空格#
  4. 分析出输入对应的移动操作后,即可走完迷宫,操作对应如下,代码附上:
'  *******   *  **** * ****  * ***  *#  *** *** ***     *********'
# 0 后退1=79
# 1 前进1=111
# 2 后退8=46
# 3 前进8=48
key=[79,111,46,48]
#    0 , 1 , 2,3
res=[1,3,1,1,3,3,0,3,3,3,1,1,1,1,2,2,0,0]
for i in range(len(res)):print(chr(key[res[i]]),end="")
flag="o0oo00O000oooo..OO"
print(len(flag))

最后flag=nctf{o0oo00O000oooo…OO}

题目:easy_go

题目地址:easy_go

  1. 无壳,直接ida打开:=
  2. 能看到的关键信息由一个字符串 “tGRBtXMZgD6ZhalBtCUTgWgZfnkTgqoNsnAVsmUYsGtCt9pEtDEYsql3”,外加一个encode_base64的加密函数,看到了base64直接去找base64表,字符串里面直接看,搜索abcdefgABCDEFG…,查询base64表:
  3. 其中发现三个比较像的字符串,三个字符串一个一个用脚本(网站)试一下,最后真正的base64表是6789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345
  4. 总结:有关于base64的题目都可以直接去找base64表和密文。

题目:polyre

题目地址:polyre

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

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

相关文章

阿里云服务器多少钱一个月?低至5元1个月

阿里云服务器一个月多少钱&#xff1f;最便宜5元1个月。阿里云轻量应用服务器2核2G3M配置61元一年&#xff0c;折合5元一个月&#xff0c;2核4G服务器30元3个月&#xff0c;2核2G3M带宽服务器99元12个月&#xff0c;轻量应用服务器2核4G4M带宽165元12个月&#xff0c;4核16G服务…

Spring+thymeleaf完成用户管理页面的增删查改功能

目录 知识点&#xff1a; 路由重定向 redirect:/*** 登录 控制层代码 接口 sql配置 页面效果 添加用户 控制层代码 接口 sql配置 页面效果 查看信息 控制层代码 接口 sql配置 页面效果 修改信息 控制层代码 接口 sql配置 页面效果 条件查询 控制层代码 …

商标跨类异议与跨类保护!

有个朋友对普推知产老杨说收到某邮件&#xff0c;名下商标让某公司抢注了现在公告期&#xff0c;让赶紧提出来异议去处理下&#xff0c;怎么会有这样的事&#xff0c;相同的名称基本上在同类别相关产品是无法公告和获得初审的。 经详细检索分析后&#xff0c;发现不是这样一回…

利用瑞士军刀netcat建立连接并实现文件上传

实验环境&#xff1a; Kali:192.168.117.129 Windows10:192.168.135.142 第一步&#xff1a;建立连接 在Windows上下载netcat(官网搜索) 下载好之后在netcat目录打开cmd进入小黑屏 实验一&#xff1a;建立虚拟机与主机的连接 命令&#xff1a; Kali:nc 192.168.135.144…

学习总结!

java目前学习到了类的实例化&#xff1a; 类&#xff1a;描述一种事物的定义&#xff0c;是抽象的概念 实例&#xff1a;该事物的一个具体的个体&#xff0c;是具体的东西 举例&#xff1a; 世界上人很多&#xff0c;可以定义一个Person类: Public Person {Public String Name…

全国草地资源类型分布图

草地出现在世界各地&#xff0c;约占全球陆地面积的24%&#xff0c;大多分布于大陆内部气候干燥、降水较少的地区&#xff0c;其中澳大利亚、俄罗斯、中国、美国和巴西等国面积较大。中国草地面积约占国土面积的40%&#xff0c;主要分布在内蒙古、东北、西北和青藏高原&#xf…

基于javaweb(springboot+mybatis)网上家具商城项目设计和实现以及文档报告

基于javaweb(springbootmybatis)网上家具商城项目设计和实现以及文档报告 博主介绍&#xff1a;多年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞…

创建AI智能体

前言 灵境矩阵是百度推出的基于文心大模型的智能体&#xff08;Agent&#xff09;平台&#xff0c;支持广大开发者根据自身行业领域、应用场景&#xff0c;选取不同类型的开发方式&#xff0c;打造大模型时代的产品能力。开发者可以通过 prompt 编排的方式低成本开发智能体&am…

【STL】string的模拟实现

目录 前言 构造函数 析构函数 迭代器 拷贝构造和赋值 深浅拷贝问题 传统写法 现代写法 插入函数 reserve() push_back() append() 操作 insert() erase() 流插入和流提取 流插入 流提取 运算符重载 其它函数实现 []重载 resize() find() substr() …

Matlab|计及电池储能寿命损耗的微电网经济调度

目录 1 主要内容 储能寿命模型 负荷需求响应 2 部分代码 3 程序结果 4 下载链接 1 主要内容 该程序参考文献《考虑寿命损耗的微网电池储能容量优化配置》模型&#xff0c;以购售电成本、燃料成本和储能寿命损耗成本三者之和为目标函数&#xff0c;创新考虑储能寿命损耗约…

基于 YAML 接口自动化测试框架设计

在设计自动化测试框架的时候&#xff0c;我们会经常将测试数据保存在外部的文件&#xff08;如Excel、YAML、CSV&#xff09;&#xff0c;或者数据库中&#xff0c;实现脚本与数据解耦&#xff0c;方便后期维护。目前非常多的自动化测试框架采用通过Excel或者YAML文件直接编写测…

python 中判断文件、目录是否存在的方法

判断目录是否存在并创建目录 一、实现上传文件功能二、判断目录是否存在的办法2.1、使用os模块2.1.1、判断目录是否存在2.1.2、os.makedirs()&#xff1a;递归创建目录 2.2、使用pathlib模块2.2.1、path.exist()判断目录是否存在2.2.1、path.mkdir()&#xff1a;创建目录 2.3、…

力扣刷题Days25-45. 跳跃游戏 II(js)

目录 1&#xff0c;题目 2&#xff0c;代码 贪心算法正向查找 3&#xff0c;学习 解题思路 具体代码处理 数组遍历的最后边界的处理&#xff1a; 1&#xff0c;题目 给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向…

程序结构

oracle从入门到总裁:​​​​​​https://blog.csdn.net/weixin_67859959/article/details/135209645 程序结构 PL/SQL程序的基本单元是语句块&#xff0c;所有的 PL/SQL程序都是由语句块组成&#xff0c;语句块之间可以相互嵌套&#xff0c;每个语句块完成特定的功能。 一个…

html页面使用@for(){},@if(){},利用jquery 获取当前class在列表中的下标

基于以前的项目进行修改优化&#xff0c;前端代码根据List元素在html里进行遍历显示 原先的代码&#xff1a; 其中&#xff0c;noticeGuide.Id是标识noticeGuide的唯一值&#xff0c;但是不是从0开始的【是数据库自增字段】 但是在页面初始化加载的时候&#xff0c;我们只想…

NO9 蓝桥杯单片机实践之串口通信的使用

1 回顾 串口通信的代码编写结构还是与中断一样&#xff0c;不同的是&#xff1a; 初始中断函数条件涉及到串口通信相关的寄存器和定时器1相关的寄存器&#xff08;定时器1用于产生波特率&#xff09;&#xff0c;但初始条件中的中断寄存器只考虑串口通信而不考虑定时器1。 vo…

基于SSM的高校推免报名(有报告)。Javaee项目。ssm项目。

演示视频&#xff1a; 基于SSM的高校推免报名&#xff08;有报告&#xff09;。Javaee项目。ssm项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过Spring Spri…

图解 python 的赋值,浅拷贝,深拷贝

上面的图中&#xff0c;我们将箭头连线看作是引用。 如果你只是简单是 b a&#xff0c;实际上两者的引用是一样的&#xff0c;相当于 b 只是 a 的另外一个名字&#xff0c;不管是对 a 或者 b 内的可变元素还是不可变元素修改&#xff0c;打印 a, b 两者都是一样的。 但是如果…

PHP+MySQL开发组合:智慧同城便民信息小程序源码系统 带完整的安装代码包以及安装部署教程

当前&#xff0c;城市生活的节奏日益加快&#xff0c;人们对各类便民信息的需求也愈发迫切。无论是寻找家政服务、二手交易&#xff0c;还是发布租房、求职信息&#xff0c;一个高效、便捷的信息平台显得尤为重要。传统的信息发布方式往往存在信息更新不及时、查找困难等问题&a…

Jenkins安装 Linux 更换镜像 安装插件

Jenkins安装 Linux 更换镜像 安装插件 前言 下面叙述了三种jenkins安装的方式,jenkins安装之前必须有java环境因为他是java写的… yum安装只能安装最新版本的jenkins,但是jenkins是java写的所以他强依赖java版本,当你的服务器的java版本与jenkins版本冲突时还需要给jenkins重…