干了这么多年,突然觉得自己跟安全离的越来越远,真正的网络安全和代码安全息息相关,包括传统的审计、逆向、漏洞以及新型的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的编码,就可以进行宽字符注入。