0.前言
1.程序分析
1.0 关闭aslr
方法使用CFF,具体操作见 http://gxkyrftx.xyz/2019/01/04/2016kxctf%E7%AC%AC28%E9%A2%98/ 中的1.0
1.1 main
比较短,就直接放出来了
n_8v1 = 0;
v0 = 65;
v1 = "A324F100182D501F6F6F78F397A3AA59641023D6A3DED8A4BF344F1E0FC71C188F4D";// 这是一个大整数
do // do——while循环,把上面的大数加载到内存
{
v2 = (unsigned __int8)byte_4281B0[v0];
shift(&n_8v1, &n_8v1);
push(v2);
v0 = (v1++)[1];
}
while ( v0 );
v3 = (void (*)(const char *, ...))printf;
printf("Please input username:");
memset(username, 0, 0x2800u);
sscanf("www.51asm.com", "%s", username);
printf("%s\n", "www.51asm.com");
init_username(username, strlen(username));
printf("Please input vericode:");
memset(username, 0, 0x2800u);
scanf("%s", username);
v4 = 0;
v5 = strlen(username);
if ( v5 ) // if判断,输入的字符串是否含有非法输入
{
while ( 1 )
{
v6 = username[v4];
if ( (unsigned __int8)(v6 - '0') > 9u && (unsigned __int8)(v6 - 'a') > 25u && (unsigned __int8)(v6 - 'A') > 25u )
break;
if ( ++v4 >= v5 )
goto LABEL_8;
}
printf("Invalid char found in input string");
getch();
result = 0;
}
else
{
LABEL_8:
v7 = username[0];
n_8v8 = 0;
if ( username[0] )
{
v8 = username;
do // 把输入也加入内存
{
v9 = (unsigned __int8)byte_4281B0[v7];
shift(&n_8v8, &n_8v8);
push(v9);
v7 = (v8++)[1];
}
while ( v7 );
v3 = (void (*)(const char *, ...))printf;
}
v3("\ninput accepted as:\n");
Size = 10240;
change_to_ascii(&n_8username, username); // 变为ascii码
v3("Username : %s\n", username);
Size = 10240;
change_to_ascii(&n_8v8, username);
v3("Vericode : %s\n", username);
v3("\nverifying...\n");
sub_403E30(&n_8username);
sub_403E30(&n_8v8);
if ( sub_401510() )
v3("%s\n", &unk_448EB5);
else
v3("failed\n");
getch();
result = 0;
}
return result;
}
1.2 问题
1.此题ida反编译出来的有点问题,反编译的结果跟正确的对不上,有几个函数参数是不对的
2.还有一些莫名其妙的问题,很长时间都没解决。函数无法反编译,这还怎么分析。。
1.3 程序流程
根据大佬wp直接贴出程序的验证流程,大佬wp https://bbs.pediy.com/thread-214562.htm
1.3.1 rsa算法
这个密码学学过。
1.选取两个强伪素数p和q。
2.计算φ(n)=(p-1)x(q-1)
3.选一个素数e,使(e,φ(n))=1。
4.计算e x d≡1 mod(φ(n)) 加密过程
c≡m^e(mod n) 解密过程
m=c^d(mod n)
1.3.2 本题中的e
通过用户名和17生成e,即:username^17%N = e,这里N为 A324F100182D501F6F6F78F397A3AA59641023D6A3DED8A4BF344F1E0FC71C188F4D,以下所有的N都为此大数。可以通过动态调试直接看到
e=9CA87DE3775787F7695F3F316E503600348AB6F58BEF375D0ED8F8BE84425FA7A6C3
e 循环 0 - 0x63,且每次e + 1,对sn 进行解密,解密后结果与 “Happy Birthday Buddy” 比较,成功则返回 1
1.3.3 本题中的n
n=A324F100182D501F6F6F78F397A3AA59641023D6A3DED8A4BF344F1E0FC71C188F4D
尝试分解n
十进制n=4836049822470645700707675549457249771340211537787234319173530875014794666294415181
分解后的p=62822928286347608648869628628072621308819。q=76979057716441943100156208562083628995999
十六进制表示p=B89EB7E0C9A568202F38B169D9D7E27B93,q=E2389B3C140BE6423EE5EB9DB5DAC2559F
得到d=1744216077318152194595333927534931955784044014454366651043557545108022731860010209
十六进制d=3AD75813052BC545DAC589519734FF0972200E8E31DFA08DE50D15CFA2667132E4E1
2.解题
将“Happy Birthday Buddy\x0ok”转换为16进制,并且反向排列,结果为
正向:4861707079204269727468646179204275646479306f6b
反向:6B6F007964647542207961646874726942207970706148
10进制:10290094653093735596660535282149174213262877870668144968
使用CrpTool计算十进制sn和Big Interger calculator转换16进制 结果如下
3.后续
这个题目调试有问题,以后调试手段熟练了,重新编辑一下,找不到问题在哪,难受。