Mobile
AreYouRich
安卓層逆向,但用實際上是可能存在多解的,這點令人有些困惑。主要是輸入用戶名和密碼,然后有一系列校驗,以及一堆亂七八糟的操作,很多可能是用來迷惑眼睛的,但這並不重要的,主要算法在這。
動態生成了一個table,並於輸入異或,隨后與加密數據v2進行比較。v2可以直接提取,table直接調解出來與加密數據異或即可,獲得token關鍵部分。
using System;
namespace solu
{
class Program
{
static void Main(string[] args)
{
byte[] enc = { 0x51, 0xf3, 0x54, 0x92, 0x48, 0x4d, 0xa0, 0x4d, 0x20, 0x8d, 0xb5, 0xda, 0x9f, 0x45, 0xc0, 0x31, 0x8, 0xe5, 0x38, 0x72, 0xbc, 0xae, 0x4c, 0x96, 0xde };
char[] secret = "5FQ5AaBGbqLGfYwjaRAuWGdDvyjbX5nH".ToCharArray();
//char[] input_byte = "ffffffffff_DDDDDDDDDD@001_1633674507603".ToCharArray();
byte[] table = new byte[0x100];
int v9;
for (v9 = 0; v9 < 0x100; ++v9)
{
table[v9] = (byte)v9;
}
{
int v9_1 = 0;
int v10 = 0;
int v11 = 0;
while (v9_1 < 0x100)
{
v11 = (secret[v10] & 0xFF) + (table[v9_1] & 0xFF) + v11 & 0xFF;
byte v12 = table[v9_1];
table[v9_1] = table[v11];
table[v11] = v12;
v10 = (v10 + 1) % secret.Length;
++v9_1;
}
}
int secret_1 = enc.Length;
int v6 = 16;
int v9_2 = 0;
int v10_1 = 0;
int v11_1 = 0;
while (v9_2 < secret_1)
{
v10_1 = v10_1 + 1 & 0xFF;
v11_1 = (table[v10_1] & 0xFF) + v11_1 & 0xFF;
byte v12_1 = table[v10_1];
table[v10_1] = table[v11_1];
table[v11_1] = v12_1;
byte res = table[(table[v10_1] & 0xFF) + (table[v11_1] & 0xFF) & 0xFF];
Console.Write((char)(res ^ enc[v9_2]));
++v9_2;
}
}
}
}
獲得了token,里面包含用戶名和密碼,直接輸入程序即可獲得flag。
flag{y0u_h@V3_@_107_0f_m0n3y!!}
designEachStep
3DES解密,了一個二進制數據文件,並且輸入的24個字節作為3DES的密鑰。前8字節直接gzip解壓提取一個文件即可獲得,隨后另外的兩個8字節,需要進行3DES取每次的文件頭前8字節。
實際上可以提取java代碼到idea中,將一些必要的包用mavn導入主要是lz4,去除一些不必要的代碼,添加一部分代碼,直接調試,然后在equals函數下斷點提取每次check比對的正確數據即可,但注意每提取一次數據都需要將代碼中的input修正一下,否則無法進入下一個equals函數。
package test.t3;
import java.io.*;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.zip.GZIPInputStream;
import java.util.zip.Inflater;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import net.jpountz.lz4.LZ4Factory;
import net.jpountz.lz4.LZ4SafeDecompressor;
public class test {
public static String Read2(String infile) throws Exception
{
StringBuffer sb = new StringBuffer();
File file = new File(infile);
FileInputStream fis = new FileInputStream(file);
byte buffer[] = new byte[1024];
int len = 0;
while((len = fis.read(buffer)) != -1)
{
sb.append(new String(buffer, 0, len));
//sb.append(new String(buffer, 0, len, "UTF-8")); //將byte轉String可以指定編碼方式
}
fis.close();
return sb.toString();
}
public static Key get_key(byte[] arg4) {
int v0 = 8;
byte[] v1 = new byte[v0];
int v2;
for(v2 = 0; v2 < arg4.length; ++v2) {
if(v2 >= v0) {
break;
}
v1[v2] = arg4[v2];
}
return new SecretKeySpec(v1, "DES");
}
public static void main(String[] args) throws IOException {
Cipher v5_8;
byte[] enc_data;
byte[] read_byte;
byte[] data;
String enc_algorithm_DES = "DES";
String input = "DE5_c0mpr355_m@yssssssss";
if(input.length() != 24) {
return;
}
byte[] input_byte = input.getBytes();
int header_size = 8;
byte[] input_header = new byte[header_size];
//讀取data.bin全部字節
try {
DataInputStream v5 = new DataInputStream(new FileInputStream("D:\\Project\\Java\\javaweb\\untitled1\\src\\main\\java\\test\\t3\\data.bin"));
data = new byte[v5.available()];
v5.readFully(data);
}
catch(IOException v15_1) {
return;
}
// 將input 前8個字節拷貝至header
System.arraycopy(input_byte, 0, input_header, 0, header_size);
ByteArrayOutputStream data_stream = new ByteArrayOutputStream();
ByteArrayInputStream v6 = new ByteArrayInputStream(data);
int v4_2 = 2;
byte[] v7 = null;
GZIPInputStream v8 = new GZIPInputStream(((InputStream)v6)); // 讀取gzip壓縮數據,即解壓縮gzip
read_byte = new byte[0x100];
while(true) {
int v9 = v8.read(read_byte);
if(v9 < 0) {
break;
}
data_stream.write(read_byte, 0, v9);
}
byte[] data_byte = data_stream.toByteArray(); //DE5_c0mp Z...AS.m
if(data_byte.length >= header_size) {
read_byte = new byte[header_size];
System.arraycopy(data_byte, 0, read_byte, 0, header_size); // DE5_c0mp
enc_data = new byte[data_byte.length - header_size];
System.arraycopy(data_byte, header_size, enc_data, 0, data_byte.length - header_size);
if(!Arrays.equals(read_byte, input_header)) { //check 輸入塊
}
try {
v5_8 = Cipher.getInstance(enc_algorithm_DES);
v5_8.init(v4_2, get_key(input_header)); //將輸入前8個字節作為DES的key,解密
data_byte = v5_8.doFinal(enc_data); //
System.out.println("Hello");
}
catch(InvalidKeyException v5_3) {
v5_3.printStackTrace();
}
catch(IllegalBlockSizeException v5_4) {
v5_4.printStackTrace();
}
catch(BadPaddingException v5_5) {
v5_5.printStackTrace();
}
catch(NoSuchPaddingException v5_6) {
v5_6.printStackTrace();
}
catch(NoSuchAlgorithmException v5_7) {
v5_7.printStackTrace();
}
if(data_byte == null) {
return;
}
System.arraycopy(input_byte, header_size, input_header, 0, header_size);
Inflater v6_2 = new Inflater();
v6_2.setInput(data_byte);
ByteArrayOutputStream v8_2 = new ByteArrayOutputStream(data_byte.length);
int v5_9 = 0x400;
try {
data_byte = new byte[v5_9];
while(!v6_2.finished()) {
v8_2.write(data_byte, 0, v6_2.inflate(data_byte));
}
}
catch(Throwable v15_2) {
}
try {
v8_2.close();
}
catch(IOException v5_11) {
v5_11.printStackTrace();
}
v6_2.end();
data_byte = v8_2.toByteArray();
if(data_byte.length < header_size) {
}
read_byte = new byte[header_size];
System.arraycopy(data_byte, 0, read_byte, 0, header_size);
enc_data = new byte[data_byte.length - header_size];
System.arraycopy(data_byte, header_size, enc_data, 0, data_byte.length - header_size);
if(!Arrays.equals(read_byte, input_header)) {
}
try {
v5_8 = Cipher.getInstance(enc_algorithm_DES);
v5_8.init(v4_2, get_key(input_header));
data_byte = v5_8.doFinal(enc_data);
}
catch(InvalidKeyException v5_3) {
v5_3.printStackTrace();
}
catch(IllegalBlockSizeException v5_4) {
v5_4.printStackTrace();
}
catch(BadPaddingException v5_5) {
v5_5.printStackTrace();
}
catch(NoSuchPaddingException v5_6) {
v5_6.printStackTrace();
}
catch(NoSuchAlgorithmException v5_7) {
v5_7.printStackTrace();
}
byte[] v9_1 = data_byte;
try {
// label_141:
// v5_10.printStackTrace();
}
catch(Throwable v15_2) {
// goto label_139;
}
try {
v8_2.close();
}
catch(IOException v5_11) {
v5_11.printStackTrace();
}
System.arraycopy(input_byte, 16, input_header, 0, header_size);
LZ4SafeDecompressor v8_3 = LZ4Factory.safeInstance().safeDecompressor();
input_byte = new byte[v9_1.length * 5];
v5_9 = v8_3.decompress(v9_1, 0, v9_1.length, input_byte, 0);
read_byte = new byte[v5_9];
System.arraycopy(input_byte, 0, read_byte, 0, v5_9);
if(v5_9 >= header_size) {
input_byte = new byte[header_size];
System.arraycopy(read_byte, 0, input_byte, 0, header_size);
v5_9 -= header_size;
enc_data = new byte[v5_9];
System.arraycopy(read_byte, header_size, enc_data, 0, v5_9);
if(!Arrays.equals(input_byte, input_header)) {
}
try {
Cipher v15_8 = Cipher.getInstance(enc_algorithm_DES);
v15_8.init(v4_2, get_key(input_header));
v7 = v15_8.doFinal(enc_data);
}
catch(InvalidKeyException v15_3) {
v15_3.printStackTrace();
}
catch(IllegalBlockSizeException v15_4) {
v15_4.printStackTrace();
}
catch(BadPaddingException v15_5) {
v15_5.printStackTrace();
}
catch(NoSuchPaddingException v15_6) {
v15_6.printStackTrace();
}
catch(NoSuchAlgorithmException v15_7) {
v15_7.printStackTrace();
}
}
}
}
}
flag{DE5_c0mpr355_m@y_c0nfu53}
Reverse
Petition
這個程序似乎將一些例如mv之類的指令等大量等效的用xor指令替代了,導致看起來有一堆xor指令,實際上題目也是里面的一堆函數也是異或加密,每個加密一個字節。
將每處的這幾條指令的三個立即數數據異或取字節,即可解密一個字節數據。實際上IDA幫助我們簡化了。
print(chr(0x1e^0x78),end='')
print(chr(0x6c^0x00),end='')
print(chr(0x7^0x66),end='')
print(chr(0xa9^0xce),end='')
print(chr(0xf9^0x82),end='')
print(chr(0x8c^0xb5),end='')
print(chr(0x88^0xbe),end='')
print(chr(0xcb^0xa8),end='')
print(chr(0x52^0x64),end='')
print(chr(0xa0^0x99),end='')
print(chr(0x19^0x2f),end='')
print(chr(0x21^0x15),end='')
print(chr(0x66^0x50),end='')
print(chr(0x3^0x2e),end='')
print(chr(0xaf^0x97),end='')
print(chr(0xf6^0xc7),end='')
print(chr(0x43^0x7b),end='')
print(chr(0x18^0x2c),end='')
print(chr(0xc9^0xe4),end='')
print(chr(0xfe^0xca),end='')
print(chr(0x66^0x55),end='')
print(chr(0x9c^0xaa),end='')
print(chr(0x4c^0x7f),end='')
print(chr(0x00^0x2d),end='')
print(chr(0x25^0x1d),end='')
print(chr(0xd6^0xb2),end='')
print(chr(0x9a^0xff),end='')
print(chr(0x7d^0x44),end='')
print(chr(0xbd^0x90),end='')
print(chr(0x45^0x72),end='')
print(chr(0x65^0x56),end='')
print(chr(0x6e^0x8),end='')
print(chr(0x85^0xb2),end='')
print(chr(0x12^0x21),end='')
print(chr(0x7f^0x46),end='')
print(chr(0x2b^0x13),end='')
print(chr(0x24^0x14),end='')
print(chr(0xfc^0xca),end='')
print(chr(0x24^0x12),end='')
print(chr(0x50^0x33),end='')
print(chr(0x12^0x23),end='')
print(chr(0xea^0x97),end='')
print(chr(0xb2^0xb2),end='')
flag{96c69646-8184-4363-8de9-73f7398066c1}