CTFShow re2 (RC4

参考:CTFSHOW re2

本文:跟着大佬的博客一步一步做CTFShow re2的记录


IDA分析

有个比较函数
在这里插入图片描述re一下

s = "DH~mqqvqxB^||zll@Jq~jkwpmvez{"
s1 = ''
for i in s:
    s1 += chr(ord(i) ^ 0x1f)
print(s1)

得到
在这里插入图片描述再四处看看
跟进sub_401028
在这里插入图片描述四个sub点进去看看,感觉最后一个比较重要(因为它的参数有stream?
在这里插入图片描述像RC4算法
我不知道啊
大概就是要%256,要打乱,要交换,要按字节运算,吧?

之后去找到RC4算法,用上面得到的[Warnning]Access_Unauthorized作为key,附件里打开是乱码的enflag.txt里的数据作为要加密的数据,改一通
因为RC4是对称加密,加密解密可以用同一个算法

enflag.txt数据怎么来的?
在这里插入图片描述
明显不能直接复制 (我就复制了当然是不行啦 ,猜想是二进制数据
那二进制数据怎么读取呢
折腾一会儿之后找到了在linux中用hexdump读取二进制数据的方法(直接使用是以十六进制显示的
参考:Linux下查看二进制文件
在这里插入图片描述看看别人的代码,发现pData的数据是以十六进制形式,每两位一存,并且上图中的四位里前两位和后两位要交换顺序 (这是什么意思啊小端序吗(混乱
也就是要改成0xc3, 0x82, 0xa3, 0x25, 0xf6, 0x4c, 0x36, 0x3b, 0x59, 0xcc, 0xc4, 0xe9, 0xf1, 0xb5, 0x32, 0x18, 0xb1, 0x96, 0xae, 0xbf, 0x08, 0x35
(亲测不换顺序不行
但至少数据能对上(我太菜了呜呜呜
十六进制两位也就是二进制八位,一个字节,对应unsigned char的size,还有一定要注意charunsigned char
来自RC4算法C语言实现

1、明文密文还有状态数组S[i](0~255)类型应该选择为unsigned char 类型,因为其取值范围为0~255,且子长为一字节。
2、明文密文以及状态数组S[i]的类型应该全部一样,这样做异或运算时就不会发生内存溢出的问题。

最后代码是这样的

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

void rc4_init(unsigned char *s, unsigned char *key, unsigned long len)
{
	char k[256] = {0};
	unsigned char tmp = 0;
	for (int i = 0; i < 256; i++)
	{
		s[i] = i;
		k[i] = key[i % len];
	}
	int j = 0;
	for (int i = 0; i < 256; i++)
	{
		j = (j + s[i] + k[i]) % 256;
		tmp = s[i];
		s[i] = s[j];
		s[j] = tmp;
	}
}

void rc4_crypt(unsigned char *s, unsigned char *data, unsigned long len)
{
	unsigned char tmp;
	unsigned long k = 0;
	int i = 0, j = 0, t = 0;
	for (k = 0; k < len; k++)
	{
		i = (i + 1) % 256;
		j = (j + s[i]) % 256;
		tmp = s[i];
		s[i] = s[j];
		s[j] = tmp;
		t = (s[i] + s[j]) % 256;
		data[k] ^= s[t] ;
	}
	
}

int main()
{
		
	unsigned char s[256] = {0}, s2[256] = {0};
	char key[256] = {"[Warnning]Access_Unauthorized"};
	char pData[512] = {0xc3, 0x82, 0xa3, 0x25, 0xf6, 0x4c, 0x36, 0x3b, 0x59, 0xcc, 0xc4, 0xe9, 0xf1, 0xb5,
0x32, 0x18, 0xb1, 0x96, 0xae, 0xbf, 0x08, 0x35};
	
	
	rc4_init(s, (unsigned char*)key, strlen(key));
	for (int i = 0; i < 256; i++)
		s2[i] = s[i];
	
	unsigned long len = strlen(pData);
	rc4_crypt(s, (unsigned char*)pData, strlen(pData));
	printf("%s\n", pData);
	rc4_crypt(s2, (unsigned char*)pData, strlen(pData));
	printf("%s\n", pData);
	return 0;
	

}

在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值