Reverse 魔法入门第一关(新世界的规则)

2024-03-19 00:12

本文主要是介绍Reverse 魔法入门第一关(新世界的规则),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

如果你是逆向入门的选手,那恭喜你现在我们是一样的,我也没有任何这方面的天赋能力值,和我组队一起寻找这片大陆的最深领域吧。
在这里插入图片描述

第一章 欢迎来到异世界,Hacker

2024年3月18日

我穿越到的地方是一个叫做NSSCTF的城邦,这里收藏着各色各样的武功秘籍,奇人异士搭建了不同的工坊来训练入门弟子。这个世界里充斥着信息网,有些人会根据你的信息来锁定你的个人身份(例如家庭住址、电话号码、上学学校…),所以一个id是必须的,再开始之前想想你的名字吧。

作为穿越之子的我,必然有着不和他人一样的悟性,我切记实力是依存下去的根源。只可惜到这个世界的我也已成年,倘若我是婴儿时期。。。。。此处省略无数不实际的幻想。没事!作为主角,应该还有加持。

我摸索了很多,注册了一下身份信息
在这里插入图片描述
这里大部分都是免费试炼靶场,所以作为菜鸟又是穷鬼的我当然是白嫖普通靶场。
里面的靶场竟然这么多,我直接被震撼住了,如若我掌握了这些秘笈我不就能称霸整个大陆吗。功法的类型有多个方向,但我听说边上选职业的选手,说什么"得逆向者得天下”。我一听,这太适合我了,我要选就得选有难度的。
在这里插入图片描述
来吧,咱虽然信心足,但第一道还是来选个这个叫<<简简单单的解密>>,看看是什么实力。这里顺带提一手,idapro是免费武器(专门解逆向的)到<csdn>魔法商店问下领取方法就可以了。看到下载附件,看看里面是什么内容,什么情况,这不就是我前世没怎么学过的python语言吗,老天这简直戏耍我,我要转职业(我要当web手)。。。硬着头皮看,好枯燥的代码,这时候我想到了一个妙招,拿出前世我老师的秘诀:“好记性不如烂笔头”.我把每句话都进行注释一下就容易懂了,哈哈哈我太聪明了。
这里我给大家贴这了
题目

import base64,urllib.parse
key = "HereIsFlagggg"   #key是密钥
flag = "xxxxxxxxxxxxxxxxxxx" #暂时看不到,但我们要求的就是flag。s_box = list(range(256)) 	#创建一个名为 s_box 的列表,其中包含从 0 到 255 的数字。
j = 0
for i in range(256):		#从0到255j = (j + s_box[i] + ord(key[i % len(key)])) % 256 #s_box[i]=i,后面规律按位取key的ascill码。s_box[i], s_box[j] = s_box[j], s_box[i]           #交换
res = []
i = j = 0
for s in flag:                                        #取flag的每一位i = (i + 1) % 256j = (j + s_box[i]) % 256                          #根据i来取s_box[i]来决定js_box[i], s_box[j] = s_box[j], s_box[i]			  #交换t = (s_box[i] + s_box[j]) % 256					  k = s_box[t]res.append(chr(ord(s) ^ k))                        #存入转为对应异或过k的flag单位字符ASCII字符的
cipher = "".join(res)								   #连起来
crypt = (str(base64.b64encode(cipher.encode('utf-8')), 'utf-8')) #为了避免报错进行utf-8加解密
enc = str(base64.b64decode(crypt),'utf-8')
enc = urllib.parse.quote(enc)
print(enc)
# enc = %C2%A6n%C2%87Y%1Ag%3F%C2%A01.%C2%9C%C3%B7%C3%8A%02%C3%80%C2%92W%C3%8C%C3%BA

总体看下来,像是一种加密,有一个按序增长的数组,经过第一层密钥加密,第二层flag加密,已经知道解密后的字符。
我试着先把enc进行url解密成第二步后的密文.
enc = urllib.parse.unquote(enc)
再反过来求flag,但这里他加密的时候用了加密的s_box数组,所以我们要先求出原来的s_box。
剖析一下,最终i和j交换了位置,那我是不是把i和j交换回来就可以了?应该没错吧,但这j应该等于什么呢,
原来的i是按顺序的,j开始也是从0开始,我把j=0带入进去试试

j=0时,key[0]=H,对应ascii码值是72,那么j===>72
j=1时,key[1]=e,对应为101,那么j===>(72+1+101)=174
j=2时,key[2

怎么没找到规律,我不是主角吗,不是应该秒懂吗,什么情况。我这时候发现,试炼靶场后是有前辈留下的心得的,我马上就是学会了前人种树,后人乘凉。让我想到了高中老师说的,这就是那句至理名言:“抄着抄着就会了”.
在心得里我发现,原来密钥是加密s_box数组的作用,flag就用这个加密后的来进行加密,那么我们解决加密前的准备就是求出加密后的s_box数组,那这里加密的时候这个算法已经在这了,我们要的就是它

j=0
for i in range(256):		j = (j + s_box[i] + ord(key[i % len(key)])) % 256 s_box[i], s_box[j] = s_box[j], s_box[i]  

同样的代码再进行一遍就是需要的数组。再开始解密,这里看res收取的是异或后的数据,那这里我从心得里知道异或的技能只要你再发动一次异或就可以变为原来的,至于s这里没有变化过,k的值也是根据i和j来决定,i和j一直都是有规律的,那我们重新算一次,但这次加密的enc,加密就等于机密,重复一遍就好

res = []
i = j = 0
for s in flag:                                        #取flag的每一位i = (i + 1) % 256j = (j + s_box[i]) % 256                          #根据i来取s_box[i]来决定js_box[i], s_box[j] = s_box[j], s_box[i]			  #交换t = (s_box[i] + s_box[j]) % 256					  k = s_box[t]res.append(chr(ord(s) ^ k))  

这里的内循环就是
在这里插入图片描述
所以这里通过招式就是把enc放最前面加密一次

import base64,urllib.parse
key = "HereIsFlagggg"
enc = "%C2%A6n%C2%87Y%1Ag%3F%C2%A01.%C2%9C%C3%B7%C3%8A%02%C3%80%C2%92W%C3%8C%C3%BA"
enc = urllib.parse.unquote(enc)
print(enc)
s_box = list(range(256))
j = 0
for i in range(256):j = (j + s_box[i] + ord(key[i % len(key)])) % 256s_box[i], s_box[j] = s_box[j], s_box[i]
res = []
i = j = 0
for s in enc:i = (i + 1) % 256j = (j + s_box[i]) % 256s_box[i], s_box[j] = s_box[j], s_box[i]t = (s_box[i] + s_box[j]) % 256k = s_box[t]res.append(chr(ord(s) ^ k))
flag="".join(res)
print(flag)
# enc = %C2%A6n%C2%87Y%1Ag%3F%C2%A01.%C2%9C%C3%B7%C3%8A%02%C3%80%C2%92W%C3%8C%C3%BA

什么东西,就这么简单,以为有多难,我拿着flag去提交点,我以为会爆出什么惊天大奖励
只出现了一个提示显示完成。。。原来在这世界的人都叫做CTFer

在这里插入图片描述
完成了我的新世界首杀,我信心倍增,喊出小说里的口号:“这一辈子我要拿回属于我的一切”!非常中二。我马上找到第二个训练靶场.

第二章 这只是新生赛,孩子

进来一看,这对手实在太矮小了,我不由的笑出声,但我想着学下大佬,给进行注释一下
题目

flag = 'xxxxxxxxxxxxxxxxxx'
list = [47, 138, 127, 57, 117, 188, 51, 143, 17, 84, 42, 135, 76, 105, 28, 169, 25]
result = ''
for i in range(len(list)):key = (list[i]>>4)+((list[i] & 0xf)<<4)result += str(hex(ord(flag[i])^key))[2:].zfill(2)
print(result)
# result=bcfba4d0038d48bd4b00f82796d393dfec
(list[i]>>4): 这将list[i]的位向右移动4位,有效地分离了高4位。
((list[i] & 0xf)<<4): 这对list[i]和0xf(二进制中的00001111,有效地分离了低4位)进行按位与操作,然后将结果向左移动4位,有效地将低4位移到了高位。
result就是先进行异或再hex编码去掉前缀0x.

我们就是反过来,key的顺序没变所以还是一样,但result需要先进行int转为10进制,然后再异或key就可以了。

list = [47, 138, 127, 57, 117, 188, 51, 143, 17, 84, 42, 135, 76, 105, 28, 169, 25]
result='bcfba4d0038d48bd4b00f82796d393dfec'
flag=''
for i in range(len(list)):key = (list[i]>>4)+((list[i] & 0xf)<<4)flag += chr(int(("0x"+result[2*i:2*i+2]),16) ^key)
print(flag)

So easy,照这情况看起来我马上要几何倍增长经验了,我继续寻找第三个靶场,这次不同前两个,这次给了我一个程序让我破解,领的ida武器终于能用了,让我看看这武器杀伤力怎么样,看看使用方法,把文件直接拖入ida。
[SWPUCTF 2021 新生赛]PYRE
铺天盖地的函数出现在我面前,woc这就是逆向吗,这怎么做的了,我也没有系统啊。
在这里插入图片描述
该怎么办,只能看心得了,”查找main函数“,原来是这样。马上依葫芦画瓢。
crtl+f召唤搜索雷达,呃这这不是c语言吗.what can I say ? **** out 给挂科的男主角整这一手,可能换了世界我的c语言实力暴涨了100倍,我侥幸继续看看。发现点击函数是可以进去的,我就勉强研究下。
在这里插入图片描述
这时候我进去看了函数,我愈发觉得不太对劲,我好像意识到什么,看了看了逆向入门手册上的建言

养成习惯,不管它是啥,都先查壳

同样是新手大礼包里面可以领取的,这是一个查文件信息工具(EXeinfo PE),发现这是python写的程序
在这里插入图片描述
ida只能反编译c语言的,呃。。。至少用了下ida还算称手。

反编译的第一步是将exe文件转换成pyc文件,这里使用的是pyinstxtractor,项目地址:
https://github.com/countercept/python-exe-unpacker/blob/master/pyinstxtractor.py

详细教程
https://blog.csdn.net/m0_37552052/article/details/88093427

经过我的一系列操作,我折腾了两个多小时还是没有解决这个问题,甚至没用反编译成功。。我觉得先行放弃,以后再战。我变的有些疲惫,但我还是继续寻找新的靶场,但不能找到那些太复杂的,因为可能就会反噬,晋级的时候不能过于着急了,想到了大师傅说的一句名言,希望大家引以重视
在这里插入图片描述
为了避免这两种情况我打算先撤一步,感受下海阔天空。
就选这个了,[LitCTF 2023]enbase64,感觉可以,吃一堑长一智,先查一手是c语言
在这里插入图片描述
出来吧,idapro(32位的程序用die.exe看一下)!!进来时汇编语言,作为新手马上F5进行反编译,如果你要秀一把自己汇编水平也是可以的。
在这里插入图片描述
厉害的你肯定能看出来source是base64的码表,还有下面的字符串要求长度是刚好33位,有一个base64check我们进去看看什么门道。
在这里插入图片描述
是一个比较字符串,很明显后面这个就是密文了,Str1就是我们输入的数据经过处理的。那现在知道结果,反求输入,就要看看加密魔法是什么了。
在这里插入图片描述
看起来很复杂的样子,但没事同学们,记住它是base64加密就可以了,因为…没有为什么,你记住就行了。
在这里插入图片描述
这里知道密文,知道base64码表,就可以求原文了,但这里码表经过了变换
qmemcpy(&Source[1], &aAbcdefghijklmn[-(Source - &Source[1])], 4 * (((Source - &Source[1] + 65) & 0xFFFFFFFC) >> 2));

qmemcpy 是一个内存复制函数,类似于 memcpy,用于将内存块从一个位置复制到另一个位置。
&Source[1] 表示 Source 数组的第二个元素的地址。
&aAbcdefghijklmn[-(Source - &Source[1])] 是一个地址,这个地址的计算可能有些复杂,需要进一步解释:
(Source - &Source[1]) 计算了 Source 数组的地址和第二个元素的地址之间的偏移量。
aAbcdefghijklmn[-(Source - &Source[1])] 根据上述偏移量,从数组 aAbcdefghijklmn 中取得一个位置的地址。
4 * (((Source - &Source[1] + 65) & 0xFFFFFFFC) >> 2) 是复制的字节数。这个表达式的计算也比较复杂:
(Source - &Source[1] + 65) 计算了从第二个元素到 Source 数组之间的偏移量,并且加上 65。
& 0xFFFFFFFC 将结果向下舍入到最接近的能被 4 整除的数。
>> 2 将结果右移两位,相当于除以 4。
最终乘以 4,得到最终的字节数。
总的来说,这行代码的作用是将从 aAbcdefghijklmn 数组中某个位置开始的一段内存(长度由复杂的表达式计算得出)复制到 Source 数组的第二个元素之后的位置。

怎么样,懂了吗,我知道你不懂,不要不懂装懂,这里有一神奇的魔法武器可以解决这一情况。
动态调试
这里调试教程自己搜索一下吧
先找到base64函数这里,发现有一个换表,我们打一个断点先,再在result打一个
在这里插入图片描述
进去之后发现这里返回的result就是source粘贴过去,source又可以由v3得出,所以我们只要看destination变量的值就知道码表了

在这里插入图片描述
双击后看到栈上的值,拿到码表gJ1BRjQie/FIWhEslq7GxbnL26M4+HXUtcpmVTKaydOP38of5v90ZSwrkYzCAuND
拥有了这把钥匙我们就可以打开这扇门了
在这里插入图片描述
这里用一个替换技能,不会是肯定的,但总能从大佬那偷学点,自己当裁缝就可以拼接出来了。

from base64 import b64decodedef decode(s):old_table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='new_table = 'gJ1BRjQie/FIWhEslq7GxbnL26M4+HXUtcpmVTKaydOP38of5v90ZSwrkYzCAuND't=''for i in s:t+=old_table[new_table.index(i)]return  b64decode(t)
print(decode("GQTZlSqQXZ/ghxxwhju3hbuZ4wufWjujWrhYe7Rce7ju"))

经过这场训练,我终于学会了base64换表和基本动调这两项技能,但我的眼睛变得有点涩,腰有点疲劳,这就是变强的征兆,但不能一直练下去,要学会休息一下。
在这里插入图片描述

第三章 地锅鸡的力量

更新ing…

这篇关于Reverse 魔法入门第一关(新世界的规则)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/824153

相关文章

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

数论入门整理(updating)

一、gcd lcm 基础中的基础,一般用来处理计算第一步什么的,分数化简之类。 LL gcd(LL a, LL b) { return b ? gcd(b, a % b) : a; } <pre name="code" class="cpp">LL lcm(LL a, LL b){LL c = gcd(a, b);return a / c * b;} 例题:

Java 创建图形用户界面(GUI)入门指南(Swing库 JFrame 类)概述

概述 基本概念 Java Swing 的架构 Java Swing 是一个为 Java 设计的 GUI 工具包,是 JAVA 基础类的一部分,基于 Java AWT 构建,提供了一系列轻量级、可定制的图形用户界面(GUI)组件。 与 AWT 相比,Swing 提供了许多比 AWT 更好的屏幕显示元素,更加灵活和可定制,具有更好的跨平台性能。 组件和容器 Java Swing 提供了许多

【IPV6从入门到起飞】5-1 IPV6+Home Assistant(搭建基本环境)

【IPV6从入门到起飞】5-1 IPV6+Home Assistant #搭建基本环境 1 背景2 docker下载 hass3 创建容器4 浏览器访问 hass5 手机APP远程访问hass6 更多玩法 1 背景 既然电脑可以IPV6入站,手机流量可以访问IPV6网络的服务,为什么不在电脑搭建Home Assistant(hass),来控制你的设备呢?@智能家居 @万物互联

poj 2104 and hdu 2665 划分树模板入门题

题意: 给一个数组n(1e5)个数,给一个范围(fr, to, k),求这个范围中第k大的数。 解析: 划分树入门。 bing神的模板。 坑爹的地方是把-l 看成了-1........ 一直re。 代码: poj 2104: #include <iostream>#include <cstdio>#include <cstdlib>#include <al

MySQL-CRUD入门1

文章目录 认识配置文件client节点mysql节点mysqld节点 数据的添加(Create)添加一行数据添加多行数据两种添加数据的效率对比 数据的查询(Retrieve)全列查询指定列查询查询中带有表达式关于字面量关于as重命名 临时表引入distinct去重order by 排序关于NULL 认识配置文件 在我们的MySQL服务安装好了之后, 会有一个配置文件, 也就

音视频入门基础:WAV专题(10)——FFmpeg源码中计算WAV音频文件每个packet的pts、dts的实现

一、引言 从文章《音视频入门基础:WAV专题(6)——通过FFprobe显示WAV音频文件每个数据包的信息》中我们可以知道,通过FFprobe命令可以打印WAV音频文件每个packet(也称为数据包或多媒体包)的信息,这些信息包含该packet的pts、dts: 打印出来的“pts”实际是AVPacket结构体中的成员变量pts,是以AVStream->time_base为单位的显

C语言指针入门 《C语言非常道》

C语言指针入门 《C语言非常道》 作为一个程序员,我接触 C 语言有十年了。有的朋友让我推荐 C 语言的参考书,我不敢乱推荐,尤其是国内作者写的书,往往七拼八凑,漏洞百出。 但是,李忠老师的《C语言非常道》值得一读。对了,李老师有个官网,网址是: 李忠老师官网 最棒的是,有配套的教学视频,可以试看。 试看点这里 接下来言归正传,讲解指针。以下内容很多都参考了李忠老师的《C语言非

MySQL入门到精通

一、创建数据库 CREATE DATABASE 数据库名称; 如果数据库存在,则会提示报错。 二、选择数据库 USE 数据库名称; 三、创建数据表 CREATE TABLE 数据表名称; 四、MySQL数据类型 MySQL支持多种类型,大致可以分为三类:数值、日期/时间和字符串类型 4.1 数值类型 数值类型 类型大小用途INT4Bytes整数值FLOAT4By

【QT】基础入门学习

文章目录 浅析Qt应用程序的主函数使用qDebug()函数常用快捷键Qt 编码风格信号槽连接模型实现方案 信号和槽的工作机制Qt对象树机制 浅析Qt应用程序的主函数 #include "mywindow.h"#include <QApplication>// 程序的入口int main(int argc, char *argv[]){// argc是命令行参数个数,argv是