GNU/Linux >> Znalost Linux >  >> Linux

Může být katování souboru potenciálním bezpečnostním rizikem?

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 ". Toto chování umožňuje programům dotazovat/nastavovat terminálové (nebo jiné) vlastnosti "v pásmu" spíše než přes ioctls nebo nějaké jiné API.

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:

  1. \e]2;...\x07 nastavit titulek okna;
  2. \e[21;;t název okna dotazu, místo ve vstupním bufferu;
  3. \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

Linux
  1. Proč může Rm odebrat soubory pouze pro čtení?

  2. 4 způsoby, jak vytvořit textový soubor v terminálu Linux

  3. Smazat historii terminálu v Linuxu

  1. Jak najdu konkrétní soubor z terminálu Linux?

  2. Jak vytvořit soubor v Linuxu z okna terminálu?

  3. Proč nemohu rolovat v terminálu?

  1. Může být soubor .sh malware?

  2. Mohu obnovit nano proces z předchozího terminálu?

  3. Proč nemohu tento soubor smazat jako root?