buuReserve(4)

[FlareOn6]Overlong

打开ida看:
有个sub_401160函数,然后里面有一组字符串,还有个28的长度
在这里插入图片描述
但是这个字符串长度并不只有28,很长
在这里插入图片描述
打开这个程序,展示的字符串有28长度,那后面的去哪里了,继续往下看
在这里插入图片描述
有个加密函数,好复杂,没见过

在这里插入图片描述
不如修改程序,把后面的给展示出来,上od,28的hex是1C,然后一步一步走,看看出现对话框的时候是哪里,然后,下个断点,再找1C,改为AF
在这里插入图片描述

在这里插入图片描述

[FlareOn3]Challenge1

看主函数,逻辑很简单,v5经历一个函数,然后跟v6对比就行了
那就看看函数sub_401260
在这里插入图片描述
这个是base64加密的模板,主要问题就是表有没有被改变,看一下
在这里插入图片描述
表变了,那就去cyberchief上改表解密把
在这里插入图片描述
得到flag
在这里插入图片描述

[UTCTF2020]basic-re

这道题白给,就一个计算器,flag可以查找字符串

[BJDCTF2020]BJD hamburger competition

这道题是一个unity,没见过,查阅资料得知,看这个文件
在这里插入图片描述
放入ida,找到一个函数能看到有个sha1还有md5

在这里插入图片描述
可以看到,在flag里面是有个md5,那md5是干啥呢,还有sha1干啥呢,看不懂,没有足够的信息进入下一步
在这里插入图片描述
查阅资料,我们下载一个dnSpy
进入dnSpy,我们直接找那个函数,还好跟ida里面的名字一样在这里插入图片描述
看到函数体,先把str进行sha1解密,然后解密后的字符串进行md5加密,且大写,取前20位(X2就是大写,substring的作用就是截取父字符串的某一部分)在这里插入图片描述在这里插入图片描述

在这里插入图片描述

将sha1解密得到1001在这里插入图片描述
那么就用1001进行md5加密,得到
在这里插入图片描述
取前二十位得到flag

[ACTF新生赛2020]Oruga

进入ida看主函数:
在这里插入图片描述
进入一个主要函数,可以看到,两个while循环,还有四个分支,得出是个迷宫,在最下面的while循环可以知道是个16x16的地图,而最下面的while也给出了我们的活动范围,第一行,在最左边不能左走,以此类推,而迷宫的结束条件就是到达!(33)

理解:那我们走迷宫,就是在数组里面走动,而v2在数组里面(也就是地图),所以v2代表我们,然后v4给出了范围,在第二个while循环里面:条件如果道路是0,那就一直走下去,最后有个v2 += v4(说明是一直沿这条路走到障碍前,也就是不是0的前面)

在这里插入图片描述
画出迷宫,走出路径得到flag
在这里插入图片描述

[Zer0pts2020]easy strcmp

进入ida看主函数,看到flag,输入不对
在这里插入图片描述
仔细观察,函数很少,一个一个看看,发现sub_6EA函数和init函数有明显逻辑
sub_6EA函数就是一个
加密过程:每八位与一个数组进行减法,第一个for循环是计算数组长度,第二个是进行加密。但是查看sub_6EA函数的引用的时候发现,并没有被引用,但没被用为什么会出现伪代码呢?

在这里插入图片描述
就看init函数:里面有其他函数的引用第一个sub_6E0函数没啥用,第二个sub_6E0函数有来头

在这里插入图片描述
在这里插入图片描述
第二个sub_6E0函数:把off_201028函数地址赋上了sub_6EA函数的地址
在这里插入图片描述
而查看off_201028函数的引用发现strcmp函数会跳到这个函数的地址,也就是说,strcmp就是一个加密函数了,加密的步骤是sub_6EA函数里面的,那就直接看sub_6EA函数吧
在这里插入图片描述
给的假flag总共33位,所以第一个for循环之后i是33,除8+1就是5,所以v4是5,然后qword_201060数组里面有四个数据,那就对着了。
第二个for循环里面是一个加密:对假flag每八位进行一次减法,那么逆过来就是加法
在这里插入图片描述
我先测试了一下

  char flag[] = "zer0pts{********CENSORED********}";
	char a[4] = { 0, 0x410A4335494A0942, 0x0B0EF2F50BE619F0, 0x4F0A3A064A35282B };
	for (int i = 0; i < 4; i++)
	{
		flag[i*8] += a[i];
	}
	printf("%s",flag);

在这里插入图片描述

可以看到第一个*被解密为l,而星号的hex是2a,数组数据里面的第一个是41,相加不是6c,那就是加上数组数据的最后两个42,刚好是l,(说明是小端存储,倒着计算)
在这里插入图片描述

于是多个验证
在这里插入图片描述

写出脚本

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
    char flag1[] ="********";
    char flag2[] ={0x43,0x45,0x4e,0x53,0x4f,0x52,0x45,0x44};
    char flag3[] ="********";
    int b[]={0,0x410A4335494A0942, 0x0B0EF2F50BE619F0, 0x4F0A3A064A35282B };
    char b1[] = {0x42,0x9,0x4a,0x49,0x35,0x43,0xa,0x41};
    char b2[] = {0xF0,0x19,0xE6,0x0B,0xF5,0xF2,0x0E,0x0B};
    char b3[] = {0x2B,0x28,0x35,0x4A,0x06,0x3A,0x0A,0x4F};
    for(int i=0;i<8;i++){
        flag1[i] +=b1[i];
    }
    for(int i=0;i<8;i++){
        printf("%c",flag1[i]);
    }
    for(int i=0;i<8;i++){
        flag2[i] +=b2[i];
    }
    for(int i=0;i<8;i++){
        printf("%c",flag2[i]);
    }
    for(int i=0;i<8;i++){
        flag3[i] +=b3[i];
    }
    for(int i=0;i<8;i++){
        printf("%c",flag3[i]);
    }
	return 0;
}

但是flag2的解密有几个一直都是相差1,我不理解,手算也是相差1
只得到,看来我还是太菜了😓
在这里插入图片描述

特殊的 BASE64

进入ida看主函数,给了字符串那就是用base64解密
在这里插入图片描述
但看题目,那表肯定变了,我查找字符串发现有一个表很可疑,就用了
在这里插入图片描述
也是很幸运😁
在这里插入图片描述

[ACTF新生赛2020]Universe_final_answer

进入ida看主函数,可以看到两个关键函数,一个sub_860函数,一个sub_C50函数在这里插入图片描述
先看sub_860函数:一看就头疼,十元一次方程,还是用python解吧
在这里插入图片描述
用numpy库也可以用z3(z3更简单)
在这里插入图片描述

在这里插入图片描述

Z3库可以进行约束求解,即解任何方程(只要有解),常用的包括整数求解、有理数求解、位向量求解(二进制位运算求解)。
解出来之后,有的顺序是错的,换一下
在这里插入图片描述

[WUSTCTF2020]level4

进去先看ida主函数
在这里插入图片描述
长久分析,得出是二叉树遍历
看文章二叉树
那么看type1和2
type1:
在这里插入图片描述
type2:
在这里插入图片描述
再结合资料:
在这里插入图片描述
得出type1是中序,type2是后序,那么已知中序后序求前序
改写一下代码即可:

#include<iostream>  
using namespace std;  
int post[] = {3, 4, 2, 6, 5, 1};  
int mid[] = {3, 2, 4, 1, 6, 5};  
void pre(int root, int start, int end) 
{  
    if(start > end)   
        return ;  
    int i = start;  
    while(i < end && mid[i] != post[root]) i++;  //定位根在中序的位置
    cout<<mid[i];  //访问当前处理的树的根
    pre(root-1-(end-i), start, i - 1);  //递归处理左子树
    pre(root-1, i + 1, end);  //递归处理右子树  
}  

int main()
 {  
    pre(5, 0, 5);  
    return 0;  
}  

crackMe

进入ida看主函数,有很多函数,从后往前看吧,看半天sub_401830函数最重要,像sub_401000函数是检查输入的用户名和密码是否合法,而sub_401830函数也影响着后面两个printf,很重要
在这里插入图片描述

进入sub_401830函数,从后面看:sub_401470函数的结果要满足v14=43925才行,进去
在这里插入图片描述
sub_401470函数:可以看到里面是对v17的条件判断,不过里面了、那个f冲突了,到最后试了试把f去掉了,因为从外面的while语句看出,长度是8,加上f就是9了,而其他的判断都没有那个( *((_DWORD *)NtCurrentPeb()->ProcessHeap + 3) != 2 )语句(好像是:如果是debug,则执行这行代码,动调这个函数会进入陷阱吗?),于是我就默认去除了
所以知道了v17是:dbappsec
在这里插入图片描述
当然,这里得到的v17还是经历一个函数之后的v17,前面的sub_401710函数也用到了v17.
首先,a3是外面的v6,而v6在外面的while条件很清楚可以看出是小于8的(也就是len),那么,这个if条件语句只会执行else if语句(也就是result = (const char *)(name[a3] ^ *(unsigned __int8 *)(a3 + a1));)
那么我们上面得到的v17就是result,只需要跟name异或就得到最终的v17了
在这里插入图片描述
看这一段代码:
30行:检查是否是十进制数字
32行:将0-9的字符改为十进制的0-9存储
34行:检查是否是十六进制数字
36-37行:反调试不管,debug执行
38行:输入的abcdef转为十六进制abcdef存储
42行:如果输入的不是abcdef区间的,那就按abcdef区间的顺序存储为abcdef
47行:if条件:奇数停止一次,那么v10就加了两次,所以两两一组存到v16里面(也就是最终密码)
在这里插入图片描述

这边圈到的上下两个if语句是反调试的,不用管
在这里插入图片描述
所以得到真v17想求v16,还差个byte_416050数组,我们看汇编,需要动调,因为静态没有值
可以看到:在xor之前,值存入了ecx里面,所以调试的时候,在xor添加断点,然后f9执行8次看ecx的值(为什么不是eax,因为eax是个定值)
得到:2a d7 92 e9 53 e2 c4 cd

在这里插入图片描述
如何在dgb里面找到:
在这里插入图片描述
然后脚本:

flag=""
a="dbappsec"
b=[0x2a,0xd7,0x92,0xe9,0x53,0xe2,0xc4,0xcd]
for i in range(len(a)):
    flag += hex(b[i] ^ ord(a[i]))
print(flag.replace('0x',''),end='')

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值