Mobile wallpaper 1Mobile wallpaper 2Mobile wallpaper 3Mobile wallpaper 4Mobile wallpaper 5Mobile wallpaper 6
1028 words
5 minutes
H&NCTF 2026 WriteUp
2026-06-07
统计加载中...

还是太菜了,打不过AI,这次比赛期间也有别的事就没怎么仔细看题了,浅捡个OSINT双一血叭,盯真神力!

ps:Crypto剩余的WriteUp后面看情况加,最近微忙了,而且有些题纯AI神力,我真不是很懂。

OSINT#

OSINT1#

我只能说牢OSINTer才懂什么叫OSINT盯真神力。

image-20260607115818736

但是其实我这里当时只盯出了*蓝星梦幻城,前面那个字我越看越像,但是没关系,我选择直接搜索蓝星梦幻城,照样也能出:

image-20260607115938735

然后就是高德地图找点了:

image-20260607120132311

根据给的约束H&NCTF{**省_**市_***街_**路}得出flag:

H&NCTF{辽宁省_沈阳市_七星大街_蒲达路}

OSINT2#

OSINT2

又是最爱的百度识图启动,找到几乎一模一样的轨迹:

image-20260607143139559

点击图片进入链接找到一些信息太原火箭

image-20260607143228192

搜索这一关键词,定位到临近时间的发射记录:

image-20260607143409662

往下翻翻会找到一个符合flag约束的叫法长征六号甲(不过现在写wp的时候看觉得很神奇当时自己为什么没有试试长征六号改,虽然这也有可能是对的flag?):

image-20260607144111885

整理一下截止目前已知flagH&NCTF{山西省_太原市_**县_***园_长征六号甲}。接下来要找找拍照位置,第一反应就是截小部分特征去识图,但是截完图盯真神力又出现了。截完下方建筑物后突然发现上面有字儿??藏得太深了:

image-20260607144446882

可以看到清源水城欢,非常好,高德地图搜索一下:

image-20260607144617233

定位到清徐县清源水城,和前面确定信息也对上了,但是是***园呢,看了看图片地下看起来有山,再结合高德地图确定了拍摄方向:

image-20260607150228187

转战百度街景,通过路灯形状和清源水城地图所在的望景花园的建筑形状确定拍摄位置位于东湖公园:

image-20260607150542488

最后得到匹配约束H&NCTF{**省_**市_**县_***园_¥¥¥号¥}flag

H&NCTF{山西省_太原市_清徐县_东湖公园_长征六号甲}

ps#

不过就是仅图里信息似乎不能排除这个人民公园的干扰项就是了。

image-20260607150724377

哦这么说来,当时做题还算做的早的,平台还没修复,一开始提示应该是:H&NCTF{**省_**市_**县_***园_***号*},然后应该是有markdown语法的原因使题目变成了 H&NCTF{**省_**市_**县_***园_**},当时看到 **还想了很久怎么能够把长征六号缩写成符合条件的,当时疑惑了一下字是个斜体,但是还是没想到了,不然应该出的还能更快点,最后还是在平台更新题目了之后出的一血。

Crypto#

rsa#

题目:

from Crypto.Util.number import *
from hashlib import *
from flag import flag
import random
from gmpy2 import *
file=open("outext.txt","w")
m=bytes_to_long(flag.encode())
e=0x10001
p=getPrime(512)
q=getPrime(512)
r=getPrime(512)
s=getRandomRange(2**0,2**5)
n=p*q*r
hint_1=powmod(p,r,n)
hint_2=powmod(r,s-2,n)
c=powmod(m,e*(s-1),n)
file.write(f"n={n}\n")
file.write(f"hint_1={hint_1}\n")
file.write(f"hint_2={hint_2}\n")
file.write(f"c={c}\n")

题目给出三素数 RSA:n = p * q * r并给出:

hint_1=powmod(p,r,n)
hint_2=powmod(r,s-2,n)
c=powmod(m,e*(s-1),n)

由于

hint1pr(modn)hint10(modp)hint_1\equiv p^r\pmod{n}\Rightarrow hint_1\equiv 0\pmod{p}

因此可以直接得到p = gcd(hint_1, n)。同理,实际数据中 s > 2,所以:

hint2rs2(modn)hint20(modr)hint_2\equiv r^{s-2}\pmod{n}\Rightarrow hint_2\equiv 0\pmod{r}

于是r = gcd(hint_2, n), q = n // p // r,第一部分n的分解问题已解决。然后枚举s找满足hint2 == pow(r, s - 2, n)s,得到s = 5,也就是

cm4e(modn)c\equiv m^{4e}\pmod{n}

这里不能直接求私钥指数:gcd(e * 4, phi) = gcd(4, phi) = 4。但e = 65537phi互素,所以可以先消去e

yce1(modφ)m4(modn)y \equiv c^{e^{-1}\pmod{\varphi}}\equiv m^4\pmod{n}

问题转化为求:

ym4(modn)y\equiv m^4\pmod{n}

m并不大,直接gmpy2库的iroot函数求四次根即可得到flag

exp.py

from Crypto.Util.number import long_to_bytes
from gmpy2 import gcd, invert, iroot
n = 979979396280795025447159604653924698007421096864863532640467914347154790478966309310242938046375382963295576018108365493749631126829441159428446514913045553768462359812141188437867022522642883215617924930162362975118753135307868195989529952635950471650238440782216155187808858076406173123376307233605251322063056796573051571421373804400742814841380628966244338908899920978345766251241466839953205051967073060065807266111902771444846685228931419177071776202794447
hint_1 = 63829737789015303255616010995430271442615363334005654136790603132124697763248934614727407142426063514798780422988294297457892974476968909011594056992955895743933371737158975962646294428475380486162081880712675820233377927503162194872237855275106302109770193104087596464371630697812485876577638759333868021626793193900551035852971032420289295901322943785198833653840660632317598841581456445704445974646032512822137015643024549120429185146320086905286336984565780
hint_2 = 811225663987535096929418484923252315039418484176390289011682551835727122657404871203738500127970361216735459526184706907379779604453737161603694233134616612209864675829711293451990923072581678837181277865189990566773712777076953922847187456309194004847987239678695437936130991596979472315709241564675102503547056625609492959906116295807701067076200192520193721233660324426348223046220024274205328004516104292752500294107591971181194232357501832617229377939678909
c = 554491127748739273581999967419384543160020010465406113035040735016528899552140169583353294062576591579973382955030891201758740151326341677432402990540380379170704264251101185973670282744523850032981933697291881931773848908998356042585230566838554495089166039238470892330078315451993029959200347825405258393357495512040019534150921164118639093729837315213487083882435472600420840995787008748593481029626822135460873446903992348211665228818922931223995184301813181
e = 0x10001
p = int(gcd(hint_1, n))
r = int(gcd(hint_2, n))
q = n // p // r
s = None
for i in range(2, 32):
if pow(r, i - 2, n) == hint_2:
s = i
break
phi = (p - 1) * (q - 1) * (r - 1)
k = s - 1
de = int(invert(e, phi))
y = pow(c, de, n)
m = iroot(y, k)[0]
print(long_to_bytes(m).decode())
# H&NCTF{c0gr4tul4ti0n!!y0u_g0t_it}

后面的下一次更新再来看吧hhhh~#

H&NCTF 2026 WriteUp
https://q1uju.cc/posts/hnctf-2026-writeup/hnctf2026writeup/
Author
Q1uJu
Published at
2026-06-07
License
CC BY-NC-SA 4.0

Some information may be outdated