reversing.kr学习之路-ransomeware

ransomeware - writeup

题目来源 http://reversing.kr

题目知识点:upx + 花指令 + 堆栈不平衡 + exe特征码提取key

前言

文章只是记录一下自己在reversing.kr上学习CTF逆向的经历,如果文中出现什么技术错误,烦请各位大佬,在评论中指正。本人技术刚刚入门,菜鸟一枚,大佬勿喷啊~

正文

首先在网站上下载附件,得到一个zip,里面包含了一个txt、一个exe和一个file。根据txt里面的提示,可以得到exe为加密程序,file为加密后的文件,并且file在加密前应该是一个exe文件。
接下来我就对exe文件进行了分析,使用PEID进行查壳发现,该exe使用了UPX进行加壳,这里大家可以使用ESP定律进行手工脱壳,而我嫌弃麻烦,直接使用UPX工具进行了脱壳,结果如下图。

在经过脱壳之后,exe文件就可以使用IDA进一步分析,但是不巧的是,在对main函数进行反编译时,出现了情况。

是的,你没看错,IDA意思是:“这个函数太大了,劳资分析不了”。
what?还有这种操作?作为一位菜鸟,还真是第一次看到IDA报这种错误。既然分析不了,那就去看看main函数的汇编代码吧。

好吧,出题人,!#@&%……#%,你开心就好啦!在main函数里面充斥了0x37195的无用代码,也可以称之为花指令,反正就是阻止IDA对其进行反编译。这里有两个思路,第一呢,使用nop指令,将大小为0x37195的指令进行替换,但是我没有选择这么做,我使用第二种方法,把main函数的起始地址进行了重新指定。既然我已经知道0x37195的数据全部是无用的,那我直接选择跳过去。如何改函数的起始地址?看下图。在IDA的function window中右键点击你想要改的函数,选择edit function就好。然后在start address填入你想要让函数起始的地址。这里是0044a775地址。

然后你是不是以为就可以F5大法了,不存在的大兄弟,你都把人家函数起始地址给改了,最后函数的堆栈极有可能是不平衡的。这不,果然是。

这里呢,就直接去调堆栈,让其平衡就好。option -> General... -> Stack pointer。然后就出现了下图中红色方框中的标识。

然后我们根据IDA报错中提到的地址,将其retn指令前面的数据调节至0即可实现堆栈平衡。这里调节,需要找距离其最近的call指令,如图中箭头所指。将光标放置在该指令上,使用快捷键alt+k

通过改变箭头指向的数值,将retn指令前面的数值调整为0。这里我好像用的是-0x34。然后就可以进行F5了。

好了,上面就是分析了,感觉很简单,但是,仔细想了一下,这个key值是出题人输入的,原始数据我们也没有,我们只有加密后的数据。这怎么实现逆向操作。那么小技巧来了?(圈起来,要考!)。相信大家都使用hex工具查看过exe文件。会发现,每个exe中都存在一个共同点。

上图中红框大家是不是很熟悉?那么这个题就根据这个来突破。exe中的这个数据位置是固定的,也就是说根据一个普通的exe文件该段数据的定位,我们可以找到加密后该段数据对应的密文数据。如下图。

如果我们用来加密的key值,并不是很长,在加密这段数据时发生了重复,那么我们就可以获取完整的key。我们直接取加密后的文件对应位置的16进制,进行异或操作。不多说了,用python跑了。

st1 = [0x54,0x68,0x69,0x73,0x20,0x70,0x72,0x6F,0x67,0x72,0x61,0x6D,0x20,0x63,0x61,0x6E,0x6E,0x6F,0x74,0x20,0x62,0x65,0x20,0x72,0x75,0x6E,0x20,0x69,0x6E,0x20,0x44,0x4F,0x53,0x20,0x6D,0x6F,0x64,0x65]
st2 = [0xC7,0xF2,0xE2,0xFF,0xAF,0xE3,0xEC,0xE9,0xFB,0xE5,0xFB,0xE1,0xAC,0xF0,0xFB,0xE5,0xE2,0xE0,0xE7,0xBE,0xE4,0xF9,0xB7,0xE8,0xF9,0xE2,0xB3,0xF3,0xE5,0xAC,0xCB,0xDC,0xCD,0xA6,0xF1,0xF8,0xFE,0xE9]
for i in range(len(st1)):
    print chr((~st2[i] ^ st1[i]) % 256),

得出用户输入的key为letsplaychess。使用key对加密后的文件进行解密操作。脚本如下。

key = "letsplaychess"
f = open("./ransomware/file","rb")
data = f.read()
fr = open("./ransomware/file.exe", "wb")
for i in range(len(data)):
    fr.write(chr(ord(data[i]) ^ 0xFF ^ ord(key[i % len(key)]) % 256)) #小技巧,在进行取反的逆运算时,可以使用~,也可使用 ^ 0xFF
f.close()
fr.close()

最终得到加密前的exe文件。然后我本来想着运行就可以得到flag。但是缺少dll文件,我嫌弃下载太麻烦,就把生成的文件拖进IDA进行分析来着。结果又加了UPX的壳。行吧,我忍,脱壳,分析拿到flag。

后记

这道题目,其实仔细分析下来,并不是很难的一个题目,但是涉及的知识点还是可以的,如果再讲算法设计复杂一下,估计会更恶心。不过通过本道题目,我真是学习到了一些东西。
1、通过改函数起始地址,绕过花指令。
2、堆栈平衡。
3、exe文件中的特征值(应该不算exe的特征值吧,先这么叫着。哈哈),猜解key。

纯属个人学习经历,真的是很菜的知识。希望大家路过觉得可以,就留下来看看。感谢!

原文地址:https://www.cnblogs.com/0x1633/p/11364930.html

时间: 2024-10-11 01:29:27

reversing.kr学习之路-ransomeware的相关文章

Reversing.Kr writeup

Reserving.Kr writeupEasy CrackEasy KeygenReplaceEasy_ELF Reversing.Kr writeup 这个网站http://reversing.kr 学习逆向很不错.各个平台的逆向都有,最近在慢慢的刷这些题 Easy Crack 看名字就知道很简单,PEID查壳,拖入OD,找到关键代码 0040109B|.8B7C2470 mov edi,dword ptr ss:[esp+0x70];|user32.76D1D2B3 0040109F|.8

Azure云平台学习之路(三)——Cloud Services

1.什么是云服务? 能够部署高度可用的且可无限缩放的应用程序和API.简而言之,就是你写的CMD程序按照一定的框架进行少量修改就能运行在Azure云平台上. 2.Azure云服务有什么特点? (1)专注应用程序而不是硬件,PaaS的一种. (2)支持多种框架和语言. (3)集成了运行状况监视和负载平衡. (4)自动缩放优化成本和性能 3.建立云服务之前,我们需要建立一个云存储,来记录我们的程序的日志信息(当然,这不是必须的) (1)选择左边导航栏的"存储".主面板上显示的是所有已有的存

linux学习之路之LVM

试想一种情况,当初我们在规划磁盘的时候,只给某一个磁盘或分区之划分了30G的容量,但是后来,随着业务的需求,该磁盘或者分区的使用量会越来越大,等到以后再有数据存放时,发现该磁盘或者分区的容量不够用,此时该怎么办了?可以新增一个磁盘,经过格式化,挂载等过程就可以使用这个磁盘了,再将原来磁盘的数据完全的复制过来.等到后来又发现,规划的磁盘又太大了,然后又使用上述方法来减少磁盘的大小.虽然这种方法可行,但是效率低,比较复杂.不应该是我们首选的方法. 当然,我们可以这样做,将多个磁盘或者分区(PV)组合

我的算法学习之路

关于 严格来说,本文题目应该是我的数据结构和算法学习之路,但这个写法实在太绕口--况且CS中的算法往往暗指数据结构和算法(例如算法导论指的实际上是数据结构和算法导论),所以我认为本文题目是合理的. 这篇文章讲了什么? 我这些年学习数据结构和算法的总结. 一些不错的算法书籍和教程. 算法的重要性. 初学 第一次接触数据结构是在大二下学期的数据结构课程.然而这门课程并没有让我入门--当时自己正忙于倒卖各种MP3和耳机,对于这些课程根本就不屑一顾--反正最后考试划个重点也能过,于是这门整个计算机专业本

一个女大学生的代码学习之路(二)

首先说一下,写这种文章是由于我在四月四日晚上,在手动搭建自己的第一个ssh项目的时候,遇到了一个配置的问题,怎么解决也弄不好,当时是四号晚上九点,我看了一眼表,我就想两个小时之内,我要是能搞定就算行了,但是其实,我搞到三点才OK(凌晨),那时候已经是五号了,转天是一家子去扫墓的时候,结果我居然以这种一个理由没有去,理由是我太累了么?我只是就是搭了一个架子,就是由于我的包太混乱了,导致不兼容,所以tomcat总也不启动,你可能认为好笑,这么简单一个问题怎么就费这多多时间呢,但是作为一个刚接触三框架

kafka学习之路(二)——提高

kafka学习之路(二)--提高 消息发送流程 因为Kafka内在就是分布式的,一个Kafka集群通常包括多个代理.为了均衡负载,将话题分成多个分区,每个代理存储一或多个分区.多个生产者和消费者能够同时生产和获取消息.     过程: 1.Producer根据指定的partition方法(round-robin.hash等),将消息发布到指定topic的partition里面 2.kafka集群接收到Producer发过来的消息后,将其持久化到硬盘,并保留消息指定时长(可配置),而不关注消息是否

Android开发学习之路--网络编程之xml、json

一般网络数据通过http来get,post,那么其中的数据不可能杂乱无章,比如我要post一段数据,肯定是要有一定的格式,协议的.常用的就是xml和json了.在此先要搭建个简单的服务器吧,首先呢下载xampp,然后安装之类的就不再多讲了,参考http://cnbin.github.io/blog/2015/06/05/mac-an-zhuang-he-shi-yong-xampp/.安装好后,启动xampp,之后在浏览器输入localhost或者127.0.0.1就可以看到如下所示了: 这个就

Qt学习之路

  Qt学习之路_14(简易音乐播放器) Qt学习之路_13(简易俄罗斯方块) Qt学习之路_12(简易数据管理系统) Qt学习之路_11(简易多文档编辑器) Qt学习之路_10(Qt中statusBar,MessageBox和Timer的简单处理) Qt学习之路_9(Qt中Item Widget初步探索) Qt学习之路_8(Qt中与文件目录相关操作) Qt学习之路_7(线性布局和网格布局初步探索) Qt学习之路_6(Qt局域网聊天软件) Qt学习之路_5(Qt TCP的初步使用) Qt学习之路

Java学习之路(二)--Thinking in Java

针对昨天Java学习之路(一)--Thinking in Java中的类的静态方法不能访问创建非静态类,给出了将内部类修改成为static静态类,操作方便简单.现在给出第二种不需要添加删除的另一种极为高效的方式.可以将内部类从你所创建的类中复制粘贴到类外,作为一个外部类,在static主方法中就可以创建类的引用了. 源代码如下: ? class test{ int s; char c; } public class test1 { public static class test{ int s;