攻防世界逆向高手题之Replace

99 篇文章 36 订阅

攻防世界逆向高手题之Replace

继续开启全栈梦想之逆向之旅~
这题是攻防世界逆向高手题的Replace
在这里插入图片描述
下载附件,照例扔入exeinfope中查看信息:
在这里插入图片描述
.
有壳,用Kali的upx -d脱壳,然后照例扔入IDA32中查看伪代码,有main函数看main函数:(脱壳后不能运行,因为伪代码信息足够,所以就不用修复了)
在这里插入图片描述
.
.
代码量很少,第一个红框不知道要输入35还是36还是37,直接看第二个红框的判断语句:
在这里插入图片描述
.
.
主要逻辑在上面了,涉及三个数组,用IDA内嵌脚本dump下来,这里积累第一个经验:数组dump下载的时候dump到0字符结尾处,不要怕dump多,就怕dump少。

addr1=0x402150
addr2=0x402151
addr3=0x4021A0
list1=[]
list2=[]
list3=[]
for i in range(0x402196-0x402150):
    list1.append(Byte(addr1+i))
for i in range(0x402196-0x402151):
    list2.append(Byte(addr2+i))
for i in range(0x4022D8-0x4021A0):
    list3.append(Byte(addr3+i))
print(list1)
print(list2)
print(list3)

.
.
在这里插入图片描述
.
.
开始编写逆向逻辑脚本,这里积累第二个经验:主要回顾一下每一步的思路,给日后自己增添一些解题模板。
.
第一步确定Flag字符数量,第一个红框处得到flag数量是35。

第二步找到已确定的字符串作为基点来反推flag字符,如第二个红框处。
在这里插入图片描述
.
第三步找出逻辑中与flag直接相关的部分,该部分可以正向爆破或者从尾到头的反向逻辑,如第一个红框所示。然后找到与flag没有直接关联的部分,该部分无需逆向逻辑,直接正向流程复现即可,如第二个红框所示。
在这里插入图片描述
.
.
梳理完这些之后就可以写脚本了:
脚本1,爆破。这里积累第三个经验:由于用了取余 % 运算,所以采用枚举正向爆破的方法,让flag中的每一个字符遍历常用的字符(ascii码表中32-126),带入加密算法,如果成功,就把这个flag存入。

脚本

list1=[50, 97, 52, 57, 102, 54, 57, 99, 51, 56, 51, 57, 53, 99, 100, 101, 57, 54, 100, 54, 100, 101, 57, 54, 100, 54, 102, 52, 101, 48, 50, 53, 52, 56, 52, 57, 53, 52, 100, 54, 49, 57, 53, 52, 52, 56, 100, 101, 102, 54, 101, 50, 100, 97, 100, 54, 55, 55, 56, 54, 101, 50, 49, 100, 53, 97, 100, 97, 101, 54]
list2=[97, 52, 57, 102, 54, 57, 99, 51, 56, 51, 57, 53, 99, 100, 101, 57, 54, 100, 54, 100, 101, 57, 54, 100, 54, 102, 52, 101, 48, 50, 53, 52, 56, 52, 57, 53, 52, 100, 54, 49, 57, 53, 52, 52, 56, 100, 101, 102, 54, 101, 50, 100, 97, 100, 54, 55, 55, 56, 54, 101, 50, 49, 100, 53, 97, 100, 97, 101, 54]
list3=[99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, 216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, 235, 39, 178, 117, 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179, 41, 227, 47, 132, 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207, 208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168, 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255, 243, 210, 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25, 115, 96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219, 224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, 231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, 225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223, 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 22, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
v4=0
flag=""
for i in range(35):
	v8=list1[2*i]
	if v8 < 48 or v8 > 57:
		v9=v8 - 87
	else:
		v9=v8 - 48
	v10=list2[2*i]
	v11=16*v9
	if v10 <48 or v10 > 57:
		v12=v10-87
	else:
		v12=v10-48
	v4=((v11+v12)^25)
	for a in range(32,127):				//取余类型正向爆破
		v5=a
		v6=(v5>>4)%16
		v7=((16*v5)>>4)%16
		if list3[16*v6+v7] == v4:
			flag+=chr(a)
print(flag)

.
.
脚本2,理解移位运算符 >> 的 不带余数的除法 / 算法,就是取商的整数部分。这里积累第四个经验:>> 运算符其实是与 不带余数的除法 / 算法。所以这里 v6 = (v5 >> 4) % 16 是除以16后的整数部分, v7 = ((16 * v5) >> 4) % 16 是乘16后除16再取16内的余数,也就是直接取16内的余数,而他们的逆向算法就是16 * v6 + v7,就是最后数组byte_4021A0[16 * v6 + v7]的下标。(既然v5 >> 4相当于v5除以16取整数部分,是不带余数的除法 / 算法。顺带说一下,v5 & 0xf 相当于v5除以16取余数部分,是完全的求余%算法,这里0xf是4位所以为16。)

所以flag就是由这些下标组成 !

因此有些是有伪代码中前面的运算逻辑如果和后面的运算逻辑如果有相似之处,要试着判断他们是反向逻辑,因为出题者的意图往往如此。

在这里插入图片描述

list1=[50, 97, 52, 57, 102, 54, 57, 99, 51, 56, 51, 57, 53, 99, 100, 101, 57, 54, 100, 54, 100, 101, 57, 54, 100, 54, 102, 52, 101, 48, 50, 53, 52, 56, 52, 57, 53, 52, 100, 54, 49, 57, 53, 52, 52, 56, 100, 101, 102, 54, 101, 50, 100, 97, 100, 54, 55, 55, 56, 54, 101, 50, 49, 100, 53, 97, 100, 97, 101, 54]
list2=[97, 52, 57, 102, 54, 57, 99, 51, 56, 51, 57, 53, 99, 100, 101, 57, 54, 100, 54, 100, 101, 57, 54, 100, 54, 102, 52, 101, 48, 50, 53, 52, 56, 52, 57, 53, 52, 100, 54, 49, 57, 53, 52, 52, 56, 100, 101, 102, 54, 101, 50, 100, 97, 100, 54, 55, 55, 56, 54, 101, 50, 49, 100, 53, 97, 100, 97, 101, 54]
list3=[99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, 216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, 235, 39, 178, 117, 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179, 41, 227, 47, 132, 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207, 208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168, 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255, 243, 210, 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25, 115, 96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219, 224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, 231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, 225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223, 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 22, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
v4=0
flag=""
for i in range(35):
	v8=list1[2*i]
	if v8 < 48 or v8 > 57:
		v9=v8 - 87
	else:
		v9=v8 - 48
	v10=list2[2*i]
	v11=16*v9
	if v10 <48 or v10 > 57:
		v12=v10-87
	else:
		v12=v10-48
	v4=((v11+v12)^25)
	flag+=chr(list3.index(v4))			//直接取下标索引
print(flag)

.
.
结果:
在这里插入图片描述
.
.
总结:

1:
这里积累第一个经验:数组dump下载的时候dump到0字符结尾处,不要怕dump多,就怕dump少。

2:
这里积累第二个经验:主要回顾一下每一步的思路,给日后自己增添一些解题模板。 .
第一步确定Flag字符数量,第一个红框处得到flag数量是35。

第二步找到已确定的字符串作为基点来反推flag字符,如第二个红框处。

第三步找出逻辑中与flag直接相关的部分,该部分可以正向爆破或者从尾到头的反向逻辑,如第一个红框所示。然后找到与flag没有直接关联的部分,该部分无需逆向逻辑,直接正向流程复现即可,如第二个红框所示。

3:
脚本1,爆破。这里积累第三个经验:由于用了取余 % 运算,所以采用枚举正向爆破的方法,让flag中的每一个字符遍历常用的字符(ascii码表中32-126),带入加密算法,如果成功,就把这个flag存入。

4:
脚本2,理解移位运算符 >> 的 不带余数的除法 / 算法,就是取商的整数部分。这里积累第四个经验:>> 运算符其实是与 不带余数的除法 / 算法。所以这里 v6 = (v5 >> 4) % 16 是除以16后的整数部分, v7 = ((16 * v5) >> 4) % 16 是乘16后除16再取16内的余数,也就是直接取16内的余数,而他们的逆向算法就是16 * v6 + v7,就是最后数组byte_4021A0[16 * v6 + v7]的下标。
(既然v5 >> 4相当于v5除以16取整数部分,是不带余数的除法 / 算法。顺带说一下,v5 & 0xf 相当于v5除以16取余数部分,是完全的求余%算法,这里0xf是4位所以为16。)
.
所以flag就是由这些下标组成 !
.
因此有些是有伪代码中前面的运算逻辑如果和后面的运算逻辑如果有相似之处,要试着判断他们是反向逻辑,因为出题者的意图往往如此。

解毕!敬礼!

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

沐一 · 林

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

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

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

打赏作者

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

抵扣说明:

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

余额充值