Chmod через веб скрипт?
к сожалению защита от подобных атак может добавлять неудобства в разработке и тестировании скриптов/сайтов, но приловчиться можно. Я делаю так:
1) устанавливаю на каждый сайт переменную "open_basedir" равной каталогу пользователя или папки с сайтом. Для каждого сайта значения устанавливаю через конфиг пула php-fpm.
Если php работает как модуль apache, тогда это делается в конфиге виртуального хоста вот такими строками:
php_admin_value open_basedir "/var/www:/tmp"
php_admin_value disable_functions "popen, pclose, exec, passthru, shell_exec, system, proc_open, proc_close, mail, symlink"
Глобальное значение в php.ini щас стоит: open_basedir = "/var/www:/tmp" на всякий случай.

2) устанавливаю глобальное значение переменной "disable_functions" в php.ini, у меня щас такое:
disable_functions = "get_defined_constants,apache_get_modules,virtual,getmyinode,apache_get_version,apache_getenv,ini_restore,-openlog,-syslog,highlight_file,show_source,symlink,-ini_get_all,-phpinfo,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,exec,shell_exec,system,passthru,proc_open,popen,proc_close,proc_get_status,proc_nice,proc_terminate,leak,listen,chown,chgrp,apache_note,apache_setenv,closelog,debugger_off,debugger_on,define_sys,getmyuid,getmypid,diskfreespace,dl,posix_ctermid,posix_getcwd,posix_getegid,posix_geteuid,posix_getgid,posix_getgrgid,posix_getgrnam,posix_getgroups,posix_getlogin,posix_getpgid,posix_getpgrp,posix_getpid,posix,_getppid,posix_getpwnam,posix_getpwuid,posix_getrlimit,posix_getsid,posix_getuid,posix_isatty,posix_kill,posix_mkfifo,posix_setegid,posix_seteuid,posix_setgid,posix_setpgid,posix_setsid,posix_setuid,posix_times,posix_ttyname,posix_uname,expose_php,curl_exec,curl_multi_exec,-parse_ini_file,eval,link,putenv,-pack,gzinflate,gzuncompress"
Если перед функцией стоит дефис, например "-ini_get_all", значит я хочу временно отключить блокировку данной функции, т.к. блокироваться будет полностью строка "-ini_get_all", а такой не существует.
Если при работе сайта/скрипта что то не работает, то смотрите error.log, там должны быть ошибки.
Если для какого то сайта нужно изменить значение disable_functions, то меняю его для отдельного сайта. Или усиливаю защиту блокируя дополнительно функции или наоборот уменьшаю.

3) Т.к. у меня php работает как php-fpm, то под каждый сайт создаю отдельного пользователя и пул в php-fpm запускается от него.
Если php работает как модуль apache, то это делается через модуль mpm-itk.
<IfModule mpm_itk_module>
    AssignUserId user1 user1
</IfModule>

4) Для apache устанавливаю модуль ModSecurity (mod_security2). Это веб фаервол. Он блокирует подозрительные http запросы ещё до того, как они попадут к скрипту/cms. Работает очень хорошо. Иногда даже слишком, что приходится отключать часть правил или полностью для какого то сайта.

Но и выполнение этих 4 пунктов не гарантирует полную безопасность сайта. Один сайт клиента был взломан даже с такими защитами.
Пробовали заливать wp не от рута? Допустим создали в этом же isp юзера с ограниченными правами, от него инсталлировали wp, тогда тоже этот шелл пускает ко всем дирректориям даже за выход прав этого ftp юзера?