好友
阅读权限25
听众
最后登录1970-1-1
|
本帖最后由 HNHuangJingYU 于 2021-9-29 23:53 编辑
1. 照常将easy-apk.apk文件拉进jeb进行分析,这题看起来挺简单的,突破口就在MainActivity如图1:
1
2. 解题流程就是将输入的字符串获取byte集放入Base64New().Base64Encode()进行加密,再对比”5rFf7E2K6rqN7Hpiyush7E6S5fJg6rsi5NBf6NGT5rs=”嗯,那么这题主要就是逆向算法了进入到Base64New类进行分析,熟悉Base64的应该就知道这就是一个换了码表的Base64加密.
3. 对于我一个刚接触ctf人来说这种解密确实挺难的,但是呢没办法硬着头皮来,励志要当一名全能CTF的选手这些必备,我将加密操作拉进AS中加上动态分析发现并不难流程如下:[Java] 纯文本查看 复制代码 //因为Base64是二进制编码,二进制无非就是常规的算术、逻辑运算,所以编码转化都是可逆的[/size][/font]
public String Base64Encode(byte[] bytes) {//字符串转化为byte数组,其实就是对字符串逐个ASCLL码组成的数列,然后对其二进制进行运算
StringBuilder res = new StringBuilder();
for (int i = 0; i <= bytes.length - 1; i += 3) { //循环输入字符串个数 循环lenght/3次 ,i%3==0,[0,3,6,9]
byte[] enBytes = new byte[4]; // 用于填充4个字节数据的寄存器,以4个字节为一组
byte tmp = 0; //临时保存单个数据的寄存器
for (int k = 0; k <= 2; k++) { //恒定循环3次 [0,1,2] ,根据上面得出每次都会遍历[0,1,2],[3,4,5],[6,7,8]
if (i + k <= bytes.length - 1) {// 任何数 |0等于本身
enBytes[k] = (byte) (((bytes[i + k] & 255) >>> ((k * 2) + 2)) | tmp); //先与运算、右移零运算、或运算
tmp = (byte) ((((bytes[i + k] & 255) << (((2 - k) * 2) + 2)) & 255) >>> 2); //字符&255就是它的ASCLL码值
} else { //这里进来的情况是当输入的字符串长度不能被3整除 ,如果取余数为1则进来2次,如果取余数为2则进来1次
enBytes[k] = tmp;
tmp = 64;
}
}
enBytes[3] = tmp; //前面的循环只填充了4个字节的前3个,故这里填充最后一位
for (int k2 = 0; k2 <= 3; k2++) {
System.out.print(enBytes[k2] + ",");
if (enBytes[k2] <= 63) { //遍历每组数逐个判断是否小于64(这里用的是十进制) ,这里就和上面fork循环里面的else对应(tmp=64)
res.append(Base64ByteToStr[enBytes[k2]]);//按值取对应码表中的索引,,所以码表必须为64个字符
} else { //
res.append('=');//这里就可以解释如果加密长度可以被整除则末尾0个=号,取余为1则末尾2个==号,取余为2则末尾1个=号;
}
}
} //总体思路就是将字符串以3个长度字节为一组进行或、位移运算,不足3个长度的一组用=代替
return res.toString();
}
4. 这里引用下大神的逆向算法,实在没算出来
[Java] 纯文本查看 复制代码 public void Base64Decode() {
String enflag = "5rFf7E2K6rqN7Hpiyush7E6S5fJg6rsi5NBf6NGT5rs=";
StringBuilder flag = new StringBuilder();
String flag_temp = "";
for (int i = 0; i < enflag.length(); i += 4) {
String enf = enflag.substring(i, i + 4);
byte flag1 = (byte) (((getIndex(enf.charAt(0)) & 255) << 2 | ((getIndex(enf.charAt(1)) & 255) >>> 4)));
byte flag2 = (byte) (((getIndex(enf.charAt(1)) & 255) << 4 | ((getIndex(enf.charAt(2)) & 255) >>> 2)));
byte flag3 = (byte) (((getIndex(enf.charAt(2)) & 255) << 6 | ((getIndex(enf.charAt(3)) & 255))));
flag_temp = "" + (char) flag1 + (char) flag2 + (char) flag3;
flag.append(flag_temp);
}
System.out.println(flag);
}
public byte getIndex(char x) {
byte index = -1;
String talbe = new String(Base64New.Base64ByteToStr);
if (x != '=') {
index = (byte) talbe.indexOf(x);
} else {
index = 0;
}
return index;
}
//输出最终flag:05397c42f9b6da593a3644162d36eb01
|
免费评分
-
查看全部评分
|
发帖前要善用【论坛搜索】功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。 |
|
|
|
|