XPath Injection Alessandro ` jekil` Tanasi Dati volubili Un informazione (dato) può avere varie rappresentazioni che non ne alterano il significato ma ne facilitano l'impiego Infomazione che vengono memorizzate in file XML piuttosto che in database tradizionali Esempi: Uso massiccio di middleware come soluzione ai problemi del mondo(TM) SQL Server e i dataset XML XPath “Mollare, non mollare. Spaghetti, non spaghetti. Ti preoccupi troppo di cio` che era, e di cio` che sara`. C’e` un detto: ieri e` storia, domani e` un mistero, ma oggi e` un dono, per questo si chiama presente” (Kung-fu Panda) WTF XPath? XPath è un linguaggio per porre interrogazioni in un modo molto simile a SQL sui dati contenuti in file XML Fornisce una sintassi standard per definire parti di un documento e path expressions per scorrerne I suoi elementi Come SQL implementa delle funzioni base ad es. substring(), current-time() E' uno standard W3C nella versione 1.0 (la più usata) e nella versione 2.0 recentemente approvata Viene usato standalone, all'interno di trasformazioni XSLT o nell'utilizzo di XQuery XPath XPath viene impiegato quando c'e` bisogno di database light o di particolari architetture ad es. Provisioning Varie librerie forniscono supporto a database XML e integrano XPath (dbXML, Xindice) Viene usato nativamente (Java, .NET, Coldfusion) Viene usato client side (Flash, Silverlight) Terminologia Relazioni di sangue <?xml version="1.0" encoding="ISO­8859­1"?> <users> <user> <username id="1">root</username> <password>OAhhgg</password> </user> </users> ✔ ✔ <user> è padre di <username> e <password> <username> e <password> sono parenti perchè hanno lo stesso padre ✔ <users> è antenato di <user> ✔ <user> è discendente di <users> Path Expressions Sintassi basata su path: nodi di un documento XML hanno analogie con directory e file di un file system Expression Description nodename Selects all child nodes of the named node / Selects from the root node // Selects nodes in the document from the current node that match the selection no matter where they are . Selects the current node .. Selects the parent of the current node Esempio Expression Result users Selects all the child nodes of the users element /users Selects the root element users users/user Selects all user elements that are children of users //users Selects all users elements no matter where they are in the document users//user Selects all user elements that are descendant of the users element, no matter where they are under the users element Predicati Vengono utilizzato per trovare specifici nodi, sono sempre indicati tra parentesi quadre Expression Result /users/user[1] Selects the first user element that is the child of the users element. /users/user[last()] Selects the last user element that is the child of the users element /users/user[position()<3] Selects the first two user elements that are children of the users element //username[@id='1'] Selects all the username elements that have an attribute named id with a value of ‘1' Location Path Example Result child::user Selects all user nodes that are children of the current node attribute::id Selects the id attribute of the current node child::* Selects all children of the current node attribute::* Selects all attributes of the current node child::text() Selects all text child nodes of the current node child::node() Selects all child nodes of the current node descendant::users Selects all users descendants of the current node Funzioni Le funzioni di XSLT e Xquery possono esser usate in Xpath Le funzioni sono legate al datatype Function Name Description substring(string,start,len) Returns the substring from the start position to the specified length. Index of the first character is 1. If length is omitted it returns the substring from the start position to the end string-length(string) Returns the length of the specified string. count((item,item,...)) Returns the count of nodes starts-with(string1,string2) Returns true if string1 starts with string2, otherwise it returns false contains(string1,string2) Returns true if string1 contains string2, otherwise it returns false number(arg) Returns the numeric value of the argument. The argument could be a boolean, string, or node-set string(arg) Returns the string value of the argument. The argument could be a number, boolean, or node-set Xpath Injection "Non aver paura di urtare i miei sentimenti, io non mi preoccupo dei tuoi" (Leoni per agnelli) WTF XPath Injection Problema: uno sviluppatore doveva fuggire a casa e non ha validato l'input utente che viene utilizzato per la creazione di query XPath Nel testing di un XPath Injection si prova ad alterare una query XPath in modo da alterarne il suo significato Senza conoscere la struttura dati Senza conoscere la sintassi della query XPath e` funny Se XPath è standard esiste un unico dialetto per le query ogni attack vector puo`essere applicato as-is su ogni implementazione L'accesso al foglio XML che contiene i dati non ha limitazioni Mancanza di controllo d'accesso e di livelli di autorizzazione Tecniche di Injection Può darsi che nella rara occasione in cui per seguire la giusta rotta ci voglia un atto di pirateria, la pirateria stessa possa essere la giusta rotta (La maledizione della prima luna) Example page XmlDocument XmlDoc = new XmlDocument(); XmlDoc.Load("..."); ... XPathNavigator nav = XmlDoc.CreateNavigator(); XPathExpression expr = nav.Compile("string(//user[name/text()='"+TextBox1.Text+ "' and password/text()='"+TextBox2.Text+ "']/account/text())"); String account=Convert.ToString(nav.Evaluate(expr)); if (account=="") { // name+password pair is not found in the XML document – // login failed. ... } else { // account found -> Login succeeded. // Proceed into the application. ... } Authentication bypass XPath non prevede delimitatori di commenti L'utilizzo coretto del form di login fa eseguire una query simile a: //user[name/text()='antani' and password/text()='tapioco']/account/text() Tentativo di abuso fatto con ' or 1=1 or ''=' //user[name/text()='' or 1=1 or ''='' and password/text()='']/account/text() L'utente e` in grado di forzare un cambiamento alla semantica della query XPath Un'attacco di questo tipo garantisce il bypass di una form di autenticazione Node guessing Leak dei dati contenuti nel database XML, ad esempio enumerazione del primo nodo figlio Utilizzando le funzioni per la selezione dei nodi si puo` tentare l'enumerazione dello schema Check sul nodo figlio: //user[name/text()='antani' or name(//user/name[1]) = 'tapioco' or 'a=b' and password/text()='']/account/text() Ritorna il primo elemento del node set P: //user[name/text()='Foobar'] | p | //user[name/text()='NoSuchUser' and password/text()='NoSuchPass']/account/text() Xpath crawling Vogliamo ottenere tutti i dati contenuti nel database XML Utilizzando le funzioni per contare nodi, navigare nei nodi, estrapolare il tipo di nodo e il suo valore Xpath 1.0 permette l'enumerazione dei figli ma non di ricavare dittamente il loro node type XPath Crawling Estrapolare il numero di nodi figli Ci sono almeno 4 tipi di nodi che ci possono interessare Contare gli elementi, reiterare il fetch per ogni elemento count(path/child::node()) - Conta il numero di noti per un path dato count(path/child::text()) - Conta il numero di campi count(path/child::comment()) - Conta il numero di commenti count(path/child::*) - Conta il numero di figli count(path/child::processing-instruction()) - Conta il numero di nodi PI L'algoritmo di crawl e` descritto da Amit Klein in Blind Xpath Injection Blind Xpath Injection La query viene eseguita in un contesto booleano Una query scalare deve essere booleanizzata Bisezione e funzioni stringa string-length e substring L'implementazione e` simile a quella usata per le blind SQL injections Lunghezza della seconda stringa del primo utente: stringlength(//user[position()=1]/child::node()[position()=2]) Fetch del primo carattere: substring((//user[position()=1]/child::node()[position()=2),1,1) Injection in XPath 2.0 Xpath 2.0 puo` accedere a dati XML via URI e senza limitazioni sul documento in uso Retrive di qualsiasi documento XML sul file system, ad es. file:///c:/data/database.xml Aggiunta la funzione string-to-codepoints() che data una stringa ritorna la sua rappresentazione di codici Unicode Problematiche Ricostruzione imperfetta del documento XML in caso di note type particolari Performance per il fetch dei dati Gestione di eventuali simboli Eventuale query size >65000 Mitigation Ciambelle... esiste qualcosa che non riescono a fare? (Homer Simpson) Mitigation Input validation Filtraggio ed escaping degli input Whitelisting / blacklisting Parametrizzazione Statement precompilati Utilizzo di query XPath precompilate (se la tecnologia usaa lo permette) Future research Il materiale disponibile non e` molto, rimangono scoperte alcune tematiche: Mappable Injections Librerie che implementano XPath Ricerca vulnerabilità XPath 2.0 Riferimenti XML Path Language (XPath) Version 1.0 http://www.w3.org/TR/xpath OWASP http://www.owasp.org/index.php/XPATH_Injection Blind XPath Injection - Amit Klein http://packetstormsecurity.org/papers/bypass/Blind_XPath_Inj ection_20040518.pdf Acunetix WSDigger Domande