SSH обес­печива­ет шиф­рование и аутен­тифика­цию, но даже с ним воз­можны уяз­вимос­ти, нап­ример, переда­ча пароля в откры­том виде через парамет­ры команд. В статье раз­берем, почему это опас­но, пос­мотрим при­меры уте­чек, пред­ложим скрип­ты и методы для обна­руже­ния и пре­дот­вра­щения этой угро­зы.

От­дель­ное вни­мание уде­лим инс­тру­мен­там, час­то исполь­зуемым адми­нис­тра­тора­ми (PuTTY Connection Manager, SuperPuTTY, mRemoteNG, WinSCP CLI, plink, pscp, rsync, sshpass и дру­гим), и рекомен­даци­ям по безопас­ной работе.

 

В чем опасность

Пе­реда­ча пароля через аргу­мен­ты коман­дной стро­ки озна­чает, что сек­ретный пароль фак­тичес­ки «зашит» в текст коман­ды. Нес­мотря на то, что сама SSH-сес­сия шиф­рует дан­ные при переда­че по сети, пароль, ука­зан­ный в парамет­рах, оста­ется видимым на локаль­ном компь­юте­ре.

Глав­ная угро­за в том, что такой пароль может быть лег­ко про­читан пос­торон­ними про­цес­сами или поль­зовате­лями на той же сис­теме. В опе­раци­онных сис­темах семей­ства Unix/Linux любой поль­зователь по умол­чанию может прос­мотреть спи­сок про­цес­сов и коман­дные стро­ки, с которы­ми они запуще­ны (нап­ример, с помощью команд ps или через чте­ние фай­лов /proc/[PID]/cmdline). Ана­логич­но в Windows дис­петчер задач или ути­литы вро­де Process Explorer поз­воля­ют уви­деть пол­ную коман­дную стро­ку запущен­ных про­цес­сов.

Дру­гими сло­вами, если адми­нис­тра­тор запус­кает ути­литу с ука­зани­ем пароля в явном виде, этот пароль может попасть в исто­рию коман­дной обо­лоч­ки или отоб­разить­ся в спис­ке про­цес­сов, дос­тупном для прос­мотра локаль­ными поль­зовате­лями. В резуль­тате зло­умыш­ленник, име­ющий огра­ничен­ный дос­туп к сис­теме (либо дру­гой поль­зователь на том же сер­вере, либо вре­донос­ное ПО), может незамет­но про­читать пароль из коман­дной стро­ки.

Это под­рыва­ет саму суть SSH-авто­риза­ции: пароль, может быть, и не переда­ется в откры­тую по сети, но хра­нит­ся в откры­том виде на сто­роне кли­ента.

Ад­минис­тра­торы час­то поль­зуют­ся надс­трой­ками и ути­лита­ми для удоб­ной работы с SSH: нап­ример, GUI-менед­жеры сес­сий (PuTTY CM, SuperPuTTY, mRemoteNG), инс­тру­мен­ты авто­мати­зации фай­ловых тран­сфе­ров (WinSCP, psftp, pscp), скрип­товые обер­тки (plink, sshpass) и даже коман­ды резер­вно­го копиро­вания (rsync с паролем). Все эти средс­тва пре­дос­тавля­ют воз­можность ука­зать пароль в парамет­рах коман­дной стро­ки, что оди­нако­во опас­но.

Ав­торы докумен­тации sshpass, нап­ример, под­черки­вают, что подоб­ный спо­соб аутен­тифика­ции небезо­пасен и не рекомен­дует­ся, так как пароли переда­ются или хра­нят­ся в виде откры­того тек­ста. В целом, любая прог­рамма, при­нима­ющая пароль через аргу­мент коман­дной стро­ки, потен­циаль­но уяз­вима, если исполь­зовать эту воз­можность.

 

Как утекают пароли

В дис­петче­ре задач Windows мож­но опре­делить, что про­цесс PuTTY (psftp) запущен с опци­ей -pw и с явным ука­зани­ем пароля. В таком слу­чае пароль сох­раня­ется в откры­том виде в коман­дной стро­ке про­цес­са. Это наг­лядно под­твержда­ет, что любые пароли, передан­ные через парамет­ры, могут быть про­чита­ны из спис­ка про­цес­сов локаль­ной сис­темой.

Точ­но так же в Linux дос­таточ­но выпол­нить коман­ду вро­де ps -ef или прос­мотреть файл /proc/<PID>/cmdline, что­бы уви­деть всю коман­дную стро­ку активно­го про­цес­са. К при­меру, адми­нис­тра­тор может выпол­нить такую коман­ду:

sshpass -p 'P@ssw0rd' ssh user@server.example.com

Тог­да дру­гой поль­зователь на этом же хос­те может выпол­нить ps aux | grep sshpass и обна­ружить в выводе стро­ку с ука­зан­ным паролем.

В жур­нале Red Hat при­водит­ся пре­дуп­режде­ние:

«Все слу­чаи пре­дос­тавле­ния пароля в коман­дной стро­ке вклю­чают риск того, что пароль будет зах­вачен в исто­рии обо­лоч­ки поль­зовате­ля или будет виден всем сис­темным поль­зовате­лям в спис­ке про­цес­сов».

До­кумен­тация PuTTY так­же отме­чает, что опция -pw дела­ет пароль видимым для дру­гих локаль­ных поль­зовате­лей (нап­ример, через коман­ду w) и не рекомен­дует­ся к исполь­зованию.

Эта проб­лема каса­ется не толь­ко sshpass и PuTTY. Ути­литы plink, pscp, psftp (вхо­дящие в сос­тав PuTTY) при­нима­ют параметр -pw <пароль> для авто­мати­зации вхо­да и таким обра­зом отоб­ража­ют пароль в памяти про­цес­са.

В Linux такой пароль мож­но получить, прос­мотрев коман­дную стро­ку про­цес­са через /proc. В Windows ситу­ация похожая: нес­коль­ких кли­ков в дис­петче­ре задач дос­таточ­но, что­бы уви­деть пол­ный запуск про­цес­са вмес­те с передан­ным паролем. WinSCP в коман­дном режиме поз­воля­ет переда­вать пароль через ключ /password=<пароль>, что тоже дела­ет этот пароль видимым локаль­но. Адми­нис­тра­тор WinSCP пре­дуп­режда­ет, что такой спо­соб небезо­пасен.

Да­же инс­тру­мен­ты, не свя­зан­ные нап­рямую с SSH, под­верже­ны этой проб­леме. Нап­ример, кли­ент MySQL поз­воля­ет ука­зать пароль через параметр --password= или корот­кий -p: при таком исполь­зовании MySQL выводит пре­дуп­режде­ние: «Using a password on the command line interface can be insecure» (исполь­зование пароля в коман­дной стро­ке может быть небезо­пас­но). При­чина все та же — пароль может быть перех­вачен локаль­но, пока про­цесс выпол­няет­ся.

Хо­тя некото­рые сов­ремен­ные прог­раммы пыта­ются очис­тить или скрыть пароль в аргу­мен­тах пос­ле запус­ка, пол­ностью полагать­ся на это нель­зя. Всег­да сущес­тву­ет корот­кий про­межу­ток вре­мени, ког­да пароль виден в памяти про­цес­са и может быть про­читан пос­торон­ними. Кро­ме того, спис­ки про­цес­сов неред­ко собира­ются сис­темами монито­рин­га и жур­налиро­вания, поэто­му пароль, даже исполь­зован­ный в быс­тром одно­разо­вом про­цес­се, может сох­ранить­ся в логах ауди­тора или монито­рин­га.

Вы­вод прос­той: пе­реда­вая пароль через аргу­мен­ты команд, ты фак­тичес­ки дела­ешь его откры­то дос­тупным на локаль­ной машине. Ниже я рас­ска­жу, как выявить такие слу­чаи и какие меры при­нять, что­бы это­го избе­жать.

 

Ищем утечки паролей в процессах Windows

Ад­минис­тра­торы Windows могут вос­поль­зовать­ся PowerShell для ска­ниро­вания запущен­ных про­цес­сов и обна­руже­ния тех, в коман­дных стро­ках которых при­сутс­тву­ют подоз­ритель­ные парамет­ры, похожие на пароли.

Для это­го нуж­но зап­рашивать у сис­темы коман­дные стро­ки про­цес­сов (атри­бут CommandLine клас­са Win32_Process) и искать в них извес­тные клю­чи или пат­терны (нап­ример, -p , -pw, --password, /password= и тому подоб­ные). Ниже при­веден скрипт на PowerShell, который мож­но запус­тить вруч­ную на отдель­ной сис­теме для выяв­ления таких слу­чаев:

$insecureProcs = Get-CimInstance Win32_Process |
Where-Object {
($_.CommandLine -match '-p\s') -or   # найдены '-p '
($_.CommandLine -match '-pw\s') -or  # найдены '-pw '
($_.CommandLine -match '--password=') -or # найдены '--password='
($_.CommandLine -match '/password=')  # найдены '/password='
} |
Select-Object ProcessId, Name, CommandLine
if ($insecureProcs) {
Write-Host "Обнаружены процессы с потенциальной утечкой пароля:"
$insecureProcs | Format-Table -AutoSize
} else {
Write-Host "Не найдено процессов с паролями в командной строке."
}

Этот скрипт выводит таб­лицу с иден­тифика­тором про­цес­са, име­нем и пол­ной коман­дной стро­кой для каж­дого най­ден­ного слу­чая. В филь­тре усло­вия -match исполь­зуют­ся регуляр­ные выраже­ния для поис­ка раз­личных спо­собов переда­чи пароля. Здесь мы про­веря­ем наличие подс­трок -p (дефис p и про­бел), -pw , а так­же --password= и /password=. Эти шаб­лоны охва­тыва­ют типич­ные клю­чи, исполь­зуемые раз­ными ути­лита­ми (sshpass, plink/pscp, WinSCP, mysql и дру­гими). При необ­ходимос­ти спи­сок мож­но рас­ширить или уточ­нить.

 

Версия для SCCM

Ес­ли нуж­но выпол­нить подоб­ную про­вер­ку цен­тра­лизо­ван­но на мно­гих машинах через System Center Configuration Manager (SCCM) или ана­логич­ную сис­тему, мож­но адап­тировать скрипт. Нап­ример, SCCM-скрипт про­вер­ки может воз­вра­щать код выпол­нения или вывод, на осно­вании которо­го сис­тема сде­лает вывод о соот­ветс­твии полити­ки.

Ни­же при­веден вари­ант, который в слу­чае обна­руже­ния небезо­пас­ного про­цес­са завер­шится кодом 1 (несо­ответс­твие), а при отсутс­твии — кодом 0 (все чис­то):

$found = $false
Get-CimInstance Win32_Process |
Where-Object {
($_.CommandLine -match '-p\s') -or
($_.CommandLine -match '-pw\s') -or
($_.CommandLine -match '--password=') -or
($_.CommandLine -match '/password=')
} |
ForEach-Object {
$found = $true
# Запись в лог при необходимости:
"$($_.ProcessId): $($_.Name) $($_.CommandLine)" | Out-File "C:\\temp\\insecure_procs.log" -Append
}
if ($found) { exit 1 } else { exit 0 }

Этот сце­нарий переби­рает про­цес­сы, записы­вает обна­ружен­ные слу­чаи (PID, имя, коман­ду) в локаль­ный лог‑файл и уста­нав­лива­ет флаг $found. В кон­це скрип­та воз­вра­том exit 1 он может сиг­нализи­ровать SCCM о проб­леме.

Ад­минис­тра­тор SCCM может нас­тро­ить соот­ветс­тву­ющее пра­вило, помеча­ющее машину как Non-compliant (несо­ответс­тву­ющую тре­бова­ниям безопас­ности), если скрипт вер­нул 1, что поз­волит быс­тро выявить сис­темы, где кто‑то исполь­зует небезо­пас­ные спо­собы переда­чи паролей.

 

Ищем утечки пароля в Linux

В Linux подоб­ную про­вер­ку мож­но выпол­нить с помощью скрип­та на Bash, ана­лизи­руя вывод коман­ды ps или содер­жимое дирек­торий /proc/<PID>/cmdline. Скрипт дол­жен выпол­нять­ся с пра­вами, дос­таточ­ными для прос­мотра про­цес­сов всех поль­зовате­лей (нап­ример, от име­ни root), ина­че он уви­дит толь­ко свои про­цес­сы.

Продолжение доступно только участникам

Материалы из последних выпусков становятся доступны по отдельности только через два месяца после публикации. Чтобы продолжить чтение, необходимо стать участником сообщества «Xakep.ru».

Присоединяйся к сообществу «Xakep.ru»!

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее

  • Подпишись на наc в Telegram!

    Только важные новости и лучшие статьи

    Подписаться

  • Подписаться
    Уведомить о
    0 комментариев
    Межтекстовые Отзывы
    Посмотреть все комментарии