[Audit ideas] How to quickly locate SQLMS injection vulnerabilities?

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.

picture.png

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.
picture.png

We can directly open the jar file, and save the decompiled resource through the shortcut key Control+S.

picture.png

After exporting, it is a java file, which is a file type that can be scanned.

picture.png

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

picture.png

One of these  com.fortify.sca.DefaultFileTypes specifies the type of document being scanned. We  ,jscan delete it.

picture.png

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 byplaces 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.
picture.png

The first GET type

IDictDao.xml Introduce  the mapping statement in  IBaseDao.xml .

picture.png

In  IDictBiz this business layer, it is inherited  IBaseBiz so that there is a query to determine that the return type is DictEntity.

picture.png

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 .
picture.png

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 .

picture.png

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.

picture.png

web/DictAction.classIn  the control layer, it can be seen that the data of the request packet here becomes an entity, and then directly passed dictBiz.queryExcludeAppin.

picture.png

Similarly, all the parameters and values ​​passed in here will not be treated as DictEntity, and the same problem exists.
picture.png

The third POST type

ICategoryDao.xml Introduce  the mapping statement in  IBaseDao.xml .
picture.png

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.

picture.png

The entity type here has changed, but it does not prevent us from passing in  sqlWherethe execution that causes the vulnerability.

picture.png

The fourth POST type

IContentDao.xml Introduce  the mapping statement in  IBaseDao.xml .

picture.png

web/ContentAction.javaIn 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.

picture.png

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  . excuteSqlThis place executes the incoming SQL statement directly.

picture.png

The persistence layer proxy IBaseDao.class has written the interface corresponding to IBaseDao.xml
picture.png

IModelDao.class inherits IBaseDao and determines the type as ModelEntity

picture.png

picture.png

The business layer IModelBiz.class defines some interfaces

picture.png

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.

picture.png

The importModel function of ModelBizImpl.class is called in the importJson function of ModelAction.class in the control layer.

picture.png

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.

picture.png

Create a new business form --> drag the form component --> fill in the field name and default value --> generate code

picture.png

You can see the generated custom model code, we copy it and change the value of the sql field to our custom one.

picture.png

Arbitrary lines are not filtered and restricted, the lines of the statement are  split(';')split by .

picture.png

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

picture.png

Further follow up queryBySQL

picture.png

View the implementation method in the corresponding interface

picture.png

Then /net/mingsoft/base/biz/impl/BaseBizImpl.javarewrite queryBySQL here, and then callgetDao().queryBySQL

picture.png

Then it was found that /net/mingsoft/basic/action/BaseAction.class#validated the call was made during verification
picture.png

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

picture.png

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

picture.png

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注入。

picture.png

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)

Guess you like

Origin blog.csdn.net/kali_Ma/article/details/128345013