当前位置: 首页 > 工具软件 > DO-CMS > 使用案例 >

刷洞1--74cms3.5后台任意文件删除漏洞

马丰
2023-12-01

干了这么多年,突然觉得自己跟安全离的越来越远,真正的网络安全和代码安全息息相关,包括传统的审计、逆向、漏洞以及新型的AI安全研究。还是安安心心写代码,调漏洞吧,要不然也枉在这个行业工作。

对于小白来说,我还是从老版本的cms开始,借助大牛们的博客开始吧。http://0day5.com/archives/3981/
使用74cms3.5
后台任意文件删除

elseif($act == 'del_img')
{

    check_token();

    $id=intval($_GET['id']);
    $img=$_GET['img'];
    $img=str_replace("../","***",$img);
    $sql="update ".table('article')." set Small_img='' where id=".$id." LIMIT 1";
    $db->query($sql);
    echo $upfiles_dir.$img;

    @unlink($upfiles_dir.$img);
    @unlink($thumb_dir.$img);
    adminmsg("ɾ������ͼ�ɹ���",2);
}

这里大牛博客里说可以直接删除,貌似不行,因为74cms默认开始了CSRF防御,所以在check_token()函数中就把任意文件删除否了。

function check_token()
{

    global $_CFG;

    if ($_CFG["open_csrf"]=="1")
    {

        if (empty($_SESSION['token']))
        {

        unset($_SESSION['token']);
        global $smarty;

        $smarty->display('sys/admin_csrf.htm');

        exit();
        }
        else
        {
            $page=!empty($_SERVER['PHP_SELF'])?md5($_SERVER['PHP_SELF']):'token';
            $hiddentoken=!empty($_POST['hiddentoken'])?$_POST['hiddentoken']:$_GET['hiddentoken'];
            if ($_SESSION['token'][$page]!=$hiddentoken)
            {
            unset($_SESSION['token'],$hiddentoken);
            global $smarty;
            $smarty->display('sys/admin_csrf.htm');
            exit();
            }
        }
    unset($_SESSION['token'],$hiddentoken);
    }
}

这里获取到的open_csrf为1,所以必须在后台系统设置->安全设置中将CSRF关掉才行。-^–……–^-好鸡肋,不过总之是后台中的漏洞,登陆了管理员完全可以操作的。打卡!
http://127.0.0.1/74cms35/upload/admin/admin_article.php?act=del_img&img=…...\a.txt
get到的tips:

看到这里过滤了../,然而在windows下使用..\也是可以的,所以可以任意删除文件。

另外一个知识点:

elseif($act == 'do_login')
{
    header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
    header("Cache-Control: no-cache, must-revalidate");
    header("Pragma: no-cache");
    $admin_name = isset($_POST['admin_name']) ? trim($_POST['admin_name']) : '';
    $admin_pwd = isset($_POST['admin_pwd']) ? trim($_POST['admin_pwd']) : '';
    $postcaptcha = isset($_POST['postcaptcha']) ? $_POST['postcaptcha'] : '';
    $remember = isset($_POST['rememberme']) ? intval($_POST['rememberme']) : 0;
    if($admin_name == '')
    {
    header("Location:?act=login&err=".urlencode('用户名不能为空'));
    exit();
    }
    elseif($admin_pwd == '')
    {
    header("Location:?act=login&err=".urlencode('密码不能为空'));
    exit();
    }
    $captcha=get_cache('captcha');
    if(empty($postcaptcha) && $captcha['verify_adminlogin']=='1')
    {
        header("Location:?act=login&err=".urlencode('验证码不能为空'));
        exit();
    }
    if ($captcha['verify_adminlogin']=='1' && strcasecmp($_SESSION['imageCaptcha_content'],$postcaptcha)!=0)
    {
        write_log("<span style=\"color:#FF0000\">验证码填写错误</span>",$admin_name,2);
        header("Location:?act=login&err=".urlencode('验证码填写错误'));
        exit();
    }
    elseif(check_admin($admin_name,$admin_pwd))
    {
        update_admin_info($admin_name);
        write_log("成功登录",$admin_name);
        if($remember == 1)
        {
            $admininfo=get_admin_one($admin_name);
            setcookie('Qishi[admin_id]', $_SESSION['admin_id'], time()+86400, $QS_cookiepath, $QS_cookiedomain);
            setcookie('Qishi[admin_name]', $admin_name, time()+86400, $QS_cookiepath, $QS_cookiedomain);
            setcookie('Qishi[admin_pwd]', md5($admin_name.$admininfo['pwd'].$admininfo['pwd_hash'].$QS_pwdhash), time()+86400, $QS_cookiepath, $QS_cookiedomain);
        }
    }
    else
    {
        write_log("<span style=\"color:#FF0000\">用户名或密码错误</span>",$admin_name,2);
        header("Location:?act=login&err=".urlencode('用户名或密码错误'));
        exit();
    }
header("Location: admin_index.php"); 
}

这里在跟check_admin函数的时候,惊奇的发现用户名和密码都没有做过滤,然后以为可以注入

function get_admin_one($username){
    global $db;
    $sql = "select * from ".table('admin')." where admin_name = '".$username."' LIMIT 1";
    echo $sql;
    return $db->getone($sql);
}

bingo,burpsuit测试

select * from qs_admin where admin_name = '�\'' LIMIT 1

出现了这种情况,利用宽字节注入没有吃掉\,为啥呢!,查资料发现网站是用gb2312编码的,gb2312是不存在宽字节注入的,摘抄笔记如下:

为什么,这归结于gb2312编码的取值范围。它的高位范围是0xA1~0xF7,低位范围是0xA1~0xFE,而\是0x5c,是不在低位范围中的。所以,0x5c根本不是gb2312中的编码,所以自然也是不会被吃掉的。

所以,把这个思路扩展到世界上所有多字节编码,我们可以这样认为:只要低位的范围中含有0x5c的编码,就可以进行宽字符注入。
 类似资料: