0x00 Preface
MCMS is a commonly used CMS in government, education and other industries. It is widely used, but there are still many problems left in the underlying code. This article mainly focuses on auditing SQL injection and discusses how to quickly locate SQL injection vulnerabilities and the application of other tools.
MCMS is a complete open source Java CMS! Based on the SpringBoot 2 architecture, the front end is based on vue and element ui. Collect issues and update the version every two months, provide developers with hundreds of free templates, and provide applicable plug-ins (articles, malls, WeChat, forums, members, comments, payment, points, workflow, task scheduling, etc... ), a set of simple and easy-to-use open source systems, and a complete set of high-quality open source ecological content systems. Mingfei's mission is to reduce development costs, improve development efficiency, and provide a full range of enterprise-level development solutions.
0x01 Audit environment
Mingsoft MCMS v5.2.8
Mysql 8.0.29
Openjdk 19.0.1
0x02 Audit ideas
There are already many tools for modern code auditing on the market. When you get the source code, of course, you should use the tool to scan it first to save labor time. Although there are tools such as fortify and Qi Anxin Code Guard, human experience is still required to avoid some mistakes.
Leverage automated code audit tools
Here we use the fortify tool to scan the source code and record the two problems I encountered. The fortify tool is a paid tool, and this article does not provide a way to download the cracked version.
[Help one by one to learn about security, where to get all the resources one by one]
① Network security learning route
② 20 penetration testing e-books
③ Security attack and defense 357-page notes
④ 50 security attack and defense interview guides
⑤ Security red team penetration toolkit
⑥ Network security essential books
⑦100 actual combat cases of vulnerabilities
⑧Internal video resources of major security companies
⑨Analysis of past CTF capture-the-flag competition questions
1. Decompile the jar package
Use fortify to import MCMS source code for code audit, but the effect is often unsatisfactory. Because this set of source code uses Maven as the project management tool software, including dependency management, the jar packages that the MCMS project depends on are all pulled remotely. Among them, net.mingsoft.ms-base, ms-basic, and ms-mdiy are the underlying logic codes. When pulling, it exists in the form of a jar package, and automated tools will not scan the jar package.
We can rename the jar package to zip, and then unzip it to get the class file. But fortify also won't scan class files, we need to decompile further. Here we can use jadx to decompile.
We can directly open the jar file, and save the decompiled resource through the shortcut key Control+S.
After exporting, it is a java file, which is a file type that can be scanned.
2. Do not scan JS files
In the practice of scanning code, I encountered too many JS files, which caused the overall scanning progress to be greatly lengthened, which is not what I want.
Find fortify-sca.properties in the fortify/Core/config directory
One of these com.fortify.sca.DefaultFileTypes
specifies the type of document being scanned. We ,js
can delete it.
Manual Audit SQL Injection Thoughts
SQL injection generally needs to meet the following two conditions:
(1) The content of input parameters is user-controllable.
(2) Directly or indirectly spelled into SQL statement execution.
And there are different ways to execute SQL statements:
(1) Use JDBC class methods directly.
For this way of executing SQL statements, we can globally search for SQL keywords such as SELECT, DELETE, and UPDATE, or search for Statement and PreparedStatement method names to locate the place where the statement is executed.
(2) Use the MyBatis persistence layer as the SQL statement execution agent.
The MyBatis persistence layer generally uses #{}
"?" as a placeholder in the underlying implementation, which is a precompiled mechanism. In practice, similar order by
places where single quotes cannot be used cannot use precompilation, and instead use ${}
direct splicing into SQL statements. Typically this requires a strict filtering step of adding content manually. So although precompilation is very powerful, there are places that are not useful, and these places are our breakthroughs.
0x03 Audit process
From the above description, we can know that ${}
there may be SQL injection risks in the places where it is used, so we can directly search globally during the audit process ${}
.
1. There is an injection vulnerability in the underlying mapping, causing multiple foreground injections
reason
In the SQL persistence layer IBaseDao.xml
file, it can be seen that the use of the Sql mapping with the binding id as sqlWhere ${}
leads to the risk of SQL injection.
The first GET type
IDictDao.xml
Introduce the mapping statement in IBaseDao.xml
.
In IDictBiz
this business layer, it is inherited IBaseBiz
so that there is a query to determine that the return type is DictEntity.
In the control layer web/DictAction.class, you can see that the data of the request packet here becomes an entity, and then directly passed in dictBiz.query
.
When we request this interface, all the parameters and values passed in will be treated as DictEntity, so it can be passed directly here sqlWhere
.
sqlWhere的值为 [{"action":"","field":"extractvalue(0x7e,concat(0x7e,(database())))","el":"eq","model":"contentTitle","name":"文章标题","type":"input","value":"a"}]
The second GET type
IDictDao.xml
Introduce the mapping statement in IBaseDao.xml
. id is queryExcludeApp
.
web/DictAction.class
In the control layer, it can be seen that the data of the request packet here becomes an entity, and then directly passed dictBiz.queryExcludeApp
in.
Similarly, all the parameters and values passed in here will not be treated as DictEntity, and the same problem exists.
The third POST type
ICategoryDao.xml
Introduce the mapping statement in IBaseDao.xml
.
web/CategoryAction.java
In the control layer, it can be seen that the data of the request packet here becomes an entity, and then directly passed categoryBiz.query
in.
The entity type here has changed, but it does not prevent us from passing in sqlWhere
the execution that causes the vulnerability.
The fourth POST type
IContentDao.xml
Introduce the mapping statement in IBaseDao.xml
.
web/ContentAction.java
In the control layer, it can be seen that the data of the request packet here becomes an entity, and then directly passed contentBiz.query
in.
As long as it is introduced, there will be loopholes if there is no filtering.
2. Execute any SQL statement in the background custom model
There is an SQL operation statement IBaseDao.xml
bound with id in the persistence layer . excuteSql
This place executes the incoming SQL statement directly.
The persistence layer proxy IBaseDao.class has written the interface corresponding to IBaseDao.xml
IModelDao.class inherits IBaseDao and determines the type as ModelEntity
The business layer IModelBiz.class defines some interfaces
The business implementation layer ModelBizImpl.class implements the IModelBiz.class interface. By reading the code, it can be found that the excuteSql method in IModelDao.class is actually used in the importModel function.
The importModel function of ModelBizImpl.class is called in the importJson function of ModelAction.class in the control layer.
The location where this vulnerability occurs is the import function of the background custom model. To use this function, you need to https://code.mingsoft.net/
generate code.
Create a new business form --> drag the form component --> fill in the field name and default value --> generate code
You can see the generated custom model code, we copy it and change the value of the sql field to our custom one.
Arbitrary lines are not filtered and restricted, the lines of the statement are split(';')
split by .
This is actually the core business of MCMS, and it cannot be avoided. Therefore, as long as you use MCMS and have the permission to import the custom model, you can use SQL injection to obtain data or system permissions.
3. Check parameter interface foreground SQL injection
Because the mybatis framework is used here, the global search uses $ for splicing, and it is found in/net/mingsoft/ms-base/2.1.13/ms-base-2.1.13.jar!/net/mingsoft/base/dao/IBaseDao.xml
Further follow up queryBySQL
View the implementation method in the corresponding interface
Then /net/mingsoft/base/biz/impl/BaseBizImpl.java
rewrite queryBySQL here, and then callgetDao().queryBySQL
Then it was found that /net/mingsoft/basic/action/BaseAction.class#validated
the call was made during verification
Continue to follow, at this time, just find that the validated method can be called in the front-end route, and then find that /net/mingsoft/ms-mdiy/2.1.13.1/ms-mdiy-2.1.13.1-sources.jar!/net/mingsoft/mdiy/action/PageAction.java#verify
the validated method is called in
Looking for routes, by analyzing our GetMapping and then constructing the parameters fieldName, fieldValue, id, idName casually, the key we saw at the beginning corresponds to the fieldName passed in from the front end
http://127.0.0.1:8008/ms/mdiy/page/verify.do?fieldName=1;select/**/if(substring((select/**/database()),1,4)='mcms',sleep(5),1)/**/and/**/1&fieldValue=b&id=c&idName=1
fieldName`是传入了 `${key}直接拼接到SQL语句导致SQL注入。
0x04 summary
The code audit demonstrates that precompilation is not a panacea, otherwise there would not be so many SQL injection vulnerabilities. In places where precompilation cannot be used to process parameter values and can only be operated by splicing, is there any way other than manually writing a filter function that matches dangerous characters? We can also strictly require the type of parameters passed in. For example, in the place of numbers, the content input by the user is forcibly converted into int, and if it fails, an error will be reported. This is called the form filter layer. If our code is too large to spend a lot of manpower to troubleshoot vulnerabilities, we can purchase code audit services and WAF firewall products from security companies.
0x05 Reference
* [https://gitee.com/mingSoft/MCMS/issues/I5OWGU](https://gitee.com/mingSoft/MCMS/issues/I5OWGU)
* [https://gitee.com/mingSoft/MCMS/issues/I5X1U2](https://gitee.com/mingSoft/MCMS/issues/I5X1U2)