首页
社区
课程
招聘
[原创]第二题 变形金钢
2019-3-23 10:53 2800

[原创]第二题 变形金钢

2019-3-23 10:53
2800

1.思路

表面上看着是

实际上关键判断在

具体这么实现的我也不太明白,貌似实在so中做了什么,太菜了!

2.正文

把apk拖入jadx中(新版的看着好像有点吊,放在下面需要的可以下哈)
直接拖到jadx

看着密码只是反转的用户名,奈何试了一下无论如何都不成功。

事出反常必有妖

仔细看了下
居然有lib库的。
于是乎在搜索框中乎输入oo000oo你将获得正确的类



看逻辑貌似关键点就是这个eq函数,返回1就会利用password当作key执行后面AES,CFB模式的解密函数。貌似解密出来的flag怎么是乱码啊!
不知所措,试了下password提交答案成功了???????????????????????
其中的login.setEnable(false)有点烦人,方便调试直接改了重打包。

有个init func 运行的时候吧加密的字符串解密出来

jni_load 找动态注册的函数

红箭头的地方就是输入的密码
直接x看引用看发现调用的就在下面,看来

算法大佬看到了的肯定一眼都看出来是魔改的base64,奈何算法见的太少的菜鸡没看出来,

最后输入密码,发现结果是线性变化的,看到后面的";;"两个这么东西才猜是魔改的base64

不想逆算法,反正是线性的直接穷举其中有个v46,是前面算出来的dump出来就好了。
开始的时候想写DFS实现的,写了一半发现自己太傻逼了!3个输入对应4个输出都嘛!真的脑残。
// KCTF2019-2.cpp: 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <string.h>
#include <stdlib.h>
#include <windows.h>
char s1[] = "650f909c-7217-3647-9331-c82df8b98e98";
//------------------------------------------------------------
//-----------       Created with 010 Editor        -----------
//------         www.sweetscape.com/010editor/          ------
//
// File    : C:\Users\thinkpad\Desktop\kanxue_CTF\debug\dump.hex
// Address : 0 (0x0)
// Size    : 256 (0x100)
//------------------------------------------------------------
//------------------------------------------------------------
//-----------       Created with 010 Editor        -----------
//------         www.sweetscape.com/010editor/          ------
//
// File    : C:\Users\thinkpad\Desktop\kanxue_CTF\debug\dump1.hex
// Address : 0 (0x0)
// Size    : 256 (0x100)
//------------------------------------------------------------
unsigned char hexData[256] = {
	0xF0, 0x37, 0xE1, 0x9B, 0x2A, 0x15, 0x17, 0x9F, 0xD7, 0x58, 0x4D, 0x6E, 0x33, 0xA0, 0x39, 0xAE,
	0x04, 0xD0, 0xBE, 0xED, 0xF8, 0x66, 0x5E, 0x00, 0xD6, 0x91, 0x2F, 0xC3, 0x10, 0x4C, 0xF7, 0xA6,
	0xC1, 0xEC, 0x6D, 0x0B, 0x50, 0x65, 0xBB, 0x34, 0xFA, 0xA4, 0x2D, 0x3B, 0x23, 0xA1, 0x96, 0xD5,
	0x1D, 0x38, 0x56, 0x0A, 0x5D, 0x4F, 0xE4, 0xCC, 0x24, 0x0D, 0x12, 0x87, 0x35, 0x85, 0x8E, 0x6F,
	0xC6, 0x13, 0x9A, 0xD3, 0xFC, 0xE7, 0x08, 0xAC, 0xB7, 0xE9, 0xB0, 0xE8, 0x41, 0xAA, 0x55, 0x53,
	0xC2, 0x42, 0xBC, 0xE6, 0x0F, 0x8A, 0x86, 0xA8, 0xCF, 0x84, 0xC5, 0x48, 0x74, 0x36, 0x07, 0xEB,
	0x88, 0x51, 0xF6, 0x7F, 0x57, 0x05, 0x63, 0x3E, 0xFE, 0xB8, 0xC9, 0xF5, 0xAF, 0xDF, 0xEA, 0x82,
	0x44, 0xF9, 0xCD, 0x06, 0xBA, 0x30, 0x47, 0x40, 0xDE, 0xFD, 0x1C, 0x7C, 0x11, 0x5C, 0x02, 0x31,
	0x2C, 0x9C, 0x5F, 0x46, 0x27, 0xC4, 0x83, 0x73, 0x16, 0x90, 0x20, 0x76, 0x7B, 0xF2, 0xE3, 0xF3,
	0x77, 0x52, 0x80, 0x25, 0x09, 0x26, 0x3F, 0xC7, 0x18, 0x1B, 0xA3, 0xFF, 0xFB, 0xCB, 0xA9, 0x8C,
	0x54, 0x7A, 0x68, 0xB4, 0x70, 0x4B, 0xE2, 0x49, 0x22, 0x7E, 0xA5, 0xB6, 0x81, 0x9D, 0x4E, 0x67,
	0xF1, 0xA7, 0x3C, 0xD9, 0x94, 0xEF, 0x32, 0x6B, 0x1F, 0xB1, 0x60, 0xB9, 0x64, 0x59, 0x01, 0xB3,
	0x7D, 0xE0, 0x6C, 0xAD, 0x97, 0x19, 0xB5, 0x3A, 0xF4, 0xD8, 0x8D, 0x98, 0x03, 0x93, 0x1A, 0xDC,
	0x1E, 0x4A, 0xC0, 0x5A, 0xE5, 0xD1, 0x3D, 0x14, 0xC8, 0x79, 0xBD, 0x43, 0xDB, 0x69, 0xD2, 0x61,
	0x95, 0x9E, 0x21, 0x45, 0x89, 0x2B, 0xAB, 0x29, 0xA2, 0x8B, 0x2E, 0xD4, 0x0E, 0x62, 0xCA, 0x28,
	0xDA, 0x5B, 0x72, 0x8F, 0x99, 0x75, 0xEE, 0x78, 0x0C, 0x71, 0xBF, 0xDD, 0xCE, 0x92, 0x6A, 0xB2
};

unsigned char table[] = "!:#$%&()+-*/`~_[]{}?<>,.@^abcdefghijklmnopqrstuvwxyz0123456789\\';";
BYTE temp[] = " {9*8ga*l!Tn?@#fj'j$\\g;;";
unsigned char temp_result[24] = { 0 };
int eq(char *input_pass)
{
	size_t len; // r10
	unsigned __int8 *v2; // r6
	BYTE *v3; // r8
	BYTE *v4; // r11
	int v5; // r0
	size_t i_1; // r2
	BYTE *un_serial; // r1
	int v8; // r3
	int v9; // r1
	unsigned int v10; // r2
	int v11; // r3
	int v12; // r0
	int v13; // r4
	unsigned __int8 v14; // r0
	BYTE *v15; // r3
	BYTE *v16; // r5
	BYTE *v17; // r4
	unsigned int v18; // r5
	int v19; // r1
	int v20; // r0
	signed int v21; // r1
	int v22; // r2
	size_t pass_len; // r0
	unsigned int pl; // r8
	unsigned int v25; // r5
	BYTE *calc_r; // r0
	int v27; // r3
	int hi; // r10
	unsigned int i; // r2
	int v30; // r12
	bool v31; // zf
	BYTE *v32; // r1
	bool v33; // zf
	int v34; // r3
	int v35; // r1
	unsigned __int8 v36; // r11
	unsigned int v37; // lr
	char v38; // r1
	BYTE *v39; // r2
	int v40; // t1
	unsigned int v42; // [sp+4h] [bp-234h]
	unsigned int v43; // [sp+8h] [bp-230h]
	unsigned int v44; // [sp+10h] [bp-228h]
	//BYTE *input_pass; // [sp+14h] [bp-224h]
	char hexdump[256]; // [sp+18h] [bp-220h]
	char v47[256]; // [sp+118h] [bp-120h]
	int v48; // [sp+218h] [bp-20h]

	//input_pass = (BYTE *)((int(*)(void))a1->functions->GetStringUTFChars)();
	
	pass_len = strlen(input_pass);
	pl = pass_len;
	v25 = 0x33;
	v43 = 8 * (3 - -3 * (pass_len / 3));
	v42 = v25 + v43 / 6;
	calc_r = (BYTE *)malloc(v42 + 1);
	//memset(calc_r+ v25, 0, 24);
	memset(temp_result, 0, 24);
	memcpy(hexdump, hexData, 256);
	if (pl)                                     // len
	{
		hi = 0;
		i = 0;
		v30 = 0;
		v44 = v25;
		do
		{
			hi = (hi + 1) % 256;
			v35 = (unsigned __int8)hexdump[hi];
			v30 = (v30 + v35) % 256;
			hexdump[hi] = hexdump[v30];
			hexdump[v30] = v35;
			v17 = (BYTE *)(unsigned __int8)hexdump[hi];
			v36 = hexdump[(unsigned __int8)(v35 + (BYTE)v17)] ^ input_pass[i];
			if (i && (v27 = 0xAAAAAAAB * (unsigned __int64)i >> 32, v37 = 3 * (i / 3), v37 != i))
			{
				v31 = i == 1;
				if (i != 1)
					v31 = v37 + 1 == i;
				if (v31)
				{
					v32 = table;
					calc_r[v44 + i] = table[(unsigned __int8)calc_r[v44 + i] | ((unsigned int)v36 >> 4)];
					v17 = &calc_r[v44 + i];
					v27 = 4 * v36 & 0x3C;
					v17[1] = v27;
					if (i + 1 >= pl)
						goto LABEL_53;
				}
				else
				{
					v33 = i == 2;
					if (i != 2)
						v33 = v37 + 2 == i;
					if (v33)
					{
						v17 = (BYTE *)(v36 & 0xC0);
						v34 = v44++ + i;
						calc_r[v34] = table[(unsigned __int8)calc_r[v34] | ((unsigned int)v17 >> 6)] ^ 0xF;
						v27 = (int)&calc_r[v34];
						*(BYTE *)(v27 + 1) = table[v36 & 0x3F];
					}
				}
			}
			else
			{
				calc_r[v44 + i] = table[(unsigned int)v36 >> 2] ^ 7;
				v17 = &calc_r[v44 + i];
				v27 = 16 * v36 & 0x30;
				v17[1] = v27;
				if (i + 1 >= pl)
				{
					v38 = table[v27];
					*((WORD *)v17 + 1) = 15163;
					goto LABEL_43;
				}
			}
			++i;
		} while (i < pl);
	}
	while (1)
	{
		if (v43)
		{
			//*v32 = 1;
			v17 = (BYTE *)v42;
			
			memcpy(temp_result,&calc_r[v25],24);
			free(calc_r);
			return 0;
		}
		else
		{
			*v32 = 1;
		}
		//calc_r = (BYTE *)(_stack_chk_guard - v48);
		//if (_stack_chk_guard == v48)
			break;
	LABEL_53:
		v38 = v32[v27];
		v17[2] = 52;
	LABEL_43:
		v17[1] = v38;
	}
	free(calc_r);
	return (unsigned __int8)v32;
}

char ascii[63] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
//char ascii[63] = {0};
int n = 62;
char all_result[62][24] = { 0 };
void find(char *f,int curr) {
	int len = strlen(f);
	for (int i = 0; i < n; i++) {
		char c1 = ascii[i];
		memcpy(f + len, &c1, 1);
		for (int j = 0; j < n; j++) {
			char c2 = ascii[j];
			memcpy(f + len + 1, &c2, 1);
			for (int m = 0; m < n; m++) {
				char c3 = ascii[m];
				memcpy(f + len + 2, &c3, 1);
				eq(f);
				if (temp_result[curr] == temp[curr]) {
					if (temp_result[curr + 1] == temp[curr + 1]) {
						if (temp_result[curr + 2] == temp[curr + 2]) {
							if (temp_result[curr + 3] == temp[curr + 3]) {
								memcpy(f + len, &c1, 1);
								memcpy(f + len + 1, &c2, 1);
								memcpy(f + len + 2, &c3, 1);
								return;
							}
						}
					}
				}
			}
		}
	}
}
int main()
{
	char f[24] = { 0 };
	int n = 63;
	//123 456 789 012 345 6
	for (int i = 0; i < 5;i++) {
		find(f, i * 4);
	}
	int len = strlen(f);
	for (int i = 0; i < n;i++) {
		char c = ascii[i];
		memcpy(f+len,&c,1);
		eq(f);
		if (temp_result[20]==temp[20] && temp_result[21] == temp[21] && temp_result[22] == temp[22]) {
			memcpy(f + len, &c, 1);
			break;
		}
	}
	printf("Found a password :%s\n",f);

    return 0;
}



[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界

最后于 2020-1-19 14:46 被大帅锅编辑 ,原因:
上传的附件:
收藏
点赞1
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回