
Todos los perros van al cielo, y todos los propietarios de tiendas en línea en Opencart, tarde o temprano en Opencartforum. Cuando la euforia de la primera instalación del motor en el hosting pasa y comienza la dura realidad, el dueño de la tienda típica siempre comienza a perder algo y comienza el difícil camino de encontrar contratistas calificados y complementos de calidad para su tienda.
El recurso más grande en Runet, en el que puedes encontrar ambos, es opencartforum.com, que hoy tiene más de 140k usuarios registrados. De estos 140 mil registros, la mitad de ellos son personas vivas con tiendas en vivo que usan plantillas o módulos de una forma u otra, que se pueden comprar de inmediato en el sitio. Y todas estas personas ni siquiera se dan cuenta de que, junto con los complementos, adquieren maravillosas puertas traseras y vulnerabilidades, con las que el hacker de cualquier madre solo puede soñar.
Aunque en forma declarativa en las reglas para publicar complementos en la tienda del foro, se escribe en blanco y negro. Tenemos qadepartment, personas especialmente capacitadas revisan los complementos para detectar vulnerabilidades.
Y ni el foro, como la plataforma que media entre el autor y el usuario final del complemento, ni los autores de los complementos, como resultaron, tienen ninguna responsabilidad.
¿Cómo es eso? Y asi! Al parecer históricamente.
Modelando por mí mismo las consecuencias hipotéticas de los incidentes, que se discutirán más adelante, mi cabello en mi cabeza se eriza.
Solo imagina. Eres un exitoso propietario de una tienda, no has dormido por la noche en un par de años, escribiste textos, mordisqueaste en negro, blanco, gris seo, peleaste pandas, minusinsk, no terminaste tu bebida, atrajiste 100,000 clientes, invertiste en posiciones. Sus hijos van a un buen jardín de infantes y, de repente, sus ventas se han reducido a la mitad, simplemente porque su base con todos los contactos de los clientes fue a la competencia. O de repente lo perdió por completo, porque durante un mes su tienda ha estado trabajando en el servidor mysql de otra persona, y ni siquiera notó el cambio de kofig, y todas las copias de seguridad en el alojamiento se han estropeado.
Presentaron sus sentimientos en una situación similar, trabajaron, trabajaron durante varios años, y en un día todo se acaba. Dices que esto no puede ser así.
Pero puede ser muy fácil. ¡Basta con comprar un complemento con una "protección" de protección no declarada no declarada contra el uso no autorizado, y sus datos pueden convertirse rápidamente en extraños!
Primer incidente
Hace seis meses, una tienda se evitó superficialmente cuando un informe del escáner Ai-Bol mostró una advertencia extraña de un código extraño en el módulo
SeoCms (más de 10,000 instalaciones activas).
Comenzamos a mirar más de cerca y resultó que este abracadabra simplemente muestra la versión del complemento:
$text_redaeh_stpo = $text_redaeh_stpo_1.$value_tnega.$text_redaeh_stpo_2.$text_redaeh_stpo_3.$text_reda eh_stpo_4.$text_redaeh_stpo_5.$text_redaeh_stpo_6.$text_redaeh_stpo_7.$text_redaeh _stpo_8.$text_redaeh_stpo_9.$value_revres.$text_redaeh_stpo_10; if ($date_diff > 7) { $ver_content = false; $opts = array( $text_ptth => array($text_dohtem =>$text_tsop, $redaeh =>$text_redaeh_stpo, $tnetnoc => $yreuq_dliub_ptth(array($text_rdda =>$value_rdda, $text_liame => $this->data['liame'], $text_rev=>$this->data['blog_version'] )))); $context = $etaerc_txetnoc_maerts($opts); $exceptionizer = new PHP_Exceptionizer(E_ALL); try { $ver_content = $stnetnoc_teg_elif($rev_knil, FALSE , $context); } catch (E_WARNING $e) {
Está bien, excepto que:
$this->language->get('text_new_version').$ver_content. " <span style='color: #000; font-weight: normal;'>(".$date_ver_update.")</span>"
no se filtra de ninguna manera, y si por accidente aparece un script como el siguiente en lugar de la versión del cliente, obtener acceso de administrador a cualquier tienda donde esté instalado el módulo es cuestión de tiempo y técnica.
<script>
Los detalles de la situación se describen
aquí . Aviso de administración
aquí .
Probablemente la quinta vez, después de haber modelado este proceso muy claramente para la administración del foro, fue posible transmitir la crítica de la situación.
Y la administración, a su vez, notificó oficialmente a los usuarios la presencia de esta vulnerabilidad, y parece que incluso hizo un boletín informativo a los clientes. Pero esto no es exacto.
Dejemos detrás de escena las amenazas y evasiones del autor del complemento y sigamos adelante por dos meses más ...
Segundo incidente
Otra tienda viene para inspección, en la que hay frisos salvajes de hasta 3-4 segundos en cada página. Comenzamos a diseccionar y ver en la carpeta con un caché de más de 20k archivos con la extensión .php. Caché de archivos con la extensión php Karl, ¡no es casualidad!
Examinamos la estructura de datos de estos archivos, y nuevamente hay piezas de nuestro hermoso módulo SEOCMS.
Y un gran método:
protected function ajax_file() { $ajax_file_cached = false; $ajax_file = DIR_CACHE.base64_decode($this->db->escape($this->request->get["ajax_file"])); if (!file_exists($ajax_file)) { $ajax_file_cached = true; } else { } return $ajax_file_cached; }
Este es un ejemplo de una vulnerabilidad clásica: la inclusión de archivos locales.
Es suficiente codificar en base64 ../....../config.php y hello - require ($ ajax_file); Y por favor: aquí tiene las contraseñas de la base de datos, y aquí está el registro de errores del sistema, y si incluso / etc / pwd es muy necesario, aunque ha sido irrelevante durante mucho tiempo, ¿y si?
¿Y cuántos servidores y servidores con configuración predeterminada brillan en el mundo de phpmyadmin? Mitad? Más?
Comenzamos a buscar más y ¿qué encontramos? Maravilloso código de descarga de avatar:
if (!$json) { if (is_uploaded_file($this->request->files['file']['tmp_name']) && file_exists($this->request->files['file']['tmp_name'])) { $file = basename($filename) . '.' . md5(substr(sha1(uniqid(mt_rand(), true)), 0, 10)); $file_original = basename($filename);
Lo cual cae perfectamente en el error al intentar cambiar el tamaño (y nos muestra la ruta completa al archivo descargado), después de cargar algún tipo de shell.php.png, y luego también se ejecuta perfectamente por el método anterior.
Video de explotación de vulnerabilidad (con la salida de error del sistema php activada):
Video de explotación de vulnerabilidad (con la salida de error del sistema php desactivada):
El análisis del código se realizó en la versión del módulo 52 en abril de 2019.
Dado que tanto el autor como la administración del foro fueron notificados en las mismas fechas, pasó suficiente tiempo para que tomen todas las medidas posibles para notificar a los compradores sobre la eliminación de vulnerabilidades, nosotros, con la conciencia tranquila, podemos revelar todos los detalles.
Y en ese momento, algo sucedió. En el servidor del desarrollador estaba su propio módulo. Pero la vulnerabilidad no funcionó en eso. Estaba cubierta ... Y esto es una gran rareza. Muy grande !!!
Y la segunda rareza de toda esta historia es que el foro abierto en la persona de la administración y el departamento de control de calidad de complementos no vio ni el primer ni el segundo incidente, y en ambos casos en la primera notificación no encontró nada crítico.
Por supuesto, no hay nada crítico cuando tus configuraciones brillan en el mundo. No hay nada crítico cuando una buena mitad de los comerciantes desconocen lo que sucede debajo de su capó. Después de todo, una vez, alguien puso este complemento, y sin enviar por correo, ni siquiera se dan cuenta de que todo el negocio está bajo amenaza directa.
Y si hubo una reacción distinta de la administración en el primer incidente, en el segundo se eliminan todas las publicaciones con una mención. Y todo esto está cubierto por una
oferta de foro , según la cual, sobre adiciones comerciales, se pueden dejar comentarios sobre los muertos, ya sea bueno o nada.
El autor también afirma que los errores y los agujeros están arreglados, qadepartment perdió el complemento para la venta, pero no, los agujeros no están arreglados ...
protected function ajax_file() { if (!class_exists('PHP_Exceptionizer', false)) { if (function_exists('modification')) { require_once(modification(DIR_SYSTEM . 'library/exceptionizer.php')); } else { require_once(DIR_SYSTEM . 'library/exceptionizer.php'); } } $exceptionizer = new PHP_Exceptionizer(E_ALL); try { $ajax_file_cached = false; $filename = preg_replace('/[^a-zA-Z0-9\.\-\s+]/', '', html_entity_decode(base64_decode($this->db->escape($this->request->get['ajax_file'])), ENT_QUOTES, 'UTF-8')); $ajax_file = DIR_CACHE . $filename; if (!file_exists($ajax_file)) { $ajax_file_cached = true; } else { ob_start(); require($ajax_file); $ajax_html = ob_get_contents(); ob_end_clean(); header('Content-type: text/html; charset=utf-8'); echo $ajax_html; $this->deletecache('cache.ajax'); exit(); } return $ajax_file_cached; } catch (E_WARNING $e) { } }
require () todavía está aquí. La entrada está ligeramente filtrada. Pero el potencial LFI vivió y vivió. Si un poco más, entonces sí, ahora no podemos cargar ni ejecutar el shell. Pero supongamos que intentamos, cerramos, cementamos la ejecución de cualquier script excepto index.php, e incluso en el nivel de configuración nginx, al que de ninguna manera se puede acceder. Pero en otro lugar, el hacker malvado tuvo la oportunidad de poner un archivo arbitrario en la carpeta de caché. Que va a pasar Así es: para ejecutar código extraño, generando un hash en la solicitud de obtención, lleva dos minutos. Es decir, al final resulta que está un poco cerrado, pero no está completamente.
Bueno, las pequeñas cosas: cómo brillaban esas relaciones tan hermosas en los archivos de idioma:
if ((isset($_SERVER['HTTPS']) && (strtolower($_SERVER['HTTPS']) == 'on' || $_SERVER['HTTPS'] == '1')) || (!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && (strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) == 'https') || (!empty($_SERVER['HTTP_X_FORWARDED_SSL']) && strtolower($_SERVER['HTTP_X_FORWARDED_SSL']) == 'on'))) { $_['value_revres'] = HTTPS_SERVER; $_['value_ctlg'] = HTTPS_CATALOG; } else { $_['value_revres'] = HTTP_SERVER; $_['value_ctlg'] = HTTP_CATALOG; }
Y brillan ... Desea conocer el camino completo a la raíz del proyecto. Simplemente encuentre la tienda con la pantalla de error activada y ejecute el enlace directamente al archivo de idioma.
Para estudiar qué más puede ser después de actualizar el complemento en megabytes de líneas de código del autor, no hay recursos ni deseo. Hay personas responsables especialmente capacitadas para esto.
Y la guinda del pastel. Recordamos que tenemos un complemento comercial ... Y en un complemento comercial tenemos texto oculto en el recurso del autor:
www.google.com/search?q=%22Powered+by+SEO+CMS%22
Curiosamente, ¿al menos uno de los compradores de complementos conoce un huevo de pascua tan "maravilloso"?
Hoy, el suplemento se vende y se vende. Las publicaciones con llamadas para prestar atención a la situación simplemente se eliminan. Ninguno de los compradores recibió notificaciones de advertencia sobre el segundo incidente. Quizás el 20-30% de los usuarios de complementos han actualizado, pero el 70%, incluso si hablamos de las estadísticas del autor oficial sobre el uso de complementos, se trata de 7000 tiendas (de hecho, más, ya que nadie sabe con seguridad cuántas copias instalaron los freelancers en las tiendas de los clientes). licencia extendida) están en una gran zona de riesgo.
En palabras del barón Munchausen, solo quiero decir una cosa: ¡Caballeros actualizados!
Para los clientes
Qué hacer, los que terminaron en este submarino que se hunde:
- No deje basura en ftp. Ver info.php, adminer.php y toda la otra basura. Solo debes tener index.php y un punto.
- Cambie regularmente las contraseñas, todas las contraseñas (ftp, panel de administración, base de datos). Y asegúrese de no tener accidentalmente cuentas extra extrañas.
- Desactivar salida de error. Siempre, si no trabaja, apague la salida de error en el nivel de configuración del intérprete y no en la configuración de la tienda.
- Sí, sé que esto no es muy factible, pero al menos debe mantenerse actualizado con las actualizaciones del código del motor relacionadas con la seguridad e, idealmente, actualizar regularmente el motor a versiones estables.
- Mire regularmente los registros de visitas, puede haber muchas cosas interesantes. Rastrea anomalías.
- Cierre adicionalmente con una contraseña o restricción en el administrador de IP de la tienda y varias secciones vulnerables, como phpmyadmin. Si este es un intercambio en el que phpmyadmin es común para todos, ¡huya de ese alojamiento!
- Si usa sxd y utilidades similares, cambie el nombre de inmediato a un conjunto de caracteres aleatorio.
- Al usar nginx, vale la pena agregar reglas a la configuración del host virtual que prohíban ejecutar cualquier script php que no sea index.php en las secciones raíz y de administración del sitio.
- No tires basura de tu cuenta. Si tienes una tienda, deja que sea una tienda. No cargue bajo una cuenta un montón de wp-blogs, un montón de errores y varios dominios de prueba.
- Nunca almacene copias de seguridad de un sitio o base de datos en la raíz de su host virtual.
- Observe la carga en el servidor / alojamiento, intente mantener el suministro al menos x2 de las cargas máximas, y si de repente la carga aumenta repentinamente sin razón, intente averiguar la razón. ¡Es mejor adelantar que no adelantar!