一个入门级CTF的Reverse
这道题是XCTF攻防世界上的一道新手入门题目!
年前刚接触逆向时IDA,OD了这些工具都不会用(负基础),当时做这些题的时候觉得挺难(主要是缺少练习,没思路无从下手)。现在回头再来看这些题目感觉确实是入门级的题目,所以逆向是门艺术更是门技术,需要多练习熟悉工具和掌握一些技巧,下面就来分析一下这道题目。
题目给了一个附件是一个exe的可执行文件,那好我们先来执行一下他好了!
结果出来一大堆英文,奈何本人英文真的很菜,高考40分:),浑身发憷,不怕手机自带拍照翻译,虽然翻译的水平很一般但是磕磕绊绊的还是能明白他什么意思:
这是个游戏(游戏规则:把那几个图形都看成灯,当其都亮时,也就是图形变成实心的游戏胜利),你必须把这个游戏过了之后才会得到我们想要的flag。 我们是要通过工具来获得这个flag,当然如果你玩游戏很nb的话你也可以通关他获得flag。
好废话不多说我们现在就来寻找flag!
1. 我们先用PEID分析一下程序的基本信息
可以看到检测到其未压缩,说明此程序无壳。下面我们可以选择用静态分析工具IDA来分析程序,也可以选用动态调试工具Ollydbg。
我们先用IDA来分析吧,因为此程序为32位的所以我们用32位的IDA打开程序。
- 我们按Ctrl + E弹出入口函数的信息,点击确定进入入口函数。因为此程序是一个控制台程序,所以我们需要找到main函数(处理逻辑在main函数里)。
进入start函数后我们就可以利用IDA一个强大插件的功能:把反汇编指令转化为C语言式的伪代码,这样我们方便寻找main函数。一般经过IDA的处理后都会显示出main函数的函数名,这种情况我们就可以直接通过寻找main函数名来寻找main函数。
但是有的程序在编译时,进行一些设置后IDA无法显示出main函数的函数名,这时我们就不能直接通过查找main函数名来寻找main函数,我们需要通过代码特征进行定位main函数,因为main()结束后会调用exit()函数来退出进程,所以我们只要找到exit函数,那么在其上方的函数就是main函数(也有可能是在这个上方函数的函数才是main函数)。
这个程序我们找到了exit函数,其上方有个invoke_main()函数,那么此函数应该为main函数(或者main函数在其内部),双击此函数进入函数内部。果然main函数在此函数内部,我们在双击进入main函数最里层,查看main函数的逻辑代码。我们对main函数中的逻辑代码进行分析看flag是怎么产生的。往下查看代码发现一处判断,正好像是判断那几盏灯是否都亮的逻辑,当这几盏灯都亮(也就是其值都为1)时,调用Sub_457Ab4( )函数,此函数应该就是flag产生的代码。
我们双击进入sub_457AB4()其处理代码为:
int sub_45E940()
{
signed int i; // [esp+D0h] [ebp-94h]
char v2; // [esp+DCh] [ebp-88h]
char v3; // [esp+DDh] [ebp-87h]
char v4; // [esp+DEh] [ebp-86h]
char v5; // [esp+DFh] [ebp-85h]
char v6; // [esp+E0h] [ebp-84h]
char v7; // [esp+E1h] [ebp-83h]
char v8; // [esp+E2h] [ebp-82h]
char v9; // [esp+E3h] [ebp-81h]
char v10; // [esp+E4h] [ebp-80h]
char v11; // [esp+E5h] [ebp-7Fh]
char v12; // [esp+E6h] [ebp-7Eh]
char v13; // [esp+E7h] [ebp-7Dh]
char v14; // [esp+E8h] [ebp-7Ch]
char v15; // [esp+E9h] [ebp-7Bh]
char v16; // [esp+EAh] [ebp-7Ah]
char v17; // [esp+EBh] [ebp-79h]
char v18; // [esp+ECh] [ebp-78h]
char v19; // [esp+EDh] [ebp-77h]
char v20; // [esp+EEh] [ebp-76h]
char v21; // [esp+EFh] [ebp-75h]
char v22; // [esp+F0h] [ebp-74h]
char v23; // [esp+F1h] [ebp-73h]
char v24; // [esp+F2h] [ebp-72h]
char v25; // [esp+F3h] [ebp-71h]
char v26; // [esp+F4h] [ebp-70h]
char v27; // [esp+F5h] [ebp-6Fh]
char v28; // [esp+F6h] [ebp-6Eh]
char v29; // [esp+F7h] [ebp-6Dh]
char v30; // [esp+F8h] [ebp-6Ch]
char v31; // [esp+F9h] [ebp-6Bh]
char v32; // [esp+FAh] [ebp-6Ah]
char v33; // [esp+FBh] [ebp-69h]
char v34; // [esp+FCh] [ebp-68h]
char v35; // [esp+FDh] [ebp-67h]
char v36; // [esp+FEh] [ebp-66h]
char v37; // [esp+FFh] [ebp-65h]
char v38; // [esp+100h] [ebp-64h]
char v39; // [esp+101h] [ebp-63h]
char v40; // [esp+102h] [ebp-62h]
char v41; // [esp+103h] [ebp-61h]
char v42; // [esp+104h] [ebp-60h]
char v43; // [esp+105h] [ebp-5Fh]
char v44; // [esp+106h] [ebp-5Eh]
char v45; // [esp+107h] [ebp-5Dh]
char v46; // [esp+108h] [ebp-5Ch]
char v47; // [esp+109h] [ebp-5Bh]
char v48; // [esp+10Ah] [ebp-5Ah]
char v49; // [esp+10Bh] [ebp-59h]
char v50; // [esp+10Ch] [ebp-58h]
char v51; // [esp+10Dh] [ebp-57h]
char v52; // [esp+10Eh] [ebp-56h]
char v53; // [esp+10Fh] [ebp-55h]
char v54; // [esp+110h] [ebp-54h]
char v55; // [esp+111h] [ebp-53h]
char v56; // [esp+112h] [ebp-52h]
char v57; // [esp+113h] [ebp-51h]
char v58; // [esp+114h] [ebp-50h]
char v59; // [esp+120h] [ebp-44h]
char v60; // [esp+121h] [ebp-43h]
char v61; // [esp+122h] [ebp-42h]
char v62; // [esp+123h] [ebp-41h]
char v63; // [esp+124h] [ebp-40h]
char v64; // [esp+125h] [ebp-3Fh]
char v65; // [esp+126h] [ebp-3Eh]
char v66; // [esp+127h] [ebp-3Dh]
char v67; // [esp+128h] [ebp-3Ch]
char v68; // [esp+129h] [ebp-3Bh]
char v69; // [esp+12Ah] [ebp-3Ah]
char v70; // [esp+12Bh] [ebp-39h]
char v71; // [esp+12Ch] [ebp-38h]
char v72; // [esp+12Dh] [ebp-37h]
char v73; // [esp+12Eh] [ebp-36h]
char v74; // [esp+12Fh] [ebp-35h]
char v75; // [esp+130h] [ebp-34h]
char v76; // [esp+131h] [ebp-33h]
char v77; // [esp+132h] [ebp-32h]
char v78; // [esp+133h] [ebp-31h]
char v79; // [esp+134h] [ebp-30h]
char v80; // [esp+135h] [ebp-2Fh]
char v81; // [esp+136h] [ebp-2Eh]
char v82; // [esp+137h] [ebp-2Dh]
char v83; // [esp+138h] [ebp-2Ch]
char v84; // [esp+139h] [ebp-2Bh]
char v85; // [esp+13Ah] [ebp-2Ah]
char v86; // [esp+13Bh] [ebp-29h]
char v87; // [esp+13Ch] [ebp-28h]
char v88; // [esp+13Dh] [ebp-27h]
char v89; // [esp+13Eh] [ebp-26h]
char v90; // [esp+13Fh] [ebp-25h]
char v91; // [esp+140h] [ebp-24h]
char v92; // [esp+141h] [ebp-23h]
char v93; // [esp+142h] [ebp-22h]
char v94; // [esp+143h] [ebp-21h]
char v95; // [esp+144h] [ebp-20h]
char v96; // [esp+145h] [ebp-1Fh]
char v97; // [esp+146h] [ebp-1Eh]
char v98; // [esp+147h] [ebp-1Dh]
char v99; // [esp+148h] [ebp-1Ch]
char v100; // [esp+149h] [ebp-1Bh]
char v101; // [esp+14Ah] [ebp-1Ah]
char v102; // [esp+14Bh] [ebp-19h]
char v103; // [esp+14Ch] [ebp-18h]
char v104; // [esp+14Dh] [ebp-17h]
char v105; // [esp+14Eh] [ebp-16h]
char v106; // [esp+14Fh] [ebp-15h]
char v107; // [esp+150h] [ebp-14h]
char v108; // [esp+151h] [ebp-13h]
char v109; // [esp+152h] [ebp-12h]
char v110; // [esp+153h] [ebp-11h]
char v111; // [esp+154h] [ebp-10h]
char v112; // [esp+155h] [ebp-Fh]
char v113; // [esp+156h] [ebp-Eh]
char v114; // [esp+157h] [ebp-Dh]
char v115; // [esp+158h] [ebp-Ch]
sub_45A7BE("done!!! the flag is ");
v59 = 18;
v60 = 64;
v61 = 98;
v62 = 5;
v63 = 2;
v64 = 4;
v65 = 6;
v66 = 3;
v67 = 6;
v68 = 48;
v69 = 49;
v70 = 65;
v71 = 32;
v72 = 12;
v73 = 48;
v74 = 65;
v75 = 31;
v76 = 78;
v77 = 62;
v78 = 32;
v79 = 49;
v80 = 32;
v81 = 1;
v82 = 57;
v83 = 96;
v84 = 3;
v85 = 21;
v86 = 9;
v87 = 4;
v88 = 62;
v89 = 3;
v90 = 5;
v91 = 4;
v92 = 1;
v93 = 2;
v94 = 3;
v95 = 44;
v96 = 65;
v97 = 78;
v98 = 32;
v99 = 16;
v100 = 97;
v101 = 54;
v102 = 16;
v103 = 44;
v104 = 52;
v105 = 32;
v106 = 64;
v107 = 89;
v108 = 45;
v109 = 32;
v110 = 65;
v111 = 15;
v112 = 34;
v113 = 18;
v114 = 16;
v115 = 0;
v2 = 123;
v3 = 32;
v4 = 18;
v5 = 98;
v6 = 119;
v7 = 108;
v8 = 65;
v9 = 41;
v10 = 124;
v11 = 80;
v12 = 125;
v13 = 38;
v14 = 124;
v15 = 111;
v16 = 74;
v17 = 49;
v18 = 83;
v19 = 108;
v20 = 94;
v21 = 108;
v22 = 84;
v23 = 6;
v24 = 96;
v25 = 83;
v26 = 44;
v27 = 121;
v28 = 104;
v29 = 110;
v30 = 32;
v31 = 95;
v32 = 117;
v33 = 101;
v34 = 99;
v35 = 123;
v36 = 127;
v37 = 119;
v38 = 96;
v39 = 48;
v40 = 107;
v41 = 71;
v42 = 92;
v43 = 29;
v44 = 81;
v45 = 107;
v46 = 90;
v47 = 85;
v48 = 64;
v49 = 12;
v50 = 43;
v51 = 76;
v52 = 86;
v53 = 13;
v54 = 114;
v55 = 1;
v56 = 117;
v57 = 126;
v58 = 0;
for ( i = 0; i < 56; ++i )
{
*(&v2 + i) ^= *(&v59 + i);
*(&v2 + i) ^= 0x13u;
}
return sub_45A7BE("%s\n");
}
其是将V2 - V57与 V59 - V114的字符分别异或之后再与0x13u异或后,得到的字符串就为flag
注意此代码不能直接复制粘贴到进行使用,因为其默认V2 - V115的变量是连续存储的(即地址是连续的),而实际其会因为字节对齐而不连续存储,所以要自己写代码的到flag。
下面是我用c++写的代码(python语法都忘光了!)。
#include <iostream>
using namespace std;
int main()
{
char a[] = {123, 32, 18, 98, 119, 108, 65, 41, 124,80,125,38, 124,111,74, 49, 83, 108,94,
108, 84, 6, 96, 83, 44, 121,104,110,32,95, 117,101, 99,123,127,119,96, 48,
107, 71, 92, 29, 81, 107, 90, 85, 64, 12,43, 76, 86, 13, 114,1, 117,126,0,
18, 64, 98, 5, 2, 4, 6, 3, 6, 48,49, 65, 32, 12, 48, 65, 31, 78, 62,
32, 49, 32, 1, 57, 96, 3, 21, 9, 4, 62, 3, 5, 4, 1, 2, 3, 44, 65,
78, 32, 16, 97, 54, 16, 44, 52, 32, 64,89, 45, 32, 65, 15, 34, 18, 16, 0 };
cout<<"done!!! the flag is: ";
for (int i = 0; i < 56; ++i )
{
a[i] = a[i] ^ a[i+57];
a[i] = a[i] ^ 0x13u;
cout<<a[i];
}
return 0;
}
flag为zsctf{T9is_tOpic_1s_v5ry_int7resting_b6t_others_are_n0t}
下面我们用Ollydbg来分析这道题:
打开OD运行这个程序,其会停在入口处,然后我们点击鼠标右键-》中文搜索引擎-》智能搜索。会弹出所有字符串的信息!我们会发现this is a flag:字符串(说明字符串是在此处产生的),我们双击此字符串进入此代码块。
进入代码块后我们往下查看代码,我们发现%s/n字符串作为参数传给一个函数,所以此函数应该为printf函数,eax为显示字符串的指针。(此字符串就是flag)
上方代码应为flag的处理代码。
我们要获得flag就必须执行这块代码,所以我们在其flag的处理代码块的第一条指令处右击鼠标-》点击设置为新eip,在printf函数的入口参数处下断点,然后运行程序。
当程序到达断点处是会停止运行,因为断点处为printf函数处,而eax为所显示flag字符串的指针所以我们在OD右上角的寄存器窗口中可以看到flag。
一个入门级CTF的Reverse的更多相关文章
- Daily,一个入门级的 React Native 应用
Daily,一个React-Native写的android app. 下拉刷新获取:图片.诗句.言语.音乐.乐评.雨声.知乎日报.历史上的今天. 可以说是一个入门级的React-Native应用. 项 ...
- 如何实现shell并发 一个入门级可控多线程shell脚本方案
如何实现shell并发 很多人都问我如何写shell脚本,如何实现同时给三台ftp服务器上传文件,如何同时检测三台服务器是否alive等,其实这就是想实现shell的并发.那么shell并 ...
- 写一个小CTF平台
0x00.前言 协会要举办信息安全大赛了,初赛的web+crypto+misc主要由我来出题,注册.比赛的平台也都要由我来写 上周日完成了注册页面的后端(前端由另一个女生写的),前天下午大概完成 ...
- 如何开始你的CTF比赛之旅-网站安全-
在过去的两个星期里,我已经在DEFCON 22 CTF里检测出了两个不同的问题:“shitsco ”和“ nonameyet ”.感谢所有 的意见和评论,我遇到的最常见的问题是:“我怎么才能在CTFs ...
- CTF各种资源:题目、工具、资料
目录 题目汇总 Reverse 签到题 Web Web中等难度 Crypto 基础网站 各类工具 综合 Web Payloads 逆向 Pwn 取证 题目汇总 这里收集了我做过的CTF题目 Rever ...
- scala 对一个数组分组操作
通常我们有一些需求,对一个数组两两进行翻转,通常就涉及到奇数偶数,否则就会出现数组index异常了,所以我们该怎么办呢? 虽然是一个入门级问题,但是我还是觉得这是一个很有意思的题目,因此写了一个对于通 ...
- 放养的小爬虫--豆瓣电影入门级爬虫(mongodb使用教程~)
放养的小爬虫--豆瓣电影入门级爬虫(mongodb使用教程~) 笔者声明:只用于学习交流,不用于其他途径.源代码已上传github.githu地址:https://github.com/Erma-Wa ...
- [Liferay6.2]Liferay入门级portlet开发示例
什么是Portlet 来自百度百科(http://baike.baidu.com/view/58961.htm)的定义如下: portlet是基于java的web组件,处理request并产生动态内容 ...
- MVC + EF + Bootstrap 2 权限管理系统入门级(附源码)
MVC .EF 学习有大半年了,用的还不是很熟练,正好以做这样一个简单的权限管理系统作为学习的切入点,还是非常合适的. 开发环境: VS 2013 + Git + MVC 5 + EF 6 Code ...
随机推荐
- 安全计算环境之剩余信息保护-windows
参考https://blog.csdn.net/ubjewen/article/details/107587951 应保证鉴别信息所在的存储空间被释放或重新分配前得到完全清除 交互式登录: 之前登录到 ...
- Linux 自定义快捷命令
Linux中一些比较常用的命令总是重复敲很麻烦,这个时候就可以使用 alias 来自定义快捷命令,用以简化操作.系统会有一些预定义的快捷命令,比如 ll 的效果就和 ls -l 一样. 可以使用 al ...
- A Color Game
题目大意: 给定一个只包含七种字母的字符串,如果满足一段连续相同的字符长度大于等于K那么即可消除,问最后能不能变为空字符. 题解:很明显是用区间dp来解决,我们设dp[l][r][k]代表的是在[l ...
- 如何获取占用U盘的进程
依次打开开始---所有程序---附件---系统工具---资源监视器. 打开CPU标签栏,在"关联的句柄"中的搜索框中输入U盘的盘符,如G: 按回车搜索即可出结果. 在搜索结果中右键 ...
- Etcd常用运维命令
目录 常用命令 常见操作 如何缩容? 如何扩容? 数据目录丢失或被误删除,节点启动失败或者加入集群报错? 操作步骤 操作步骤不正确的各种常见错误日志 常用命令 #查看集群member情况 etcdct ...
- 201871010129-郑文潇 实验三 结对项目—《D{0-1}KP 实例数据集算法实验平台》项目报告
项目 内容 课程班级博客 https://edu.cnblogs.com/campus/xbsf/2018CST 这个作业要求链接 https://www.cnblogs.com/nwnu-daizh ...
- (七)Struts2Action访问Servlet API
第一种方式: Struts2提供了一个ServletActionContext对象可以访问ServletAPI. 例如 HttpServletRequest request=ServletAction ...
- Recoil Input 光标位置被重置到末尾的问题
考察如下代码,页面中有个输入框,通过 Recoil Atom 来存储输入的值. App.tsx function NameInput() { const [name, setName] = useRe ...
- ubuntu16.04 安装opencv3.4.0
参考 https://www.cnblogs.com/arkenstone/p/6490017.html https://blog.csdn.net/u013180339/article/detail ...
- Leedcode算法专题训练(链表)
1.发现两个链表的交点 160.两个链表的交集(容易) Leetcode /力扣 public class Solution { public ListNode getIntersectionNode ...