TLS/SSL Verbindungen herausfinden

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
cailleachsiam
User
Beiträge: 9
Registriert: Montag 11. August 2014, 22:25

Hey Leute,

ich habe eine Liste mit den 1000 most visited Seiten online. Jetzt möchte ich die Seiten gerne analyiseren (welche TLS Version sie unterstützen usw..). Das Skript hab ich auch schon soweit.
Bevor ich das tun kann, muss ich aber wissen, welche der 1000 Seiten überhaupt TLS/SSL unterstützen.
Dafür lese ich mir die Liste ein und ich dachte mir, dass ich wget auf "Platz:https://" grep. Aber bei Seiten wie Google.de kommt das gar nicht (da gibt es sowieso keine Hinweis, dass sich eine HTTPS-Seite öffnet, komisch..).

Code: Alles auswählen

    process = os.popen("wget https://"+site+" | grep -o -a'Platz:https://'")
    result = process.read()
    if result == "Platz:https://": ...#speicher mir Seite in eine Liste
Dann dachte ich, mit openssl komme ich weiter. Aber da werden mir Seiten ausgegeben,die in Wirklichkeit gar kein TLS/SSL unterstützen, bzw einen Redirect auf http haben (wie z.B. howtogeek.com)

Code: Alles auswählen

    process = os.popen("timeout 0.8 openssl s_client -connect "+site+":443 | grep -o 'TLS session ticket:'")
    result = process.read()
        if result == "TLS session ticket": ...#speicher mir Seite in eine Liste
Ich weiß, das ist keine wirkliche Python-Frage, aber vllt könnt ihr mir ja helfen oder vllt gibt es einen besseren Weg direkt über Python.

Dankeschön! :D
Sirius3
User
Beiträge: 17748
Registriert: Sonntag 21. Oktober 2012, 17:20

@cailleachsiam: Wo ist das Problem, die Seiten mit https zu öffnen und zu schauen, ob das erfolgreich ist?

Code: Alles auswählen

>>> site = urllib2.urlopen('https://www.howtogeek.com')
>>> site.url
'http://www.howtogeek.com/'
cailleachsiam
User
Beiträge: 9
Registriert: Montag 11. August 2014, 22:25

@Sirius3 Danke dir, hab es jetzt mit Requests (urllib2) gelöst.
Hat auch gut funktioniert. Nur habe ich jetzt geschaut, wie viele Seiten, wenn ich http eingebe, einen Redirect auf https habe (weil "normale" User ja nicht https://... eingeben sondern nur facebook.com als Bsp.).
Jetzt wollte ich noch testen, welche der Seiten, bei direktem Öffnen von httpS://... eine https Verbindung aufbauen. Das Problem ist, dass viele Seiten (wie bspw http://www.taobao.com) ein falsches/abgelaufenes/... Zertifikat haben. Dann kommt ein Error und das Programm bricht ab. Weißt du/ oder irgendjmd sonst, ob es eine Möglichkeit gibt, sowas zu umgehen?! (Hab auch schon überlegt, dass dann doch mit openssl s_client zu machen und auszuwerten, ob eine Verbindung zustande kommt oder nicht, das Problem sind dann aber wieder Seiten wie howtogeek.com, die ein Zertifikat haben, aber einen Redirect auf HTTP, die verschlüsselte Seite also nicht abrufbar ist..)
Dankeschön für die Hilfe!

Code: Alles auswählen

with open("Liste","r") as list:
    website = list.read()

for site in website.split("\n"):
    link = "https://"+site
    r=requests.get(link)
    if string.find(r.url,"https://") == 0:
	with open("RESULT","a") as outputfile:
	    outputfile.write(site+"\n")
BlackJack

@cailleachsiam: Was heisst „da kommt ein Error”? Ich vermute doch mal stark das eine Ausnahme ausgelöst wird, und die kannst Du doch einfach entsprechend behandeln.
cailleachsiam
User
Beiträge: 9
Registriert: Montag 11. August 2014, 22:25

Das klingt schlau. Ich schau mir das mal an. Sry, hab erst relativ wenig mit Python gemacht. Thx
cailleachsiam
User
Beiträge: 9
Registriert: Montag 11. August 2014, 22:25

Soo, jetzt funktioniert das Meiste. Eine Frage habe ich noch.
Die Seiten die eine Exception werfen, habe ich jetzt aussortiert. Aber es gibt ja mehrere Exceptions. Z.B. wenn die Seite eine reine http-Seite ist und https überhaupt nicht unterstützt. Dann kommt ein:

requests.exceptions.SSLError: [Errno 1] _ssl.c:510: error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol

Und wenn es Zertifikatsprobleme gibt, sieht die Exception so aus:

requests.exceptions.SSLError: hostname 'www.XYZ.com' doesn't match either of '*...

Gibt es die Möglichkeit die Exceptions trotz gleichem Namen unterschiedlich zu behandeln?
Oder ein grep über die Exception laufen zu lassen?!
Danke für die Hilfe!
Sirius3
User
Beiträge: 17748
Registriert: Sonntag 21. Oktober 2012, 17:20

@cailleachsiam: es gibt leider keine bessere Methode, als ex.message auf den Fehlercode z.B. "SSL23_GET_SERVER_HELLO" zu untersuchen.
Die String-Funktionen in string sind alle veraltet. Man sollte (glaube seit Python 2.0) die entsprechenden Methoden der Strings direkt benutzen, also 'r.url.find(...)'. In diesem Fall willst Du aber wissen, ob die URL mit "https" anfängt, und dafür gibt es 'startswith'.
'list' ist ein schlechter Variablenname, weil er den Builtin list überschreibt. Statt die ganze Datei auf einmal zu laden solltest Du das Dateiobjekt als Iterator benutzen, das liefert Dir nämlich die einzelnen Zeilen in der for-Schleife gleich (strip nicht vergessen : ). Statt "RESULT" jedes mal zum anhängen zu öffnen, könntest Du das auch einmal vor der Schleife tun.
cailleachsiam
User
Beiträge: 9
Registriert: Montag 11. August 2014, 22:25

@Sirius3: Jetzt hat alles funktioniert. Dankeschön! Hab den Code "aktualisiert". Gut zu wissen was man macht und was eher nicht mehr. Hab es mit str(exception.message).find(...) gelöst :)
BlackJack

@cailleachsiam: Das `find()` solltest Du aber auch als Methode nicht verwenden wenn Dich nur interessiert *ob* da etwas bestimmtes enthalten ist. Das geht einfacher und lesbarer mit dem ``in``-Operator.
Antworten