REVERSE-PRACTICE-CTFSHOW-1

REVERSE-PRACTICE-CTFSHOW-1

逆向签到题

ida打开即可得到明文flag
逆向签到题-flag

re2

附件是一个加密过的flag文本和勒索病毒exe
运行程序,输入1,回车,直接退出,ida分析
选项1的逻辑为,打开flag.txt和enflag.txt,要求输入正确的密钥,然后使用密钥对明文flag进行RC4加密,密文写到enflag.txt
re2-main
分析check_key部分,简单的异或运算和比较
re2-checkkey
写脚本可得到密钥

s="DH~mqqvqxB^||zll@Jq~jkwpmvez{"
key=""
for c in s:
    key+=chr(ord(c)^0x1f)
print(key)
#[Warnning]Access_Unauthorized

程序用密钥对明文flag进行RC4加密,现已知密文和密钥,写RC4解密脚本即可得到flag

#include<stdio.h>
void rc4_init(unsigned char* s, unsigned char* key, unsigned long Len_k) //初始化函数
{
	int i = 0, j = 0;
	char k[256] = { 0 };
	unsigned char tmp = 0;
	for (i = 0; i < 256; i++) {
		s[i] = i;
		k[i] = key[i % Len_k];
	}
	for (i = 0; i < 256; i++) {
		j = (j + s[i] + k[i]) % 256;
		tmp = s[i];
		s[i] = s[j];
		s[j] = tmp;
	}
}
void rc4_crypt(unsigned char* Data, unsigned long Len_D, unsigned char* key, unsigned long Len_k) //加解密
{
	unsigned char s[256];
	rc4_init(s, key, Len_k);
	int i = 0, j = 0, t = 0;
	unsigned long k = 0;
	unsigned char tmp;
	for (k = 0; k < Len_D; k++) {
		i = (i + 1) % 256;
		j = (j + s[i]) % 256;
		tmp = s[i];
		s[i] = s[j];
		s[j] = tmp;
		t = (s[i] + s[j]) % 256;
		Data[k] = Data[k] ^ s[t];
	}
}
void main()
{
	unsigned char key[] = "[Warnning]Access_Unauthorized";
	unsigned long key_len = sizeof(key) - 1;
	unsigned char data[] = { 0xC3,0x82,0xA3,0x25,0xF6,0x4C,
	0x36,0x3B,0x59,0xCC,0xC4,0xE9,0xF1,0xB5,0x32,0x18,0xB1,
	0x96,0xAe,0xBF,0x08,0x35};
	rc4_crypt(data, sizeof(data), key, key_len);
	for (int i = 0; i < sizeof(data); i++)
	{
		printf("%c", data[i]);
	}
	printf("\n");
	return;
}
//flag{RC4&->ENc0d3F1le}

逆向4

exe程序,要求输入正确的数字,ida分析
静态看不明白,起调试
可以看到,输入作为第一个参数,传入了sub_7FF62E5010E0函数
re4-main
F7步入sub_7FF62E5010E0函数,先分析第一部分
21行和22行合并后,可以理解为,输入的数字对26取余,余数作为下标在一个table里取值,然后输入的数字除以26得到新的数字,再用新的数字对26取余,余数作为下标在table取值,以此类推,直到最后的数字除以26为0终止,取出的值放到一块连续的内存
re4-step1
然后分析第二部分
index是上面取出的值的数目,也就是说v7是从高地址向低地址依次取值的
因为上面先用余数作的下标,再做的除运算,于是每次取出的值可以理解为是按输入的数字的较小的部分取出的
暂时忽略在table里取值这一步,实际上就是小值存储在小地址,小端序的特点
re-step2
v7依次取值,和7异或一下,结果存储到一块内存
re-value
sub_7FF62E501220函数是check的部分,最后要比较的字符串是明文可知的,每次循环比较两个字符
re4-check
最后写脚本即可得到正确的输入数字

table=")(*&^%489$!057@#><:2163qwe"
ans="/..v4p$$!>Y59-"
ans_s=""
for c in ans:
    ans_s+=chr(ord(c)^7)
print(ans_s)
num=0
for c in ans_s:
    num *= 26
    index=table.find(c)
    num+=index
print(num)
#())q3w##&9^2>*
#2484524302484524302

逆向5

附件是一个dll和一个exe,exe运行直接弹窗,点击确定后直接退出,ida分析
main->sub_4015BD
可以看到,这里判断Str[1]是否等于1,而Str是给定的明文且Str[1]!=1,于是这个判断不成立
re5-mian
分析sub_401520函数,这里加载了另一个附件1.dll,然后找到了H
循环体中依次取Str中的值,然后作为参数传入H
最后sub_40163E函数里有个putchar打印H处理Str[i]后的内容
re5-dll
因为之前Str[1]!=1,所以不会执行sub_401520函数
起调试,停在那条if语句处,在执行jnz之前把ZF标志为由0改为1
re5-debug
修改后在下图所示语句处下断点,F9运行到此处,再F8执行sub_40163E函数,即可在黑窗看到flag
re5-flag

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

P1umH0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值