SHCTF2026hash1-3WriteUp

admin 2026-03-10 01:31:27 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文为SHCTF2026哈希碰撞题目WriteUp。hash1利用未过滤输入使用已知MD5碰撞值解题。hash2通过hashclash工具生成符合字母数字前缀限制的碰撞数据。hash3利用hashclash脚本构造前缀不同的TwinKeys碰撞。文章详细展示了针对不同限制条件利用MD5弱点解题的全过程,提供了具体命令与脚本,具有很强的可操作性。 综合评分: 95 文章分类: CTF,漏洞分析,安全工具,实战经验


cover_image

SHCTF 2026 hash1-3 WriteUp

原创

Pirater Pirater

Pirater

2026年3月9日 19:43 广东

上个月在SHCTF2026出了几道题,都是关于哈希碰撞的题。比赛快结束的时候电脑坏了,所以官方WriteUp是让g0ubu1i师傅代写的,非常感谢!!!现在换新电脑了,特此补上这篇本来应该写的WriteUp。

hash1

题目代码

import hashlib

with open("/flag.txt","r") as f:
    flag = f.read().strip()

msg = input(f"Give me both different apples (hex(apple1), hex(apple2)) : ")

try:
    apples = msg.split(",")
    apple1 = bytes.fromhex(apples[0])
    apple2 = bytes.fromhex(apples[1])
    hash_apple1 = hashlib.md5(apple1).hexdigest()
    hash_apple2 = hashlib.md5(apple2).hexdigest()

    if apple1 == apple2:
        print(f"Oh snap, both apples are exactly the same")
    elif hash_apple1 != hash_apple2:
        print(f"Oh no, they taste different")
    else:
        print(f"Yeah, both apples are delicious!!! This is your prize: {flag}")

except:
    print(f"format fault :(")
    exit()

解题思路

题目的意思是让我们给出两个不同的字符串,使得md5(apple1) = md5(apple2)。那么这里一定有什么缺陷,能使得两个不同的字符串相同。

搜索一下hash,vulnerability类似的关键词,就能搜出类似collsion的字眼。

这里搜出了维基百科的哈希碰撞词条:https://en.wikipedia.org/wiki/MD5#Collision_vulnerabilities

由于题目并没有检查我们的输入,所以我们可以用前人已经搓出来的哈希值。而维基百科里面也给了两条现成的值,我们直接拿来用就行了。

hash1

这里结合pwntools写了一个交互脚本(建议学习pwntools的使用哦):

from pwn import *

hex_m1 = 'd131dd02c5e6eec4693d9a0698aff95c2fcab58712467eab4004583eb8fb7f8955ad340609f4b30283e488832571415a085125e8f7cdc99fd91dbdf280373c5bd8823e3156348f5bae6dacd436c919c6dd53e2b487da03fd02396306d248cda0e99f33420f577ee8ce54b67080a80d1ec69821bcb6a8839396f9652b6ff72a70'
hex_m2 = 'd131dd02c5e6eec4693d9a0698aff95c2fcab50712467eab4004583eb8fb7f8955ad340609f4b30283e4888325f1415a085125e8f7cdc99fd91dbd7280373c5bd8823e3156348f5bae6dacd436c919c6dd53e23487da03fd02396306d248cda0e99f33420f577ee8ce54b67080280d1ec69821bcb6a8839396f965ab6ff72a70'

io = remote("", ) # 填入网址和端口

entry = f"{hex_m1},{hex_m2}".encode()
io.sendlineafter(b" : ",entry)

flag = io.recvline().strip(b"\n").decode().split(": ")[-1]
io.close()
print(flag)

hash2

题目代码

import hashlib
import string

with open("/flag.txt","r") as f:
    flag = f.read().strip()

msg = input(f"Give me both special apples (hex(apple1), hex(apple2)) : ")

try:
    table = (string.ascii_letters + string.digits).encode()

    apples = msg.split(",")
    apple1 = bytes.fromhex(apples[0])
    apple2 = bytes.fromhex(apples[1])
    hash_apple1 = hashlib.md5(apple1).hexdigest()
    hash_apple2 = hashlib.md5(apple2).hexdigest()

&nbsp; &nbsp;&nbsp;if&nbsp;len(apple1) <=&nbsp;16&nbsp;or&nbsp;len(apple2) <=&nbsp;16:
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;print(f"Both apples are too small")
&nbsp; &nbsp;&nbsp;elif&nbsp;not&nbsp;all(ch&nbsp;in&nbsp;table&nbsp;for&nbsp;ch&nbsp;in&nbsp;apple1[:16])&nbsp;or&nbsp;not&nbsp;all(ch&nbsp;in&nbsp;table&nbsp;for&nbsp;ch&nbsp;in&nbsp;apple2[:16]):
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;print(f"No, both apples are too ordinary")
&nbsp; &nbsp;&nbsp;elif&nbsp;apple1 == apple2:
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;print(f"Oh snap, both apples are exactly the same")
&nbsp; &nbsp;&nbsp;elif&nbsp;hash_apple1 != hash_apple2:
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;print(f"Oh no, they taste different")
&nbsp; &nbsp;&nbsp;else:
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;print(f"Yeah, both apples are delicious!!! This is your prize:&nbsp;{flag}")

except:
&nbsp; &nbsp;&nbsp;print(f"format fault :(")
&nbsp; &nbsp; exit()

解题思路

和上题相比,本题强制要求前十六个字符在大小写字母和数字的范围内,并且两条消息不能完全相等而哈希值得相等。

直接用维基百科的两条消息肯定是会失败的,所以这里我们选择自己生成两条消息。

哈希碰撞的工具并不难找:https://marc-stevens.nl/research/hashclash/

Win32位可运行的版本即可,否则编译也要时间,有点麻烦。

hash2

WelcometoSHCTF2025输入到1.txt保存,然后把它拖拽到exe文件,自动就会生成两个文件1_msg1.txt1_msg2.txt。将两个文件的字节读取后再转十六进制,传给服务器即可得到flag

from&nbsp;pwn&nbsp;import&nbsp;*

with&nbsp;open("1_msg1.txt","rb")&nbsp;as&nbsp;f:
&nbsp; &nbsp; m1 = f.read()

with&nbsp;open("1_msg2.txt",&nbsp;"rb")&nbsp;as&nbsp;f:
&nbsp; &nbsp; m2 = f.read()

hex_m1 =&nbsp;bytes.hex(m1)
hex_m2 =&nbsp;bytes.hex(m2)

io = remote("challenge-only-test-for-prepare.shc.tf",&nbsp;31700)

entry =&nbsp;f"{hex_m1},{hex_m2}".encode()
io.sendlineafter(b" : ",entry)

flag = io.recvline().strip(b"\n").decode().split(": ")[-1]
io.close()
print(flag)

hash3

题目代码

import&nbsp;hashlib
import&nbsp;string

with&nbsp;open("/flag.txt","r")&nbsp;as&nbsp;f:
&nbsp; &nbsp; flag = f.read().strip()

msg =&nbsp;input(f"Give me both special apples (hex(apple1), hex(apple2)) : ")

try:
&nbsp; &nbsp; table = (string.ascii_letters + string.digits).encode()

&nbsp; &nbsp; apples = msg.split(",")
&nbsp; &nbsp; apple1 =&nbsp;bytes.fromhex(apples[0])
&nbsp; &nbsp; apple2 =&nbsp;bytes.fromhex(apples[1])
&nbsp; &nbsp; hash_apple1 = hashlib.md5(apple1).hexdigest()
&nbsp; &nbsp; hash_apple2 = hashlib.md5(apple2).hexdigest()

&nbsp; &nbsp;&nbsp;if&nbsp;len(apple1) <=&nbsp;16&nbsp;or&nbsp;len(apple1) <=&nbsp;16:
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;print(f"Both apples are too small")
&nbsp; &nbsp;&nbsp;elif&nbsp;not&nbsp;all(ch&nbsp;in&nbsp;table&nbsp;for&nbsp;ch&nbsp;in&nbsp;apple1[:16])&nbsp;or&nbsp;not&nbsp;all(ch&nbsp;in&nbsp;table&nbsp;for&nbsp;ch&nbsp;in&nbsp;apple2[:16]):
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;print(f"No, both apples are too ordinary")
&nbsp; &nbsp;&nbsp;elif&nbsp;apple1[:16] == apple2[:16]:
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;print(f"Oh snap, both apples are the same")
&nbsp; &nbsp;&nbsp;elif&nbsp;hash_apple1 != hash_apple2:
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;print(f"Oh no, they taste different")
&nbsp; &nbsp;&nbsp;else:
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;print(f"Yeah, both apples are delicious!!! This is your prize:&nbsp;{flag}")

except:
&nbsp; &nbsp;&nbsp;print(f"format fault :(")
&nbsp; &nbsp; exit()

解题思路

题目来源:https://cryptohack.org/challenges/hashes/的Twin Keys

题意很简单,需要构造构造两个前缀不同且哈希值相同的明文。

找到这个工具并且下载:https://github.com/cr-marcstevens/hashclash/releases/tag/hashclash-static-release-v1.2b

输入以下命令:

mkdir&nbsp;hash3
cd&nbsp;hash3
echo&nbsp;"SHCTF2025ISFUNNY"&nbsp;> prefix.txt
../scripts/poc_no.sh prefix.txt
hexdump -v -e&nbsp;'/1 "%02X"'&nbsp;collision1.bin
hexdump -v -e&nbsp;'/1 "%02X"'&nbsp;collision2.bin

解题脚本(需要一点时间):

from&nbsp;pwn&nbsp;import&nbsp;*

hex_m1 =&nbsp;"534843544632303235495346554E4E592DA1C748F4B488F5CEB4DD3FEFB90404BDD1865069B4EE374D9D9F86D1B57CC48224E19BAA422DE18F47806702A6D17B05194901DFF4446D9D40DBD9DA84DC4A523A23C33FF3D4ECFC1564C16F999B5B2DADC97BB14ECA2A3185F8E53058D0CD3259A94AA7808A6A00281806250493D3"&nbsp;# 将hexdump后得到的十六进制串填上去
hex_m2 =&nbsp;"5348435446323032354A5346554E4E592DA1C748F4B488F5CEB4DD3FEFB90404BDD1865069B4EE374D9D9F86D1B57CC48224E19BAA422DE18F47806702A6D17B05194901DFF4446D9D3FDBD9DA84DC4A523A23C33FF3D4ECFC1564C16F999B5B2DADC97BB14ECA2A3185F8E53058D0CD3259A94AA7808A6A00281806250493D3"

io = remote("", )

entry =&nbsp;f"{hex_m1},{hex_m2}".encode()
io.sendlineafter(b" : ",entry)

flag = io.recvline().strip(b"\n").decode().split(": ")[-1]
io.close()
print(flag)

免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:Pirater Pirater Pirater《SHCTF 2026 hash1-3 WriteUp》

评论:0   参与:  0