前言
这篇文章是我做完攻防世界练习区的题目后对这十道题做的总结。emmm,其实这几道题我几个月前就做完了,这几天又回去试着再做一遍发现还是有一些地方存在疑惑,并且速度也没有太大的提升。所以决定把之前做过的题目整理一下都写在博客里,便于以后复习顺便把一些我没搞懂的地方也记录在这里,希望以后可以解决。也希望能有大佬有缘看到我这个小菜鸟的文章,可以帮我指点迷津。
这一篇只写攻防世界新手区的几道题,之后我还会把BUUCTF做的题也做个总结,写一篇博客,希望可以把这个习惯保持下去。说了这么多废话,下面开始正文。

第一题:open-source

首先把附件下载下来,在exeinfope里查壳(虽然第一道题基本上没有加壳的可能性,但我觉得这是个很好的习惯) 可见这个文件没有加壳。这个文件的后缀是.c,所以直接在IDE里打开,这里我用的是DEVC++
#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[]) {
if (argc != 4) {
printf(“what?\n”);
exit(1);
}

unsigned int first = atoi(argv[1]);
if (first != 0xcafe) {printf("you are wrong, sorry.\n");exit(2);
}unsigned int second = atoi(argv[2]);
if (second % 5 == 3 || second % 17 != 8) {printf("ha, you won't get it!\n");exit(3);
}if (strcmp("h4cky0u", argv[3])) {printf("so close, dude!\n");exit(4);
}printf("Brr wrrr grr\n");unsigned int hash = first * 31337 + (second % 17) * 11 + strlen(argv[3]) - 1615810207;printf("Get your key: ");
printf("%x\n", hash);
return 0;

}`
由最后的两个printf语句可以看出flag就是hash,由%x可以看出是十六进制表示。
所以向上看对hash进行运算的只有

 unsigned int hash = first * 31337 + (second % 17) * 11 + strlen(argv[3]) - 1615810207;

可知hash的值与first,second,argv[3]的值有关,从上面的3个if语句可以判断出:当if()里的条件为真时,都会提示错误并退出程序,所以3个if()里的条件都为假,所以可以推测出下列条件;first=0xcafe,second % 5 != 3&&second % 17 == 8(最小的second是25),argv[3]=h4cky0u(所以strlen(argv[3])=7)。将上述条件带入计算hash的那段代码可以得出hash,下面是我写的代码`#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
int first=0xcafe;
int second=25;
int a=7;

int hash=0;
hash=first * 31337 + (second % 17) * 11 + 7 - 1615810207;printf("%x",hash);
return 0;

}`
结果是
所以flag就是c0ffee。
第一题拿下!

第二题:simple-unpack

由题目描述可以看出这是一个加壳的文件,所以先拖到exeinfope里查壳


可以看出加了UPX这一类壳。所谓加壳就是为了隐藏程序真正的OEP(入口点),所以为了正常地打开程序使程序正常运行,我们必须脱壳。我选择的是用upx脱壳。

脱壳成功!关于upx脱壳我之前看到一篇博客讲得挺详细的,我把超链接放在下面。
使用upx脱壳工具脱壳
脱壳结束后再把脱壳后的文件放在exeinfope里看一下。

可以看到现在已经没有UPX壳了,之后把文件拉到IDA里打开。


按F5反汇编后发现flag相当可疑,双击flag追踪过去看到

发现了flag{Upx_1s_n0t_a_d3liv3r_c0mp4ny}。
第二题拿下!

第三题:logmein

下载附件后老规矩拿到exeinfope里查壳,


发现没壳,而且是64位的文件,所以放到IDA64里静态分析。ctrl+f搜索main函数,再按F5反汇编,如图


双击sub_4007F0看到


说明输入正确的flag会让程序输出上述printf的一句话并退出。
再双击sub_4007C0看到


所以当输入错误的flag时会使程序输出上述一句话并退出。
所以不能让程序运行sub_4007C0这个函数,所以*s[i] = (char)(*((_BYTE )&v7 + i % v6) ^ v8[i])
必须成立。去上面的代码找到v7,v6,v8[]


看出v6=7 , v8[]=:"AL_RT^L*.?+6/46 , v7=28537194573619560LL,将28537194573619560LL转换成字符,如图
因为IDA是小段法存储,所以真正的v7应该是ebmarah倒过来变成harambe。下面是我写的解题代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>int main()
{char v8[50]=":\"AL_RT^L*.?+6/46";char v7[50]="harambe";int v6 =7;char flag[50];for ( int i = 0; i < strlen(v8); ++i ){flag[i] = (char)(*((unsigned char*)&v7 + i % v6) ^ v8[i]) ;}printf("%s",flag);return 0;
}

结果为


第三题拿下!

第四题:insanity

老规矩先把附件下载后放在exeinfope里查壳


看出文件无壳且是32位的,用IDA打开


发现整段代码没有什么运算,感觉&strs有点可疑,双击进去


发现9447{This_is_a_flag}…感觉简单得有点过分

又去字符串窗口看了一下

flag确实就是这个了(难道这才是第一题?)

第五题:python-trade

老规矩查壳


无壳是用python写的。发现IDA打开之后无法反汇编,所以当时我去找了一些博客,发现是要用python反汇编,这里我用的是在线Python反汇编,超链接我放在下面。

在线Python反编译工具

推测出当flag在encode函数中加密后与correct相等就成功。


由这一段看出将correct通过base64解码后,经过xor异或可以再得出原来的flag。
下面是我写的解题代码

import base64correct = 'XlNkVmtUI1MgXWBZXCFeKY+AaXNt'
the_flag = base64.b64decode(correct)flag=''
for i in the_flag:x =(ord(chr(i))-16) ^ 32flag+=chr(x)print(flag)

得出结果nctf{d3c0mpil1n9_PyC}

第五题拿下!

第六题:re1

老规矩先查壳


无壳且是32位,拉到IDA里反汇编


双击aFlag_0进去


发现aFlag_0意思是flag错误,双击unk_413E90进去


发现显示的是flag get,所以正确的flag会使程序进行unk_413E90

所以if()里的条件要为假才可以不进行aFlag_0,所以v3要为0
因为v3是由 *v3 = strcmp((const char )&v5, &v9) 决定的,当v5=v9时v3才=0,发现v9由 **_mm_storeu_si128((__m128i )&v5, _mm_loadu_si128((const __m128i )&xmmword_413E34))决定,
发现
xmmword_413E34
有点可疑,双击进去

猜测v9就等于xmmword的值,将3074656D30633165577B465443545544h转换成字符


因为IDA是小端法,所以这一串字符应该反过来输出,即为DUTCTF{We1c0met0}
一看就知道这就是flag

第六题拿下!

第七题:game

老规矩下载之后放到exeinfope里查壳


发现无壳且是32位的exe文件,发现是exe可执行文件,直接双击打开


这一看我就乐了,经典点灯小游戏,简单地说就是12345678分别控制1234578这8盏灯及其相邻的灯的灭亮(1和8也算作相邻的),了解过这个游戏的都知道直接按12345678的顺序点一遍就可以全部点亮了。全点亮后如下图


……发现flag真的出来了。

下面放在IDA里看一下,发现下面这一段很明显是判断灯是否全亮的


双击sub_457AB4()进去,最后发现一段循环异或,猜测这就是flag的算法


写一段代码把v2到v58,v59到v115的值分别放在2个数组里,再进行异或运算,最后输出结果。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>int main()
{int a[57]={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};int b[57]={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};for (int i = 0; i < 57; ++i ){a[i] ^= b[i];a[i] ^= 0x13u;printf("%c",a[i]);}return 0;
}

(把这些数据拿到数组里真是太麻烦了,本人太菜,一个个复制粘贴过去的,有大佬知道什么快速的方法希望能告诉我 (~ ̄▽ ̄)~)

有个地方我想说一下,本来我的代码是把printf放到for循环之外的,我打算一次性输出整个字符串,但是控制台老是显示NULL,我到现在也不清楚是为什么,最后只能一个一个字符输出了,有大佬知道为什么的话希望能告知 o()o。

最后结果如下图


第七题拿下!

第八题:Hello,CTF

老规矩下载附件拖到exeinfope查壳


发现无壳且是32位的exe文件,啧啧,一看又是exe我想不会又可以不写代码直接玩出flag吧,结果我双击进去发现只有一句话:please input your serial:……emmm还是老老实实的IDA打开吧。ctrl+F查找main之后按F5反汇编,然后直接去找判断成功的代码如下


看出v3要大于等于17,并且v10与v13要相同才可以进行aSuccess。继续往上看

要输入v9,并且v9的长度要小于等于17,然后在do循环里把v9[v3]赋给v4,发现sprintf很像printf,猜测是输出函数,感觉asc_408044可疑,双击进去发现


有%x表示十六进制,猜测sprintf就是把v4用十六进制表示,再往上看


发现v13=437261636b4d654a757374466f7246756e,所以flag应该就是把437261636b4d654a757374466f7246756e用十六进制表示出来,为了方便我就直接用在线转换工具把它转换成16进制了,结果如下。


flag就是CrackMeJustForFun
第八题拿下!

第九题:no-strings-attached

老规矩下载附件拉到exeinfope查壳。


发现无壳且是32位的,拉到IDA里去反汇编,发现main函数反汇编后只有这些东西


发现authenticate是证实的意思,所以猜测flag与authenticate有关系,双击进去看见


发现最后的if-else与判断胜负的函数很像,双击unk_8048B44进去


发现有Success,估计正确的flag就可以进入unk_8048B44
发现wcscmp和strcmp很像估计作用也是一样的,就是当ws=s2的时候就可以进入if了,再往上看发现decrypt函数,decrypt是翻译的意思,猜测是加密函数,双击进去。


发现这段代码先把s的值复制给dest,然后将dest的每个值减去a2的每个值,然后返回值是dest,从原函数可知dest的值就是之前的s2。接下来就是要找出传入的s和a2的值,即原来的s和dword_8048A90,双击原来的dword_8048A90进去,看见了s和dword_8048A90的值,分别选中它们的值后按Shift+E,选择C无符号字符数组(十进制),将值复制下来准备写解题代码时用。记得最后的4个0不要复制,因为字符串默认结尾为0。



下面是我写的解题代码。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>int main()
{int a2[]={1,20,0,0,2,20,0,0,3,20,0,0,4,20,0,0,5,20,0,0};int s[]={58,20,0,0,54,20,0,0,55,20,0,0,59,20,0,0,128,20,0,0,122,20,0,0,113,20,0,0,120,20,0,0,99,20,0,0,102,20,0,0,115,20,0,0,103,20,0,0,98,20,0,0,101,20,0,0,115,20,0,0,96,20,0,0,107,20,0,0,113,20,0,0,120,20,0,0,106,20,0,0,115,20,0,0,112,20,0,0,100,20,0,0,120,20,0,0,110,20,0,0,112,20,0,0,112,20,0,0,100,20,0,0,112,20,0,0,100,20,0,0,110,20,0,0,123,20,0,0,118,20,0,0,120,20,0,0,106,20,0,0,115,20,0,0,123,20,0,0,128,20,0,0,0,0,0,0,83,0,0,0,117,0,0,0,99,0,0,0,99,0,0,0,101,0,0,0,115,0,0,0,115,0,0,0,33,0,0,0,32,0,0,0,87,0,0,0,101,0,0,0,108,0,0,0,99,0,0,0,111,0,0,0,109,0,0,0,101,0,0,0,32,0,0,0,98,0,0,0,97,0,0,0,99,0,0,0,107,0,0,0,33,0,0,0,10,0,0,0};int x=0,i=0,j=0;while ( i < 156 ){x=s[i++]-a2[j++%20];//写EXP的要点是把字符都转换成整数,并且最后一个一个地将整数换成字符输出 ,之前也提过了,为了加深我自己的印象,又啰嗦了一遍
//          if(x>32){printf("%c",x);
//          }}
// 这里我把if(x>32)给注释掉了,如果直接用这段代码,会发现结果的字符之间会有很多的空格,为了消除这些空格,我设置了x>32这个条件,因为空格的ASCII代码对应的十进制是32return 0;
}

最后删去空格的结果如下


第九题拿下!

第十题:maze

l老规矩拿到附件之后查壳


发现无壳且是64位的文件,根据题目描述这应该是一道迷宫题。关于迷宫题,我当时做完这道题之后专门去找了一些资料学习,其中有一篇博客讲的很好,由题目也有解析,我把超链接和网址放在下面。
逆向迷宫题总结
网址:https://blog.csdn.net/weixin_50549897/article/details/110633105

用IDA打开文件,ctrl+F查找main函数,F5反汇编之后,看了看发现有4个if语句,因为是迷宫题,所以推测这四个if就是用来判断上下左右的,把if()里的数字都换成字符,发现4个方向键是 ‘O’ , ‘o’ , ‘.’ , ‘0’ 。发现四个if语句最后都会到LABEL_14,一直追踪下去,发现如下代码

发现**if ( asc_601060[8 * (signed int)v10 + SHIDWORD(v10)] != ‘#’ )**应该就是判断是否到达终点的函数,双击asc_601060进去发现如下图
数了数空格,*,#一共有64个字符,推测应该是8x8的迷宫
四个if语句进行的函数代码如下

bool __fastcall sub_400650(_DWORD *a1)//对应O
{int v1; // eaxv1 = (*a1)--;return v1 > 0;
}
bool __fastcall sub_400660(int *a1)//对应o
{int v1; // eaxv1 = *a1 + 1;*a1 = v1;return v1 < 8;
}
bool __fastcall sub_400670(_DWORD *a1)//对应.
{int v1; // eaxv1 = (*a1)--;return v1 > 0;
}
bool __fastcall sub_400680(int *a1)//对应0
{int v1; // eaxv1 = *a1 + 1;*a1 = v1;return v1 < 8;
}

可以看出上下和左右应该分别由 ‘O’,‘o’ 和 ‘.’ ,'0’控制,并且发现有>0和<8来控制边界所以可以确定这个迷宫就是8x8的迷宫了。
因为O和o传入的参数是+1的,4个方向函数传入的参数都是4个字节的,所以O和o应该是高位4字节,而.和0应该是低位4字节,推测高位决定行低位决定列,所以推测O和o应该决定左右,.和0应该决定上下,所以上下左右分别为 ‘.’ , ‘0’ , ‘O’,‘o’ .方向搞定。。再往上看发现如下代码

puts("Input flag:");scanf("%s", &s1, 0LL);if ( strlen(&s1) != 24 || strncmp(&s1, "nctf{", 5uLL) || *(&byte_6010BF + 24) != '}' )

可以看出输入的s1就是flag,并且flag的长度等于24,并且开头前5个字符就是 “nctf{”,并且结尾的字符是 ‘}’。所以能够操作的步数是并且只能是24-6=18步,下面是我写的打印迷宫的代码。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>int main()
{char v[100]="  *******   *  **** * ****  * ***  *#  *** *** ***     *********";printf("%d\n",strlen(v));for(int i=0;i<64;i++){printf("%c",v[i]);if((i+1)%8==0){printf("\n");}}return 0;
}

打印出来为


其中*为墙壁,空格为可走的路径。走几次迷宫就可以判断出来走法了,走法为:右下右右下下左下下下右右右右上上左左,所以flag=nctf{o0oo00O000oooo…OO}。
第十题拿下!

总结

首先当时做题时遇到的最大问题就是见过的题目太少,基本每一道题都是新的题型,媒体都要去查资料。所以我认为,想要提高自己的技术,最重要的就是要都做题,关键是做不同类型的题,不然很容易遇到无从下手的情况。
还有两道题我还要再琢磨一下,这次再次回顾做题的时候发现那两道题思路还是不太清晰,所以我这次没有写进来。等之后有空我就会写出来的。

后续要学习的东西,在此立个flag

1.脱壳方法与技术
目前脱壳我只会用upx脱壳,但我之前在找资料的时候看到很多大佬都是用的ollydbg动态调试来脱壳的,之后我肯定是要重点学习一下的。
2.相关汇编基础打牢
没有系统地专门学习过汇编,只是在网上找资料学会了一些皮毛,对于堆栈的理解还是不够深刻,之后也要找时间打打牢。
3.做题做题再做题
果然做题才是积累经验的好方法,之后题目肯定不能断
4.博客继续写
这次回顾攻防世界的题目让我再次对自己的记性产生了怀疑,果然好记性不如烂笔头,之后每做完一些题我都要写一下博客。

攻防世界RE练习区题目总结(1-10)相关推荐

  1. 20200109攻防世界WEB高手区题目一题多解全教程通关(13-18)

    欢迎大家一起来Hacking水友攻防实验室学习,渗透测试,代码审计,免杀逆向,实战分享,靶场靶机,求关注 目录 013unserialize3 014upload1 015Web_python_tem ...

  2. 攻防世界MISC进阶区刷题记录

    文章目录 攻防世界MISC进阶区刷题记录 Ditf 运用stegextract进行分离 glance-50 gif图片分离组合脚本 hit-the-core Test-flag-please-igno ...

  3. 攻防世界-MISC-练习区12题解

    攻防世界-MISC-新手区 一.this_is_flag 题目描述: Most flags are in the form flag{xxx}, for example:flag{th1s_!s_a_ ...

  4. 攻防世界高手进阶区——dice_game

    攻防世界高手进阶区--dice_game 题目里面啥都没有. 一.分析文件 checksec 只有栈溢出保护关闭了,其他都是开着的. 运行 可以看出是要猜数字,猜对50次. ida逆向 __int64 ...

  5. 攻防世界MISC高手区Avatar

    攻防世界MISC高手区五分题[Avatar] 题目 解题分析过程 题目 解题分析过程 1.下载附件得一张图片(jpg) 2.扔进winhex,分析无果: 扔进Stegsolve,分析无果: binwa ...

  6. 攻防世界- CRYPTO -练习区12题解

    攻防世界- CRYPTO-新手区 一.base64 题目描述: 元宵节灯谜是一种古老的传统民间观灯猜谜的习俗. 因为谜语能启迪智慧又饶有兴趣,灯谜增添节日气氛,是一项很有趣的活动. 你也很喜欢这个游戏 ...

  7. 【pwn】攻防世界 pwn新手区wp

    [pwn]攻防世界 pwn新手区wp 前言 这几天恶补pwn的各种知识点,然后看了看攻防世界的pwn新手区没有堆题(堆才刚刚开始看),所以就花了一晚上的时间把新手区的10题给写完了. 1.get_sh ...

  8. 攻防世界web进阶区Web_php_wrong_nginx_config详解

    攻防世界web进阶区Web_php_wrong_nginx_config详解 题目 详解 题目 打开发现无论我们输入什么他都会弹出网站建设不完全 那么我们使用御剑进行扫描,扫描到了admin和robo ...

  9. 攻防世界高手进阶区 ——反应釜开关控制

    攻防世界高手进阶区 --反应釜开关控制 题目没什么信息.在这里插入图片描述 1.分析文件 运行一下,可能为栈溢出的题. checkse 无栈溢出保护,无地址随机化,只有堆栈不可执行. 栈溢出可能性大. ...

最新文章

  1. python---简单数据库
  2. Tungsten Fabric SDN — 软件项目编译与打包
  3. linux复习资料非编程
  4. Angular jasmine单元测试框架里使用it函数定义single spec
  5. 初识ABP vNext(6):vue+ABP实现国际化
  6. onvif概念及应用?
  7. ES6学习笔记(五):轻松了解ES6的内置扩展对象
  8. python虚拟环境中安装diango_创建python虚拟环境,安装django,创建一个django项目,在项目中创建一个应用(ubuntu16.04)...
  9. IIS Express介绍与使用
  10. python语言特点粘性扩展_【语言处理与Python】9.2处理特征结构\9.3扩展基于特征的文法...
  11. 09月28日 pytorch与resnet(四)三种主要的转移学习方案,微调ConvNet,ConvNet 作为固定特征提取器
  12. python __file__怎么实现_python怎么实现文件上传界面
  13. xftp连接不上虚拟机linux,XFTP如何连接LINUX虚拟机
  14. 安卓udp发包工具_Sendip 命令行发包工具,支持IP、TCP、UDP等
  15. markman,让设计更有爱!
  16. qt中画出漂亮的函数曲线
  17. FFmpeg命令行(ffmpeg、ffplay、ffprobe)
  18. “入门大数据分析:探索海量数据的奥秘“
  19. 编译librtmp for Android
  20. HTML 简易、易懂版轮播图 有图有真相 JavaScript实现

热门文章

  1. 深入理解B/S与C/S架构
  2. 计算机名(主机名)、本机地址(IP/IPv4)、localhost、127.0.0.1的关系
  3. 9 客户端认证方式 之 PKCE
  4. 【转载】为什么要用50欧姆?
  5. 服务器摆放需要预留U位么_客厅沙发怎么摆放?六种方法教你如何摆放!(实用荐读)...
  6. SAP商超订单统一管理系统
  7. iOS面试题目及答案总结
  8. vue 仿外卖app-数据mock部分
  9. 干货分享 | Windows系统下载SRA数据方法——生信小白亲测可行
  10. 简单工厂方法模式(Simple Factory Methord)