首页
社区
课程
招聘
看雪CTF.TSRC 2018 团队赛-第11题
2018-12-22 19:10 4410

看雪CTF.TSRC 2018 团队赛-第11题

2018-12-22 19:10
4410
1. 总体逻辑
(1)已知原函数(前缀表达式)的前面与后面部分, 中间部分取自sn
(2)已知该表达式的导函数
求解sn

正常解法: 求导函数的积分得到原函数? 
不会求, 不过还好猜出来了

2. Base62解码

str_b62 = g_str_primitive_part1 + sn + g_str_primitive_part2_1 + g_str_primitive_part2_2;
str_b62.size() == 0x4407
str_primitive = Base62_decode(str_b62);
str_primitive.size() == 0x31AB

base62是变形的base64, 表的前面61位跟原来一样, 后3位分别用9A, 9B, 9C来替代, 9D为padding

.text:00401230 x_init_g_str_primitive_part1
.text:00401280 x_init_g_str_primitive_part2_1
.text:004012D0 x_init_g_str_primitive_part2_2
..
.text:0040342F                 mov     [ebp+b62.vtbl], offset ??_7Base62@@6B@ ; const Base62::`vftable'
...
.text:0040344E                 push    3Dh             ; a3
.text:00403450                 push    offset aAbcdefghijklmn ; "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklm"...
.text:00403455                 lea     ecx, [ebp+b62.table] ; this
.text:0040345B                 mov     byte ptr [ebp+var_4], 2
.text:0040345F                 call    x_std_string_ctor
.text:00403464                 mov     [ebp+b62.pad], '9'
...
.text:0040349C                 lea     eax, [ebp+str_sn]
.text:0040349F                 mov     edx, offset g_str_primitive_part1 ; a2
.text:004034A4                 push    eax             ; a3
.text:004034A5                 lea     ecx, [ebp+a1]   ; a1
.text:004034A8                 call    x_std_string_ctor_0
.text:004034AD                 add     esp, 4
.text:004034B0                 push    offset g_str_primitive_part2_1 ; a1
.text:004034B5                 mov     edx, eax        ; edx0
.text:004034B7                 mov     byte ptr [ebp+var_4], 5
.text:004034BB                 lea     ecx, [ebp+a2]   ; a2
.text:004034C1                 call    x_std_string_concat
.text:004034C6                 add     esp, 4
.text:004034C9                 push    offset g_str_primitive_part2_2 ; a1
.text:004034CE                 mov     edx, eax        ; edx0
.text:004034D0                 mov     byte ptr [ebp+var_4], 6
.text:004034D4                 lea     ecx, [ebp+str]  ; a2
.text:004034DA                 call    x_std_string_concat
.text:004034DF                 add     esp, 4
.text:004034E2                 lea     ecx, [ebp+str_sn] ; this
.text:004034E5                 push    eax             ; a2
.text:004034E6                 call    x_std_string_ctor_1
..
.text:00403623                 cmp     [ebp+str_sn._Mysize], 4407h
..
.text:00403669                 call    x_Base62_decode
..
.text:00403697                 cmp     [ebp+str_sn._Mysize], 31ABh

3.  求导函数后比较

.text:00401320 x_init_g_str_derivative
..
.text:004036DE                 call    x_parse_expression
..
.text:004037D9                 cmp     g_str_derivative._Myres, 10h
.text:004037E0                 lea     ecx, [ebp+str_sn]
.text:004037E3                 push    g_str_derivative._Mysize ; a4
.text:004037E9                 mov     edx, [ebp+str_sn._Mysize] ; a1
.text:004037EC                 mov     eax, offset g_str_derivative
.text:004037F1                 cmovnb  eax, dword ptr g_str_derivative.anonymous_0
.text:004037F8                 cmp     [ebp+str_sn._Myres], 10h
.text:004037FC                 push    eax             ; a3
.text:004037FD                 cmovnb  ecx, dword ptr [ebp+str_sn.anonymous_0] ; a2
.text:00403801                 call    x_std_compare

4. 前缀表达式

node_type
0: value
1: operator
2: tag

tags
0: x
1: e
2: pi

operators
0: +
1: -
2: *
3: /
4: Power_xa
5: Power_ax
6: Log
7: Sin
8: Cos

base62解码后, sn所在位置的前后的表达式如下, 满足前面长度检测条件的sn_mid的长度为55
*,*,Log,x,x,pi,75
sn_mid
,/,Power_ax,36,x,x,*,Power_ax,68

经过观察发现,
前缀表达式中有不少重复的子表达式,
且有不少满足如上特征,  使用正则匹配找到符合条件的子表达式
def test():
    ary = ['final_part1.txt', 'final_part2.txt', 'derivative_token.txt']
    for file_name in ary:
        buf = read_file(file_name)
        r = re.findall('\\*,\\*,Log,x,x,pi,(.*?),/,Power_ax,36,x,x,\\*,Power_ax,68', buf)
        for m in r:
            if len(m) == 55:
                print m
    return

# 75,Log,*,-,Power_ax,23,-,Power_xa,+,Log,Power_ax,90,Log

base62编码一下测试, 发现刚好符合条件, 得到sn: 
BpLDc1LExvZywqLC0sUG9A3ZXJfYXgsMjMsLSxQb3dlcl9A4YSwrLExvZyxQb3dlcl9AheCw5MCxMb2c
void test_sn()
{
	string sn;
	sn += ",pi,";
	// 55
	string token = "75,Log,*,-,Power_ax,23,-,Power_xa,+,Log,Power_ax,90,Log";
	sn += token;
	sn += ",";
	string src = g_b62_part1.substr(0, g_b62_part1.size() - 2) + Base62::Encode(sn) + g_b62_part2.substr(1, g_b62_part2.size() - 1);
	string final_sn = Base62::Encode(sn);
	final_sn = final_sn.substr(2, final_sn.size() - 3);
	printf("%s\n", final_sn.c_str());
	if (final_sn.size() != 80)
	{
		printf("fail, %d\n", final_sn.size());
		return;
	}
	string dst = Base62::Decode(src);
	if (src.size() == 0x4407 && dst.size() == 0x31AB)
	{
		printf("ok\n");
		printf("%s\n", sn.c_str());
		util::SaveFile(dst, util::GetAppPath() + "\\mydec.txt");
	} else
	{
		printf("fail\n");
		printf("%x\n", src.size()); // 0x4407
		printf("%x\n", dst.size()); // 0x31AB
	}
}



[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
点赞4
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回