Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

automatyczne logowanie przez www do sieci wifi

182 views
Skip to first unread message

Tomasz 'Piniu' Pichliński

unread,
Jul 15, 2007, 9:31:51 AM7/15/07
to
Witam!

Chce sobie napisac automat do logowania do sieci wifi, z ktorej
korzystam. Probowalem na podstawie tutoriala
(http://www.voidspace.org.uk/python/articles/urllib2.shtml) skleic jakis
kod i wykonywac go w sesji interaktywnej, ale nie dziala i nie bardzo
mam pomysl jak sie do tego zabrac.

Ponizej istotne moim zdaniem fragmenty strony logowania:

...

<form name="sendin" action="http://hotspot.dns/login" method="post">
<input type="hidden" name="username">
<input type="hidden" name="password">
<input type="hidden" name="dst" value="">
<input type="hidden" name="popup" value="true">
</form>
<script language="JavaScript" src="/md5.js">
</script>
<script language="JavaScript">
<!--
function doLogin() {
document.sendin.username.value = document.login.username.value;
document.sendin.password.value = hexMD5('\325' +
document.login.password.value +
'\142\277\221\277\236\213\012\131\160\257\223\051\301\024\251\066');
document.sendin.submit();
return false;
}
//-->
</script>


...


<form name="login" action="http://hotspot.dns/login" method="post"
onSubmit="return doLogin()" >
<input type="hidden" name="dst" value="">
<input type="hidden" name="popup" value="true">
<table width="284" >
<tr>
<td align="right" class="zielen"><font
color="#FFCC00">Nazwa
użytkownika</font>:</td>
<td><input style="width: 120px" name="username"
type="text" value=""/></td>

</tr>
<tr>
<td align="right" class="zielen"><font
color="#FFCC00">Hasło:</font></td>
<td><input style="width: 120px" name="password"
type="password"/></td>
</tr>
<tr>
<td>&nbsp;</td>
<td><input name="image" type="image" value="OK"
src="img/zaloguj.gif" border="0" alt="Log into system" width="87"
height="17" ></td>
</tr>

</table>
</form></td>

Cale zamieszanie wywoluje ta funkcja doLogin(), gdyby nie ona, raczej
nie mialbym problemu. Trzeba najpierw otworzyc strone, odczytac, co
zostalo przyslane w tej funkcji, potraktowac haslo z przyslanymi danymi
funkcja md5 i odeslac.


import urllib
import urllib2
import md5

url = 'moja_strona_logowania'
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
values = {'username' : 'moj_login', 'password': 'moje_haslo'}
headers = { 'User-Agent' : user_agent }
m = md5.new()

No i tutaj zaczynaja sie moje klopoty. Jezeli zrobie jak w tutorialu:
data = urllib.urlencode(values)
req = urllib2.Request(url, data, headers)
response = urllib2.urlopen(req)
the_page = response.read()

to repsonse wysyla moje dane z pominieciem tego co sie dzieje w doLogin().

Nie bardzo mam pomysl co z tym zrobic, kazde odswierzenie strony
powoduje, ze te dane w doLogin() sa na nowo generowane.


Pozdrawiam
Tomasz 'Piniu' Pichlinski

Rob Wolfe

unread,
Jul 15, 2007, 11:32:05 AM7/15/07
to
Tomasz 'Piniu' Pichliński <pini...@interia.pl> writes:

> Witam!
>
> Chce sobie napisac automat do logowania do sieci wifi, z ktorej
> korzystam. Probowalem na podstawie tutoriala
> (http://www.voidspace.org.uk/python/articles/urllib2.shtml) skleic
> jakis kod i wykonywac go w sesji interaktywnej, ale nie dziala i nie
> bardzo mam pomysl jak sie do tego zabrac.

[...]

> Cale zamieszanie wywoluje ta funkcja doLogin(), gdyby nie ona, raczej
> nie mialbym problemu. Trzeba najpierw otworzyc strone, odczytac, co
> zostalo przyslane w tej funkcji, potraktowac haslo z przyslanymi
> danymi funkcja md5 i odeslac.
>
>
> import urllib
> import urllib2
> import md5
>
> url = 'moja_strona_logowania'
> user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
> values = {'username' : 'moj_login', 'password': 'moje_haslo'}
> headers = { 'User-Agent' : user_agent }
> m = md5.new()
>
> No i tutaj zaczynaja sie moje klopoty. Jezeli zrobie jak w tutorialu:
> data = urllib.urlencode(values)
> req = urllib2.Request(url, data, headers)
> response = urllib2.urlopen(req)
> the_page = response.read()
>
> to repsonse wysyla moje dane z pominieciem tego co sie dzieje w doLogin().
>
> Nie bardzo mam pomysl co z tym zrobic, kazde odswierzenie strony
> powoduje, ze te dane w doLogin() sa na nowo generowane.

Nie bardzo rozumiem jak to działa. Dlaczego nie możesz wykonać
dokładnie tego, co robi funkcja `doLogin`, czyli wypełnienie
formularza `login` i wysłanie go? Np.:

<code>
haslo = md5.new('\325moje_haslo\142\277\221\277\236\213\012\131\160'
+ '\257\223\051\301\024\251\066').hexdigest()
values = {'username' : 'moj_login', 'password': haslo}
req = urllib2.Request('http://hotspot.dns/login', data, headers)
</code>

RW

Tomasz 'Piniu' Pichliński

unread,
Jul 15, 2007, 11:53:36 AM7/15/07
to
to ponizej nie dziala:

import urllib2
import urllib
import md5

url = 'http://hotspot.dns/login'
page = urllib2.urlopen(url).read()
page = page[page.find('\''):page.find('\');')]
username = 'Pichlinski'
password = 'Mv313'
page = page.split('+')
page = page[0] + password + page[2]
page = page.replace('\'','')
page = page.replace(' ','')

m=md5.new()
m.update(page)


print page
print type(page)
print m.hexdigest()
print type(m.hexdigest)
password=m.hexdigest()
values = {'username' : 'moj_login', 'password': password}
data = urllib.urlencode(values)
req = urllib2.Request(url, data)


hexdigest zwraca takiego stringa: 6dfc53bf18743c0363ee3d217b191b39
a moze ten ichni hexMD5 zwraca stringa w sposob podobny do
\142\277\221\277... bo to mi wyglada na wartosci 0-255 zapisane osemkowo.

Tomasz 'Piniu' Pichliński

unread,
Jul 15, 2007, 11:54:50 AM7/15/07
to
Tomasz 'Piniu' Pichliński napisał(a):

> username = 'Pichlinski'
> password = 'Mv313'

no i poszlo w swiat :)
na szczescie to dosc lokalne i sie raczej nikomu nie przyda

Rob Wolfe

unread,
Jul 15, 2007, 12:15:44 PM7/15/07
to
Tomasz 'Piniu' Pichliński <pini...@interia.pl> writes:

> to ponizej nie dziala:
>
> import urllib2
> import urllib
> import md5
>
> url = 'http://hotspot.dns/login'
> page = urllib2.urlopen(url).read()
> page = page[page.find('\''):page.find('\');')]
> username = 'Pichlinski'
> password = 'Mv313'
> page = page.split('+')
> page = page[0] + password + page[2]
> page = page.replace('\'','')
> page = page.replace(' ','')
>
> m=md5.new()
> m.update(page)

Ale o so chodzi?
Z tego kodu domyślam się, że w jakiś magiczny sposób pierwsze
odwołanie do formularza 'http://hotspot.dns/login' zwraca
jakiś ciąg, z którego obliczasz md5 i co dalej?
Ponownie odwołujesz się do tego samego formularza, czy jak?

> print page
> print type(page)
> print m.hexdigest()
> print type(m.hexdigest)
> password=m.hexdigest()
> values = {'username' : 'moj_login', 'password': password}
> data = urllib.urlencode(values)
> req = urllib2.Request(url, data)
>
>
> hexdigest zwraca takiego stringa: 6dfc53bf18743c0363ee3d217b191b39
> a moze ten ichni hexMD5 zwraca stringa w sposob podobny do
> \142\277\221\277... bo to mi wyglada na wartosci 0-255 zapisane
> osemkowo.

A mi nie wygląda wcale, bo kompletenie nie rozumiem jaka jest
sekwencja zdarzeń, a jedyne co dla mnie ten kod generuje to
błąd 404 Not Found.

RW

Tomasz 'Piniu' Pichliński

unread,
Jul 15, 2007, 12:35:17 PM7/15/07
to
Rob Wolfe napisał(a):

> Ale o so chodzi?
> Z tego kodu domyślam się, że w jakiś magiczny sposób pierwsze
> odwołanie do formularza 'http://hotspot.dns/login' zwraca
> jakiś ciąg, z którego obliczasz md5 i co dalej?
> Ponownie odwołujesz się do tego samego formularza, czy jak?

Tak, staram sie odwolac do tego samego formularza. Problem w tym, ze
wartosci liczbowe w ponizszej linii


hexMD5('\325' + document.login.password.value +

'\142\277\221\277\236\213\012\131\160\257\223\051\301\024\251\066')
sa jakos generowane dynamicznie po stronie serwera, nie sa wiec stale.
Musze je najpierw odczytac, zeby moc je wykorzystac do haszowania.
Ponizej kod samej funkcji.

function doLogin() {
document.sendin.username.value = document.login.username.value;
document.sendin.password.value = hexMD5('\325' +
document.login.password.value +

'\142\277\221\277\236\213\012\131\160\257\223\051\301\024\251\066');
document.sendin.submit();
return false;
}


> A mi nie wygląda wcale, bo kompletenie nie rozumiem jaka jest
> sekwencja zdarzeń, a jedyne co dla mnie ten kod generuje to
> błąd 404 Not Found.

Sprawdze co otrzymuje w odpowiedzi, bo do tej pory sprawdzalem tylko
przegladarka czy jestem zalogowany.

Tomasz 'Piniu' Pichliński

unread,
Jul 15, 2007, 12:42:06 PM7/15/07
to
Tomasz 'Piniu' Pichliński napisał(a):

> Sprawdze co otrzymuje w odpowiedzi, bo do tej pory sprawdzalem tylko
> przegladarka czy jestem zalogowany.

Jako odpowiedz od serwera otrzymuje ponownie strone logowania - te
liczby, o ktorych wspominalem sa inne za kazdym razem i to moze byc
przyczyna nieudanego logowania.

Rob Wolfe

unread,
Jul 15, 2007, 1:47:52 PM7/15/07
to
Tomasz 'Piniu' Pichliński <pini...@interia.pl> writes:

> Rob Wolfe napisał(a):
>> Ale o so chodzi?
>> Z tego kodu domyślam się, że w jakiś magiczny sposób pierwsze
>> odwołanie do formularza 'http://hotspot.dns/login' zwraca
>> jakiś ciąg, z którego obliczasz md5 i co dalej?
>> Ponownie odwołujesz się do tego samego formularza, czy jak?
>
> Tak, staram sie odwolac do tego samego formularza. Problem w tym, ze
> wartosci liczbowe w ponizszej linii
> hexMD5('\325' + document.login.password.value +
> '\142\277\221\277\236\213\012\131\160\257\223\051\301\024\251\066')
> sa jakos generowane dynamicznie po stronie serwera, nie sa wiec
> stale. Musze je najpierw odczytac, zeby moc je wykorzystac do
> haszowania. Ponizej kod samej funkcji.

Ale dlaczego musisz wykonywać to haszowanie? Cały czas myślałem,
że możesz się tam zalogować ręcznie z poziomu przeglądarki.
Czy tak nie jest?

>
> function doLogin() {
> document.sendin.username.value = document.login.username.value;
> document.sendin.password.value = hexMD5('\325' +
> document.login.password.value +
> '\142\277\221\277\236\213\012\131\160\257\223\051\301\024\251\066');
> document.sendin.submit();
> return false;
> }

Programowa akcja powinna dokładnie symulować to co robisz
ręcznie. Jeśli ręcznie wypełniasz tylko raz formularz `login`
i logowanie następuje, to program powinien zrobić dokładnie
to samo bez odczytywania jakichś dodatkowych liczb ze strony.

Może problem polega na tym, że nie podajesz dokładnie wszystkich
pól formularza w żądaniu (łącznie z polami `dst`, `popup` i `image`),
np:

values = {'username' : 'moj_login', 'password': haslo,
'dst': '', 'popup': 'true', 'image': 'OK'}


Co do stringa, to nie ma znaczenia, czy znaki są zapisane
ósemkowo, czy szesnastkowo.

RW

Tomasz 'Piniu' Pichliński

unread,
Jul 15, 2007, 2:39:44 PM7/15/07
to
Rob Wolfe napisał(a):

> Ale dlaczego musisz wykonywać to haszowanie? Cały czas myślałem,
> że możesz się tam zalogować ręcznie z poziomu przeglądarki.
> Czy tak nie jest?

Tak, moge sie zalogowac recznie z poziomu przegladarki. Nie znam sie za
dobrze na technologiach webowych, ale calkiem prawdopodobne wydaje mi
sie, ze przed submitem formularza funkcja doLogin zmienia password na
jego wersje haszowana z 'dodatkami', ktore sa dynamicznie generowane i
zawarte w samym ciele funkcji.


> Programowa akcja powinna dokładnie symulować to co robisz
> ręcznie. Jeśli ręcznie wypełniasz tylko raz formularz `login`
> i logowanie następuje, to program powinien zrobić dokładnie
> to samo bez odczytywania jakichś dodatkowych liczb ze strony.

Takie rozumowanie jest jak najbardziej sluszne, jednak jak juz
wspomnialem, po aktywacji przeslania formularza w ruch idzie skrypt js,
ktorego dzialanie tez musze zasymulowac.

> Może problem polega na tym, że nie podajesz dokładnie wszystkich
> pól formularza w żądaniu (łącznie z polami `dst`, `popup` i `image`),
> np:
>
> values = {'username' : 'moj_login', 'password': haslo,
> 'dst': '', 'popup': 'true', 'image': 'OK'}

Nie wykluczone, ze rzeczywiscie tak jest.

> Co do stringa, to nie ma znaczenia, czy znaki są zapisane
> ósemkowo, czy szesnastkowo.

dzialanie funkcji hexMD5 w JS nie jest mi znane (moze ona robic
wszystko). Google milczy na ten temat, to jest cos co jest umieszczone w
oprogramowaniu routera/serwera. Od znajomego dowiedzialem sie, ze to
jest oprogramowanie MikroTik i na ich forum zapytalem co i jak ta
funkcja dokladnie robi, na razie czekam na odpowiedz. Co ona robi, to
mozna sie domyslec z nazwy, ale w jakiej postaci zwraca wynik haszowania
juz takie oczywiste nie jest - tutaj tylko zdrowy rozsadek podpowiada,
ze powinien to byc taki sam ciag, jak ten generowany przez pythonowe md5.

Rob Wolfe

unread,
Jul 15, 2007, 2:50:15 PM7/15/07
to
Tomasz 'Piniu' Pichliński <pini...@interia.pl> writes:

> Rob Wolfe napisał(a):
>> Ale dlaczego musisz wykonywać to haszowanie? Cały czas myślałem,
>> że możesz się tam zalogować ręcznie z poziomu przeglądarki.
>> Czy tak nie jest?
>
> Tak, moge sie zalogowac recznie z poziomu przegladarki. Nie znam sie
> za dobrze na technologiach webowych, ale calkiem prawdopodobne wydaje
> mi sie, ze przed submitem formularza funkcja doLogin zmienia password
> na jego wersje haszowana z 'dodatkami', ktore sa dynamicznie
> generowane i zawarte w samym ciele funkcji.

Niech sobie robi co chce. To nie powinno Cię interesować w tym wypadku.
Masz podać programowo dokładnie to samo co wklepujesz w formularzu
przy ręcznym jego wypełnianiu. Kropka.

>> Programowa akcja powinna dokładnie symulować to co robisz
>> ręcznie. Jeśli ręcznie wypełniasz tylko raz formularz `login`
>> i logowanie następuje, to program powinien zrobić dokładnie
>> to samo bez odczytywania jakichś dodatkowych liczb ze strony.
>
> Takie rozumowanie jest jak najbardziej sluszne, jednak jak juz
> wspomnialem, po aktywacji przeslania formularza w ruch idzie skrypt
> js, ktorego dzialanie tez musze zasymulowac.

Czy przy ręcznym logowaniu też symulujesz działanie skryptu?

>> Może problem polega na tym, że nie podajesz dokładnie wszystkich
>> pól formularza w żądaniu (łącznie z polami `dst`, `popup` i
>> `image`), np:
>> values = {'username' : 'moj_login', 'password': haslo,
>> 'dst': '', 'popup': 'true', 'image': 'OK'}
>
> Nie wykluczone, ze rzeczywiscie tak jest.
>
>> Co do stringa, to nie ma znaczenia, czy znaki są zapisane
>> ósemkowo, czy szesnastkowo.
>
> dzialanie funkcji hexMD5 w JS nie jest mi znane (moze ona robic
> wszystko). Google milczy na ten temat, to jest cos co jest umieszczone
> w oprogramowaniu routera/serwera. Od znajomego dowiedzialem sie, ze to
> jest oprogramowanie MikroTik i na ich forum zapytalem co i jak ta
> funkcja dokladnie robi, na razie czekam na odpowiedz. Co ona robi, to
> mozna sie domyslec z nazwy, ale w jakiej postaci zwraca wynik
> haszowania juz takie oczywiste nie jest - tutaj tylko zdrowy rozsadek
> podpowiada, ze powinien to byc taki sam ciag, jak ten generowany przez
> pythonowe md5.

No to powtórzę pytanie. Jakim cudem logujesz się tam ręcznie?
Podajesz użytkownika, hasło i koniec, tak? Czy może jeszcze coś?
To, że pod spodem odbywa się jakieś haszowanie hasła nie powinno
tu mieć żadnego znaczenia. Gdy logujesz się do bazy danych,
to hasła też są mielone na różne sposoby, ale to nie zmienia
faktu, że użytkownik zawsze podaje *zwykły string*.

RW

Grzegorz Staniak

unread,
Jul 15, 2007, 2:59:51 PM7/15/07
to
On 15.07.2007, Tomasz 'Piniu' Pichliński <pini...@interia.pl> wroted:

>> Ale dlaczego musisz wykonywać to haszowanie? Cały czas myślałem,
>> że możesz się tam zalogować ręcznie z poziomu przeglądarki.
>> Czy tak nie jest?
>
> Tak, moge sie zalogowac recznie z poziomu przegladarki. Nie znam sie za
> dobrze na technologiach webowych, ale calkiem prawdopodobne wydaje mi
> sie, ze przed submitem formularza funkcja doLogin zmienia password na
> jego wersje haszowana z 'dodatkami', ktore sa dynamicznie generowane i
> zawarte w samym ciele funkcji.

Czy ty nie opisujesz w tej chwili najzwyklejszego w świecie CRBA?
http://en.wikipedia.org/wiki/Challenge-response_authentication
http://roborant.info/main.do?entry=1331
http://pajhome.org.uk/crypt/md5/auth.html

[...]


>> Co do stringa, to nie ma znaczenia, czy znaki są zapisane
>> ósemkowo, czy szesnastkowo.
>
> dzialanie funkcji hexMD5 w JS nie jest mi znane (moze ona robic
> wszystko). Google milczy na ten temat, to jest cos co jest umieszczone w
> oprogramowaniu routera/serwera.

Jeśli JavaScript jest wykonywany w przeglądarce, musi być dostępny dla
przeglądarki. Poszukaj w źródle dokumentu osadzonych skryptów bądź linków
do skryptów, gdzieś tam musi się znajdować definicja tej funkcji jeśli
to nie jest builtin.

GS
--
Grzegorz Staniak <gstaniak _at_ wp [dot] pl>

Grzegorz Staniak

unread,
Jul 15, 2007, 3:03:32 PM7/15/07
to
On 15.07.2007, Rob Wolfe <r...@smsnet.pl> wroted:

>>> Programowa akcja powinna dokładnie symulować to co robisz
>>> ręcznie. Jeśli ręcznie wypełniasz tylko raz formularz `login`
>>> i logowanie następuje, to program powinien zrobić dokładnie
>>> to samo bez odczytywania jakichś dodatkowych liczb ze strony.
>>
>> Takie rozumowanie jest jak najbardziej sluszne, jednak jak juz
>> wspomnialem, po aktywacji przeslania formularza w ruch idzie skrypt
>> js, ktorego dzialanie tez musze zasymulowac.
>
> Czy przy ręcznym logowaniu też symulujesz działanie skryptu?

Jeśli tam rzeczywiście siedzi JavaScript realizujący CRBA, to robi
to za niego - pod 'onClick' ma podpięte funkcje które kalkulują hash
z wprowadzonego hasła i nadesłanej z serwera soli, podmieniają obiekty
formularza _kasując_ plaintekstowe hasło i wysyłając tylko hash. Na tym
polega bezpieczeństwo procesu logowania.

[...]


> No to powtórzę pytanie. Jakim cudem logujesz się tam ręcznie?
> Podajesz użytkownika, hasło i koniec, tak? Czy może jeszcze coś?
> To, że pod spodem odbywa się jakieś haszowanie hasła nie powinno
> tu mieć żadnego znaczenia. Gdy logujesz się do bazy danych,
> to hasła też są mielone na różne sposoby, ale to nie zmienia
> faktu, że użytkownik zawsze podaje *zwykły string*.

Do lokalnej funkcji javascriptowej. Która do serwera wysyła tylko wynik
haszowania, nigdy hasło w plain tekście.

Tomasz 'Piniu' Pichliński

unread,
Jul 15, 2007, 3:07:32 PM7/15/07
to
Rob Wolfe napisał(a):

> Czy przy ręcznym logowaniu też symulujesz działanie skryptu?

> No to powtórzę pytanie. Jakim cudem logujesz się tam ręcznie?


> Podajesz użytkownika, hasło i koniec, tak? Czy może jeszcze coś?
> To, że pod spodem odbywa się jakieś haszowanie hasła nie powinno
> tu mieć żadnego znaczenia. Gdy logujesz się do bazy danych,
> to hasła też są mielone na różne sposoby, ale to nie zmienia
> faktu, że użytkownik zawsze podaje *zwykły string*.

Zainstalowalem tekstowa przegladarke - Lynx. Przegladarka ta nie
obsluguje javascriptu i logowac sie z niej recznie nie da. Wniosek: w
tle, po akcji uzytkownika wykonywane sa operacje i dopiero ich wynik
przesylany jest do serwera/routera. Zasymulowac je wiec na pewno trzeba.

Tomasz 'Piniu' Pichliński

unread,
Jul 15, 2007, 3:13:43 PM7/15/07
to
Grzegorz Staniak napisał(a):
> http://roborant.info/main.do?entry=1331

Tak, to jest ta technika.

Grzegorz Staniak

unread,
Jul 15, 2007, 3:22:01 PM7/15/07
to
On 15.07.2007, Tomasz 'Piniu' Pichliński <pini...@interia.pl> wroted:

>> http://roborant.info/main.do?entry=1331


>
> Tak, to jest ta technika.

Gdzieś musisz mieć tę JavaScriptową funkcję. Znajdź, zasymuluj jej działanie
w Pythonie i nie ma prawa nie działać.

Rob Wolfe

unread,
Jul 15, 2007, 3:25:39 PM7/15/07
to
Tomasz 'Piniu' Pichliński <pini...@interia.pl> writes:

Teraz do mnie dotarło. Faktycznie trzeba. Sorry za zamieszanie.

RW

Tomasz 'Piniu' Pichliński

unread,
Jul 15, 2007, 3:37:42 PM7/15/07
to
Rob Wolfe napisał(a):

> Teraz do mnie dotarło. Faktycznie trzeba. Sorry za zamieszanie.

Nie ma problemu. Istotniejsze, ze probowales pomoc.

Zaczynam myslec, ze nie da sie tego zrealizowac przy pomocy urllib2.
Musze miec rozdzielone pobranie strony od wysylania danych. Pomiedzy
tymi dwoma etapami trzeba przeczytac strone w poszukiwaniu potrzebnych
fragmentow i haszowac, dopiero potem wyslac. Robiac urllib2.Request(url,
data) moje dane zawsze trafiaja w strone, na ktorej interesujaca mnie
czesc juz sie zmienila.

Grzegorz Staniak

unread,
Jul 15, 2007, 3:49:56 PM7/15/07
to
On 15.07.2007, Tomasz 'Piniu' Pichliński <pini...@interia.pl> wroted:

>> Teraz do mnie dotarło. Faktycznie trzeba. Sorry za zamieszanie.

Czekaj, ale przecież to powinno być trywialne do zrobienia: odbierasz
stronę, czytasz, analizujesz, robisz CRBA i wysyłasz wyliczone wartości
pod ten sam URL metodą POST - oczywiście spełniając wszelkie warunki
jakie powinieneś spełnić, ale to zależy od samego dokumentu: jeśli masz
tam jakieś dodatkowe, ukryte pole w formularzu czy co tam, też musisz
to wziąć pod uwagę.

Grzegorz Staniak

unread,
Jul 15, 2007, 3:51:07 PM7/15/07
to
On 15.07.2007, Tomasz 'Piniu' Pichliński <pini...@interia.pl> wroted:

>> Teraz do mnie dotarło. Faktycznie trzeba. Sorry za zamieszanie.

Czekaj, ale przecież to powinno być trywialne do zrobienia: odbierasz


stronę, czytasz, analizujesz, robisz CRBA i wysyłasz wyliczone wartości

pod URL z 'action' metodą POST - oczywiście spełniając wszelkie warunki

Tomasz 'Piniu' Pichliński

unread,
Jul 15, 2007, 3:54:38 PM7/15/07
to
Grzegorz Staniak napisał(a):

> Czekaj, ale przecież to powinno być trywialne do zrobienia: odbierasz
> stronę, czytasz, analizujesz, robisz CRBA i wysyłasz wyliczone wartości
> pod URL z 'action' metodą POST

a jak zrobic takiego POST w pythonie? wiem, ze pytanie moze sie wydawac
glupie, ale nie mam poje, w urllib nie widze niczego podobnego, a
przegladajac dokumentacje pythona na temat httplib tez nie bardzo widze.

Rob Wolfe

unread,
Jul 15, 2007, 3:58:27 PM7/15/07
to
Tomasz 'Piniu' Pichliński <pini...@interia.pl> writes:

Ty już używasz metody POST. Jeśli w Request oprócz url-a podasz
dodatkowe parametry, to automatycznie używana jest metoda POST.

RW

Tomasz 'Piniu' Pichliński

unread,
Jul 15, 2007, 4:00:20 PM7/15/07
to
Rob Wolfe napisał(a):

> Ty już używasz metody POST. Jeśli w Request oprócz url-a podasz
> dodatkowe parametry, to automatycznie używana jest metoda POST.

tylko jezeli dobrze rozumiem dzialanie request, to strona jest
odczytywana i potem wysylane sa dane, jezeli zdefiniowano. czyli ilekroc
podstawie w request dane juz spreparowane, beda one niekatualne,
poniewaz strona jest generowana na nowo a co za tym idzie, interesujace
mnie fragmenty potrzebne do haszowania hasla sa nowe.

Grzegorz Staniak

unread,
Jul 15, 2007, 4:00:56 PM7/15/07
to
On 15.07.2007, Tomasz 'Piniu' Pichliński <pini...@interia.pl> wroted:

>> Czekaj, ale przecież to powinno być trywialne do zrobienia: odbierasz

http://docs.python.org/lib/node578.html

The following example uses the "POST" method instead:

>>> import urllib
>>> params = urllib.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
>>> f = urllib.urlopen("http://www.musi-cal.com/cgi-bin/query", params)
>>> print f.read()

Rob Wolfe

unread,
Jul 15, 2007, 4:04:45 PM7/15/07
to
Tomasz 'Piniu' Pichliński <pini...@interia.pl> writes:

Dokładnie. To spowodowało, że się tak zakręciłem. :)
Ta sprawa pozornie wygląda trywialnie, ale teraz widzę poważne
schody.

RW

Grzegorz Staniak

unread,
Jul 15, 2007, 4:05:39 PM7/15/07
to
On 15.07.2007, Tomasz 'Piniu' Pichliński <pini...@interia.pl> wroted:

>> Ty już używasz metody POST. Jeśli w Request oprócz url-a podasz


>> dodatkowe parametry, to automatycznie używana jest metoda POST.
>
> tylko jezeli dobrze rozumiem dzialanie request, to strona jest
> odczytywana i potem wysylane sa dane, jezeli zdefiniowano.

Nie. Nie pamiętam jak działa Request, ale POST w HTTP wysyła dane
(zakodowane urlencode) na standardowe wejście programu do którego
rozwiązuje się dany URL. Serwer HTTP wiedząc że użyłeś metody POST
nie wyśle Ci nowego dokumentu, tylko Twoje dane prześle do skryptu
i odeśle Ci wynik. Czyli jeśli dobrze zasymulujesz logowanie,
dostaniesz stronę dla zalogowanych.

Rob Wolfe

unread,
Jul 15, 2007, 4:42:12 PM7/15/07
to
Grzegorz Staniak <gsta...@wp.pl> writes:

Tak, tylko że ta strona wygląda na generowaną dynamicznie
i nie ma żadnej gwarancji, że akurat użycie metody POST spowoduje,
iż serwer uzna to za ostateczne żądanie logowania.
Chyba pozostaje metoda prób i błędów.

RW

Paweł Goleń

unread,
Jul 15, 2007, 4:41:55 PM7/15/07
to
Grzegorz Staniak wrote:
> Nie. Nie pamiętam jak działa Request, ale POST w HTTP wysyła dane
> (zakodowane urlencode) na standardowe wejście programu do którego
> rozwiązuje się dany URL. Serwer HTTP wiedząc że użyłeś metody POST
> nie wyśle Ci nowego dokumentu, tylko Twoje dane prześle do skryptu
> i odeśle Ci wynik. Czyli jeśli dobrze zasymulujesz logowanie,
> dostaniesz stronę dla zalogowanych.

Ja bym taki całkiem pewny nie był, że to zadziała bez problemu.
Podstawowe pytanie - skąd serwer wie, jaki challenge wysłał do klienta?
Być może tam jeszcze jakieś ciasteczka latają... Sam algorytm jest dość
prosty, ale dla pewności jeszcze powinno się prześledzić dokładnie co w
takim "logowaniu" lata, od chwili wywołania strony z formularzem, do
chwili zalogowania do WiFi. Tu się może fajnie WebScarab sprawdzić,
ewentualnie Fiddler.
http://www.owasp.org/index.php/Category:OWASP_WebScarab_Project
http://www.fiddlertool.com/fiddler/

--
Paweł Goleń
mailto:p_g...@ks.onet.pl
"Wszyscy przecież wiemy, że nikt nie dostaje żadnych spamów" - mój trol
UGVybCBTVUNLUw==

Grzegorz Staniak

unread,
Jul 15, 2007, 4:53:05 PM7/15/07
to
On 15.07.2007, Rob Wolfe <r...@smsnet.pl> wroted:

>>> tylko jezeli dobrze rozumiem dzialanie request, to strona jest

>>> odczytywana i potem wysylane sa dane, jezeli zdefiniowano.
>>
>> Nie. Nie pamiętam jak działa Request, ale POST w HTTP wysyła dane
>> (zakodowane urlencode) na standardowe wejście programu do którego
>> rozwiązuje się dany URL. Serwer HTTP wiedząc że użyłeś metody POST
>> nie wyśle Ci nowego dokumentu, tylko Twoje dane prześle do skryptu
>> i odeśle Ci wynik. Czyli jeśli dobrze zasymulujesz logowanie,
>> dostaniesz stronę dla zalogowanych.
>
> Tak, tylko że ta strona wygląda na generowaną dynamicznie
> i nie ma żadnej gwarancji, że akurat użycie metody POST spowoduje,
> iż serwer uzna to za ostateczne żądanie logowania.

Gdyby było tak jak mówisz, nie dałoby się w ogóle na nią zalogować,
bo niby skąd serwer miałby wiedzieć, że POST ze statycznego formularza
który sam wysłał jest "ostatecznym żądaniem logowania"? Serwer HTTP
ma się stosować do protokołu: dostaje POST - odkodowuje argumenty podane
w treści zapytania, wysyła na stdin programu z URLa, zwraca wynik
działania tegoż programu do przeglądarki, kropka. Trzeba tylko zadbać
o to, żeby dobrze zasymulować działanie przeglądarki - wysłać wszystkie
pola formularza które powinny zostać wysłane, zasymulować działanie
javascriptu realizującego CRBA, po otrzymaniu wyniku odebrać i przechować
cookie sesji (zwykle nadawany po pomyślnym logowaniu) itd. itp.

Grzegorz Staniak

unread,
Jul 15, 2007, 4:54:28 PM7/15/07
to
On 15.07.2007, Paweł Goleń <p_g...@ks.onet.pl> wroted:

>> Nie. Nie pamiętam jak działa Request, ale POST w HTTP wysyła dane
>> (zakodowane urlencode) na standardowe wejście programu do którego
>> rozwiązuje się dany URL. Serwer HTTP wiedząc że użyłeś metody POST
>> nie wyśle Ci nowego dokumentu, tylko Twoje dane prześle do skryptu
>> i odeśle Ci wynik. Czyli jeśli dobrze zasymulujesz logowanie,
>> dostaniesz stronę dla zalogowanych.
>
> Ja bym taki całkiem pewny nie był, że to zadziała bez problemu.
> Podstawowe pytanie - skąd serwer wie, jaki challenge wysłał do klienta?

Dlatego pisałem o tym, żeby zadbać o dobrą symulację działania formularza.

Albo choćby pligin "Tamper Data" w Firefoksie. Albo jakiś logging proxy.
Metod jest sporo.

William

unread,
Jul 16, 2007, 2:45:34 AM7/16/07
to
Grzegorz Staniak napisał(a):

> Je�li tam rzeczywi�cie siedzi JavaScript realizuj�cy CRBA, to robi
> to za niego - pod 'onClick' ma podpi�te funkcje kt�re kalkuluj� hash
> z wprowadzonego has�a i nades�anej z serwera soli, podmieniaj� obiekty
> formularza _kasuj�c_ plaintekstowe has�o i wysy�aj�c tylko hash. Na tym
> polega bezpiecze�stwo procesu logowania.
>

Tylko że to bardzo iluzoryczne bezpieczeństwo - zabezpiecza przed
podsłuchem ale nie przed podszywaniem się. Jeśli nie jest dostępny https
to najlepszym rozwiązaniem jest http digest auth.

Grzegorz Staniak

unread,
Jul 16, 2007, 3:06:19 AM7/16/07
to
On 16.07.2007, William <wil...@null.pl> wroted:

>> Jeśli tam rzeczywiście siedzi JavaScript realizujący CRBA, to robi
>> to za niego - pod 'onClick' ma podpięte funkcje które kalkulują hash
>> z wprowadzonego hasła i nadesłanej z serwera soli, podmieniają obiekty

>> formularza _kasując_ plaintekstowe hasło i wysyłając tylko hash. Na tym
>> polega bezpieczeństwo procesu logowania.


>
> Tylko że to bardzo iluzoryczne bezpieczeństwo - zabezpiecza przed
> podsłuchem ale nie przed podszywaniem się. Jeśli nie jest dostępny https
> to najlepszym rozwiązaniem jest http digest auth.

Obawiam się że rozmówca nie ma takiego wyboru, musi dostosować się do tego
co ma. No i to przecież nie jest haszowanie samego hasła, przeczytaj
któryś z linków, CRBA jest bezpieczniejsze od Digest.

Tomasz 'Piniu' Pichliński

unread,
Jul 16, 2007, 2:35:17 PM7/16/07
to
William napisał(a):

> Tylko że to bardzo iluzoryczne bezpieczeństwo - zabezpiecza przed
> podsłuchem ale nie przed podszywaniem się. Jeśli nie jest dostępny https
> to najlepszym rozwiązaniem jest http digest auth.

Tutaj nie ma potrzeby jakiegos mocnego zabezpieczania. To jest logowanie
do sieci wifi, do konkretnego nadajnika, ktory jest ograniczony
terytorialnie, uzytkownik jest przypisany do nadajnika, wiec iloc osob,
ktore moga sie podszyc jest ograniczona jego zasiegiem. Bez zalogowania
sie nie mam aktywnego lacza.
Cale zamieszanie tylko dlatego, ze chce zamiast odpalac przegladarke,
czekac az sie zaladuje strona i wpisywac dane ograniczyc sie do
uruchomienia skrotu na pulpicie.

Tomasz 'Piniu' Pichliński

unread,
Jul 16, 2007, 5:01:24 PM7/16/07
to
Jakby sie komus chcialo przez to przegryzc i powiedziec, co dokladnie
mam wyslac do serwera, bo ja odpadam, nie mam juz pomyslow. Pola ukryte
z formularza sendin tez wysylalem i nic. Ponizej kod strony logowania.
Zeby to przeczytac, lepiej pewnie przekleic do jakiegos edytora.

A zadanie probuje zrealizowac przy pomocy roznych wariacji ponizszego
skryptu:
import urllib2
import urllib
import md5

url = 'http://hotspot.dns/login'
page = urllib2.urlopen(url).read()
page = page[page.find('\''):page.find('\');')]
username = 'Pichlinski'
password = 'MOJE_HASLO'
page = page.split('+')
page = page[0] + password + page[2]
#page = password
page = page.replace('\'','')
page = page.replace(' ','')

m=md5.new()
m.update(page)


print page
#print type(page)
print m.hexdigest()
#print type(m.hexdigest)
password=m.hexdigest()
values = {'username' : 'Pichlinski', 'password': password, 'dst':'',

'popup':'true', 'image': 'OK'}

data = urllib.urlencode(values)
req =
urllib2.Request('http://hotspot.dns/login?image.x=30&image.y=6&image=log+in',
data)
response = urllib2.urlopen(req)
the_page = response.read()
print the_page

#############################################################

<html>
<head>
<title>.:: RDI - Logowanie ::.</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2">
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="expires" content="-1">
<style type="text/css">
<!--
textarea,input,select {
background-color: #FDFBFB;
border: 1px #BBBBBB solid;
padding: 2px;
margin: 1px;
font-size: 14px;
color: #808080;
}

body{ color: #737373; font-size: 10px; font-family: verdana; }

a, a:link, a:visited, a:active { color: #AAAAAA; text-decoration: none;
font-size: 10px; }
a:hover { border-bottom: 1px dotted #c1c1c1; color: #AAAAAA; }
img {border: none;}
td { font-size: 14px; color: #7A7A7A; }

-->
</style>
<link href="css.css" rel="stylesheet" type="text/css">
<script language="JavaScript" type="text/JavaScript">
<!--
function MM_reloadPage(init) { //reloads the window if Nav4 resized
if (init==true) with (navigator) {if
((appName=="Netscape")&&(parseInt(appVersion)==4)) {
document.MM_pgW=innerWidth; document.MM_pgH=innerHeight;
onresize=MM_reloadPage; }}
else if (innerWidth!=document.MM_pgW || innerHeight!=document.MM_pgH)
location.reload();
}
MM_reloadPage(true);
//-->
</script>
</head>

<body background="img/tlo.gif" leftmargin="0" topmargin="0"
marginwidth="0" marginheight="0">
<div id="Layer2" style="position:absolute; left:612px; top:38px;
width:250px; height:395px; z-index:5"><a
href="http://olesnica.zhp.pl/"><img src="img/pobierowo.gif" width="250"
height="396" border="0"></a></div>
<div id="Layer1" style="position:absolute; left:357px; top:38px;
width:220px; height:346px; z-index:6"><a
href="http://www.panoramaolesnicka.pl/"><img src="img/panorama.gif"
width="250" height="345" border="0"></a></div>


<form name="sendin" action="http://hotspot.dns/login" method="post">
<input type="hidden" name="username">
<input type="hidden" name="password">
<input type="hidden" name="dst" value="">
<input type="hidden" name="popup" value="true">
</form>
<script language="JavaScript" src="/md5.js">
</script>
<script language="JavaScript">
<!--


function doLogin() {
document.sendin.username.value = document.login.username.value;

document.sendin.password.value = hexMD5('\324' +
document.login.password.value +
'\142\342\314\100\322\261\134\207\004\173\217\110\321\175\015\011');
document.sendin.submit();
return false;
}
//-->
</script>


<table width="100%" height="100%">
<tr>
<td width="40" align="center" valign="middle"> <br> </td>
<td width="240" align="left" valign="middle"> <table width="240"
height="100%" align="left" cellpadding="0" cellspacing="0">
<tr>
<td height="87" colspan="2" align="center" valign="top"
bgcolor="#000000"><p><img src="img/rdi.gif" width="208" height="22"></p>
<p><img src="img/oczka.gif" width="296" height="82"></p></td>
</tr>

<tr>
<td height="60" colspan="2" align="center" valign="top"
bgcolor="#000000">
<form name="login" action="http://hotspot.dns/login"
method="post"
onSubmit="return doLogin()" >
<input type="hidden" name="dst" value="">
<input type="hidden" name="popup" value="true">
<table width="284" >
<tr>
<td align="right" class="zielen"><font
color="#FFCC00">Nazwa
użytkownika</font>:</td>
<td><input style="width: 120px" name="username"
type="text" value=""/></td>

</tr>
<tr>
<td align="right" class="zielen"><font
color="#FFCC00">Hasło:</font></td>
<td><input style="width: 120px" name="password"
type="password"/></td>
</tr>
<tr>
<td>&nbsp;</td>
<td><input name="image" type="image" value="OK"
src="img/zaloguj.gif" border="0" alt="Log into system" width="87"
height="17" ></td>
</tr>

</table>
</form></td>
</tr>
<tr>
<td height="22" colspan="2" align="center" valign="middle"
bgcolor="#000000">
<p class="white"> <br>
<br>
</p></td>
</tr>

<tr>
<td height="22" colspan="2" align="center" valign="middle"
bgcolor="#000000">
<span class="white">Twój nadajnik to: </span><br> <span
class="nadajnik"><font color="#FFCC00">.:: Twister - 3c ::.</font></span>
<br> </td>
</tr>
<tr>
<td height="22" colspan="2" align="center" valign="middle"
bgcolor="#000000"><span class="white"><br>
Po zalogowaniu zostaniesz przekierowany na swoją<br>

stronę domową:</span> <span class="zielen"><font
color="#FFCC00"></font></span><br>
<br> </td>
</tr>
<tr>
<td height="22" colspan="2" align="center" valign="middle"
bgcolor="#000000"><span class="white">Twój
wewnętrzny adres IP to:</span> <span class="zielen"><font
color="#FFCC00">10.134.2.22</font></span>
<br> </td>
</tr>

<tr>
<td height="100" colspan="2" align="center" valign="top"
bgcolor="#000000"><div align="center">
<object
classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,29,0"
width="220" height="80">
<param name="movie" value="img/guziczki.swf">
<param name="quality" value="high">
<embed src="img/guziczki.swf" quality="high"
pluginspage="http://www.macromedia.com/go/getflashplayer"
type="application/x-shockwave-flash" width="220"
height="80"></embed></object>
</div></td>
</tr>
<tr>
<td height="148" align="center" bgcolor="#000000"><a
href="http://olesnica.org.pl"><img src="img/button-pio.gif" width="200"
height="148" align="top"></a></td>

</tr>
<tr>
<td align="center" bgcolor="#000000">&nbsp;</td>
</tr>
</table>
&nbsp;</td>
<td height="100%" align="left" valign="middle">&nbsp;</td>
</tr>
</table>

<script language="JavaScript">
<!--
document.login.username.focus();
//-->
</script>
</body>
</html>

Grzegorz Staniak

unread,
Jul 17, 2007, 7:36:13 AM7/17/07
to
On 15.07.2007, Tomasz 'Piniu' Pichliński <pini...@interia.pl> wroted:

Popatrzyłem sobie jeszcze na ten problem z logowaniem; IMVHO coś takiego
jak niżej, z pewnymi zastrzeżeniami, powinno zadziałać (doinstaluj sobie
PięknąZupę, do skrobania ekranów dobrze się nadaje):

--- cut here ---
#!/usr/bin/python

import urllib, md5, BeautifulSoup

url = 'http://hotspot.dns/login'
username = 'Pichlinski'
password = 'Mv313'

# pobranie dokumentu z formularzem logowania
page = urllib.urlopen(url).read()

# wydlubanie formularza, a z niego wartosci soli i challenge
html = BeautifulSoup.BeautifulSoup(page)
scriptlines = str(html.fetch("script")[1]).split('\n')
saltpos = scriptlines[4].find('\'')
salt = scriptlines[4][saltpos+1:saltpos+5]
challenge = scriptlines[6].split('\'')[1]

# ???

# digest md5 wedlug zachowania funkcji 'doLogin'
m = md5.new()
m.update(salt + password + challenge)
response = m.hexdigest()

# wyslanie calosci metoda POST, odebranie wyniku
params = urllib.urlencode({'username': username,
'password': response,
'dst': '',
'popup': 'true'})
result = urllib.urlopen(url, params).read()
--- cut here ---

> hexdigest zwraca takiego stringa: 6dfc53bf18743c0363ee3d217b191b39
> a moze ten ichni hexMD5 zwraca stringa w sposob podobny do
> \142\277\221\277... bo to mi wyglada na wartosci 0-255 zapisane osemkowo.

"Pewne zastrzeżenia" są następujące: to, co podaje formularz
(\142\277\221\277...) etc. wygląda na zwykły, escape'owany string.
Jeśli zrobisz sobie w przeglądarce 'alert(\142\277\221\277...);',
zobaczysz coś bardzo podobnego do wyjścia z md5.digest(). Mam natomiast
problem ze złożeniem tych escape'ów w string który posłużyłby do
wyprodukowania digestu, ponieważ to są liczby spoza zakresu 0-255,
więc nie da się nimi nakarmić chr(). Dlatego tam gdzie jest komentarz
'# ???' trzeba zrobić z tymi javascriptowymi stringami coś, co pozwoli
złożyć ciąg znaków na którym zapuścisz md5.hexdigest().

Tak poza tym, mam wrażenie, że powinno zadziałać.

0 new messages