ISCTF2023 Reverse方向 WP

文章目录

  • Reverse
    • crackme
    • EasyRe
    • babyRe
    • easy_z3
    • FloweyRSA
    • easy_flower_tea
    • mfx_re
    • z3_revenge
    • WHERE

Reverse

crackme

image-20231128235807877

加了UPX壳,可以看到EP Section处UPX标识被修改了

用WinHex修改

image-20231128235912601

之后UPX脱壳

image-20231128235954127

image-20231129000032590

得到flag。


EasyRe

image-20231129000118429

image-20231129002417390

逆向一下,先逆序,再做一些字符的替换,最后异或0x11.

for ( i = v6 - 1; i >= 0; --i )v4[v6 - i + 111] = v4[i + 112];

这一部分,实际上就是将数组 v4 中的元素从索引 iv6 - 1 复制到数组 v4 中的索引 v6 - i + 111v6 + 110 的位置

EXP:

enc = ']P_ISRF^PCY[I_YWERYC'
trans_table = str.maketrans('YC', 'BX')
result = enc.translate(trans_table)
re_result = result[::-1]
flag = ''.join([chr(ord(char) ^ 0x11) for char in re_result])print(flag)
# ISCTFSNXJSIAOWCBXNAL

babyRe

image-20231209082308108

py逆向。用pyinstxtractor解包。

image-20231209082421065

之后找到babyRe.pyc和struct.pyc 拖进WinHex中比较magic number

image-20231209082519282

image-20231209082548264

相同,没有魔改。则直接对babyRe进行反编译,使用uncompyle6 或者 pyc在线反编译

image-20231209082653959

发现是个rsa加密,结合output;已知(p+1)*(q+1)和(p+q);那么根据简单的数学公式,我们可以知道phi 即 (p-1)(q-1) = (p+1)(q+1) - 2(p+q),以及n = p * q = (p+1)(q+1) - (p+q) - 1;

之后根据RSA的计算公式可以解出flag

EXP:

from Crypto.Util.number import long_to_bytes
from gmpy2 import invertpaddq=292884018782106151080211087047278002613718113661882871562870811030932129300110050822187903340426820507419488984883216665816506575312384940488196435920320779296487709207011656728480651848786849994095965852212548311864730225380390740637527033103610408592664948012814290769567441038868614508362013860087396409860
p1xq1=21292789073160227295768319780997976991300923684414991432030077313041762314144710093780468352616448047534339208324518089727210764843655182515955359309813600286949887218916518346391288151954579692912105787780604137276300957046899460796651855983154616583709095921532639371311099659697834887064510351319531902433355833604752638757132129136704458119767279776712516825379722837005380965686817229771252693736534397063201880826010273930761767650438638395019411119979149337260776965247144705915951674697425506236801595477159432369862377378306461809669885764689526096087635635247658396780671976617716801660025870405374520076160
c=5203005542361323780340103662023144468501161788183930759975924790394097999367062944602228590598053194005601497154183700604614648980958953643596732510635460233363517206803267054976506058495592964781868943617992245808463957957161100800155936109928340808755112091651619258385206684038063600864669934451439637410568700470057362554045334836098013308228518175901113235436257998397401389511926288739759268080251377782356779624616546966237213737535252748926042086203600860251557074440685879354169866206490962331203234019516485700964227924668452181975961352914304357731769081382406940750260817547299552705287482926593175925396
n = p1xq1 - paddq - 1
phi = p1xq1 - 2*paddq
e = 65537
d = invert(e,phi)
m = pow(c,d,n)
print(long_to_bytes(m))# ISCTF{kisl-iopa-qdnc-tbfs-ualv}

easy_z3

py文件打开,发现就是一堆约束条件,用python的z3约束求解。

image-20231209162340796

根据源代码,还需要将计算出的整数转换为ascii码的形式。

EXP:

from z3 import *s = Solver()l = [Int(f"l_{i}") for i in range(6)]s.add((593*l[5] + 997*l[0] + 811*l[1] + 258*l[2] + 829*l[3] + 532*l[4]) == 0x54eb02012bed42c08)
s.add((605*l[4] + 686*l[5] + 328*l[0] + 602*l[1] + 695*l[2] + 576*l[3]) == 0x4f039a9f601affc3a)
s.add((373*l[3] + 512*l[4] + 449*l[5] + 756*l[0] + 448*l[1] + 580*l[2]) == 0x442b62c4ad653e7d9)
s.add((560*l[2] + 635*l[3] + 422*l[4] + 971*l[5] + 855*l[0] + 597*l[1]) == 0x588aabb6a4cb26838)
s.add((717*l[1] + 507*l[2] + 388*l[3] + 925*l[4] + 324*l[5] + 524*l[0]) == 0x48f8e42ac70c9af91)
s.add((312*l[0] + 368*l[1] + 884*l[2] + 518*l[3] + 495*l[4] + 414*l[5]) == 0x4656c19578a6b1170)flag = ''
if s.check() == sat:model = s.model()for i in range(6):hex_model = hex(model[l[i]].as_long())[2:]flag += "".join(chr(int(hex_model[j:j+2],16))for j in range(0,len(hex_model),2))print(flag)
# ISCTF{N0_One_kn0ws_m@th_B3tter_Th@n_me!!!}

FloweyRSA

image-20231209090613829

ida打开之后全是爆红,找到花指令的地方。

image-20231209090717075

jz到label1中间的内容是混淆的东西,全部nop掉,

image-20231209090759097

之后在main函数处用P 创建函数,根据提示对相应地址的内容进行修复(nop掉再C转化代码)修完之后,回到main处 P 一下,之后反编译就可以了。

image-20231209090936754

得到:

image-20231209091039222

可以知道是一个RSA加密,密文数据在c中,e为 465,n很小,可以分解得到 p 和 q。

EXP:

from Crypto.Util.number import long_to_bytes
from gmpy2 import invertenc = [0x753C2EC5, 0x8D90C736, 0x81282CB0, 0x7EECC470, 0x944E15D3, 0x2C7AC726, 0x717E8070, 0x30CBE439, 0x0B1D95A9C,0x6DB667BB, 0x1240463C, 0x77CBFE64, 0x11D8BE59]
e = 0x1D1
p = 56099
q = 56369
n = p * q
phi = (p - 1) * (q - 1)
d = invert(e, phi)
flag = b''
for key in enc:m = pow(key, d, n)flag += long_to_bytes(m)
print(flag)# b'flag{reverse_is_N0T_@lways_jusT_RE_myy_H@bIb1!!!!!!}'

easy_flower_tea

image-20231209160252169

IDA打开后无法加载,地址爆红,看汇编

image-20231209160415934

image-20231209160459378

直接NOP掉,然后P了反编译就好。

image-20231209160534610

要求我们输入number 1 和number 2,对着俩个数进行加密之后进行验证。查看一下加密函数sub_41100A

image-20231209160631080

就是一个简单的TEA加密。

EXP:


#include <stdio.h>
#include <stdint.h>  // 使用uint32_t数据类型需要包含此头文件
#include <string.h>#include<iostream>using namespace std;
// 定义加密函数
// 定义加密函数
void tea_decrypt(uint32_t *v, uint32_t *k) {uint32_t v0 = v[0], v1 = v[1], i;  // 根据TEA算法,解密轮次的计算需要初始化sumuint32_t delta = 0x61C88647;uint32_t sum = -(delta*32);for (i = 0; i < 32; i++) {v1 -= ((v0 * 16) + k[2]) ^ (v0 + sum) ^ ((v0 >> 5) + k[3]);v0 -= ((v1 * 16) + k[0]) ^ (v1 + sum) ^ ((v1 >> 5) + k[1]);sum += delta;}v[0] = v0;v[1] = v1;
}int main() {uint32_t enc[2]={1115126522,2014982346};uint32_t key[]={12,34,56,78};tea_decrypt(enc,key);cout<<enc[0]<<endl;cout<<enc[1];return 0;
}

mfx_re

UPX魔改壳,使用WinHex将MFX都改成UPX,mfx改成upx就好了。之后用UPX脱壳

image-20231209162759835

只有处–s[i],逆向一下就是 +1

EXP:

enc = 'HRBSEz51e1a81c,78b3,34d`,84`4,6acce2c776a0|'
print("".join(chr(ord(enc[i])+1)for i in range(len(enc))))
# ISCTF{62f2b92d-89c4-45ea-95a5-7bddf3d887b1}

z3_revenge

image-20231209163202351

image-20231209163235461

一样的用python的z3约束求解。

实际上v4可以看做v0,之后SBYTE1(v4)就是v1,SBYTE2(v4) 为v2;以此类推

z3可以解出

solution_values = [73, 83, 67, 84, 70, 123, 53, 53, 54, 52, 48, 48, 53, 102, 45, 50, 100, 100,56, 45, 52, 100, 57, 53, 45, 57, 100, 50, 55, 45, 48, 100, 98, 102, 52, 48,48, 49, 57, 54, 49, 57, 125
]
flag = []
for i in range(len(solution_values)):flag.append(chr(solution_values[i]))
print(''.join(flag))
# ISCTF{5564005f-2dd8-4d95-9d27-0dbf40019619}

WHERE

image-20231214080514798

IDA打开

image-20231214082750499

程序开始23行处设置了一个异常处理函数

  • 使用了 NtCurrentTeb() 函数来获取当前线程的TEB
  • 访问 NtTib 结构,从中获取 ExceptionList 成员的值。
  • 在Windows中,ExceptionList 是 TEB 的一部分,用于指向当前线程的异常链表的头部。
  • 异常链表用于管理当前线程的异常处理信息,当线程执行发生异常时,系统会根据这个链表找到对应的异常处理程序。

之后往下看,

image-20231214083436214

GetModuleHandleA函数 获取 kernel32.dll 动态链接库中的 AddVectoredExceptionHandler 函数的地址,而AddVectoredExceptionHandler 函数用于向进程中添加一个矢量化的异常处理程序。所以这里也是关于异常处理的操作。

接着,

image-20231214083622518

又一次通过 NtCurrentTeb() 函数来获取当前线程的TEB,这一次是通过访问TEB的 ProcessEnvironmentBlock 成员,最终获取了一个叫做 BeingDebugged 的成员的值。在Windows中, BeingDebugged 是用于指示当前进程是否被调试的,如果当前值为非零,表示进程正在被调试。

image-20231214083853664

接上面,如果进程没有被调试,则这里会进入401520中,

image-20231214083954918

这里看一下,似乎都是对调试器的操作,阻止动态分析。

还有一处loc_401660,点进去看看

image-20231214084425601

发现一小段花指令,去除后发现是一个TEA加密,但是目前不清楚是哪里的。

image-20231214084511856

再次返回主函数的时候,发现不见了。不知道是什么情况了,看了wp好像是 VEH异常处理还是SEH异常处理,不太懂(待学)

image-20231214084556145

往下看。

image-20231214084111919

第一部分flag的地方,可以用z3解出来。

再往下,

image-20231214084727331

先验证了 Str 长度为32,爆红的不知道什么,好像是什么空指针异常,想起上面讲的异常处理函数,

image-20231214085941647

点进去看,

image-20231214090000890

发现是一个魔改了一点的RC4

image-20231214090023692

接着看到 sub_401660,这里不就是1我们刚刚 修复的花指令处,虽然不懂具体的过程,但是这里应该就是 TEA加密。

再看下面。

image-20231214085158466

这里拿 刚刚 TEA加密后的密文,先是异或,将得到的数据作为一个二维数组的索引,把当前位置的值设置为1,最后比较返回0。

其实到这里就分析完了。好像也不是很难,但是当初纠结了好久。

逆向一下就好了。

但是其实现在也还有点疑惑,为什么TEA加密的时候的明文和key是相同的,解密的时候密文和key也可以相同,当时就是这里纠结不出来。o(╥﹏╥)o、

具体的EXP就不再写了,分析完了。主要是这个拖了好久了,今天补一下。可以去找官方wp。有EXP。

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

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

相关文章

机器人行业数据闭环实践:从对象存储到 JuiceFS

JuiceFS 社区聚集了来自各行各业的前沿科技用户。本次分享的案例来源于刻行&#xff0c;一家商用服务机器人领域科技企业。 商用服务机器人指的是我们日常生活中常见的清洁机器人、送餐机器人、仓库机器人等。刻行采用 JuiceFS 来弥补对象存储性能不足等问题。 值得一提的是&am…

godot 报错Unable to initialize Vulkan video driver解决

版本 godot 4.2.1 现象 godot4.2.1 默认使用vulkan驱动&#xff0c;如果再不支持vulkan驱动的主机上&#xff0c;进入引擎编辑器将报错如下 解决 启动参数添加 –rendering-driver opengl3 即可进入引擎编辑器 此时运行项目仍然会报错无法初始化驱动 在项目设置中配置编…

编译Sqlite3记录

下载源文件&#xff1a; 下载地址&#xff1a;SQLite Download Page 打开QtCreator创建新的工程&#xff0c;选择纯C工程&#xff0c;将main.c删除&#xff0c;将下载的源码解压后的文件复制到并添加到工程中&#xff0c;其中的文件包括&#xff1a;sqlite3ext.h、sqlite3.h、…

Android多进程和跨进程通讯方式

前言 我们经常开发过程中经常会听到线程和进程&#xff0c;在讲述Android进程多进程前我打算先简单梳理一下这俩者。 了解什么是进程与线程 进程&#xff1a; 系统中正在运行的一个应用程序&#xff0c;某个程序一旦运行就是一个进程&#xff0c;是资源分配的最小单位&#…

自动化测试 (二) Web自动化测试原理

目前市面上有很多Web UI自动化测试框架&#xff0c;比如WatiN, Selinimu,WebDriver&#xff0c;还有VS2010中的Coded UI等等. 这些框架都可以操作Web中的控件&#xff0c;模拟用户输入&#xff0c;点击等操作&#xff0c;实现Web自动化测试。其实这些工具的原理都一样&#xf…

element-ui样式(一)

1.去掉表格横线 HTML表格标签&#xff1a; table&#xff1a;定义表格&#xff0c;生成的表格在一对<table></table>中&#xff1b; <th>&#xff1a;定义表格的表头&#xff0c;一般是表头中的内容会被加黑&#xff08;table head&#xff09;&#xff1b;…

MySQL 系列:注意 ORDER 和 LIMIT 联合使用的陷阱

文章目录 前言背后的原因ORDER BY 排序列存在相同值时返回顺序是不固定的LIMIT 和 ORDER BY 联合使用时的行为ORDER BY 或 GROUP BY 和 LIMIT 联合使用优化器默认使用有序索引 如何解决其它说明个人简介 前言 不知道大家在在分页查询中有没有遇到过这个问题&#xff0c;分页查…

通俗易懂:插入排序算法全解析(C++)

插入排序算法是一种简单直观的排序算法&#xff0c;它的原理就像我们玩扑克牌时整理手中的牌一样。下面我将用通俗易懂的方式来解释插入排序算法的工作原理。 假设我们手上有一副无序的扑克牌&#xff0c;我们的目标是将它们从小到大排列起来。插入排序算法的思想是&#xff0…

0基础学习VR全景平台篇第127篇:什么是VR全景/720全景漫游?

“全景”作为一种表现宽阔视野的手法&#xff0c;在很久之前就得到了普遍的认同。北宋年间&#xff0c;由张择端绘制的《清明上河图》就是一幅著名的全景画。摄影术出现后&#xff0c;全景摄影也随之而生。 到今天&#xff0c;全景拍摄不再被专业摄影师所独享&#xff0c;广大…

leetcode--3. 无重复字符的最长子串[滑动窗口\哈希表 c++]

原题 &#xff1a; 3. 无重复字符的最长子串 - 力扣&#xff08;LeetCode&#xff09; 题目解析&#xff1a; 最长子串可以用滑动窗口解决&#xff0c;无重复字符可以使用哈希表解决。 算法原理&#xff1a; 滑动窗口哈希表 哈希表作为一个数组存放每个字符出现的次数。 …

06进程间关系-学习笔记

Orphan Process孤儿进程 父进程先于子进程退出&#xff0c;子进程失去托管&#xff0c;这种子进程统称为孤儿进程 失效进程&#xff08;孤儿进程&#xff09;&#xff1a;导致内存泄漏&#xff0c;影响新进程的创建孤儿进程的危害不可预测&#xff0c;如果一个孤儿进程持续的申…

Spark环境搭建和使用方法

目录 一、安装Spark &#xff08;一&#xff09;基础环境 &#xff08;二&#xff09;安装Python3版本 &#xff08;三&#xff09;下载安装Spark &#xff08;四&#xff09;配置相关文件 二、在pyspark中运行代码 &#xff08;一&#xff09;pyspark命令 &#xff08…

go自带rpc框架生产环境使用demo

基础使用 序列化使用自带gob协议 server package mainimport ("net""net/rpc" )// 定义一个handler结构体 type HelloService struct { }// 定义handler方法,大小写&#xff0c;参数&#xff0c;返回值都是固定的&#xff0c;否则无法注册 func (receiv…

五、Microsoft群集服务(MSCS)环境的搭建

一、【目的】 学会利用Windows Server布置群集环境。 二、【设备】 FreeNAS11.2&#xff0c;Windows Server 2019 三、【要求】 学会利用Windows Server布置群集环境&#xff0c;掌握处理问题的能力。 配置表&#xff1a; 节点公网IP(public)内网IP(private)群集IP(clust…

vue2-安装elementUI时警告

警告内容&#xff1a;npm WARN deprecated core-js2.6.12: core-js<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up …

JavaScipt验证URL新方法(2023 年版)

JavaScript诞生以来&#xff0c;一直没有一种简单的方法验证URL&#xff0c;现在JavaScript新增了一个新方法——URL.canParse。 URL.canParse(https://www.stefanjudis.com); // true URL.canParse(www.stefanjudis.com); // falseURL.canParse() 是一种快速验证字符串是否为…

改进的A*算法的路径规划(1)

引言 近年来&#xff0c;随着智能时代的到来&#xff0c;路径规划技术飞快发展&#xff0c;已经形成了一套较为 成熟的理论体系。其经典规划算法包括 Dijkstra 算法、A*算法、D*算法、Field D* 算法等&#xff0c;然而传统的路径规划算法在复杂的场景的表现并不如人意&#xf…

【网络协议】LACP(Link Aggregation Control Protocol,链路聚合控制协议)

文章目录 LACP名词解释LACP工作原理互发LACPDU报文确定主动端确定活动链路链路切换 LACP和PAgP有什么区别&#xff1f;LACP与LAG的关系LACP模式更优于手动模式LACP模式对数据传输更加稳定和可靠LACP模式对聚合链路组的故障检测更加准确和有效 推荐阅读 LACP名词解释 LACP&…

【论文笔记】Gemini: A Family of Highly Capable Multimodal Models——细看Gemini

Gemini 【一句话总结&#xff0c;对标GPT4&#xff0c;模型还是transformer的docoder部分&#xff0c;提出三个不同版本的Gemini模型&#xff0c;Ultra的最牛逼&#xff0c;Nano的可以用在手机上。】 谷歌提出了一个新系列多模态模型——Gemini家族模型&#xff0c;包括Ultra…

Cocos Creator:创建棋盘

Cocos Creator&#xff1a;创建棋盘 创建地图三部曲&#xff1a;1. 创建layout组件2. 创建预制体Prefab&#xff0c;做好精灵贴图&#xff1a;3. 创建脚本LayoutSprite.ts收尾工作&#xff1a; 创建地图三部曲&#xff1a; 1. 创建layout组件 使用layout进行布局&#xff0c;…