[HNCTF 2022 WEEK4]flower plus

43 篇文章 1 订阅
20 篇文章 0 订阅

第一种花指令
image.png
第二种花指令
image.png
根据两种花指令特征,写出去花指令脚本
image.png
image.png

saddr=0x401000
eaddr=0x435000
for i in range(saddr,eaddr):
    if get_wide_dword(i)==0x01740275:
        print(hex(i)+','+hex(get_wide_dword(i)))
        patch_byte(i-5,0x90)
        patch_dword(i-4,0x90909090)
        patch_dword(i,0x90909090)
        patch_word(i+4,0x9090)
    if get_qword(i)==0x8336E800000001E8:
            print(hex(i)+','+hex(i+4)+','+hex(get_wide_dword(i)))
            patch_qword(i,0x9090909090909090)
            patch_dword(i+8,0x90909090)
            patch_byte(i+12,0x90)

使用脚本将花指令去除后,u,c,p一下基本没啥问题。
可以得到下面正常main函数
image.png
分析可得为rc4+xor加密

saddr=0x401000
eaddr=0x435000
for i in range(saddr,eaddr):
    if get_wide_dword(i)==0x01740275:
        print(hex(i)+','+hex(get_wide_byte(i)))
        patch_dword(i,0x90909090)
        patch_dword(i-4,0x90909090)
        patch_word(i+4,0x9090)
        patch_byte(i-5,0x90)
    if get_wide_dword(i)==0x000001E8:
        if get_wide_dword(i+4)==0x8336E800:
            print(hex(i)+','+hex(get_wide_byte(i)))
            patch_dword(i,0x90909090)
            patch_dword(i+4,0x90909090)
            patch_dword(i+8,0x90909090)
            patch_byte(i+12,0x90)

用下面idapython脚本得到密文和key

enc=list(map(lambda x:get_wide_dword(x),range(0x004440E0,0x004440E0+27*4,4)))
print(enc)
key=''.join(map(lambda x:chr(get_wide_byte(x)),range(0x00446900,0x0044690f)))
print(key)

exp

#include<iostream>
#include<cstdint>
using namespace std;

void main()
{
	uint8_t aHelloCtfers[] = "Hello_Ctfers!!!";
	uint32_t key_len = sizeof(aHelloCtfers);
	uint32_t data[] = { 77, 4294967270, 73, 4294967189, 3, 45, 43, 4294967226, 4294967274, 109, 4294967295, 89, 112, 0, 27, 4294967209, 44, 4294967216, 50, 4294967192, 111, 4294967180, 86, 4294967202, 76, 121, 127 };
	uint32_t data_len = 27;
	for (int i = data_len - 1; i >= 0; i--) 
	{
		data[i] = data[i] ^ data[(i + 1) % data_len];
	}
	uint32_t result; // eax
	uint8_t v4[320]; // [esp+Ch] [ebp-25Ch]
	uint32_t v5; // [esp+14Ch] [ebp-11Ch]
	uint32_t k; // [esp+150h] [ebp-118h]
	uint32_t j; // [esp+154h] [ebp-114h]
	uint32_t i; // [esp+158h] [ebp-110h]
	uint32_t v9; // [esp+15Ch] [ebp-10Ch]
	uint32_t m; // [esp+160h] [ebp-108h]
	uint8_t v11[256]; // [esp+164h] [ebp-104h] BYREF

	for (i = 0; i < 256; ++i)
	{
		v11[i] = i;
		v4[i] = aHelloCtfers[i % key_len];
	}
	v9 = 0;
	for (j = 0; j < 256; ++j)
	{
		v9 = (v4[j] + v9 + v11[j]) % 256;
		swap(v11[j], v11[v9]);
	}
	m = 0;
	v9 = 0;
	for (k = 0; k < data_len; ++k)
	{
		m = (m + 3) % 256;
		v9 = (v9 + v11[m] + 1) % 256;
		swap(v11[m], v11[v9]);
		v5 = (v11[v9] + v11[m]) % 256;
		v4[k + 256] = v11[v5];
	}
	for (m = 0; ; ++m)
	{
		result = m;
		if (m >= data_len)
			break;
		data[m] ^= v4[m + 256];
	}
	for (int i = 0; i < 27; i++)
		cout << (char)data[i];
}
  
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值