您的位置:首页 > 其它

170920 逆向-CTF练习平台(RE-love)

2017-09-21 00:39 495 查看
1625-5 王子昂 总结《2017年9月20日》 【连续第353天总结】

A. CTF练习平台-RE

B.

love

偶然看到这个平台,找了下RE,只有四题 看起来都很简单

粗略观察了一下Solves数,前三题都高达数百,最后一题却只有五个解决

嗯……有挑战性!做了!

下下来先查壳,果然没有

拖入IDA

没有找到main函数,start里也没有东西

Shift+f12查看字符串,发现了”please enter the flag”的字样

很简单,双击跳过去,然后按x查看交叉引用

锁定sub_4156E0,F5反编译以后粗略看了一下,从头到尾要求输入flag,验证,输出正确/错误提示,很完整

那么它就是main了

int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // ebx@0
int v4; // esi@0
int len_input; // eax@6
const char *v6; // eax@6
size_t v7; // eax@9
char v9; // [sp+0h] [bp-188h]@6
char v10; // [sp+Ch] [bp-17Ch]@1
int v11; // [sp+10h] [bp-178h]@3
int j; // [sp+DCh] [bp-ACh]@6
int i; // [sp+E8h] [bp-A0h]@1
char Dest[108]; // [sp+F4h] [bp-94h]@5
char input; // [sp+160h] [bp-28h]@6
char v16; // [sp+17Ch] [bp-Ch]@6
unsigned int v17; // [sp+184h] [bp-4h]@1
int savedregs; // [sp+188h] [bp+0h]@1

memset(&v10, 0xCCu, 0x17Cu);
v17 = (unsigned int)&savedregs ^ __security_cookie;
for ( i = 0; i < 100; ++i )                   // 清空Dest
{
v11 = i;
if ( (unsigned int)i >= 0x64 )
sub_411154(v3, (int)&savedregs, v4);
Dest[v11] = 0;
}
sub_41132F("please enter the flag:", v9);
sub_411375("%20s", &input);
len_input = j_strlen(&input);
v6 = (const char *)deal((int)&input, len_input, (int)&v16);// b64
strncpy(Dest, v6, 0x28u);
sub_411127();
i = j_strlen(Dest);
for ( j = 0; j < i; ++j )
Dest[j] += j;                               // str
= str
+ n
v7 = j_strlen(Dest);
strncmp(Dest, Str2, v7);
if ( sub_411127() )
sub_41132F("wrong flag!\n", v9);
else
sub_41132F("rigth flag!\n", v9);
sub_41126C(&savedregs, &dword_415890);
sub_411280();
return sub_411127();
}


虽然很多库函数都被封装了,但是从参数还是可以很轻松看出来的

正好今天看书的时候看到了,IDA有自动解开包装函数的功能

例如j_strlen()函数,在OD中是看不出来的,sub_4110C8的函数体只有一句jmp strlen,是很明显的包装函数

不过printf和scanf这种有其他调用的不够单纯的包装函数就没识别了

很明显,先经过deal函数加工,然后与下标做和后与常量字符串比较即可

那么重点在于deal函数的过程了:



贼复杂,让人禁不住感叹果然是只有5个人做出来的题吗……

本来准备留到最后结合OD动态调试慢慢逆的,先看看外面main函数中出现了三次的不明函数sub_411127的

反编译失败,汇编也看不出啥名堂,直接动态调吧

OD加载时被断在了ntdll处,不知道出了啥幺蛾子……

还是从字符串下手,智能搜索找到printf和scanf下断,然后输入试验字符串1234567890后先跳过复杂的deal函数,令人惊喜的一幕出现了:



这个熟悉的格式……后面len函数的结果表示正好长度还是0x10=16位,这不就是base64么!

找个加密来验证一下,还真的是

那么问题就很简单了,找到Str2字符串,先于下标作差然后b64解码即可:

import base64
s = "e3nifIH9b_C@n@dH"
flag = ""
for i in range(len(s)):
flag += chr(ord(s[i]) - i)
flag = base64.b64decode(flag)
print(flag)


b’{i_l0ve_you}’

最后记得把bytes格式标志去了,拼装上’flag’头

C. 明日计划

加密与解密 壳相关知识
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: