吾爱破解春节红包三、四解题python版
由于春节时候回家,笔记本一直没在身边,就临时用家里的电脑尝试答了一下题。好在安卓的题都没有混淆,成功直接把源码转成了python,解出了答案。下面回忆下两道题的解题过程。
红包三
由于没有安装app,直接看的源码,先找\u的编码,找到了关键点decrypt
if (mainActivity.check() == 999) {
Toast.makeText(context, "快去论坛领CB吧!", 1).show();
textView.setText(mainActivity.decrypt("hnci}|jwfclkczkppkcpmwckng\u007f", 2));
}
public final String decrypt(String str, int i) {
Intrinsics.checkNotNullParameter(str, "encryptTxt");
char[] charArray = str.toCharArray();
Intrinsics.checkNotNullExpressionValue(charArray, "this as java.lang.String).toCharArray()");
StringBuilder sb = new StringBuilder();
for (char c : charArray) {
sb.append((char) (c - i));
}
String sb2 = sb.toString();
Intrinsics.checkNotNullExpressionValue(sb2, "with(StringBuilder()) {\n\u2026 toString()\n }");
return sb2;
}
解密代码看到了,用python写出来
s='hnci}|jwfclkczkppkcpmwckng\u007f'
a=''
for i in s:
#print(chr(ord(i)-2))
a+=''.join(chr(ord(i)-2))
print(a)
运行结果是flag{zhudajiaxinniankuaile}
红包四
这个题加上了uid,变得复杂了些,首先也是先找的正确的字符串。
if (a.B(obj, StringsKt.trim((CharSequence) editText2.getText().toString()).toString())) {
Toast.makeText(mainActivity, "恭喜你,flag正确!", 1).show();
}
定位到a.b函数
public final boolean B(String str, String str2) {
Intrinsics.checkNotNullParameter(str, "str");
Intrinsics.checkNotNullParameter(str2, "str2");
if ((str.length() == 0 && str2.length() == 0) || !StringsKt.startsWith$default(str2, "flag{", false, 2, (Object) null) || !StringsKt.endsWith$default(str2, "}", false, 2, (Object) null)) {
return false;
}
String substring = str2.substring(5, str2.length() - 1);
Intrinsics.checkNotNullExpressionValue(substring, "this as java.lang.String\u2026ing(startIndex, endIndex)");
C c = C.INSTANCE;
MD5Utils mD5Utils = MD5Utils.INSTANCE;
Base64Utils base64Utils = Base64Utils.INSTANCE;
String encode = B.encode(str + "Wuaipojie2023");
Intrinsics.checkNotNullExpressionValue(encode, "encode(str3)");
byte[] bytes = encode.getBytes(Charsets.UTF_8);
Intrinsics.checkNotNullExpressionValue(bytes, "this as java.lang.String).getBytes(charset)");
return Intrinsics.areEqual((Object) substring, (Object) c.cipher(mD5Utils.MD5(base64Utils.encodeToString(bytes)), 5));
}
这是一个比较的函数,输入参数应该是uid和flag
B.encode
的是这样的
public static String encode(String str) {
int length = str.length();
char[] cArr = new char[length];
int i = length - 1;
while (i >= 0) {
int i2 = i - 1;
cArr[i] = (char) (str.charAt(i) ^ '5');
if (i2 < 0) {
break;
}
i = i2 - 1;
cArr[i2] = (char) (str.charAt(i2) ^ '2');
}
return new String(cArr);
}
用python实现一下
def xor_with_string(x_1, x_2):
n = len(x_1)
x = int(x_1, 2) ^ int(x_2, 2)
return f'{x:08b}'
s=uid+'Wuaipojie2023'
l=['','','','','','','','','','','','','','','','','','','',]
lens=len(s)
i=lens-1
while i>=0:
i2=i-1
l[i]=chr(int(xor_with_string(bin(ord(s[i])),bin(ord('5'))),2))
if i2<0:
break
i=i2-1
l[i2]=chr(int(xor_with_string(bin(ord(s[i2])),bin(ord('2'))),2))
s_byte=''.join(l).encode('utf-8')
print(s_byte)
之后会将B.encode
的结果base64加密再MD5,python代码如下
bs = base64.b64encode(s_byte).decode('utf-8')
print(bs)
md5 = hashlib.md5()
md5.update(bs.encode('utf-8'))
res = md5.hexdigest()
print(res)
最后会执行c.cipher(mD5Utils.MD5(base64Utils.encodeToString(bytes)), 5)
cipher源码是这样写的
private final char cipher(char c, int i) {
char c2 = Character.isUpperCase(c) ? 'A' : 'a';
return (char) (((char) (((((char) (c - c2)) + (i % 26)) + 26) % 26)) + c2);
}
public final String cipher(String str, int i) {
Intrinsics.checkNotNullParameter(str, "str");
StringBuilder sb = new StringBuilder();
int length = str.length();
for (int i2 = 0; i2 < length; i2++) {
if (Intrinsics.compare((int) str.charAt(i2), 65) >= 0 && Intrinsics.compare((int) str.charAt(i2), 90) <= 0) {
sb.append(cipher(str.charAt(i2), i));
} else if (Intrinsics.compare((int) str.charAt(i2), 97) < 0 || Intrinsics.compare((int) str.charAt(i2), 122) > 0) {
sb.append(str.charAt(i2));
} else {
sb.append(cipher(str.charAt(i2), i));
}
}
String sb2 = sb.toString();
Intrinsics.checkNotNullExpressionValue(sb2, "sb.toString()");
return sb2;
}
同样用python实现一下
def ciper1(c,i):
if c.isupper():
c2='A'
else:
c2='a'
s=chr((ord(c)-ord(c2)+i%26+26)%26+ord(c2))
#print(s)
return s
def ciper(strs,i):
lens=len(strs)
sb=[]
for it in strs:
#print(it,ord(it))
if ord(it)>=65 and ord(it)<=90:
sb.append(ciper1(it,i))
elif ord(it)<97 or ord(it)>122:
sb.append(it)
else:
sb.append(ciper1(it,i))
#print(''.join(sb))
return ''.join(sb)
这样,基本整个生成flag的过程就很明显了,汇总下代码
import base64
import hashlib
def xor_with_string(x_1, x_2):
n = len(x_1)
x = int(x_1, 2) ^ int(x_2, 2)
return f'{x:08b}'
def ciper1(c,i):
if c.isupper():
c2='A'
else:
c2='a'
s=chr((ord(c)-ord(c2)+i%26+26)%26+ord(c2))
#print(s)
return s
def ciper(strs,i):
lens=len(strs)
sb=[]
for it in strs:
#print(it,ord(it))
if ord(it)>=65 and ord(it)<=90:
sb.append(ciper1(it,i))
elif ord(it)<97 or ord(it)>122:
sb.append(it)
else:
sb.append(ciper1(it,i))
#print(''.join(sb))
return ''.join(sb)
uid='' #输入自己的uid
s=uid+'Wuaipojie2023'
l=['','','','','','','','','','','','','','','','','','','',]
lens=len(s)
i=lens-1
while i>=0:
i2=i-1
l[i]=chr(int(xor_with_string(bin(ord(s[i])),bin(ord('5'))),2))
if i2<0:
break
i=i2-1
l[i2]=chr(int(xor_with_string(bin(ord(s[i2])),bin(ord('2'))),2))
s_byte=''.join(l).encode('utf-8')
print(s_byte)
bs = base64.b64encode(s_byte).decode('utf-8')
print(bs)
md5 = hashlib.md5()
md5.update(bs.encode('utf-8'))
res = md5.hexdigest()
print(res)
flag=ciper(res,5)
print(f"flag:flag{{{flag}}}")
最后
还尝试了一下红包六,还是太菜了,哭。