Bir alt sürece bir şifre nasıl geçirilir?


18

Komut satırına (programımdan başlatılan bir alt işleme) bir parola geçirmenin güvenli olmadığı bilinmektedir (çünkü ps komutu olan diğer kullanıcılar tarafından bile görülebilir). Bunun yerine bir ortam değişkeni olarak iletilmesi uygun mudur?

Onu geçmek için başka ne kullanabilirim? (Ortam değişkeni hariç) en kolay çözüm bir boru kullanıyor gibi görünmektedir, ancak bu en kolay çözüm kolay değildir.

Perl'de program yapıyorum.


2
Neden kolay değil? Ayrı / adlandırılmış bir boru olmak zorunda değil, sadece düzenli stdin / out yapacak ... bu herhangi bir dilde çok fazla sorun olmamalı. Yalnızca ilgilenilen işlemlerle (göründüğünden çok daha zor) okunabilir olduğundan emin olursanız, düz bir yapılandırma dosyasına koyabilirsiniz.
frostschutz

1
Çocukta exec çağırmazsanız, hiçbir şey yapmanıza gerek kalmadan şifrenin bir kopyasına sahip olursunuz.
James Youngman

Yanıtlar:


26

İşlem argümanları tüm kullanıcılar tarafından görülebilir, ancak ortam yalnızca aynı kullanıcı tarafından görülebilir ( en azından Linux'ta ve her modern unix varyantında düşünüyorum). Böylece bir ortam değişkeninden şifre geçmek güvenlidir. Birisi ortam değişkenlerinizi okuyabilirse, işlemleri sizin gibi yürütebilir, bu yüzden zaten oyun biter.

Çevrenin içeriği dolaylı olarak sızıntı riskiyle karşı karşıyadır; örneğin, bir şeyi psaraştırmaya çalışırsanız ve gizli bir ortamdaki gizli ortam değişkenleri de dahil olmak üzere sonucu yanlışlıkla kopyalayıp yapıştırırsanız. Başka bir risk, ortam değişkenini, ona ihtiyaç duymayan bir programa (parolaya ihtiyaç duyan sürecin çocukları dahil) geçirmeniz ve bu programın ortam değişkenlerini gizli olmalarını beklemediği için ortaya çıkarmasıdır. Bu ikincil sızıntı riskinin ne kadar kötü olduğu, parola ile yapılan işlemin ne yaptığına bağlıdır (ne kadar süre çalışır? Alt işlemleri çalıştırıyor mu?).

Parolanın, boru gibi gizlice gizlenecek şekilde tasarlanmamış bir kanaldan geçerek yanlışlıkla sızmamasını sağlamak daha kolaydır. Gönderen tarafta bunu yapmak oldukça kolaydır. Örneğin, bir kabuk değişkeninde parolanız varsa,

echo "$password" | theprogram

eğer theprogramstandart girişinde şifre bekleniyorsa. Bunun bir güvenli olduğu echoiçin güvenli olduğunu unutmayın ; argüman psçıktıda açıklanacağı için harici bir komutla güvenli olmazdı . Aynı etkiyi elde etmenin başka bir yolu da buradaki bir belgedir:

theprogram <<EOF
$password
EOF

Şifre gerektiren bazı programlara şifreyi belirli bir dosya tanımlayıcıdan okuması söylenebilir. Başka bir şey için standart girdiye ihtiyacınız varsa, standart girdi dışında bir dosya tanımlayıcı kullanabilirsiniz. Örneğin gpg:

get-encrypted-data | gpg --passphrase-fd 3 --decrypt … 3<<EOP >decrypted-data
$password
EOP

Programın bir dosya tanımlayıcısından okuması söylenemez, ancak bir dosyadan okuması söylenebilirse, / dev / fd / 3 gibi bir dosya adı kullanarak bir dosya tanımlayıcısından okumasını söyleyebilirsiniz.

theprogram --password-from-file=/dev/fd/3 3<<EOF
$password
EOF

Ksh, bash veya zsh olarak, bunu işlem ikamesi yoluyla daha kısaca yapabilirsiniz.

theprogram --password-from-file=<(echo "$password")

Solaris 9 ve daha eski sürümlerde, /usr/ucb/psdiğer işlemlerin ortam değişkenlerini okuyabilen ve görüntüleyebilen setuid root oldu - bu Solaris 10'da kaldırıldı, bu nedenle yukarıdaki "diğer tüm modern Unix varyantları" yanıtı 2005 ve sonrasındaki Solaris sürümleri için geçerlidir.
alanc

@alanc Gerçekten de Solaris <10'un bugünlerde modern olduğunu düşünmüyorum. Solaris 9 neredeyse Windows XP kadar eskidir!
Gilles 'SO- kötü olmayı bırak

Gilles: Solaris 10 modern'i düşünmekte zorlandığım günler var, Solaris 11 5 yıldan fazla sürdü, bu yüzden tamamen anlıyorum ve katılıyorum, ama ne yazık ki bazı insanlar hala Solaris 8 veya 9 çalıştırıyor.
alanc

10

Parolayı doğrudan bir bağımsız değişken veya ortam değişkeni içinden geçirmek yerine

#!/bin/bash
#filename: passwd_receiver
echo "The password is: $1"

bir dosya adı iletmek için aynı argümanı veya ortam değişkenini kullanın :

#!/bin/bash
#filename: passwd_receiver
echo "The password is: $(< "$1")"

O zaman ya geçebilir izni korumalı düzenli dosyasını (yani aynı kullanıcı altında çalışan diğer işlemlerden korumaz gerçi) ya /dev/stdinve boru da (AFAIK aynı kullanıcı altında çalışan diğer süreçlerden sizi koruyacak olan) içinde:

 echo PASSWORD | ./passwd_receiver /dev/stdin 

/dev/stdinBurada kullanırsanız , bunun bir boru olması zorunludur . Terminal ise, aynı kullanıcı altında çalışan diğer işlemler tarafından okunabilir.

Zaten /dev/stdinbaşka bir şey için kullanmanız gerekiyorsa , onu destekleyen bir kabuk üzerindeyseniz, esasen boruları kullanmaya eşdeğer olan işlem ikamesini kullanabilirsiniz :

./passwd_receiver <(echo PASSWORD)

Adlandırılmış kanallar (FIFO'lar) aynı gibi görünebilir, ancak ele geçirilebilir.

Bu çözümler de mükemmel bir şekilde güvenli değildir , ancak çok fazla takas eden bellek kısıtlı bir sistemde olmadığınız sürece yeterince yakın olabilirler.

İdeal olarak, bu dosyaları (boru da bir dosyadır) mlock (2) ile işaretlenmeyen bir belleğe okunamaz olarak okurdunuz, bu da gnupg gibi şifre işleme programlarının genellikle yaptığı şeydir.

Notlar:

  1. Filedescriptor numaralarını Geçme dosya aktarma gibi dosya olarak teorik sadece iyi, ama çünkü dosya isimleri, daha pratik olan <()size bir dosya adı değil, bir Filedescriptor numarası verir (ve coprocs işaretlenmiş FileDescriptorları boşaltmanın vermek FD_CLOEXEC bu FileDescriptorları boşaltmanın bu bağlamda kullanılamaz hale getirir).

  2. AFAIK
    /proc/sys/kernel/yama/ptrace_scopeolarak ayarlanmış bir Linux sistemindeyseniz 0, kendinizi aynı kullanıcı altında çalışan diğer işlemlerden korumanın kurşun geçirmez bir yolu yoktur (işleminize eklemek ve belleğinizi okumak için ptrace kullanabilirler)

  3. Parolanızı yalnızca farklı (kök olmayan) kullanıcılar altında çalışan işlemlerden uzak tutmanız gerekiyorsa, bağımsız değişkenler, ortam değişkenleri, kanallar ve izin korumalı dosyalar işe yarayacaktır.


7

Hayır, çevre değişkenleri de kolayca okunabilir ve alt süreçlere sızabilir. bir boru kullanarak geçirin.


2
"ortam değişkenleri ... alt süreçlere sızıntı" Bu bir ortam değişkeni kullanmanın temel noktasıdır. Miras alınmazlarsa işe yaramazlardı. "ortam değişkenleri de kolayca okunabilir", hayır değil.
Patrick

2
Değişkeni okuyun, ayarını kaldırın. Zor değil. Ve boru hakkında aynı argümanı kullanabilirsiniz. Boru okunmazsa, alt işleme geçirilir ve alt işlem onu ​​okuyabilir ve parolayı alabilir.
Patrick

1
@Patrick Belgelendirilmiş ortam değişkenlerini ayarlama araçları, değeri mutlaka bulunduğu yerden görebiliyor psve /procgörebiliyor.
zwol

1
Bazı sistem keyfi süreçlerin ortam değişkenlerini okumanıza izin veriyor mu? Linux'un başkalarının sahip olduğu işlemlere izin verdiğini düşünmüyorum ve aynı kullanıcıysanız, sadece ptrace()hedefi hedefleyebilir ve yine de belleğini okuyabilirsiniz.
ilkkachu

5
Bu cevap yanlış. Ortam değişkenleri diğer kullanıcılar tarafından okunamaz.
Gilles 'SO- kötü olmayı kes'

1

Başka hiçbir şey uygun değilse, Linux Anahtar Saklama hizmetini (çekirdek anahtarlıklar) düşünün.

Başlangıç: güvenlik / keys.txt . Varsayılan anahtarlıklardan biri, üst ve alt işlemler arasında klonlanabilir.

En basit çözüm değil, ama orada ve bakımı ve kullanımı görünüyor (geçen yıl bir Android hatasıyla da ilgili.)

"Siyasi" durumunu bilmiyorum, ama benzer bir ihtiyacım vardı ve bir Guile bağlayıcılığı üzerinde çalışmaya başladım. Önceden var olan Perl desteğiyle karşılaşmadım.

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.