easy-apk
![](https://damoxilai.github.io/post-images/1627005217353.png)
new Base64New().Base64Encode(((EditText)
MainActivity.this.findViewById(R.id.editText)).
getText().toString().getBytes()).equals
("5rFf7E2K6rqN7Hpiyush7E6S5fJg6rsi5NBf6NGT5rs=")
由关键代码可知,是一串字符在base64 加密后与"5rFf7E2K6rqN7Hpiyush7E6S5fJg6rsi5NBf6NGT5rs="匹配,那么可以逆向将已知密文串base64 解密获得输入明文
![](https://damoxilai.github.io/post-images/1627005235846.png)
由Base64NEW包可得到新base64 算法,发现其更改了码表
原来:s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
新码表: s = "vwxrstuopq34567ABCDEFGHIJyz012PQRSTKLMNOZabcdUVWXYefghijklmn89+/"
python脚本实现解码
# coding:utf-8
#s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
s = "vwxrstuopq34567ABCDEFGHIJyz012PQRSTKLMNOZabcdUVWXYefghijklmn89+/"
def My_base64_encode(inputs):
# 将字符串转化为2进制
bin_str = []
for i in inputs:
x = str(bin(ord(i))).replace('0b', '')
bin_str.append('{:0>8}'.format(x))
#print(bin_str)
# 输出的字符串
outputs = ""
# 不够三倍数,需补齐的次数
nums = 0
while bin_str:
#每次取三个字符的二进制
temp_list = bin_str[:3]
if(len(temp_list) != 3):
nums = 3 - len(temp_list)
while len(temp_list) < 3:
temp_list += ['0' * 8]
temp_str = "".join(temp_list)
#print(temp_str)
# 将三个8字节的二进制转换为4个十进制
temp_str_list = []
for i in range(0,4):
temp_str_list.append(int(temp_str[i*6:(i+1)*6],2))
#print(temp_str_list)
if nums:
temp_str_list = temp_str_list[0:4 - nums]
for i in temp_str_list:
outputs += s[i]
bin_str = bin_str[3:]
outputs += nums * '='
print("Encrypted String:\n%s "%outputs)
def My_base64_decode(inputs):
# 将字符串转化为2进制
bin_str = []
for i in inputs:
if i != '=':
x = str(bin(s.index(i))).replace('0b', '')
bin_str.append('{:0>6}'.format(x))
#print(bin_str)
# 输出的字符串
outputs = ""
nums = inputs.count('=')
while bin_str:
temp_list = bin_str[:4]
temp_str = "".join(temp_list)
#print(temp_str)
# 补足8位字节
if(len(temp_str) % 8 != 0):
temp_str = temp_str[0:-1 * nums * 2]
# 将四个6字节的二进制转换为三个字符
for i in range(0,int(len(temp_str) / 8)):
outputs += chr(int(temp_str[i*8:(i+1)*8],2))
bin_str = bin_str[4:]
print("Decrypted String:\n%s "%outputs)
print()
print(" *************************************")
print(" * (1)encode (2)decode *")
print(" *************************************")
print()
num = input("Please select the operation you want to perform:\n")
if(num == "1"):
input_str = input("Please enter a string that needs to be encrypted: \n")
My_base64_encode(input_str)
else:
input_str = input("Please enter a string that needs to be decrypted: \n")
My_base64_decode(input_str)
或者用
#使用python2运行
#若使用python3.4以上,需把string.maketrans改为str.maketrans
import base64
import string
string1 = string.maketrans("vwxrstuopq34567ABCDEFGHIJyz012PQRSTKLMNOZabcdUVWXYefghijklmn89+/",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/")
strEnBase64 = "5rFf7E2K6rqN7Hpiyush7E6S5fJg6rsi5NBf6NGT5rs=".translate(string1)
print(strEnBase64)
strFlag = base64.b64decode(strEnBase64)
print(strFlag.decode("utf-8")
![](https://damoxilai.github.io/post-images/1627005258916.png)
获得明文
05397c42f9b6da593a3644162d36eb01
加上flag{}
flag{05397c42f9b6da593a3644162d36eb01}
easy-so
![](https://damoxilai.github.io/post-images/1627005272123.png)
发现使用cyberpeace类中CheckString关键函数
![](https://damoxilai.github.io/post-images/1627005288217.png)
于cyberpeace类找到函数,可以看出使用native函数CheckString,判断在so层实现该函数,拿出加载库so文件,用ida反编译得下图
![](https://damoxilai.github.io/post-images/1627005299069.png)
拿出代码
_BOOL4 __cdecl Java_com_testjava_jack_pingan2_cyberpeace_CheckString(int a1, int a2, int a3)
{
size_t v3; // edi
char *v4; // esi
size_t v5; // edi
char v6; // al
char v7; // al
size_t v8; // edi
char v9; // al
const char *v11; // [esp+18h] [ebp-14h]
v11 = (const char *)(*(int (__cdecl **)(int, int, _DWORD))(*(_DWORD *)a1 + 676))(a1, a3, 0);
v3 = strlen(v11);//取字符串长
v4 = (char *)malloc(v3 + 1);//申请内存
memset(&v4[v3], 0, v3 != -1);
memcpy(v4, v11, v3);//拷贝赋值
if ( strlen(v4) >= 2 )
{
v5 = 0;
do
{
v6 = v4[v5];
v4[v5] = v4[v5 + 16];
v4[v5++ + 16] = v6;//前十六字符与后十六字符置换
}
while ( v5 < strlen(v4) >> 1 );//直到字符串结束
}
v7 = *v4;
if ( *v4 )
{
*v4 = v4[1];
v4[1] = v7;//第一个字符与第零个字符置换
if ( strlen(v4) >= 3 )
{
v8 = 2;
do
{
v9 = v4[v8];//从第二个字符开始
v4[v8] = v4[v8 + 1];//后一个字符
v4[v8 + 1] = v9;//前后交换
v8 += 2;//隔两个数递增
}
while ( v8 < strlen(v4) );//直到字符末尾结束
}
}
return strcmp(v4, "f72c5a36569418a20907b55be5bf95ad") == 0;
}
写个python跑出来
a="f72c5a36569418a20907b55be5bf95ad"
a=list(a);
for i in range(0,len(a),2):
b=a[i]
a[i]=a[i+1]
a[i+1]=b
b=a[:16]
a[:16]=a[16:]
a[16:]=b
a=''.join(a)
print (a)
得到结果
90705bb55efb59da7fc2a5636549812a
flag{90705bb55efb59da7fc2a5636549812a}
easyjni
根据入口找到a函数
![](https://damoxilai.github.io/post-images/1627005316163.png)
package com.a.easyjni;
public class a {
private static final char[] a = {'i', '5', 'j', 'L', 'W', '7', 'S', '0', 'G', 'X', '6', 'u', 'f', '1', 'c', 'v', '3', 'n', 'y', '4', 'q', '8', 'e', 's', '2', 'Q', '+', 'b', 'd', 'k', 'Y', 'g', 'K', 'O', 'I', 'T', '/', 't', 'A', 'x', 'U', 'r', 'F', 'l', 'V', 'P', 'z', 'h', 'm', 'o', 'w', '9', 'B', 'H', 'C', 'M', 'D', 'p', 'E', 'a', 'J', 'R', 'Z', 'N'};
public String a(byte[] bArr) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i <= bArr.length - 1; i += 3) {
byte[] bArr2 = new byte[4];
byte b = 0;
for (int i2 = 0; i2 <= 2; i2++) {
if (i + i2 <= bArr.length - 1) {
bArr2[i2] = (byte) (b | ((bArr[i + i2] & 255) >>> ((i2 * 2) + 2)));
b = (byte) ((((bArr[i + i2] & 255) << (((2 - i2) * 2) + 2)) & 255) >>> 2);
} else {
bArr2[i2] = b;
b = 64;
}
}
bArr2[3] = b;
for (int i3 = 0; i3 <= 3; i3++) {
if (bArr2[i3] <= 63) {
sb.append(a[bArr2[i3]]);
} else {
sb.append('=');
}
}
}
return sb.toString();
}
}
与easy-apk类似,使用base64加密,并且改了码表
#python2运行
import base64
import string
string1=string.maketrans("i5jLW7S0GX6uf1cv3ny4q8es2Q+bdkYgKOIT/tAxUrFlVPzhmow9BHCMDpEaJRZN","ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/")
strEnBase64 = "QAoOQMPFks1BsB7cbM3TQsXg30i9g3==".translate(string1)
print(strEnBase64)
strFlag = base64.b64decode(strEnBase64)
print(strFlag.decode("utf-8")
得到flag
flag{just_ANot#er_@p3}
apk逆向
jd龟打开,入口好找
![](https://damoxilai.github.io/post-images/1627010921553.png)
找到检查函数checkSN
public boolean checkSN(String userName, String sn) {
if (userName == null) {
return false;
}
try {
if (userName.length() == 0 || sn == null || sn.length() != 22) { //输入的username不空,sn必须22位
return false;
}
MessageDigest digest = MessageDigest.getInstance("MD5");
digest.reset();
digest.update(userName.getBytes());
String hexstr = toHexString(digest.digest(), "");//将username的MD5值作为toHexString参数
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hexstr.length(); i += 2) {
sb.append(hexstr.charAt(i));
}
if (("flag{" + sb.toString() + "}").equalsIgnoreCase(sn)) {
return true;
}
return false;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return false;
}
}
private static String toHexString(byte[] bytes, String separator) {
StringBuilder hexString = new StringBuilder();
for (byte b : bytes) {
String hex = Integer.toHexString(b & 255);
if (hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex).append(separator);
}
return hexString.toString();
}
}
直接拿这些现有代码出来跑
package xctf_apk;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class apk {
private static String toHexString(byte[] bytes, String separator) {
StringBuilder hexString = new StringBuilder();
for (byte b : bytes) {
String hex = Integer.toHexString(b & 255);
if (hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex).append(separator);
}
return hexString.toString();
}
public static void main(String[] args) throws NoSuchAlgorithmException {
String username="Tenshine";
MessageDigest digest = MessageDigest.getInstance("MD5");
digest.reset();
digest.update(username.getBytes());
String hexstr = toHexString(digest.digest(), "");
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hexstr.length(); i += 2) {
sb.append(hexstr.charAt(i));
}
System.out.printf("flag{" + sb.toString() + "}") ;
}
}
![](https://damoxilai.github.io/post-images/1627010937880.png)
得到flag
flag{bc72f242a6af3857}
然后这题很坑
![](https://damoxilai.github.io/post-images/1627010948830.png)
提交bc72f242a6af3857
人民的名义-抓捕赵汉德
拿到jar文件,用jd龟打开
![](https://damoxilai.github.io/post-images/1627052454731.png)
找到关键代码
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
CheckInterface checkerObject = loadCheckerObject();//实现接口句柄
BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
while (true) {
System.out.println("Enter password:");
String line = stdin.readLine();
if (checkerObject.checkPassword(line)) {
System.out.println("Well done, that is the correct password");
System.exit(0);
continue;
}
System.out.println("Incorrect password");
}
}
checkerObject.checkPassword(line)
找到接口类
![](https://damoxilai.github.io/post-images/1627052472315.png)
发现checkPassword函数
![](https://damoxilai.github.io/post-images/1627052487486.png)
从代码明显看出MD5操作,
将"fa3733c647dca53a66cf8df953c2d539"MD5解密即可
解密得monkey99
flag{monkey99}
Android基础
拿到apk,jadx龟打开
![](https://damoxilai.github.io/post-images/1627123535938.png)
找MainActivicity,找到oncreate方法,发现关键函数checkPassword()
找到代码
public class Check {
public boolean checkPassword(String str) {
char[] pass = str.toCharArray();
if (pass.length != 12) { //12字符长
return false;
}
for (int len = 0; len < pass.length; len++) {
pass[len] = (char) (((255 - len) - 100) - pass[len]);//155-len
if (pass[len] != '0' || len >= 12) { //减了之后字符为0,对应ascii码48
return false;
}
}
return true;
}
}
写个python跑出字符串
>>> key = list('000000000000')
>>> key
['0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0']
>>> for i in range(12):
value = 255 - 100 - i - ord(key[i])
key[i] = chr(value)
>>> print("".join(str(i) for i in key))
kjihgfedcba`
打开apk,输入kjihgfedcba` 验证
![](https://damoxilai.github.io/post-images/1627123554911.png)
还要求输入显示码
回头看AndroidManifest.xml文件
![](https://damoxilai.github.io/post-images/1627123568823.png)
找到触发动作
输入android.is.very.fun
得到flag