2020mrctf(Re)-hard-to-go

Hard-to-go

拿到程序查壳后发现无壳直接拖入ida进行分析

然后发现没有符号表

http://www.syjblog.com/wp-content/uploads/2021/04/VIK9X82XVN90AUV3TS-1024x601.png

我们导入一个插件

https://github.com/Mas0nShi/IDAGolangHelper

直接将zip下载下来然后解压,解压之后将文件夹中的两个内容移动到IDA7.5的plugins目录下,然后重新打开ida即可

http://www.syjblog.com/wp-content/uploads/2021/04/image-13-1024x629.png

然后将文件载入的时候

http://www.syjblog.com/wp-content/uploads/2021/04/image-14.png

点击Rename function,即可重新命名函数

之后直接找到main.main开始分析

// main.main
__int64 __fastcall main_main(__int64 *a1, __int64 a2, int a3, __int64 a4, int a5, int a6)
{
int v6; // edx
int v7; // ecx
int v8; // er8
int v9; // er9
int v10; // er8
int v11; // er9
int v12; // edx
__int64 v13; // rcx
int v14; // er8
int v15; // er9
int v16; // edx
int v17; // ecx
int v18; // er8
int v19; // er9
int v20; // edx
int v21; // ecx
int v22; // er8
int v23; // er9
int v24; // er8
__int64 v25; // r9
int v26; // esi
int v27; // er8
__int64 *v28; // r9
int v29; // er8
int v30; // er9
int v31; // edx
__int64 result; // rax
_QWORD *v33; // [rsp+8h] [rbp-C0h]
__int64 v34; // [rsp+18h] [rbp-B0h]
__int64 v35; // [rsp+18h] [rbp-B0h]
unsigned __int64 v36; // [rsp+20h] [rbp-A8h]
__int64 v37; // [rsp+28h] [rbp-A0h]
__int64 v38; // [rsp+28h] [rbp-A0h]
__int64 v39; // [rsp+30h] [rbp-98h]
unsigned __int64 v40; // [rsp+40h] [rbp-88h]
_BYTE key[12]; // [rsp+48h] [rbp-80h] BYREF
_BYTE v42[12]; // [rsp+54h] [rbp-74h] BYREF
__int64 v43; // [rsp+80h] [rbp-48h] BYREF
_QWORD *v44; // [rsp+88h] [rbp-40h]
__int128 v45; // [rsp+90h] [rbp-38h] BYREF
__int128 v46; // [rsp+A0h] [rbp-28h] BYREF
__int128 v47; // [rsp+B0h] [rbp-18h] BYREF
while ( (unsigned __int64)&v43 <= *(_QWORD *)(__readfsqword(0xFFFFFFF8) + 16) )
runtime_morestack_noctxt();
qmemcpy(v42, "MRCTF_GOGOGO", sizeof(v42));
crypto_rc4_NewCipher((int)a1, a2, a3, (int)v42, a5, a6, (__int64)v42, 12LL);
if ( dword_592FA0 )
{
a1 = &byte_577540;
runtime_gcWriteBarrier(&byte_577540, a2, v6, v7, v8, v9);
}
else
{
byte_577540 = v34;
}
runtime_newobject((_DWORD)a1, a2, v6, v7, v8, v9, (__int64)&unk_4ACA60);
v44 = v33;
*(_QWORD *)&v47 = &unk_4A9740;
*((_QWORD *)&v47 + 1) = v33;
fmt_Fscanln( // 输入
(int)a1,
a2,
(int)&byte_4EBFC0,
(unsigned int)&v47,
v10,
v11,
(__int64)&byte_4EBFC0,
byte_577550,
(__int64)&v47,
1LL,
1LL);
main_move(
(int)a1,
a2,
v12,
v13,
v14,
v15,
4LL,
(__int64)&unk_4D0B6F,
1LL,
(__int64)&unk_4D0B76,
1LL,
(__int64)&unk_4D0B70,
1LL);
qmemcpy(key, "MRCTF_GOGOGO", sizeof(key));
crypto_rc4_NewCipher((int)a1, a2, v16, v17, v18, v19, (__int64)key, 12LL);// rc4初始化
if ( dword_592FA0 )
{
a1 = &byte_577540;
runtime_gcWriteBarrier(&byte_577540, a2, v20, v21, v22, v23);
}
else
{
byte_577540 = v35;
}
v40 = v44[1];
runtime_makeslice((int)a1, a2, (__int64)qword_4ACBA0, v40, v22, v23, qword_4ACBA0, v40, v40);
v43 = v35;
runtime_stringtoslicebyte((_DWORD)a1, a2, v44[1], *v44, v24, v25);
v26 = v40;
v39 = v37;
crypto_rc4__ptr_Cipher_XORKeyStream((int)a1, v40, v36, v35, v27, v28, byte_577540, v43, v40, v40, v35, v36);// rc4_crypto部分,点击a1过去可以看见第一个参数就是我们输入的字符串
v31 = qword_577948;
if ( qword_577948 == v40 || (v26 = v43, v38 = qword_577950, internal_bytealg_Compare(), v39) )
{
*(_QWORD *)&v45 = &unk_4ACA60;
*((_QWORD *)&v45 + 1) = &off_4EA7D0;
result = fmt_Fprintln(
(_DWORD)a1,
v26,
v31,
(unsigned int)&off_4EBFE0,
v29,
v30,
(__int64)&off_4EBFE0,
byte_577558,
(__int64)&v45,
1LL,
1LL,
v38,
v39);
}
else
{
*(_QWORD *)&v46 = &unk_4ACA60;
*((_QWORD *)&v46 + 1) = &off_4EA7C0;
result = fmt_Fprintln(
(_DWORD)a1,
v26,
v31,
(unsigned int)&off_4EBFE0,
v29,
v30,
(__int64)&off_4EBFE0,
byte_577558,
(__int64)&v46,
1LL,
1LL,
v38,
0LL);
}
return result;
}

可以看出就是一个标准的RC4加密,我们可以直接操作内存得到flag

先逐步动调,修改跳转条件(一个jz改为jnz),因为此时我们是随便输入的长度,让程序能够执行函数

internal_bytealg_Compare

http://www.syjblog.com/wp-content/uploads/2021/04/SE8KPISVDR_@P4RTSO2-1024x710.png

将rdi,即最后加密的数据复制出进行处理

string = "7D306EC9CC03931E854D455FC546F4A8A03E11BE70751DA3CD7FFFBD8112"
i = 0
while string:
    i += 1
    string = string[2:]
print(i)
# 得出我们输入的字符串长度必须为29
print('a' * 30)
# 这样就可以免去最后修改汇编跳转到internal_bytealg_Compare函数之后得到的加密之后的数据(即flag长度不对)

然后再次重新动调,这次我们要输入30个字符长度的字符串aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

http://www.syjblog.com/wp-content/uploads/2021/04/VF0LMWW57VUGH5KLSTL-1024x746.png

到这个函数时,将参数a1所对应内存的值直接修改为加密后的数据

http://www.syjblog.com/wp-content/uploads/2021/04/5KHEUYX2YUJWV@OJ@OZKICJ-1024x528.png

最后查看rsi的值

http://www.syjblog.com/wp-content/uploads/2021/04/2J@LZAK69DWSL9DACH.png

http://www.syjblog.com/wp-content/uploads/2021/04/1FISW_A96PQFS24U05CWH-1024x309.jpg

就得到了flag:

CTCFTFCTFCFTCTCFTFTCFCTFCTCFTF

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值