Kas teid rünnatakse? Võtke ühendust intsidentidele reageerimise meeskonnaga

Turvaline arendus

Kõigi kasutaja sisendist koostatud shelli kutsete leidmine

Kuidas leida kasutaja sisendist koostatud shelli kutsed ja asendada need teegi API-de või argumendimassiividega, mitte escape'imisele toetudes.

Saadaval ka:EnglishTürkçeDeutschFrançaisEspañolItalianoPolskiNederlands

Illustratsioon: Kõigi kasutaja sisendist koostatud shelli kutsete leidmine

OS command injection'i usaldusväärne lahendus on lõpetada kasutaja mõjutatavate sõnede andmine shellile. Parem escape'imine on nõrgem valik. Praktiline töö on leida kõik kohad, kus teie kood käivitab protsessi, ja otsustada iga koha puhul, kas see peab üldse olemas olema.

Command injection tekib siis, kui rakendus annab ebaturvalised kasutajaandmed süsteemi shellile ning süstitud käsud töötavad tavaliselt rakenduse õigustes. CWE-78 lisab ebameeldiva üksikasja: kuna käsud käivitab rakendus, võib tegevus paista pärinevat rakenduselt või selle omanikult.

Miks escape'imine on vale esimene vastus

PHP funktsioon escapeshellarg() ümbritseb väärtuse ülakomadega, nii et shell käsitleb seda ühe argumendina. See takistab & echo "hello" käivitumist eraldi käsuna. See ei takista ründajal valimast, millist ühte argumenti programm saab.

Iga OS command injection on ühtlasi ka argument injection. OWASP spikris prindib curlile antud escape("--help") ikkagi abiteksti. Sõltuvalt programmist ulatub mõju teabe avalikuks tulekust kuni kaugkoodi täitmiseni.

Lugejamärkus PHP käsiraamatu leheküljel escapeshellarg() näitab sama viga tari abil. Iga failinimi on õigesti escape'itud, kuid sidekriipsuga algav väärtus loetakse ikkagi valikuks ja taril on valik, mis käivitab mõne teise käsu. Kriipsude -- lisamine enne failinimesid parandab selle, kuid märkuse autor toob välja, et mitte iga programm seda eraldajat ei toeta.

Windowsis ütleb käsiraamat, et escapeshellarg() kasutab jutumärke ning asendab protsendimärgid, hüüumärgid ja jutumärgid tühikutega. Lugejamärkus lisab, et tulemus on turvaline, kuid kadudega. Mõlemal juhul on see põhjus shelli vältida, mitte lahendus.

Leidke kutsed üles

Käivitage need otsingud kõigis hoidlates. Kohandage failitüübid oma struktuurile vastavaks:

rg -n 'shell=True|os\.system|os\.popen' --type py
rg -n "subprocess\.(run|Popen|call|check_output)\(\s*[f\"']" --type py
rg -n '\b(system|exec|shell_exec|passthru|popen|proc_open)\s*\(' --type php
rg -n '`[^`]*\$' --type php
rg -n 'Runtime\.getRuntime\(\)\.exec|ProcessBuilder' --type java
rg -n 'ProcessStartInfo|Process\.Start|UseShellExecute' --type cs
rg -n '\bsystem\s*\(|popen\s*\(|exec[lv]p?e?\s*\(' --type c

Teine Pythoni muster tabab juhud, kus käsuna antakse üks sõne. Ilma shell=True-ta töötab see ainult siis, kui sõne nimetab programmi ega midagi muud, seega tuleb iga tabamust käsitsi vaadata. PHP tagurpidi ülakomade muster on mürarikas, sest see sobib ka kommentaaride ja SQL-i tagurpidi ülakomadega. Otsige ka shelliskriptidest, juurutusskriptidest ja cron-wrapperitest, mis koostavad käske muutujatest sama sageli kui rakenduse kood.

KeelOtsigeAsendage
PHPsystem(), exec(), shell_exec(), passthru(), popen(), proc_open(), tagurpidi ülakomade operaatorSisseehitatud funktsioonidega, näiteks mkdir()
Pythonshell=True; os.system; os.popen; üks käsusõnesubprocess.run koos loendiga
JavaRuntime.exec(String)ProcessBuilder, kus programm ja iga argument on eraldi elemendid
.NETcmd.exe, powershell.exe, sh -c, kokku ehitatud Arguments sõneProcessStartInfo koos ArgumentListiga
Csystem()Teegi kutse

Kaasake ka kõvakodeeritud käsud. OWASP kogukonna ülevaade kirjeldab privilegeeritud CGI programmi, mis käivitab cd /var/yp && make ilma et sõnes oleks kasutaja sisendit. make jaoks polnud absoluutset teed kasutatud, nii et ründaja sai muuta $PATHi ja panna oma binaarfaili töötama programmi õigustes.

Sorteerige tabamused

Tabamuste toorloend ei ole leidude loend. Jälgige iga väärtust tagasi ja küsige, kas päring võib selleni jõuda. Ilmsed allikad on marsruudi- ja päringuparameetrid, vormiväljad, küpsised ja HTTP päised. Need, mida unustatakse, on üleslaaditud failinimed, andmebaasiväärtused, millesse kasutajad saavad kirjutada, järjekorrasõnumid ja keskkonnamuutujad.

Jagage tabamused kolme hunnikusse: kättesaadavad autentimata päringuga, kättesaadavad alles pärast sisselogimist ja üldse kättesaamatud. Parandage esimene hunnik esimesena. Hoidke kolmas loendis, sest hilisem refaktoreerimine võib selle kellegi märkamata päringuga ühendada.

Asendage kutse API-ga

Teegi sisseehitatud funktsioone ei saa panna tegema midagi muud peale nende ettenähtud ülesande. Kasutage system("mkdir /dir_name") asemel mkdir(). Kasutage Java meili API-t javax.mail.* selle asemel, et kutsuda shellist mail. CWE-78 annab sama nõu disainiks: kasutage teegi kutseid, mitte väliseid protsesse.

Kui peate protsessi käivitama

Mõnel tööriistal puudub teegi vaste. Sel juhul kasutage koos kahte kihti: argumendiloend ilma shellita ning valideerimine.

Pythoni subprocess'i dokumentatsioon ütleb, et argumentide jada on üldiselt eelistatum, sest moodul hoolitseb escape'imise ja jutumärkide eest. Selles on märge lugeda enne shell=True kasutamist läbi jaotis Security Considerations. Samuti soovitatakse käivitatava faili jaoks täielikku teed, mis kaotab PATHi otsingu, mida ülaltoodud make näide ära kasutab.

import re, subprocess

if not re.fullmatch(r"[a-z0-9]{3,10}", name):
    raise ValueError("rejected")

subprocess.run(["/usr/bin/tar", "cf", "out.tar", "--", name], check=True)

Muster lükkab sidekriipsuga algava väärtuse juba tagasi, seega paistab -- üleliigne. See on kaitse sügavuti (defence in depth): kui keegi hiljem regulaaravaldist leevendab, takistab eraldaja ikkagi namei lugemist valikuna.

.NET-is kasutage FileName jaoks fikseeritud täielikku teed, määrake UseShellExecute = false ja lisage iga argument ArgumentList kaudu. Ärge kunagi andke ebausaldusväärset sisendit cmd.exe, powershell.exe ega sh -c käsule. Argumentide eraldamine ei ole valideerimine, ei Javas ega .NET-is.

Seejärel valideerige väärtused. Kontrollige käsku lubatud käskude loendi vastu ning iga argumenti lubatud väärtuste või mustri vastu, millel on maksimaalne pikkus ning kust on metamärgid ja tühikud välja jäetud.

Curli puhul ei piisa ---st, sest hilisemad argumendid on endiselt URL-i operandid ja täiendavad edastused on võimalikud. Andke täpselt üks valideeritud URL, kasutage --globoff ja rakendage SSRF-kaitset.

Käivitage rakendus väikseimate vajalike õigustega ja andke ühe ülesande töödele oma isoleeritud konto. Sandbox, näiteks chroot, AppArmor või SELinux, aitab, kuid CWE-78 hindab selle tõhusust piiratuks. See kitsendab, millele ründaja ligi pääseb, kuid ei kõrvalda viga.

Kust alustada

  1. Käivitage ülaltoodud otsingud kõigis hoidlates, kaasa arvatud juurutusskriptid, CI tööd ja cron-wrapperid. Loetlege iga tabamus koos sisendiga, mis selleni jõuab, ja sorteerige loend selle järgi, kas päring võib sinna jõuda.
  2. Küsige iga tabamuse kohta, kas sama töö teeb ära teegi või sisseehitatud funktsioon. Kui teeb, asendage kutse ja kustutage protsessi käivitamine.
  3. Kirjutage ülejäänud kutsed ümber nii, et need kasutaksid argumendiloendit, ei kasutaks shelli ja käivitatava faili absoluutset teed. Lisage lubatud väärtuste loendil põhinev valideerimine ja -- eraldaja, kus programm seda toetab.
  4. Käivitage protsessid pühendatud vähese õigusega konto all, et märkamata jäänud juhul oleks ründajal vähem võimalusi.
  5. Testige iga allesjäänud kutset väärtusega nagu bob.txt;sleep 5 ja väärtusega, mis algab sidekriipsuga. Mõõtke vastuse aega, selle asemel et väljundit oodata. Sidekriipsuga algav väärtus peab olema tagasi lükatud või käsitletud failinimena. Välise kontrolli jaoks proovib penetratsioonitest mõlemat või meie turvalise tarkvaraarenduse meeskond saab koodi teiega koos üle vaadata.

Kuidas saame aidata

Läbistustestimine

Ründame teie võrke, rakendusi ja inimesi nagu päris vastane ning näitame, kuidas iga turvaauk sulgeda.

Kirjutage meile
AngelForce’i meeskond

Kirjutanud AngelForce’i meeskond: CEH-, LPT Masteri ja CISA-sertifikaadiga turvakonsultandid, kes testivad, jälgivad ja kaitsevad organisatsioonide süsteeme kogu Euroopas.

Artikkel on kirjutatud tehisintellekti abil allpool loetletud avalike allikate põhjal ning AngelForce’i meeskond vaatas selle enne avaldamist üle.

Allikad

  1. cheatsheetseries.owasp.org/cheatsheets/OS_Command_Injection_Defense_Cheat_Sheet.html
  2. community.owasp.org/attacks/Command_Injection
  3. cwe.mitre.org/data/definitions/78.html
  4. docs.python.org/3/library/subprocess.html
  5. www.php.net/manual/en/function.escapeshellarg.php

Artiklid teemal „Turvaline arendus“

Rääkige meile, mida soovite kaitsta

Kirjeldage oma keskkonda ja seda, mida soovite saavutada. Vastame e-posti teel.

Kirjutage meile
info@angelforce.eu +372 5705 2044

AngelForce OÜ · Tallinn, Eesti