京麒CTF 2025 热身赛 wp re1 rust,缺少符号表,很难看
使用bindiff恢复符号表,首先需要配置rust环境
Rust语言开发环境搭建详细教程_rust环境搭建-CSDN博客
参考rust恢复符号表 | clev1L’s blog
恢复了一点点吧
根据可疑字符串定位到
关键部分
v29是
将内存地址 v16
处的前两个字节解释为一个 unsigned short
(即 16 位无符号整数),赋值给 v29
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 enc = [0x0 , 0xA1 , 0xFB , 0x53 , 0x1C , 0xFA , 0xF0 , 0x1B , 0x6 , 0x40 , 0xD4 , 0x8C , 0x16 , 0xF4 , 0x90 , 0x27 , 0x42 , 0xB9 , 0x8B , 0xF , 0x2 , 0xD7 , 0x31 , 0xB7 , 0x26 , 0x12 , 0x6 , 0x7E , 0xAE , 0xDF , 0xDA , 0x68 , 0xAF , 0x35 , 0xCC , 0xB7 , 0xB0 , 0xD0 , 0x9A , 0x59 , 0x2B , 0xB ] def rol (val, r_bits, max_bits=8 ): return ((val << r_bits) & (2 **max_bits - 1 )) | (val >> (max_bits - r_bits)) def decrypt (ciphertext ): prefix = b"fl" result = bytearray (len (ciphertext)) v29 = int .from_bytes(prefix[:2 ], "little" ) for i in range (len (ciphertext)): v33 = ((v29 >> 2 ) ^ (v29 >> 3 ) ^ (v29 >> 1 )) & 0xFFFF next_v29 = ((v29 >> 1 ) | (v33 << 15 )) & 0xFFFF v34 = rol(v29 & 0xFF , 4 ) v35 = ((4 * (v34 & 0x33 )) | ((v34 >> 2 ) & 0x33 )) & 0xFF xor_val = (i + ((2 * (v35 & 0x55 )) | ((v35 >> 1 ) & 0x55 ))) & 0xFF result[i] = ciphertext[i] ^ xor_val v29 = next_v29 return bytes (result) ciphertext = bytes (enc) plaintext = decrypt(ciphertext) print (plaintext.decode(errors='ignore' ))
仔细解释下
1 2 next_v29 = ((v29 >> 1) | (v33 << 15)) & 0xFFFF v34 = rol(v29 & 0xFF, 4)
为什么是v29 & 0XFF,因为rol是byte,而v33的byte是v29
flag{1c98572d-7f7b-4fbf-8750-4a2986c695ce}
re2 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 shuffle_mask = list (reversed (range (16 ))) add_mask = bytes ([ 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 , 0x08 , 0x09 , 0x0A , 0x0B , 0x0C , 0x0D , 0x0E , 0x0F , 0x10 ]) ciphertext = b"cge87k?9<>?@=pss393=>;8@:Cp@DAuH" def decrypt_block (block: bytes ) -> bytes : subtracted = bytes ((b - m) & 0xFF for b, m in zip (block, add_mask)) return bytes (subtracted[i] for i in shuffle_mask) plaintext = b"" for i in range (0 , len (ciphertext), 16 ): block = ciphertext[i:i+16 ] plaintext += decrypt_block(block) print (f"flag{{{plaintext.decode()} }}" )
GPT速通
flag{cdb0444318e24beb8f374e9181599072}
re!!! IOS逆向
看着像密文
rc4 –> base64 –> obfusecateString –> transformString.
先看最后一个
根据 n190
的大小分三种情况(单字节、两字节、三字节或四字节)
逆一下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 def decrypt_specialized (hex_str: str ) -> str : hex_str = '' .join(hex_str.split()) if len (hex_str) % 2 != 0 : raise ValueError(f"Invalid hex string length {len (hex_str)} , must be even." ) data = bytes .fromhex(hex_str) transformed = data.decode('utf-8' ) result_chars = [] for i, ch in enumerate (transformed): key = 0xEF if (i % 2 == 0 ) else 0xBE code = ord (ch) if code <= 0x7F : n190 = code - 1 else : n190 = code orig_cp = n190 ^ key result_chars.append(chr (orig_cp)) return '' .join(result_chars) if __name__ == '__main__' : cipher_hex = ( "c2a7c3b9c2acc3a5c2a2c3b6c391c295c2aac38cc28bc38ac2a6c3aec28bc28f" "c2a1c3aac287c382c2bfc3b6c282c38ec2b9c3a2c2a13cc28ac3adc2b1c28" "0c2b2c384c28dc3bbc283c396c2b03dc28a3bc2b12cc287c3b0c2852bc282" "c39ac28432c29320c29d21c29ac392c291c3a1c296c3a06d1866396c25631" "0c299c3946931c291c3917a2e470b632a7811730f65c385" ) try : plaintext = decrypt_specialized(cipher_hex) print (plaintext) except Exception as e: print ("解密失败:" , e)
接下来那部分:
这段是核心混淆逻辑:
将当前字符值加上迭代器 v6
(动态偏移);
再加一个固定偏移 0xDEADBEEF
;
然后取低字节;
如果结果非负,取负值再取反(取补码)形成非线性变换。
1 2 3 4 if ((v11 & 0xFFFFFF80 ) != 0 ) v13 = (((v11 & 0x3F ) << 8 ) | ((unsigned int )v11 >> 6 )) + 33217 ; else v13 = v11 + 1 ;
这是根据字符值决定如何处理的分支:
如果是高位字符(非 ASCII),执行位运算变换并加上 33217。
否则简单地加一。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 import base64def decrypt_specialized (hex_str: str ): hex_str = '' .join(hex_str.split()) if len (hex_str) % 2 != 0 : raise ValueError(f"Invalid hex string length {len (hex_str)} , must be even." ) data = bytes .fromhex(hex_str) transformed = data.decode('utf-8' ) result_chars = [] for i, ch in enumerate (transformed): key = 0xEF if (i % 2 == 0 ) else 0xBE code = ord (ch) if code <= 0x7F : n190 = code else : n190 = code orig_cp = n190 ^ key result_chars.append(chr (orig_cp)) return result_chars if __name__ == '__main__' : hex_enc = "c2a7c3b9c2acc3a5c2a2c3b6c391c295c2aac38cc28bc38ac2a6c3aec28bc28fc2a1c3aac287c382c2bfc3b6c282c38ec2b9c3a2c2a13cc28ac3adc2b1c280c2b2c384c28dc3bbc283c396c2b03dc28a3bc2b12cc287c3b0c2852bc282c39ac28432c29320c29d21c29ac392c291c3a1c296c3a06d1866396c256310c299c3946931c291c3917a2e470b632a7811730f65c385" cipher_hex = ( "c2a7c3b9c2acc3a5c2a2c3b6c391c295c2aac38cc28bc38ac2a6c3aec28bc28fc2a1c3aac287c382c2bfc3b6c282c38ec2b9c3a2c2a13cc28ac3adc2b1c280c2b2c384c28dc3bbc283c396c2b03dc28a3bc2b12cc287c3b0c2852bc282c39ac28432c29320c29d21c29ac392c291c3a1c296c3a06d1866396c256310c299c3946931c291c3917a2e470b632a7811730f65c385" ) try : plaintext = decrypt_specialized(cipher_hex) flag_base64 = '' for i in range (len (plaintext)): flag_base64 += chr ((ord (plaintext[i]) - i - 0xDEADBEEF ) & 0xFF ) base64.b64decode(flag_base64).decode() except Exception as e: print ("解密失败:" , e)
adbe2979358798308c911dd4647a2f6a13c042cc324597e1edbc089a9e9015fba9
还有个RC4,key找了一圈发现几个init
跟进下
处理下大小端序的问题
Haruhikage
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 import base64def decrypt_specialized (hex_str: str ): hex_str = '' .join(hex_str.split()) if len (hex_str) % 2 != 0 : raise ValueError(f"Invalid hex string length {len (hex_str)} , must be even." ) data = bytes .fromhex(hex_str) transformed = data.decode('utf-8' ) result_chars = [] for i, ch in enumerate (transformed): key = 0xEF if (i % 2 == 0 ) else 0xBE code = ord (ch) if code <= 0x7F : n190 = code else : n190 = code orig_cp = n190 ^ key result_chars.append(chr (orig_cp)) return result_chars def rc4_decrypt (data: bytes , key: str ) -> bytes : S = list (range (256 )) j = 0 key_bytes = key.encode('utf-8' ) for i in range (256 ): j = (j + S[i] + key_bytes[i % len (key_bytes)]) % 256 S[i], S[j] = S[j], S[i] i = j = 0 out = bytearray () for byte in data: i = (i + 1 ) % 256 j = (j + S[i]) % 256 S[i], S[j] = S[j], S[i] K = S[(S[i] + S[j]) % 256 ] out.append(byte ^ K) return bytes (out) if __name__ == '__main__' : hex_enc = "c2a7c3b9c2acc3a5c2a2c3b6c391c295c2aac38cc28bc38ac2a6c3aec28bc28fc2a1c3aac287c382c2bfc3b6c282c38ec2b9c3a2c2a13cc28ac3adc2b1c280c2b2c384c28dc3bbc283c396c2b03dc28a3bc2b12cc287c3b0c2852bc282c39ac28432c29320c29d21c29ac392c291c3a1c296c3a06d1866396c256310c299c3946931c291c3917a2e470b632a7811730f65c385" cipher_hex = ( "c2a7c3b9c2acc3a5c2a2c3b6c391c295c2aac38cc28bc38ac2a6c3aec28bc28fc2a1c3aac287c382c2bfc3b6c282c38ec2b9c3a2c2a13cc28ac3adc2b1c280c2b2c384c28dc3bbc283c396c2b03dc28a3bc2b12cc287c3b0c2852bc282c39ac28432c29320c29d21c29ac392c291c3a1c296c3a06d1866396c256310c299c3946931c291c3917a2e470b632a7811730f65c385" ) try : plaintext = decrypt_specialized(cipher_hex) flag_base64 = '' for i in range (len (plaintext)): flag_base64 += chr ((ord (plaintext[i]) - i - 0xDEADBEEF ) & 0xFF ) rc4_enc = base64.b64decode(flag_base64) rc4_enc_bytes = bytes .fromhex(rc4_enc.decode()) key = 'Haruhikage' decrypted = rc4_decrypt(rc4_enc_bytes, key) print (decrypted) except Exception as e: print ("解密失败:" , e)
flag{N4nd3_H4ruhik4g3_Y4tt4n0?!!}