Сканирование загрузки php файлов с использованием clamav, разрешения на /tmp/
Я пытаюсь сканировать файлы (обычно 100MB+ zips), используя clamav на apache 2.4, php 5.6, используя сокет для clamav-daemon. Я не использую PHP-FPM. (PS сокет работает, я могу отправить PING и получить PONG).
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
if (isset($_FILES['file']) && is_uploaded_file($_FILES['file']['tmp_name'])) {
$socket = socket_create(AF_UNIX, SOCK_STREAM, 0);
if(socket_connect($socket, '/var/run/clamav/clamd.ctl')) {
$result = "";
$file = $_FILES['file']['tmp_name'];
socket_send($socket, "SCAN $file", strlen($file) + 5, 0);
socket_recv($socket, $result, 20000, 0);
var_dump($result);
}
socket_close($socket);
}
?>
<form method="post" enctype="multipart/form-data"><input type="file" name="file"><input type="submit"></form>
Загрузка файла дает:
string(65) "/tmp/phpxYBjyS: lstat() failed: No such file or directory. ERROR "
Это мне кажется ошибкой разрешения (хотя /tmp drwxrwxrwt 9 root root 4096 Dec 4 13:10 tmp
). Но я могу ошибаться. Я не могу легко посмотреть на файл, так как после завершения процесса php файл удаляется.
clamdscan
в командной строке работает конечно (например /tmp/virus.txt: Eicar-Test-Signature FOUND
).
мой /etc/clamav/clamd.conf
по-прежнему по умолчанию. Это выглядит так:
LocalSocket /var/run/clamav/clamd.ctl
FixStaleSocket true
LocalSocketGroup clamav
LocalSocketMode 666
# TemporaryDirectory is not set to its default /tmp here to make overriding
# the default with environment variables TMPDIR/TMP/TEMP possible
User clamav
AllowSupplementaryGroups true
ScanMail true
ScanArchive true
ArchiveBlockEncrypted false
MaxDirectoryRecursion 15
FollowDirectorySymlinks false
FollowFileSymlinks false
ReadTimeout 180
MaxThreads 12
MaxConnectionQueueLength 15
LogSyslog false
LogRotate true
LogFacility LOG_LOCAL6
LogClean false
LogVerbose false
DatabaseDirectory /var/lib/clamav
OfficialDatabaseOnly false
SelfCheck 3600
Foreground false
Debug false
ScanPE true
MaxEmbeddedPE 10M
ScanOLE2 true
ScanPDF true
ScanHTML true
MaxHTMLNormalize 10M
MaxHTMLNoTags 2M
MaxScriptNormalize 5M
MaxZipTypeRcg 1M
ScanSWF true
DetectBrokenExecutables false
ExitOnOOM false
LeaveTemporaryFiles false
AlgorithmicDetection true
ScanELF true
IdleTimeout 30
CrossFilesystems true
PhishingSignatures true
PhishingScanURLs true
PhishingAlwaysBlockSSLMismatch false
PhishingAlwaysBlockCloak false
PartitionIntersection false
DetectPUA false
ScanPartialMessages false
HeuristicScanPrecedence false
StructuredDataDetection false
CommandReadTimeout 5
SendBufTimeout 200
MaxQueue 100
ExtendedDetectionInfo true
OLE2BlockMacros false
ScanOnAccess false
AllowAllMatchScan true
ForceToDisk false
DisableCertCheck false
DisableCache false
MaxScanSize 100M
MaxFileSize 25M
MaxRecursion 16
MaxFiles 10000
MaxPartitions 50
MaxIconsPE 100
PCREMatchLimit 10000
PCRERecMatchLimit 5000
PCREMaxFileSize 25M
ScanXMLDOCS true
ScanHWP3 true
MaxRecHWP3 16
StatsEnabled false
StatsPEDisabled true
StatsHostID auto
StatsTimeout 10
StreamMaxLength 25M
LogFile /var/log/clamav/clamav.log
LogTime true
LogFileUnlock false
LogFileMaxSize 0
Bytecode true
BytecodeSecurity TrustSigned
BytecodeTimeout 60000
/ Edit Пробовал использовать exec вместо сокета.
if (isset($_FILES['file']) && is_uploaded_file($_FILES['file']['tmp_name'])) {
$path = escapeshellarg($_FILES['file']['tmp_name']);
$code = -1;
$result = '';
exec('clamdscan ' . $path, $result, $code);
if ($code !== 0) {
var_dump($result);
}
}
это также приводит к аналогичной ошибке
array(6) {
[0]=>
string(64) "/tmp/php2hQTE8: lstat() failed: No such file or directory. ERROR"
[1]=>
string(0) ""
[2]=>
string(36) "----------- SCAN SUMMARY -----------"
[3]=>
string(17) "Infected files: 0"
[4]=>
string(15) "Total errors: 1"
[5]=>
string(25) "Time: 0.000 sec (0 m 0 s)"
}
3 ответа
Похоже, что Moodle работает под службой, использующей systemd PrivateTmp.
Многие дистрибутивы теперь настраивают модули systemd для таких сервисов, как apache и php-fpm, чтобы предоставить сервису собственный частный каталог tmp (по крайней мере, частично из соображений безопасности).
Если вы посмотрите в файлах модулей systemd для apache или php-fpm (см.
/lib/systemd/system
для файла с именем что-то вроде
apache2.service
,
httpd.service
или
php-fpm.service
), вы, вероятно, увидите строку
PrivateTmp=true
в
[Service]
раздел.
Лучший способ переопределить это, если вы решите, что вам нужно это сделать, — создать файл переопределения в соответствующем
/etc/systemd/systemd/
подкаталог службы. Вы можете сделать это, используя
systemctl edit
для рассматриваемой услуги, например
systemctl edit php-fpm.service
при работе под php-fpm на RHEL. Имя службы будет отличаться для apache2 в зависимости от вашего дистрибутива.
Файл переопределения должен содержать только:
# A comment to explain why you're doing this
[Service]
PrivateTmp=false
Вероятно, вам также потребуется добавить пользователя clamd в группу веб-серверов, чтобы дать ему разрешение на доступ к временному файлу, как только он сможет его увидеть, например
usermod -a -G apache clamscan
на РХЕЛ.
Бег
clamdscan $the_file
не обязательно будет работать из-за файла systemd-private-tmp Apache. И вы получаете сообщение журнала «Ошибка проверки пути к файлу: нет такого файла или каталога».
Но самый простой способ:
cat $the_file | clamdscan -
Или используйте
--stream
вариант, (хотя я нашел
--fdpass
вариант не помогает).
Попробуйте пройти
--fdpass
как вариант для clamscan.
У меня была похожая проблема, когда файлы можно было найти с помощью clamscan, но не clamscan, и это сработало для меня.
--fdpass Передать разрешения файлового дескриптора в clamd. Это полезно, если clamd работает от имени другого пользователя, так как это быстрее, чем потоковая передача файла на clamd. Доступно только при подключении к clamd через локальный (unix) сокет.
Источник: https://linux.die.net/man/1/clamdscan