看雪论坛作者ID:vagr4nt
1
int vuln()
{
__int64 buf; // [rsp+0h] [rbp-10h]
__int64 v2; // [rsp+8h] [rbp-8h]
buf = 0LL;
v2 = 0LL;
printf("You can set message: ", 0LL, 0LL);
read(0, &buf, 0x1AuLL);
return printf("OK, recv!", &buf);
}
signed __int64 __fastcall public_block_operation(__int64 a1, unsigned int *a2, __int64 a3, unsigned int a4, _DWORD *a5)
{
_DWORD *v6; // [rsp+8h] [rbp-468h]
char v7; // [rsp+30h] [rbp-440h]
char m; // [rsp+140h] [rbp-330h]
char e; // [rsp+250h] [rbp-220h]
char c; // [rsp+360h] [rbp-110h]
unsigned int edigits; // [rsp+468h] [rbp-8h]
unsigned int ndigits; // [rsp+46Ch] [rbp-4h]
v6 = a5;
bn_decode((__int64)&m, 65u, a3, a4);
bn_decode((__int64)&v7, 0x41u, (__int64)(v6 + 1), 256);
bn_decode((__int64)&e, 0x41u, (__int64)(v6 + 65), 256);
ndigits = bn_digits((__int64)&v7, 65);
edigits = bn_digits((__int64)&e, 65);
if ( (signed int)bn_cmp((__int64)&m, (__int64)&v7, ndigits) >= 0 )
return 4097LL;
bn_mod_exp((__int64)&c, (__int64)&m, (__int64)&e, edigits, (__int64)&v7, ndigits);
*a2 = (unsigned int)(*v6 + 7) >> 3;
bn_encode(a1, *a2, (__int64)&c, ndigits);
memset(&c, 0, 0x104uLL);
memset(&m, 0, 0x104uLL);
return 0LL;
}
注意到这里的e是用十六进制去存储的,也就是{0x01, 0x00, 0x01},即65537。N是小端序存储的,即0xdbea。
回到核心判断逻辑:
puts("LoginnPlease input your name:");
v13 = read(0, buf, 0x100uLL);
public_block_operation((__int64)v11, (unsigned int *)&v10, (__int64)buf, v13, &pk);
for ( i = 0; i <= 255 && !v11[i]; ++i )
;
v0 = &v11[i];
v1 = v0[1];
*(_QWORD *)s2 = *v0;
v9 = v1;
puts("Please input your password:");
memset(buf, 0, 0x100uLL);
v13 = read(0, buf, 0x100uLL);
public_block_operation((__int64)v11, (unsigned int *)&v10, (__int64)buf, v13, &pk);
for ( i = 0; i <= 255 && !v11[i]; ++i )
;
v2 = &v11[i];
v3 = v2[1];
*(_QWORD *)s = *v2;
v7 = v3;
if ( strcmp("root", s2) )
goto LABEL_22;
if ( strlen(s) != 6 )
goto LABEL_22;
i = 0;
while ( i <= 5 )
{
v4 = i++;
asc_2040A3[v4] ^= 0x11u;
}
if ( !strcmp(asc_2040A3, s) )
{
puts("Welcome back, administrator. ");
result = vuln();
}
说穿了就是截取加密后密文的前8个字节,然后去和'root'作比较。这里可以用GDB简单调试验证下:
我输入的username是'aaan',跟进来在strcmp之前rsi的值与RSA加密结果的前几位一致。
下面那个password处理和这个同理,只不过加了一个简单异或,就不再赘述。
那么问题的核心就在于找到一个明文字符串,用公钥加密后的前几个字节必须是root。
from pwn import *
rs = process('./rsa')
rs.sendline('2')
rs.recvuntil('your name:n')
fuck="TNHx8bx96xcaxedx02xbdpbxecvxc2_x87x91x8cFUxf1^xd7L3xc4Xxcd1Exc7dxa7xcbx83x08xecx1eQxfe;xe5xd1Kxf5xa0x06xdcx1a@Ux8xe2kE[xe9exnx06xe2xd2xadrxccx99x14nxb0,xe8x95//x0ca\n[x9e4Oxdex9b>x9axedLfxa0'ax8bxc7wW0x85nxa4Cx94oxabxb4KxfcDvx96f5]cx97xd9`x00xbexc4Rx19xd9Qxeb<"
rs.send(fuck)
fuck2='x80xc7x1exc6xfex92xeexcbxef2xe3xdfxc2xc2x8axb0xa6xdax8bxbbxddWxbd9[x97xa9xeebx9fxbaxbe]xa3xd21(@x04x01x9eg\jx89xf2xc6xd2x87xd5xebx8exbfxccx00xc0qx89x19?xcfxfcUxfeq-{xb6xb9xafxe8xb6excbxb9x12x13.hxce@xd2xcefxffxd8xd2xa5xc4^x8eKBxeexf5Qx17Xxb60xcdxaa>7x1fx82Sxb9F Hgxf5xdexb0r*xdax9axaax99M`xe8,xa0dxb2'
rs.recvuntil('your password:n')
rs.send(fuck2)
rs.interactive()
看雪ID:vagr4nt
https://bbs.pediy.com/user-home-904020.htm
*本文由看雪论坛 vagr4nt 原创,转载请注明来自看雪社区
# 往期推荐
1. 【分析记录】疑似Confucius组织组件CuoliVXaRAT分析
球分享
球点赞
球在看
点击“阅读原文”,了解更多!
本文始发于微信公众号(看雪学院):MTCTF-PSA-Writeup
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论