赞
踩
(1)做题步骤:
双击exe文件看有无信息
使用查壳软件查壳,了解程序是多少位的(64位或32位)
使用ida进行分析
(2)ida分析过程:
Shift+F12查看一下字符串,寻找关键词(如flag等) ,如没有关键词,就在main函数里查找信息
双击字符串,查看包含该字符串的位置,查看引用该字符串的详细地址
ctrl+x(交叉引用)查看是哪段函数调用了该字符串
使用F5反汇编,查看伪C代码
分析伪代码(选中数字后按键盘“R”键,即可将数字转换为字符;选中变量后 ,按下键盘“X”键查看该变量的交叉引用)
(3)工具下载网站
逆向工具下载
用notepad++打开附件,直接ctrl+F搜索就能找到
flag{this_Is_a_EaSyRe}
参考文章:BUUCTF-reverse-reverse1(面向新手超详细)
先用DIE查下壳,是PE文件(exe文件是属于PE文件的一种)
显示64位,无壳
加壳的目的:为了隐藏程序真正的OEP(入口点),防止被破解
用IDA64位打开,先用shift + F12(不行的话再+Fn试试)查找一下flag关键词
双击进入该字符串位置
ctrl+x(交叉引用)查看是哪段函数调用了该字符串
点击“OK”进入该段程序
按“F5”查看伪C代码
然后对代码进行分析
strncmp()是字符串比较函数,代码表示如果str1和str2的前v5位相等,则输出"this is the right flag"
可以猜测 "sub_1400111D1"是"printf"之类的输出函数
接着往上分析的其他语句,看看str1和str2的具体内容是什么
可以猜测 “sub_14001128F"是"scanf"之类的输入函数,字符串str1为我们输入的内容
然后分析一下str2
随便双击一个str2,点进去后找到是一个字符串 ‘{hello_world}’
继续往上分析代码
发现对str2做了替换处理,将ascii码为111的字符转换ascii码为48的字符
选中数字按"R"键可以将数字转换为字符
str2中所有的"o"都被转换成了"0”
所以flag为 flag{hell0_w0rld}
先用DIE查下壳,显示64位,不是exe文件,而是一个ELF文件,ELF文件是linux平台上常见的可执行文件
用IDA64位打开,通过流程图可以找到关键字:flag
认为offset flag就是flag地址,直接双击进入
这段字符有点像flag的格式,尝试提交发现不对
找到左侧的main函数,按“F5”查看伪C代码
s2是我们输入的字符串,将flag字符串和s2对比,如果一致,则是正确的flag
往上分析代码,发现flag字符串被做了替换处理,将ascii码为105和114的字符转换ascii码为49的字符
选中数字按"R"键可以将数字转换为字符,flag中所有的’i’和’r’都被转换成了’1’
也可以编写python脚本得到flag
key = '{hacking_for_fun}'
flag = 'flag'
for i in key:
if i=='i' or i=='r':
flag = flag + '1'
else:
flag = flag + i
print(flag)
flag{hack1ng_fo1_fun}
下载的附件先运行一下,输入y或者n,程序都会自动退出
先用DIE查下壳,显示32位
用32位的IDA打开
按“F5”查看伪C代码,发现里面还有一个main_0()的函数,直接双击进入
发现一段变量名为v5的可疑字符串,但是代码并未调用v5
结合最开始程序运行的提示:“这里本来应该是答案的,但是粗心的程序员忘记把变量写进来了,你要不逆向试试看:(Y/N)”
可以猜测程序员忘记调用v5,尝试提交这段字符串(记得花括号前加上flag):
flag{49d3c93df25caad81232130f3d2ebfad}
提交后显示正确
先看看题目要求,flag是一个字符串
用DIE查下壳,显示32位,发现有UPX的壳
下载脱壳工具:upx脱壳工具
在文件目录输入cmd
在终端打开该工具,输入:upx -d 存放exe文件的目录
显示脱壳成功
用32位的IDA打开脱壳后的exe文件,shift+F12查看所有字符串,找到带flag的语句双击进入
ctrl+x(交叉引用)查看是哪段函数调用了该字符串,点OK
按“F5”查看伪C代码
其中Str2是"HappyNewYear!"字符串,Str1是我们输入的内容
strncmp()函数比较Str1和Str2字符串,相等则说明是正确的flag
提交flag{HappyNewYear!},显示正确
用IDA64位打开附件,按“F5”查看伪C代码
要求输入的字符串_b长度为33
从第2个字符开始,每一个都与前一个做异或运算
运算得到的字符串与global比较,如果相同,字符串就是flag
找到global的值
选中上面这些字符,shift+E导出数据,选中十六进制格式
编写python脚本
# 定义一个列表key key = [ 0x66, 0x0A, 0x6B, 0x0C, 0x77, 0x26, 0x4F, 0x2E, 0x40, 0x11, 0x78, 0x0D, 0x5A, 0x3B, 0x55, 0x11, 0x70, 0x19, 0x46, 0x1F, 0x76, 0x22, 0x4D, 0x23, 0x44, 0x0E, 0x67, 0x06, 0x68, 0x0F, 0x47, 0x32, 0x4F, 0x00 ] flag = '' # 遍历key中的元素,从最后一个元素(索引为 len(key)-1)开始到第一个元素(索引为 0),向前依次进行操作。 for i in range(len(key)-1,0,-1): # 对每个元素进行异或运算,将当前元素与前一个元素(key[i-1])进行异或,然后将结果保存到当前元素位置(key[i])上。 key[i] ^= key[i-1] for i in range(len(key)): # 将每个元素转换为对应的ASCII字符,按顺序拼接起来 flag += chr(key[i]) print(flag)
打印出结果,得到flag:
flag{QianQiuWanDai_YiTongJiangHu}
下载附件得到一个apk文件(apk是AndroidPackage的缩写,即Android安装包)
将后缀改为zip即可打开看到该文件内容
方法一(用ida)
可以直接打开zip格式的文件
也可以把apk文件拖入ida中,选中apk格式打开
按shift+F12查找字符串即可找到flag
方法二(用APKIDE)
安卓逆向工具下载地址:https://down.52pojie.cn/Tools/Android_Tools/
打开apk文件,在右侧搜索flag{即可找到
flag{7631a988259a00816deda84afb29430a}
先用DIE查下壳,显示32位,无壳
用ida32位打开,按F5查看伪C代码
双击进入main_0函数
接下来分析代码内容
str是我们输入的字符串
使用一个sub_4110BE()函数得到v4的值,然后复制给Dest
对Dest字符串做一个简单的循环运算
第一次循环:Dest[0]+0 第二次为:Dest[1] +1 …
如果Dest和str2相等时,flag正确,所以Str2为flag经过变换后的字符串
点进去看一下str2的值为:e3nifIH9b_C@n@dH
变化前的Dest从v4来,得到v4的sub_4110BE有什么作用我们不清楚,点进去看看
这个函数看上去很复杂,自己很难分析出来实现了什么具体功能
代码的后面有一个叫aAbcdefghijklmn的数组,点进去看看,发现是base64编码表
所以还原的思路为:将Str2还原为Dest,再对Dest进行base64解码
import base64
Des = "e3nifIH9b_C@n@dH"
flag = ""
for i in range(len(Des)):
# ord()函数返回字符对应的ASCII数值
# chr()函数将结果转换为对应的字符
flag += chr(ord(Des[i]) - i)
print(base64.b64decode(flag))
得到flag{i_l0ve_you}
下载附件运行一下,要求输入数字操作
用DIE查下壳,显示32位,无壳
用32位ida打开,按F5查看伪c代码,分析一下这段代码
将25个字节的字符串复制到v3
v5是我们输入的操作数
49和35的ascii码正好对应1和#,上面那个v3字符串也有1和#
当等于1时,退出程序;等于#时,表示输入的顺序是正确的flag
结合上面那一大堆0、1字符串和“up”"down"等提示,猜想这道题是一个迷宫
通过第51行代码的5 * ,说明这是一个5行5列的迷宫(一共25个字符)
遇到1会退出,所以要避开1,得到flag{222441144222}
参考文章:[BUUCTF] simpleRev (涉及大小端序存储)
用DIE查下壳,显示64位,无壳
用ida64位打开,按F5查看伪C代码,有一个Decry()函数
点进去看看
unsigned __int64 Decry() { char v1; // [rsp+Fh] [rbp-51h] int v2; // [rsp+10h] [rbp-50h] int v3; // [rsp+14h] [rbp-4Ch] int i; // [rsp+18h] [rbp-48h] int v5; // [rsp+1Ch] [rbp-44h] char src[8]; // [rsp+20h] [rbp-40h] BYREF __int64 v7; // [rsp+28h] [rbp-38h] int v8; // [rsp+30h] [rbp-30h] __int64 v9[2]; // [rsp+40h] [rbp-20h] BYREF int v10; // [rsp+50h] [rbp-10h] unsigned __int64 v11; // [rsp+58h] [rbp-8h] v11 = __readfsqword(0x28u); *(_QWORD *)src = 0x534C43444ELL; v7 = 0LL; v8 = 0; v9[0] = 0x776F646168LL; v9[1] = 0LL; v10 = 0; text = (char *)join(key3, v9); strcpy(key, key1); strcat(key, src); v2 = 0; v3 = 0; getchar(); v5 = strlen(key); for ( i = 0; i < v5; ++i ) { if ( key[v3 % v5] > 64 && key[v3 % v5] <= 90 ) key[i] = key[v3 % v5] + 32; ++v3; } printf("Please input your flag:"); while ( 1 ) { v1 = getchar(); if ( v1 == 10 ) break; if ( v1 == 32 ) { ++v2; } else { if ( v1 <= 96 || v1 > 122 ) { if ( v1 > 64 && v1 <= 90 ) { str2[v2] = (v1 - 39 - key[v3 % v5] + 97) % 26 + 97; ++v3; } } else { str2[v2] = (v1 - 39 - key[v3 % v5] + 97) % 26 + 97; ++v3; } if ( !(v3 % v5) ) putchar(32); ++v2; } } if ( !strcmp(text, str2) ) puts("Congratulation!\n"); else puts("Try again!\n"); return __readfsqword(0x28u) ^ v11; }
分析一下代码内容
首先定义了一些变量,src和v9的内容比较特殊,按R转换一下
src=‘SLCDN’ v9=‘wodah’
数据存储是按照大端模式进行,但在读取时需要注意大小端序,下面是以char格式读取,故读取用小端序
text由key3和v9连接而成
可以看到key3=‘kills’,v9=‘wodah’
所以text=‘killshadow’ (v9为小端序,故读取时要逆序)
将key1的值复制给 key,将 src 接在 key 后面
其中 key1 = ‘ADSFK’ , *src = ‘SLCDN’
所以key = ‘ADSFKNDCLS’ (src 为小端序,故读取时要逆序)
64和90对应的ascii值为’@‘和’Z’
这个循环的作用就是将key数组中ASCII码在64和90之间的字符都加32,实际上就是把key数组中的大写字母全部变成小写字母,key字符串变为’adsfkndcls’
v1是我们输入的flag值,这个循环对v1做了一系列的变换,并将变换后的值放在了str2中
比较text和变换后的值str2,如果相等,则我们的输入是正确的flag
所以就要思考怎么推出str2变换前的v1值(也就是我们输入的值)
可以用暴力破解的方法,将每一个字母都带入处理的式子中,并将结果与text中的进行对比,找到使结果成立的字母
flag = ''
text = 'killshadow'
key = 'adsfkndcls'
for i in range(len(text)):
for x in range(65,123):
if text[i] == chr((x - 39 - ord(key[i]) + 97) % 26 + 97):
flag += chr(x)
break
print('flag{'+flag+'}')
flag{KLDQCUDFZO}
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。