⇽ Einträge 7 bis 4⇾ Ende

OSPF, BGP, und warum das alles trotz dem ganzen Spass manchmal zum Kotzen ist

2005年06月14日 (火曜日) 02時31分
Tags: BGP, diac24, Hecking

So. Wieder 2 nächtliche Stunden auf's diac-Netz» verwendet. Dies mal, um den Astro» mal wieder mit IPv6 und VPNv4 zu versorgen. Das war vielleicht ein Abenteuer...

Los geht's mit openvpn» und persistenten Tunnels mit tunctl (aus der User Mode Linux» Toolbox). Oder auch nicht. Das ganze funktioniert nämlich absolut nicht... irgendwie sind die Pakete immer im falschen Format, egal was man probiert...

... 1 Stunde und einen harten Reset dank eines netten Kernelbugs später kam dann so langsam die Einsicht, es doch mal mit nichtpersistenten Devices zu probieren. Genauer gesagt hat Astro meine Sturheit bezwungen ;).

Nachdem der Tunnel funktionierte ging's ans BGP. telnet ::1 2605, paar Zeilen in unser hassgeliebtes Quagga» einhacken (von dem afaik keine 2 gleichen Versionen im VPN existieren...) und ... warten ... es funktioniert!

Naja, dachten wir. Damit fangen die eigentlichen Probleme erst an. Ich habe - noch bis Ende des Monats - 2 Router. Einen in Leipzig (KabelSalatDeutschland), einen in Döbeln (T-Offline).
Die beiden sind im selben BGP AS und peeren untereinander auch mit BGP. Nun erwartet BGP aber eigentlich AS-intern vollständige Routingtabellen - deshalb werden die Next-Hop-Adressen innerhalb des AS nicht angepasst:

Announce-Beispiel:
    Astro -----{172.22.16.0/23}
[172.22.16.1]
      |
[172.22.2.22]           
   charon    <-- 172.22.16.0/23 nexthop 172.22.16.1
                 172.22.16.1 dev dc16
[172.22.2.22]
      |
[172.22.2.2]
   mercury   <-- 172.22.16.0/23 nexthop 172.22.16.1
                 172.22.16.1 ???

Die Letzte Zeile des Beispiels mausert sich zu einem ziemlich nervigen Problem, dessen korrekte Lösung in der Verwendung eines IGPs wie RIP, OSPF oder IS-IS besteht. Die einzige Aufgabe des IGPs bestünde in diesem Fall darin, die Route für 172.22.16.1 von charon zu mercury weiterzuverteilen.

OSPF war ziemlich lange im diac-VPN im Einsatz - ungefähr so lange wie uns die fehlenden Filtermöglichkeiten und die zugetrashte Routingtabelle nicht gestört haben. Jetzt wieder OSPF zu fahren, wenn auch nur für 20 Tage zwischen 2 Kisten, schreckt mich daher ziemlich ab.

Fortsetzung folgt wenn das Problem "richtig" gelöst wurde, sprich nicht durch Abklemmen von mercury ;) ...

Busy Week

2005年05月23日 (月曜日) 23時05分

XPath Injections

2005年05月18日 (水曜日) 01時07分
Tags: Hecking

Für die Datenspeicherung dieses Blogs habe ich mich nach einigem Grübeln für XML entschieden. Weiterhin brauchte ich dann, für den Teil zur Kommentierung eines Kommentars (beurk!), eine Möglichkeit zur Selektion von Nodes aus dem Baum.
Was liegt, verwendet man XML, also nächer als XPath? - gedacht, getan. Wie dem geneigten Leser jetzt vielleicht nach etwas Linkhovering aber auffallen mag, haben die "Antworten"-Links die Form ...?select=X.Y. - und nicht etwa ...?select=comment[X]. Und zwar aus gutem Grund:

XPath Injection.

Während wohl viele SQL Injection kennen, ist XPath Injection etwas eher neues (es existiert zumindest ein Paper: PDF»). Am besten ist das ganze wohl anhand eines Beispiels gezeigt:

sample.xml:
<?xml version="1.0" encoding="utf-8"?>
<sample>
 <secret><password>23</password></secret>
 <public>
  <page no="1">page1</page>
  <page no="2">page2</page>
 </public>
</sample>
sample.py:
#!/usr/bin/python

from sys import stdin
import libxml2

doc = libxml2.parseFile("sample.xml")
root = doc.getRootElement()

query = stdin.readline().strip()
res = root.xpathEval("public/page[@no = %s]" % (query))
if len(res):
	for one in res:
		print one.content
else:
	print "Nothing found."
doc.freeDoc()

Die beiden Files sollen ein einfaches Seitenabrufsystem nachbilden, das aus einer XML-Datei je nach Anfrage eine Seite liefert.

Probieren wir mal, wie das Programm auf unterschiedliche Eingaben reagiert:

	» 1
	« page1

Prima.

	» 3
	« Nothing found.

Auch gut.

	» ?
	« Invalid expression
	« xmlXPathEval: evaluation failed

Mmmh...

	» 1 or 1
	« page1
	« page2

Uh-Oh...

	» 1]/../../secret/password[1 = 1
	« 23

Shit!

Das Problem ist ziemlich klar - die Eingabe wird direkt in die XPath-Query eingefügt. public/page[@no = 1]/../../secret/password[1 = 1] bildet einen gültigen XPath-Ausdruck und liefert uns ohne Umwege das Passwort.

Nun ist dieses Beispiel zwar konstruiert, aber keineswegs unrealistisch. Immerhin sind XML-basierte Datenbanken momentan ziemlich angesagt, und wenn Otto Anwendungsprogrammierer nicht aufpasst ist schnell ein XPath-Ausdruck zugänglich.

Maßnahmen konkret am Beispiel:

  • erst mal Quoten. "...[@no = '%s']" % (query) ist ein guter Anfang, aber man kann immernoch ausbrechen.
  • Datentypen beschränken. "...[@no = '%d']" % (int(query)) schützt zuverlässig vor allem was keine Zahl ist
  • Strings auf gültige Angaben (z.B. via regexp /^\d+$/)

Allgemeinere Maßnahmen

  • Korrekt Quoten. Müsste man aber vorher intensiv Nachdenken was man denn alles quoten muss - z.B. für XSLT select="'%s'" müsste man nicht nur ' sondern auch " quoten...
  • Bei XSLT: als Parameter übergeben. Die meisten XSLT-Prozessoren können Parameter an ein Stylesheet übergeben. Allerdings wertet libxslt Parameter auch als XPath aus...
  • Für XML-Datenbanken: Zugriffsbeschränkungen einführen. Was bei SQL Alltag ist, fehlt teilweise noch in XML-Datenbanken, wo jeder die komplette Datenbank einfach auslesen kann.

Von deutlichem Nachteil ist hier, dass es - im Gegensatz zu SQL - für XML keine mir bekannten Quoting-Funktionen gibt. Ein zu mysql_escape_string analog arbeitendes xpath_escape_string wäre in XML-Bibliotheken sehr angebracht.
Evtl. kann man auch html_escape_string benutzen, falls dieses " escaped und man seine Strings alle mit " begrenzt. (' ist auch möglich)

Copyright © 2005, 2006, 2007 by David L. (equinox)
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 2.0 Germany License
Creative Commons License

Impressum

      mode   index
      uri    
      offset 12