XMAN CTF 2017

0x1 re3

首先先分析一下程序,它是Linux下的.O文件,直接用IDA打开,Shift+F12查找下有没有关键字符串,发现了get flag!等这样的字符串,双击去到代码的关键处,F5查看C的伪代码

1

代码的逻辑已经很清晰了,v5是我们输入的字符串,然后传给sub_400C12这个函数验证,如果正确则输出get flag!说明v5就是我们要正确flag

2

算法流程:输入的v5经过base64加密然后与下标i进行异或,现在就可以写解密代码了

1
2
3
4
5
from __future__ import print_function
str=[0x58,0x4C,0x36,0x4D,0x7F,0x36,0x6A,0x61,0x57,0x38,0x59,0x54,0x5F,0x3D,0x51,0x49,0x45,0x5F,0x6F]
for i in range(len(str)):
print (chr(str[i]^i),end='')

最后得到的flag:XM4N{3lf_1S_S0_FUN}

####0x2 HelloSmali2
这道题是一题smali文件,之前做CTF题也遇到过,直接用工具Smali2JavaUI.exe转成java代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/**
* Generated by smali2java 1.0.0.558
* Copyright (C) 2013 Hensence.com
*/
package com.example.hellosmali.hellosmali;
public class Digest {
public static boolean check(String p1) {
String str = "+/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
int a1 = 6;
int a2 = 2;
if((p1 != null) && (length() != 0)) {
char[] charinput = toCharArray();
for(int i = 0; i < charinput.length; i = i + 1) {
for(String intinput = Integer.toBinaryString(charinput[i]); intinput.length() < 8; intinput) {
}
v2.append(intinput); //连接一个字符串到末尾
}
while((v2.length() % 6) != 0) {
v2.append("0");
}
String v1 = String.valueOf(v2);
char[] v4 = new char[(v1.length() / 6)];
for(int i = 0; i < v4.length; i = i + 1) {
int v6 = Integer.parseInt(v1.substring(0, a1), a2); //substring(0,a1)的二进制数
v1 = v1.substring(a1); //截取掉v1从首字母起长度为a1的字符串,将剩余字符串赋值给v1
v4[i] = str.charAt(v6); //此方法返回这个字符串的指定索引处的char值。第一个char值的索引为0.
}
if((length() % 3) == 1) {
v3.append(!?);
} else if((length() % 3) == a2) {
v3.append(!);
}
String key = String.valueOf(v3); //这将返回一个v3对象持有的指定字符串表示的值
if(key.equals("xsZDluYYreJDyrpDpucZCo!?"))//比较对象是否相等
{
return true;
}
return false;
}
return false;
}
}

算法流程:取输入的字符串转成二进制,然后判断二进制的长度模6是否等于0,如果不等则在末尾加0,之后将二进制6位一组切分再将其转化成十进制,转成的十进制作为索引号在str中找到索引的字符串,之后判断查到到的字符串的长度模3看是否等于1,不等则在后面接”!?”,最后与字符串比较”xsZDluYYreJDyrpDpucZCo!?”是否相等,如果相等则输入的字符串就是正确的flag

####持续更新中