攻防世界逆向高手题之Replace

攻防世界逆向高手题之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就是由这些下标组成 !
.
因此有些是有伪代码中前面的运算逻辑如果和后面的运算逻辑如果有相似之处,要试着判断他们是反向逻辑,因为出题者的意图往往如此。

解毕!敬礼!

<think>好的,我现在需要帮助用户解决关于CTF攻防比赛中数据校验目的问。用户想了解相关解和技术,我需要结合已有的引用信息,整理出清晰的回答结构。 首先,回顾用户提供的引用内容,引用1和引用2提到了逆向工程中的数据处理,比如十六进制转换和字符串操作,这可能和数据校验有关。引用3提到GPX格式的数据处理,引用4涉及加密和填充方式,如AES的使用。这些都可能与数据校验相关,比如验证输入是否符合特定格式或加密后的正确性。 接下来,我需要确定数据校验在CTF中的常见形式。通常包括文件格式验证、加密数据完整性校验、输入数据的格式或内容校验等。例如,目可能要求参赛者修复损坏的文件头,解密后验证哈希,或者逆向分析程序如何校验输入数据。 根据引用1中的例子,sprintf将输入转为十六进制,并填入数组,这可能涉及到将用户输入转换为特定格式后进行比对。参赛者需要逆向这一过程,将十六进制字符串还原为原始输入。类似的情况可能出现在其他目中,如Base64编码、异或加密等。 引用4中的AES加密和填充处理,说明数据校验可能涉及加密算法的正确实现,比如填充方式、模式选择。参赛者需要识别加密参数,正确解密后验证数据是否符合预期。 引用3中的GPX处理涉及XML结构和地理数据,可能需要校验数据结构或提取特定字段。这类目可能要求解析文件,验证数据完整性或提取隐藏信息。 接下来,需要总结解思路。首先是分析校验逻辑,通过逆向或静态分析找到关键代码。例如,引用1中通过定位sprintf函数找到数据处理点。其次是数据转换,如十六进制、Base64、加密算法等。然后是对比验证,找到正确的校验结果,如正确的哈希值或解密后的明文。 常见技术点包括编码转换、加密算法识别、文件格式解析、哈希校验等。例如,处理十六进制可能需要Python的binascii模块,处理加密可能需要PyCryptodome库。 最后,生成相关问,帮助用户深入理解,如数据校验的常见加密算法、逆向工程工具使用、文件格式分析工具等。 需要确保回答结构清晰,分点说明,并引用相关示例。同时,检查是否有遗漏的技术点,确保覆盖用户的需求。</think>### CTF数据校验类目解析 数据校验类目在CTF中常涉及编码转换、加密验证、协议分析等。以下是典型技术点和解思路: --- #### 1. **常见数据校验类型** - **文件格式校验** 例如GPX、PNG等文件头修复,需验证文件结构是否符合标准格式[^3]。 示例:修复GPX文件中的`<trkpt>`标签经纬度数据。 ```python with open("flag.gpx", "r") as f: data = f.read().replace("<latitude>0</latitude>", "<latitude>32.1234</latitude>") ``` - **加密数据完整性校验** 如AES加密后密文需满足特定填充规则(如ZeroPadding)或模式(如ECB)[^4]。 示例:解密时手动补0处理NoPadding模式: ```python from Crypto.Cipher import AES cipher = AES.new(key, AES.MODE_ECB) decrypted = cipher.decrypt(ciphertext).rstrip(b'\x00') # 去除末尾补0 ``` - **输入内容格式校验** 如将用户输入转为十六进制后比对固定值[^1]。 示例:逆向十六进制字符串`437261636b4d654a757374466f7246756e`还原为ASCII: ```python bytes.fromhex("437261636b4d654a757374466f7246756e").decode() # 输出'CrackMeJustForFun' ``` --- #### 2. **解核心思路** - **定位校验逻辑** 逆向分析时,需快速定位`strcmp`、`memcmp`等比对函数,或加密函数(如AES_encrypt)[^1][^4]。 - **数据转换还原** 常见编码:Base64、Hex、URL编码;常见加密:异或、AES、RC4。 示例:Base64隐写提取: ```python import base64 stego_data = base64.b64decode("SGVsbG8gQ1RGIQ==") ``` - **动态验证与爆破** 若校验过程含部分未知参数(如密钥前3位),可通过脚本爆破: ```python for i in range(0x100): attempt_key = f"{i:03x}" + known_part if decrypt(attempt_key) == expected: print("Found key:", attempt_key) ``` --- #### 3. **实战案例参考** - **案例1:逆向十六进制校验** 引用[^1]中,输入需等于固定Hex字符串。解时需将Hex逐字节转为ASCII,或通过`binascii.unhexlify`处理。 - **案例2:加密填充模式识别** 引用[^4]中,AES使用ZeroPadding但工具库不支持,需手动补0并截取有效密文。 ---
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

沐一 · 林

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

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

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

打赏作者

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

抵扣说明:

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

余额充值