IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> PHP知识库 -> 如何审计一个冷门的cms? -> 正文阅读

[PHP知识库]如何审计一个冷门的cms?

ae51151790861bb5af4deb3ef2046d74.png

点击"蓝字"关注,获取更多技术内容!

前言

刚开始代码审计多多少少会有种无从下手的感觉,想要通过自己的代码审计能力直接审计出漏洞未免有些困难。但是如果直接拿到一个cms开始审,刚开始可能富有激情,可是越审到后面就会越怀疑自己,然后放弃代码审计。造成这样的现象的原因便是:不知道自己到底能不能审到漏洞。

那如何审出一个很少人知道,并且肯定存在的洞呢?

本文介绍的办法就是:上cnvd看看以前师傅提交的洞,虽然大多数的洞都是不公开的,但是我们还是可以根据cnvd给的一点点信息来尝试复现。

因此,本文涉及到的漏洞都是比较早被发现,危害性较低,并且已经被厂商修复的漏洞,本文仅对代码审计的过程做一个分析。

确定目标

刚开始审计,可以选择一些比较冷门的cms(内容管理系统),挑选一个自己擅长的cms语言审计,之所以选择冷门的cms是因为这些cms一般存在的安全问题会比热门cms多。

本文选用的cms是:emlog(V5.3.1),这个cms是使用PHP语言开发的个人博客管理系统

信息收集

确定完目标之后,就需要上cnvd搜索该cms历史存在的一些漏洞,本文演示的是emlog

cbcc6ba8062c4b0ccf58b776aefa7020.png

可以看到在cnvd上存在这么一些漏洞,虽然在漏洞详情页面并没有直接写漏洞是怎么形成的,但是在这里或多或少会存在一些信息。比如在哪个地方会存在什么类型的洞。

接下里挑选一个简单的漏洞进行演示

21f2a1a4c6262013623ef49b40595ce4.png

复现漏洞

由上图可知,在后台页面,一般是admin目录下,有一个ta打头的文件,而我们查看一下emlog目录,唯一一个ta打头的文件就是tags.php

7d324b09570f32d8e53a7d24e27e2e61.png

而在tag.php仅有50余行代码,因此想在50行左右的代码地方找到一个SQL注入还是比较简单的

f8fb0da12b91e32c8683e9e3dae1239d.png

首先是大概了解一下这50余行代码的作用,对于一个博客内容管理系统来说,tag.php应该是一个处理文章标签管理的文件

因此我们这个cms可能会用到这个文件的页面

58d80ba84345636681f03523883dda46.png

在这个页面中存在几种操作,一个是全选,一个是删除,其中点进标签后还存在标签修改的功能

ed6fc74b36bbb8a28c42e37817071872.png

这几个功能对应在tag.php中就是这么几个if语句

3665b7b45bdea10cc7a239a05bb37567.png

而执行哪一种操作是根据传入action的值来决定的

因此,接来下审计在这些if语句中可能存在的SQL注入的点

首先是第一个if判断

if?($action?==?'')?{
?$tags?=?$Tag_Model->getTag();
?include?View::getView('header');
?require_once?View::getView('tag');
?include?View::getView('footer');
?View::output();
}

这一个if判断只有一个action是可控的,其余没有参数可控,因此这个函数不存在SQL注入的点

然后再看一下第二个if判断

if?($action==?"mod_tag")?{
?$tagId?=?isset($_GET['tid'])???intval($_GET['tid'])?:?'';
?$tag?=?$Tag_Model->getOneTag($tagId);
?extract($tag);
?include?View::getView('header');
?require_once?View::getView('tagedit');
?include?View::getView('footer');View::output();
}

这一个if判断相比上一个多一个tid为可控参数,不过cms对传入的tid进行了intval的转换

不过我们还是跟进getOneTag方法看一下

function?getOneTag($tagId)?{
??$tag?=?array();
??$row?=?$this->db->once_fetch_array("SELECT?tagname,tid?FROM?".DB_PREFIX."tag?WHERE?tid=$tagId");
??$tag['tagname']?=?htmlspecialchars(trim($row['tagname']));
??$tag['tagid']?=?intval($row['tid']);
??return?$tag;
?}

getOneTag方法具有一个参数tagId,这个tagId就是前面我们自定义传入的tid,不过这个地方没法传入字符串进行闭合注入,因为在传入这个方法以前就已经intval转换了,所以这个点不存在sql注入

接下来看第三个if判断

//标签修改
if?($action=='update_tag')?{
?$tagName?=?isset($_POST['tagname'])???addslashes($_POST['tagname'])?:?'';
?$tagId?=?isset($_POST['tid'])???intval($_POST['tid'])?:?'';
????
????if?(empty($tagName))?{
????????emDirect("tag.php?action=mod_tag&tid=$tagId&error_a=1");
????}
????
?$Tag_Model->updateTagName($tagId,?$tagName);
?$CACHE->updateCache(array('tags',?'logtags'));
?emDirect("./tag.php?active_edit=1");
}

这里相比上面多了一个tagname,这个tagname可以传入字符串,也就是有可能会存在SQL注入,不过在传入的时候,cms会对这个tagname进行一个addslashes函数转换,也就是传入的单引号以及一些特殊符号会被转译。

我们这边抓包尝试一下

首先查看一下现在的标签,此时有两个标签tag112以及tags2123

5651232ce52c1cb4b88fd239b35631fc.png

上面提到的tagname其实就是标签的名字,我们抓包将tag112修改为tag112',尝试能否闭合

36f21cedcb92ccd9cad75a81dbf9902c.png

这时候我们返回主页面

26ee11f6dbcf86b0ea30a15186b54da0.png

发现此时标签变为了tag112',所以单引号是被转义了,没法直接进行SQL注入。

当然,如果数据库的编码为GBK,那么可以尝试宽字节注入,不过默认使用的数据库为utf8,因此无法使用宽字节注入。

接下来看第4个if判断

//批量删除标签
if?($action==?'dell_all_tag')?{
?$tags?=?isset($_POST['tag'])???$_POST['tag']?:?'';

????LoginAuth::checkToken();

?if?(!$tags)?{
??emDirect("./tag.php?error_a=1");
?}
?foreach?($tags?as?$key=>$value)?{
??$Tag_Model->deleteTag($key);
?}
?$CACHE->updateCache(array('tags',?'logtags'));
?emDirect("./tag.php?active_del=1");
}

这个地方POST传入了一个tag,是我们的可控参数,并且这里没有对tag进行转义,所以我们再往下看是否存在SQL注入

其中我们传入的tag最终会成为tags数组中的key,仔细看一下foreach循环中,传入的deleteTag方法的参数是数组中的key,而在PHP中,数组的key并不一定需要是数字,也可以是一个字符串,只要keyvalue对应即可。

我们这个时候先不着急抓包,先看看deleteTag方法是如何实现的。

跟进deleteTag方法

function?deleteTag($tagId)?{
??$this->db->query("DELETE?FROM?".DB_PREFIX."tag?where?tid=$tagId");
?}

可以发现,SQL语句执行的时候也是没有进行任何过滤的。

这里我们开始抓包

065c7b95ab9989cabe6695d57485352d.png

可以看到post传入了tag[1],这里我们对方括号中的1开始注入,这里也不需要引号闭合,直接注即可。

我使用的是报错注入

tag%5B1%20and%20updatexml(0,concat(0x7e,version()),1)%20%23%5D=1&token=c16eaff79a17d690f5c0caae66276085
d864b1337cdf65bd6843dd80a0f5de3e.png

看下方的结果,已经把数据库的版本爆出来了。

15396327a19b4138d84690d49ccfc0ea.png

总结

本文所复现的是在后台的SQL注入,利用难度较大,危害性较低。并且审计这个cms并不是直接拿一个cms从头开始审,而是根据在cnvd中存在的一些模糊信息进行审计,来提高自己复现这个漏洞的成功率,不至于在一开始就碰壁,而能在相对短的时间里获得较大的成就感,提高学习效率。

大家也可以多在练习中,积累,复制下方链接实操起来吧

https://www.hetianlab.com/expc.do?ec=ECID6db7-2f16-4ce6-aab8-9298490e2821&pk_campaign=weixin-wemedia#stu

f04c27a7c5937c9cf0dbb94e353cc87d.gif

戳“阅读原文”体验靶场实操

  PHP知识库 最新文章
Laravel 下实现 Google 2fa 验证
UUCTF WP
DASCTF10月 web
XAMPP任意命令执行提升权限漏洞(CVE-2020-
[GYCTF2020]Easyphp
iwebsec靶场 代码执行关卡通关笔记
多个线程同步执行,多个线程依次执行,多个
php 没事记录下常用方法 (TP5.1)
php之jwt
2021-09-18
上一篇文章      下一篇文章      查看所有文章
加:2022-01-24 10:36:11  更:2022-01-24 10:38:12 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/27 5:32:15-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计