LitCTF 2023 部分wp

by shenghuo2部分

注意
本文最后更新于 2024-06-30,文中内容可能已过时。
RANK

rank:18

睡醒的时候比赛开始一小时了,队友秒了不少了

个人就做了这些,剩下的部分队友做了,趁大家不熟otp的知识拿了个一血

还得是靠ACM爷带飞

有空可以再补其他题的wp

Misc

签到!(初级)

关注长亭珂兰寺公众号,发送签到即可获取flag。

LitCTF{Welcome_t0_LitCTF2023}

签到成功

What_1s_BASE (初级)

LitCTF{KFC_Cr4zy_Thur3day_V_me_50}

Take me hand (初级)

Tcp 第1流

img

404notfound (初级)

img

LitCTF{Its_404_but_1ts_n0t_a_page}

喜欢我的压缩包么 (初级)

压缩包密码114514

img

这羽毛球怎么只有一半啊(恼 (初级)

直接改高度,然后用画图无视crc校验打开

img

破损的图片(初级)

png,前八位文件头损坏

89 50 4E 47 0D 0A 1A 0A

修复 打开

img

(明明.后面还有空格的说)

问卷

img

NSSCTF{LitCTF_2023?It’s_time_to_g0to_zh1hu!!!}

两仪生四象 (中级)

其实看懂逻辑,就能做出来

就是每个字符 ord转成十位二进制

然后按照reverse_hash的dict,三位二进制一组转成卦

1
2
3
4
5
6
7
_hash = {"乾": "111", "兑": "011", "离": "101", "震": "001", "巽": "110", "坎": "010", "艮": "100", "坤": "000"}

encoded_text = "坤乾兑艮兑坎坤坤巽震坤巽震艮兑坎坤震兑乾坤巽坤艮兑震巽坤巽艮坤巽艮艮兑兑艮震兑乾坤乾坤坤兑艮艮坤巽坤坤巽坎坤兑离坎震艮兑坤巽坎艮兑震坤震兑乾坤乾坎坤兑坎坤震艮离坤离乾艮震艮巽震离震坤巽兑艮兑坎坤震巽艮坤离乾艮坎离坤震巽坎坤兑坤艮兑震巽震巽坎坤巽坤艮兑兑坎震巽兑" 

binary_text = "".join([_hash.get(i) for i in encoded_text])

print("".join([chr(int(binary_text[x:x+10],2)) for x in range(0,len(binary_text),10)]))

wh1ch_ag4in_pr0duced_the_3ight_Tr1grams

ssvvgg

先把jpg保存出来

img

就是这段base64

img

文件尾提示steghide

用stegseek 梭

img

LitCTF{svg?_base642png!&steghide!}

Easy shark

img

🐎的key是a

最后一流追踪http

img

得到个方程组和flag

flag看起来是仿射密码,而且有方程组

不过拿sagemath解了个94出来(?)

用脚本爆破出的flag

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
cipher = "gezx{j13p5oznp_1t_z_900y_k3z771h_k001}"

for a in range(100):
    for b in range(100):
        flag=''
        for i in cipher:
            if ord(i) >= ord("a") and ord(i) <= ord("z"):
                cha=ord(i)-ord('a')
                flag+=chr((a*(cha-b)%26)+97)
            else:
                flag+=i
                
        if 'flag' in flag:
            print(flag,(a,b))
flag{w13e5hake_1s_a_900d_t3a771c_t001} (23, 25)
flag{w13e5hake_1s_a_900d_t3a771c_t001} (23, 51)
flag{w13e5hake_1s_a_900d_t3a771c_t001} (23, 77)
flag{w13e5hake_1s_a_900d_t3a771c_t001} (49, 25)
flag{w13e5hake_1s_a_900d_t3a771c_t001} (49, 51)
flag{w13e5hake_1s_a_900d_t3a771c_t001} (49, 77)
flag{w13e5hake_1s_a_900d_t3a771c_t001} (75, 25)
flag{w13e5hake_1s_a_900d_t3a771c_t001} (75, 51)
flag{w13e5hake_1s_a_900d_t3a771c_t001} (75, 77)

拼起来

NSSCTF{w13e5hake_1s_a_900d_t3a771c_t001_a}

crypto

(校外)md5的破解

一共缺了4位

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import string
import itertools
import hashlib

def md5(str:str):
    return hashlib.md5(str.encode()).hexdigest()

for i in itertools.product(string.ascii_lowercase+string.digits,repeat=4):
    flag = 'LitCTF{md5can%s%s3de%srypt213thoughcr%ssh}'%i
    # print((flag))
    if md5(flag) == '496603d6953a15846cd7cc476f146771':
        print(flag)
        break

LitCTF{md5can123dexrypt213thoughcrpsh}

The same common divisor (高级)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
from libnum import n2s,invmod,gcd

n1= 9852079772293301283705208653824307027320071498525390578148444258198605733768947108049676831872672654449631852459503049139275329796717506126689710613873813880735666507857022786447784753088176997374711523987152412069255685005264853118880922539048290400078105858759506186417678959028622484823376958194324034590514104266608644398160457382895380141070373685334979803658172378382884352616985632157233900719194944197689860219335238499593658894630966428723660931647038577670614850305719449893199713589368780231046895222526070730152875112477675102652862254926169713030701937231206405968412044029177246460558028793385980934233
n3= 4940268030889181135441311597961813780480775970170156650560367030148383674257975796516865571557828263935532335958510269356443566533284856608454193676600884849913964971291145182724888816164723930966472329604608512023988191536173112847915884014445539739070437180314205284883149421228744714989392788108329929896637182055266508625177260492776962915873036873839946591259443753924970795669864031580632650140641456386202636466624658715315856453572441182758855085077441336516178544978457053552156714181607801760605521338788424464551796638531143900048375037218585999440622490119344971822707261432953755569507740550277088437182
c1= 7066425618980522033304943700150361912772559890076173881522840300333719222157667104461410726444725540513601550570478331917063911791020088865705346188662290524599499769112250751103647749860198318955619903728724860941709527724500004142950768744200491448875522031555564384426372047270359602780292587644737898593450148108629904854675417943165292922990980758572264063039172969633878015560735737699147707712154627358077477591293746136250207139049702201052305840453700782016480965369600667516646007546442708862429431724013679189842300429421340122052682391471347471758814138218632022564279296594279507382548264409296929401260
c2= 854668035897095127498890630660344701894030345838998465420605524714323454298819946231147930930739944351187708040037822108105697983018529921300277486094149269105712677374751164879455815185393395371001495146490416978221501351569800028842842393448555836910486037183218754013655794027528039329299851644787006463456162952383099752894635657833907958930587328480492546831654755627949756658554724024525108575961076341962292900510328611128404001877137799465932130220386963518903892403159969133882215092783063943679288192557384595152566356483424061922742307738886179947575613661171671781544283180451958232826666741028590085269

e = 65537

n2 = n3^n1

q = gcd(n1, n2)
p = n1 // q
r = n2 // q
print(n2s(pow(c1, int(invmod(e, (p - 1) * (q - 1))), n1)).decode())
# LitCTF{TH3_Tw0_nUmb3rs_H@v3_The_sAme_D1v1s0r!!}

easy_math (中级)

p**3 >> q**5

所以hint近似于,p的三次根方

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import libnum

n = 2230791374046346835775433548641067593691369485828070649075162141394476183565187654365131822111419512477883295758461313983481545182887415447403634720326639070667688614534290859200753589300443797
c = 2168563038335029902089976057856861885635845445863841607485310134441400500612435296818745930370268060353437465666224400129105788787423156958336380480503762222278722770240792709450637433509537280
hint = 392490868359411675557103683163021977774935163924606169241731307258226973701652855448542714274348304997416149742779376023311152228735117186027560227613656229190807480010615064372521942836446425717660375242197759811804760170129768647414717571386950790115746414735411766002368288743086845078803312201707960465419405926186622999423245762570917629351110970429987377475979058821154568001902541710817731089463915930932142007312230897818177067675996751110894377356758932

e = 65537
p = libnum.nroot(hint,3) + 1
q = n//p

print(libnum.n2s(pow(c, int(libnum.invmod(e, (p - 1) * (q - 1))), n)).decode())

(校外)babyLCG

lcg板子题,seed恢复

 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
# MMI = lambda A, n,s=1,t=0,N=0: (n < 2 and t%N or MMI(n, A%n, t, s-A//n*t, N or n),-1)[n<1] #逆元计算
from functools import reduce
from gmpy2 import invert,gcd
from Crypto.Util.number import long_to_bytes

results = [699175025435513913222265085178805479192132631113784770123757454808149151697608216361550466652878, 193316257467202036043918706856603526262215679149886976392930192639917920593706895122296071643390, 1624937780477561769577140419364339298985292198464188802403816662221142156714021229977403603922943, 659236391930254891621938248429619132720452597526316230221895367798170380093631947248925278766506, 111407194162820942281872438978366964960570302720229611594374532025973998885554449685055172110829, 1415787594624585063605356859393351333923892058922987749824214311091742328340293435914830175796909, 655057648553921580727111809001898496375489870757705297406250204329094679858718932270475755075698, 1683427135823894785654993254138434580152093609545092045940376086714124324274044014654085676620851, 492953986125248558013838257810313149490245209968714980288031443714890115686764222999717055064509, 70048773361068060773257074705619791938224397526269544533030294499007242937089146507674570192265]

def crack_unknown_increment(states, modulus, multiplier):
    increment = (states[1] - states[0]*multiplier) % modulus
    seed = (invert(multiplier,modulus)*(states[0]-increment))%modulus
    return crack_unknown_seed(modulus, multiplier, increment, states[0])

def crack_unknown_multiplier(states, modulus):
    multiplier = (states[2] - states[1]) * invert(states[1] - states[0], modulus) % modulus
    return crack_unknown_increment(states, modulus, multiplier)

def crack_unknown_modulus(states): 
    diffs = [s1 - s0 for s0, s1 in zip(states, states[1:])] 
    zeroes = [t2*t0 - t1*t1 for t0, t1, t2 in zip(diffs, diffs[1:], diffs[2:])] 
    modulus = abs(reduce(gcd, zeroes)) 
    return crack_unknown_multiplier(states, modulus)

def crack_unknown_seed(modulus, multiplier, increment, states0):
    return (invert(multiplier,modulus)*(states0-increment))%modulus

seed = crack_unknown_modulus(results)
print(seed)
print(long_to_bytes(seed))

# 637558173724466419277009432838902680292766683894338509150988265759228898373642016332098881873533
# b'LitCTF{31fcd7832029a87f6c9f760fcf297b2f}'

(校外)我测你vva

flag.txt就是flag

HZCTF{Java666}

NSSCTF{Java666}

(校外)Virginia

维吉尼亚,分成两段

img

数组前7个,每个和LitCTF{相减,得到10 11 12 13 14 15 16

也就是按位+10再加index

1
2
3
4
flag=[86, 116, 128, 80, 98, 85, 139, 122, 134, 114, 125, 136, 117, 123, 129, 127, 128, 128, 142, 130, 140, 147, 127, 132, 131, 136, 151, 134, 152, 164] 

# print(len(flag))
print("".join(chr(v-10-i) for i,v in enumerate(flag)))

LitCTF{it_is_different_caesar}

(校外)隐晦的聊天记录(一血)

otp被称为完美加密,就是在key的长度大于等于明文长度的前提下

每次一密,不复用

算法就是xor,返璞归真

1
2
3
4
5
6
from Crypto.Util.strxor import strxor
import binascii
key = strxor((b'attack at dawn') ,binascii.unhexlify(b'6c73d5240a948c86981bc294814d'))

flag = strxor(key,b'Monday or Thur')
print(binascii.hexlify(flag).decode())

NSSCTF{4068cf2108868c889e1bf29d8351}

(校外)Where is P?

p**3是2052bit 比n 2048bit只差一点

先爆破,得到P

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import libnum
n= 24479907029118467064460793139240403258697681144532146836881997837526487637306591893357774423547391867013441147680031968367449693796015901951120514250935018725570026327610524687128709707340727799633444550317834481416507364804274266363478822257132586592232042108076935945436358397787891169163821061005102693505011197453089873909085170776511350713452580692963748763166981047023704528272230392479728897831538235554137129584665886878574314566549330671483636900134584707867654841021494106881794644469229030140144595938886437242375435914268001721437309283611088568191856208951867342004280893021653793820874747638264412653721
c= 6566517934961780069851397787369134601399136324586682773286046135297104713708615112015588908759927424841719937322574766875308296258325687730658550956691921018605724308665345526807393669538103819281108643141723589363068859617542807984954436567078438099854340705208503317269397632214274507740533638883597409138972287275965697689862321166613821995226000320597560745749780942467497435742492468670016480112957715214640939272457886646483560443432985954141177463448896521810457886108311082101521263110578485768091003174683555938678346359150123350656418123918738868598042533211541966786594006129134087145798672161268647536724
a= 22184346235325197613876257964606959796734210361241668065837491428527234174610482874427139453643569493268653377061231169173874401139203757698022691973395609028489121048788465356158531144787135876251872262389742175830840373281181905217510352227396545981674450409488394636498629147806808635157820030290630290808150235068140864601098322473572121965126109735529553247807211711005936042322910065304489093415276688746634951081501428768318098925390576594162098506572668709475140964400043947851427774550253257759990959997691631511262768785787474750441024242552456956598974533625095249106992723798354594261566983135394923063605

for i in range(100):
    P3 = n*i + a
    P = libnum.nroot(P3,3)
    if pow(P,3,n) == a:
        print('P =',P)
        break

P知道860bit,高位泄露恢复p

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
from sage.all import *
import gmpy2
p4 = 66302204855869216148926460265779698576660998574555407124043768605865908069722142097621926304390549253688814246272903647124801382742681337653915017783954290069842646020090511605930590064443141710086879668946
n =  24479907029118467064460793139240403258697681144532146836881997837526487637306591893357774423547391867013441147680031968367449693796015901951120514250935018725570026327610524687128709707340727799633444550317834481416507364804274266363478822257132586592232042108076935945436358397787891169163821061005102693505011197453089873909085170776511350713452580692963748763166981047023704528272230392479728897831538235554137129584665886878574314566549330671483636900134584707867654841021494106881794644469229030140144595938886437242375435914268001721437309283611088568191856208951867342004280893021653793820874747638264412653721
e = 0x10001
c = 6566517934961780069851397787369134601399136324586682773286046135297104713708615112015588908759927424841719937322574766875308296258325687730658550956691921018605724308665345526807393669538103819281108643141723589363068859617542807984954436567078438099854340705208503317269397632214274507740533638883597409138972287275965697689862321166613821995226000320597560745749780942467497435742492468670016480112957715214640939272457886646483560443432985954141177463448896521810457886108311082101521263110578485768091003174683555938678346359150123350656418123918738868598042533211541966786594006129134087145798672161268647536724
pbits = 1024
kbits = pbits - p4.nbits()
print(p4.nbits())
p4 = p4 << kbits
PR.<x> = PolynomialRing(Zmod(n))
f = x + p4
roots = f.small_roots(X=2^kbits, beta=0.4)
if roots:        
    p = p4+int(roots[0])
    print ("p: ", p)
    
    d = gmpy2.invert(e, (p - 1) * ((n//p) - 1))
    print(long_to_bytes(int(pow(c, int(d),n))))

b’LitCTF{Y0U_hAV3_g0T_Th3_r1ghT_AnsW3r}

(校外)baby_xor(赛后复现)

和ctfshow愚人杯的的xor差不多

不过泄露了只有一半bit

可以通过LitCTF{头补56位

然后coppersmith

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
from Crypto.Util.number import *

n = 139167681803392690594490403105432649693546256181767408269202101512534988406137879788255103631885736461742577594980136624933914700779445704490217419248411578290305101891222576080645870988658334799437317221565839991979543660824098367011942169305111105129234902517835649895908656770416774539906212596072334423407
c1 = 11201139662236758800406931253538295757259990870588609533820056210585752522925690049252488581929717556881067021381940083808024384402885422258545946243513996
c2 = 112016152270171196606652761990170033221036025260883289104273504703557624964071464062375228351458191745141525003775876044271210498526920529385038130932141551598616579917681815276713386113932345056134302042399379895915706991873687943357627747262597883603999621939794450743982662393955266685255577026078256473601

t = bytes_to_long(b'LitCTF{')
c0 = c1^^(t<<(8*25))
P.<x> = PolynomialRing(Zmod(n))
f = c0+x
a = f.monic().small_roots(X=2^(256-(7*8)), beta=0.4)


p = f(a)
m = int(p)^^c1
print(long_to_bytes(m))

# b'LitCTF{oh!!!!coppersmith_is_fun}'

web

我Flag呢?

Ctrl+u看源码

flag在最下面

导弹迷踪

看源码找到game.js

img

Follow me and hack me

GET和POST传参

img

PHP是世界上最好的语言!!

img

1
<?php system('cat /*');

Vimyyds

扫得index.php.swp

Vim -r恢复

img

可知传password=R2l2ZV9NZV9Zb3VyX0ZsYWc可以命令执行

1
password=R2l2ZV9NZV9Zb3VyX0ZsYWc=&cmd=cat /f*

img

作业管理系统

admin admin登录

然后传个马

img

这是什么?SQL !注一下 !

Sqlmap 梭

img

Http pro max plus

分别传

img

然后得到

1
借一步说话--->> /wtfwtfwtfwtf.php

img

得到flag

img

Ping

;截断

img

1zjs

眼都找瞎了

img

就当无事发生

https://github.com/ProbiusOfficial/ProbiusOfficial.github.io/commit/main

直接看commit

img

pwn

只需要nc一下~

感觉,是题目环境问题

反正flag在环境变量里,没写入文件

输入env看到flag

口算题卡

交互题

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
from pwn import *
context.log_level = 'debug' 
p = remote('node5.anna.nssctf.cn','28533')

r = lambda : p.recv()
rx = lambda x: p.recv(x)
ru = lambda x: p.recvuntil(x)
rud = lambda x: p.recvuntil(x, drop=True)
s = lambda x: p.send(x)
sl = lambda x: p.sendline(x)
sa = lambda x, y: p.sendafter(x, y)
sla = lambda x, y: p.sendlineafter(x, y)
close = lambda : p.close()
debug = lambda : gdb.attach(p)
shell = lambda : p.interactive()

rud(b'Good luck & Have fun!\n')
# print(p.recvline())
while True:
    calc = p.recvline().decode()[8:-2]
    sl(str(eval(calc)))
    p.recvline()

img

Re

世界上最棒的程序员

看字符串

img

LitCTF{I_am_the_best_programmer_ever}

ez_XOR

img

异或

img

LitCTF{XOR_1s_3asy_to_OR}

enbase64

base64变表

basecheck下个断点,动调

img

把source提出来

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
basetable = [  0x67, 0x4A, 0x31, 0x42, 0x52, 0x6A, 0x51, 0x69, 0x65, 0x2F, 
  0x46, 0x49, 0x57, 0x68, 0x45, 0x73, 0x6C, 0x71, 0x37, 0x47, 
  0x78, 0x62, 0x6E, 0x4C, 0x32, 0x36, 0x4D, 0x34, 0x2B, 0x48, 
  0x58, 0x55, 0x74, 0x63, 0x70, 0x6D, 0x56, 0x54, 0x4B, 0x61, 
  0x79, 0x64, 0x4F, 0x50, 0x33, 0x38, 0x6F, 0x66, 0x35, 0x76, 
  0x39, 0x30, 0x5A, 0x53, 0x77, 0x72, 0x6B, 0x59, 0x7A, 0x43, 
  0x41, 0x75, 0x4E, 0x44]

basetable = "".join([chr(x) for x in basetable])
print(basetable)

# gJ1BRjQie/FIWhEslq7GxbnL26M4+HXUtcpmVTKaydOP38of5v90ZSwrkYzCAuND

然后变表

img

LitCTF{B@5E64_l5_tooo0_E3sy!!!!!}

snake

pyc缺magic文件头

文件名是37,找个3.7的pyc头补上去

img

uncompyle6

img

1
2
3
4
5
6
flag = [
30, 196, 52, 252, 49, 220, 7, 243, 3, 241, 24, 224, 40, 230, 25, 251, 28, 233, 40, 237, 4, 225, 4, 215, 40, 231, 22, 237, 14, 251, 10, 169]
for i in range(0, len(flag), 2):
    flag[i], flag[i + 1] = flag[(i + 1)] ^ 136, flag[i] ^ 119

print(''.join([chr(i) for i in flag]))

LitCTF{python_snake_is_so_easy!}

0%