记一次Re栅栏解密

我们打开压缩包,发现里两个图片,我们直接看最外面的图片,拖到01editor中查看,其开头就是jpeg的经典格式

但是根据后面的模板内容识别,后面还有exe文件

那么这里应该就跟misc类题目一样了,图片里面藏了其他文件,我们先拖到kali的binwalk进行分离

我们只选取最外层的re.exe进行分析,或者我们直接在7zip中进行选取(骚操作,非常神奇,虽然少东西,但提取出来的是对的)

接下来我们对re.exe进行分析,二话不说,我们先放到detectItEasy中进行查看,看看有关信息

根据上图所示,该PE文件是32位编写的,于是乎我们将其拖入到ida32中进行分析,函数结构很清晰,我们从main进入到main0中进行分析

可以看到左边红框圈住的就是我们的核心代码,右边的话应该是有关提示,我们按下F5反编译大法

我们看到这里的核心处理代码和前面的汇编代码并不相同,明显少了一个异或,根据汇编处的逻辑,应该是对数组中每一个数据依次进行+9,之后与9进行异或,而ida中只有+9操作。

我们可以据此来直接写脚本破解,因为逻辑并不困难,但是作为“武器大师”不能这么搞,我们拖到ghidra中进行测试

我们根据前面的xor的特征地址在鸡爪中使用导航快速来到相应位置,我们发现此时右边的反编译代码和我们的分析相照应,于是乎我们将这个函数截取出来进行脚本编写

上面只是粗糙的代码,我们需要先验证一下思路是否正确,编译运行后我们发现结果如下:

根据之前在ida中看到的提示“琪露诺酱在冻青蛙的路上,突然被9层栅栏反方向围住了,找不到方向,你可以帮助她找”我们很容易能够猜测到,这个字符串需要进行栅栏解密,需要注意的就是其中提到的“反方向”,也就是我们需要将这个字串先倒置再解密。我们找一个在线网站进行暴力测试

结果如上,思路正确,那么我们对脚本进行优化一下:

1.	#include<stdio.h>  
2.	int main(){  
3.	  int reverse[24] = {0};  
4.	  int i;  
5.	  int local_64 [24] = {0x73, 0x5e, 0x61, 0x72, 0x67, 0x2f, 0x6b, 0x72, 0x41, 0x30, 0x31, 0x69, 0x75, 0x76, 0x65, 0x30, 0x71, 0x5f, 99, 0x2f, 0x5c, 0x74, 0x5d, 0x66};  
6.	  for (i = 0; i < 24; ++i) {  
7.	    reverse[23 - i] = local_64[i] + 9U ^ 9;  
8.	  }//uncry1}rC03{wvg0sae1ltof  
9.	  for(int j = 0; j < 24; ++j){  
10.	    printf("%c", reverse[j]);  
11.	  }//fotl1eas0gvw{30Cr}1yrcnu  
12.	  printf("\n");  
13.	  int k = 0;  
14.	  for(i = 0; i < 24; i++){  
15.	    k = i / 8;  
16.	    printf("%c", reverse[(i * 3) % 24 + k]);  
17.	  }//flag{C1co1sv3rynte0w0}ru  
18.	  return 1;  
19.	}

这里如果我们用这个网站解密的话,会出来不一样的结果(栅栏密码在线加密解密),中间结果是正确的!!!!!)

而其他网站如下:

栅栏加密/解密 - Bugku CTF

栅栏密码在线加密解密 - 站长工具网 (zhanid.com)

和本人的脚本解出来的是上面的类似答案,也就是ru在括号外。

那么我们推测一下,为什么会出现这种结果,我们对上面的flag{C1rno1sv3rycute0w0},进行正向栅栏密码,可以得到前面的图中所示结果,可以看到24并非9的整数倍,后面多出来的3×2的数字,在其他网站中如果进行解密的话就是“@”字符进行顶替。

也就是说,此脚本是应该得是横向优先,而非本人的脚本这样的纵轴优先。修改后的脚本如下(不是很通用):

1.	#include<stdio.h>  
2.	int main(){  
3.	  int reverse[24] = {0};  
4.	  int i;  
5.	  int local_64 [24] = {0x73, 0x5e, 0x61, 0x72, 0x67, 0x2f, 0x6b, 0x72, 0x41, 0x30, 0x31, 0x69, 0x75, 0x76, 0x65, 0x30, 0x71, 0x5f, 99, 0x2f, 0x5c, 0x74, 0x5d, 0x66};  
6.	  for (i = 0; i < 24; ++i) {  
7.	    reverse[23 - i] = local_64[i] + 9U ^ 9;  
8.	  }//uncry1}rC03{wvg0sae1ltof  
9.	  for(int j = 0; j < 24; ++j){  
10.	    printf("%c", reverse[j]);  
11.	  }//fotl1eas0gvw{30Cr}1yrcnu  
12.	  printf("\n");  
13.	  int result[3][9];  
14.	  int k = 0;  
15.	  for(i = 0; i < 24; i++){  
16.	    if(i < 18){  
17.	      result[i % 3][i / 3] = reverse[i];  
18.	    }else{  
19.	      result[i % 2][(i - 18) / 2 + 6] = reverse[i];  
20.	    }  
21.	  }  
22.	  for(k = 0; k < 24; k++){  
23.	    printf("%c",result[k / 9][k % 9]);  
24.	  }//flag{C1rno1sv3rycute0w0}  
25.	  return 1;  
26.	}  

  • 14
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值