ISCTF2023 Reverse方向 WP

news2024/11/17 20:19:19

文章目录

  • 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 invert

paddq=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 invert

enc = [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算法,解密轮次的计算需要初始化sum
    uint32_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.coloradmin.cn/o/1309355.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

华为云sp2服务器系统根分区扩容后重启失败解决

lvm根分区扩容 概念&#xff1a; PV&#xff08;物理卷&#xff1a;Physical Volumes&#xff09; VG&#xff08;物理卷组&#xff1a;Volume Group&#xff09; LV&#xff08;逻辑卷&#xff1a;Logical Volumes&#xff09; R系 V10服务器&#xff1a; 显示当前Logic…

HTTP、HTTPS、SSL协议以及相关报文讲解

目录 HTTP/HTTPS介绍 HTTP/HTTPS基本信息 HTTP如何实现有状态 HTTP请求与应答报文 HTTP请求报文 HTTP响应报文 SSL协议 SSL单向认证 SSL双向认证 HTTP连接建立与传输步骤 HTTP访问全过程相关报文&#xff08;以访问www.download.cucdccom为例子&#xff09; DNS报文…

努比亚×实在RPA丨全域数据获取时长降低67%以上,累计节省人天1900+

国际知名数码品牌努比亚的服务和销售网络遍及海内外市场&#xff0c;其中&#xff0c;国内线上渠道包含淘系、京东、拼多多、快手等10余个主流电商平台。 为了更好满足年轻消费群体需求&#xff0c;努比亚每天需要获取各平台销售数据&#xff0c;对于需要管理10平台的运营部门…

@Valid注解的使用

Valid注解的使用 Valid 用来对参数进行验证&#xff0c;在变量信息中添加用于充当校验条件的注解 需要传入BindingResult对象&#xff0c;用于获取校验失败情况下的反馈信息 用法示例

DevOps搭建(十)-安装Harbor镜像仓库详细步骤

1、下载Harbor 官方地址: https://goharbor.io/ 下载地址: https://github.com/goharbor/harbor/tags 选择文档版本进行下载,这里我们选择v2.7.2版本 2、上传到服务器并解压 上传压缩包到服务器后,解压到/usr/local目录下,执行以下解压命令 tar -zxvf harbor-offli…

windows任务计划的创建、导出和导入

创建任务计划 任务名称 任务触发器 执行bat的话起始于必须填写 创建成功 导出任务计划 选择导出路径 导出成功 导入任务计划 可视化界面导入任务计划 选择任务计划的xml文件 点击确定 导入成功 命令行导入计划任务 cd /d D:\迅雷下载schtasks.exe /create /tn 1234 /xml 123…

【XR806开发板试用】+2.鸿蒙内核

非常感谢基于安谋科技STAR-MC1的全志XR806 Wi-FiBLE开源鸿蒙开发板试用活动&#xff01;非常感谢极术社区&#xff01;非常感谢极术小姐姐&#xff01;非常感谢全志在线开发者社区&#xff01;非常感谢通过试用申请&#xff01;非常感谢安谋科技&#xff01; 接上一篇&#xff…

CSS新手入门笔记整理:CSS定位布局

定位布局概述 浮动布局比较灵活&#xff0c;但是不容易控制。而定位布局的出现&#xff0c;使得用户精准定位页面中的任意元素成为可能。当然了&#xff0c;由于定位布局缺乏灵活性&#xff0c;这给空间大小和位置不确定的版面布局带来困惑。因此在实际开发中&#xff0c;大家…

数据服务化在京东的实践

01 缘起&#xff1a;数据服务化从 0 到 1 1. 缘起 京东数据智能部负责维护数据资产和对外提供数据服务&#xff0c;很多业务方要求我们尽快地提供开放的数据 API供其使用&#xff0c;但开发一个 API 的平均周期在两周左右&#xff0c;遇到 618 大促时还要提供 80 个接口。在…

Mrdoc知识文档

MrDoc知识文档平台是一款基于Python开发的在线文档系统&#xff0c;适合作为个人和中小型团队的私有云文档、云笔记和知识管理工具&#xff0c;致力于成为优秀的私有化在线文档部署方案。我现在主要把markdown笔记放在上面&#xff0c;因为平时老是需要查询一些知识点&#xff…

一张图看懂NvMDynamicConfiguration和NvMResistantToChangedSw对NvM数据变更的影响

一、背景 在实际项目中&#xff0c;我们会通过NvM将易失性数据存入EEPRAM。如果说NvM中配置好的Block List在项目迭代过程中没有Block的增加或减少&#xff0c;没有Block数据长度的增加或减少&#xff0c;那么NvM的使用就不会有什么问题。 但是如果Block List在某一天要增加一…

C_10练习题答案

一、单项选择题(本大题共 20小题,每小题 2分,共 40分。在每小题给出的四个备选项中,选出一个正确的答案,并将所选项前的字母填写在答题纸的相应位置上。) 1,结构化程序由三种基本结构组成,三种基本结构组成的算法是(A) A.可以完成任何复杂的任务 B.只能完成部分复杂的任务…

护眼台灯真的护眼吗?专业的学生护眼台灯推荐

最为家长&#xff0c;日常最关心的事情除了孩子的学习以外&#xff0c;就是视力健康问题。通过数据显示&#xff0c;在我国小学生人群中&#xff0c;每47人中就有一位近视&#xff0c;发病率约为23%。中学生约为55%,大学生约为76%,这个近视率是非常高的&#xff0c;因此很多家长…

C语言 内存操作函数 +内存分区

内存操作函数 memset() //memset 函数将指定内存区域 ptr 开始的 num 个字节设置为 value。 void *memset(void *ptr, int value, size_t num);参数&#xff1a;ptr&#xff1a;指向要填充的内存区域的指针。value&#xff1a;要填充的值&#xff0c;以整数形式传递。num&…

专题地图制作与布局编辑

一、实验名称&#xff1a; 专题地图制作与布局编辑 二、实验目的&#xff1a; 通过本实验练习&#xff0c;掌握ARCGIS专题地图制作与布局编辑。 三、实验内容和要求&#xff1a; 实验内容&#xff1a; 利用ARCGIS软件相关分析工具及实验数据&#xff0c;制作专题地图&…

MySQL索引_什么是索引_索引的分类_什么时候需要/不需要创建索引_优化索引_索引失效

文章目录 索引1. 什么是索引2. 索引的分类按数据结构分类按物理存储分类按字段特性分类按字段个数分类 3. 什么时候需要 / 不需要创建索引&#xff1f;什么时候适用索引&#xff1f;什么时候不需要创建索引&#xff1f; 4. 优化索引的方法前缀索引优化覆盖索引优化主键索引最好…

迅腾文化助力企业品牌创新,加快增强品牌发展新动能

迅腾文化助力企业品牌创新&#xff0c;加快增强品牌发展新动能 随着市场竞争的日益激烈&#xff0c;品牌创新已成为企业持续发展的关键。为了在市场中脱颖而出&#xff0c;许多企业纷纷寻求外部合作伙伴以加快品牌发展。广州迅腾文化传播有限公司拥有13年品宣经验的企业&#…

迪文屏图标控件保姆级教程

要主图的去末尾&#xff0c;末尾福利图在等着你~~~ 文章目录 前言 开发环境 二、使用步骤 1.添加图标控件 2.设置图标属性 3.图标库ICL文件生成 4.单片机程序编写 容易踩得坑 一、前言 本篇文章主要介绍了在DGBUS平台上使用图标变量的步骤。首先需要在DGBUS中添加一个图标变量控…

【教学类-35-07】正方形折纸上的学号描字帖(15*15CM1份)

背景需求&#xff1a; 尝试将加减法题目打印在手工纸上&#xff0c;写完书写题后&#xff0c;反面绘画&#xff0c;最后折纸。 用同样的思路&#xff0c;在15*15CM正方形手工纸上做一套幼儿学号描字帖 素材准备 WORD模板&#xff08;纸张长宽15*15CM&#xff0c;边距上下左右0&…

【源码解析】从Conditon角度聊聊AQS原理

前几篇文章&#xff0c;我们详细描述了线程池的原理以及核心代码&#xff0c;以及阻塞队列&#xff0c;ReentrantLock的核心流程&#xff0c;本篇主要介绍下lock锁中的condition 公平锁和非公平锁 public ReentrantLock() {sync new NonfairSync();}public ReentrantLock(boo…