{"id":767,"date":"2020-08-20T18:09:19","date_gmt":"2020-08-20T16:09:19","guid":{"rendered":"https:\/\/www.pinguytaz.net\/?p=767"},"modified":"2020-08-20T18:09:21","modified_gmt":"2020-08-20T16:09:21","slug":"ld_preload-vector-de-ataque","status":"publish","type":"post","link":"https:\/\/www.pinguytaz.net\/index.php\/2020\/08\/20\/ld_preload-vector-de-ataque\/","title":{"rendered":"LD_PRELOAD (Vector de ataque)"},"content":{"rendered":"\n<p>Las librerias compartidas (shared libraries) se cargan en tiempo de ejecuci\u00f3n, logrando binarios m\u00e1s peque\u00f1os, pero esto puede darnos peque\u00f1os sustos. Las maneras en que se buscan y cargas las librer\u00edas tenemos:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>LD_PRELOAD<\/strong>: Objetos compartidos que se cargaran antes de cualquier libreria.<\/li><li><strong>LD_LIBRARY_PATH<\/strong>:  Camino a los directorios de librerias.<\/li><li><strong>\/etc\/ld.so.conf<\/strong> <\/li><\/ul>\n\n\n\n<p>Hoy hablaremos de LD_PRELOAD, tanto como funciona y como nos puede afectar en nuestra seguridad como por ejemplo el c\u00f3modo y a veces temido <a href=\"https:\/\/www.pinguytaz.net\/index.php\/2019\/08\/17\/sudo-administra-sin-ser-root\/\">sudo<\/a> cuando no tenemos una configuraci\u00f3n correcta.<\/p>\n\n\n\n<p>Lo primero sera ver como funciona LD_PRELOAD, para luego contar las cosas divertidas y problemas de seguridad con los que nos podemos encontrar.<\/p>\n\n\n\n<p>Al ejecutar un programa con librer\u00edas din\u00e1micas, no todo el c\u00f3digo esta en el ejecutable, para localizar las funciones que no se encuentran en el c\u00f3digo realiza los siguientes pasos:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li> El programa se carga en memoria.<\/li><li>El enlazador dinamico determina las bibliotecas (.so) necesarias y las carga en memoria<\/li><li>Si esta definida la variable <strong>LD_PRELOAD<\/strong> le indica que esta biblioteca es la primera donde deber\u00e1 buscar primero.<\/li><\/ol>\n\n\n\n<p>Esto que nos puede ser muy \u00fatil si estamos redise\u00f1ando una librer\u00eday queremos probar una nueva versi\u00f3n sin instalarla definitivamente,  puede ser un problema de seguridad como veremos. Y como lo mejor es con un ejemplo.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Como funciona LD_PRELOAD<\/h2>\n\n\n\n<p>Primero crearemos nuestro programa simple que nos dice la hora y un n\u00famero aleatorio<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.pinguytaz.net\/wp-content\/uploads\/2020\/08\/image.png\" alt=\"\" class=\"wp-image-771\" width=\"396\" height=\"280\" srcset=\"https:\/\/www.pinguytaz.net\/wp-content\/uploads\/2020\/08\/image.png 536w, https:\/\/www.pinguytaz.net\/wp-content\/uploads\/2020\/08\/image-300x212.png 300w, https:\/\/www.pinguytaz.net\/wp-content\/uploads\/2020\/08\/image-120x85.png 120w\" sizes=\"auto, (max-width: 396px) 100vw, 396px\" \/><\/figure><\/div>\n\n\n\n<p>y lo compilamos simplemente<\/p>\n\n\n\n<p class=\"has-text-align-center\"><strong>gcc ej1.c -o ej1.bin<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"405\" height=\"37\" src=\"https:\/\/www.pinguytaz.net\/wp-content\/uploads\/2020\/08\/image-1.png\" alt=\"\" class=\"wp-image-772\" srcset=\"https:\/\/www.pinguytaz.net\/wp-content\/uploads\/2020\/08\/image-1.png 405w, https:\/\/www.pinguytaz.net\/wp-content\/uploads\/2020\/08\/image-1-300x27.png 300w\" sizes=\"auto, (max-width: 405px) 100vw, 405px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.pinguytaz.net\/wp-content\/uploads\/2020\/08\/image-3.png\" alt=\"\" class=\"wp-image-774\" width=\"402\" height=\"145\" srcset=\"https:\/\/www.pinguytaz.net\/wp-content\/uploads\/2020\/08\/image-3.png 402w, https:\/\/www.pinguytaz.net\/wp-content\/uploads\/2020\/08\/image-3-300x108.png 300w\" sizes=\"auto, (max-width: 402px) 100vw, 402px\" \/><\/figure><\/div>\n\n\n\n<p class=\"has-text-align-left\">Tambi\u00e9n crearemos una librer\u00eda, con la funci\u00f3n rand, que modificaremos y llamaremos \u00absinrand.c\u00bb y la libreria \u00absinrand.so\u00bb.<\/p>\n\n\n\n<p class=\"has-text-align-center\"><strong>gcc -shared -fPIC sinrand.c -o sinrand.so<\/strong><\/p>\n\n\n\n<p>Y podremos comprobar las diferencias de ejecuci\u00f3n sin cargar este objeto antes de las librer\u00edas (LD_PRELOAD) ya sea solo para esta ejecuci\u00f3n o si lo fijamos para todas como se puede ver en la figura.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignright size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.pinguytaz.net\/wp-content\/uploads\/2020\/08\/image-4.png\" alt=\"\" class=\"wp-image-776\" width=\"510\" height=\"134\" srcset=\"https:\/\/www.pinguytaz.net\/wp-content\/uploads\/2020\/08\/image-4.png 625w, https:\/\/www.pinguytaz.net\/wp-content\/uploads\/2020\/08\/image-4-300x79.png 300w\" sizes=\"auto, (max-width: 510px) 100vw, 510px\" \/><\/figure><\/div>\n\n\n\n<p>Podemos ver dos formas de cargar el objeto generado \u00absinrand.so\u00bb, uno anteponiendo la variable LD_PRELOAD y otra dej\u00e1ndola fija. Ojo eliminarla despu\u00e9s de las pruebas para evitar errores en otros programas (ya vemos el problema de precargar funciones estandard modificadas.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignright size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.pinguytaz.net\/wp-content\/uploads\/2020\/08\/image-5.png\" alt=\"\" class=\"wp-image-777\" width=\"525\" height=\"150\" srcset=\"https:\/\/www.pinguytaz.net\/wp-content\/uploads\/2020\/08\/image-5.png 535w, https:\/\/www.pinguytaz.net\/wp-content\/uploads\/2020\/08\/image-5-300x86.png 300w\" sizes=\"auto, (max-width: 525px) 100vw, 525px\" \/><\/figure><\/div>\n\n\n\n<p>Tambi\u00e9n podr\u00edamos analizar las librer\u00edas cargadas con el comando \u00abldd\u00bb, viendo que se a\u00f1ade .\/sinrand.so delante de todas. El primer objeto \u00ab<a href=\"https:\/\/man7.org\/linux\/man-pages\/man7\/vdso.7.html\">linux-vdso.<\/a>\u00bb es un obejto virtual perteneciente al kernel.<\/p>\n\n\n\n<p>Podemos listar los simbolos con la instrucci\u00f3n \u00ab<strong>nm<\/strong>\u00bb tanto de las librer\u00edas que carga el programa <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>nm -D \/lib\/x86_64-linux-gnu\/libc.so.6<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Trabajando con LD_PRELOAD<\/h2>\n\n\n\n<p>Ya hemos visto como funciona <strong>LD_PRELOAD<\/strong> y ha llegado el momento de ver que cosas podemos hacer. Se ha visto que es muy sencillo modificar el funcionamiento de una funci\u00f3n, pero si lo que deseamos es interceptarla para analizar algo y que luego se ejecute de forma normal.<\/p>\n\n\n\n<p>Lo que parecer\u00eda tan simple como ejecutar la funci\u00f3n, como nos podemos imaginar no valdr\u00eda, ya que entrar\u00edamos en una recursividad infinita. Para esto debemos realizar unos peque\u00f1os cambios en nuestro c\u00f3digo anterior.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.pinguytaz.net\/wp-content\/uploads\/2020\/08\/image-6.png\" alt=\"\" class=\"wp-image-780\" width=\"451\" height=\"279\" srcset=\"https:\/\/www.pinguytaz.net\/wp-content\/uploads\/2020\/08\/image-6.png 610w, https:\/\/www.pinguytaz.net\/wp-content\/uploads\/2020\/08\/image-6-300x185.png 300w\" sizes=\"auto, (max-width: 451px) 100vw, 451px\" \/><\/figure><\/div>\n\n\n\n<p>A\u00f1adimos la directiva _GNU_SOURCE y se incluye \u00abdlfcn.h\u00bb.<\/p>\n\n\n\n<p>Definimos, con typedef, el alias a la funci\u00f3n puntero de rand original.<\/p>\n\n\n\n<p>Se recoge el puntero a la funci\u00f3n original con \u00abdlsym(RTLD_NEXT,&lt;funcion&gt;)\u00bb y se llama al rand original con el puntero. compilar con libreria dl (<strong>-ldl<\/strong>)<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignright size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.pinguytaz.net\/wp-content\/uploads\/2020\/08\/image-7.png\" alt=\"\" class=\"wp-image-781\" width=\"406\" height=\"40\" srcset=\"https:\/\/www.pinguytaz.net\/wp-content\/uploads\/2020\/08\/image-7.png 618w, https:\/\/www.pinguytaz.net\/wp-content\/uploads\/2020\/08\/image-7-300x30.png 300w\" sizes=\"auto, (max-width: 406px) 100vw, 406px\" \/><\/figure><\/div>\n\n\n\n<p><strong>gcc -shared -fPIC intercepta_rand.c -o intercepta_rand.so -ldl<\/strong><\/p>\n\n\n\n<p>Esto ha sido un ejemplo sencillo con una funci\u00f3n simple sin par\u00e1metros. Si us\u00e1ramos una funci\u00f3n m\u00e1s compleja, como <em>printf<\/em> por ejemplo,  con par\u00e1metros tampoco se complicar\u00eda ya que lo \u00fanico que se cambiar\u00eda es el prototipo de la funci\u00f3n puntero y se a\u00f1adir\u00edan los par\u00e1metros como podemos ver en el ejemplo en el que se realiza una captura de  s<em>printf<\/em> pero a\u00f1adiendo a la cadena a devolver \u00ab***Interceptado***&lt;texto original&gt;***FIN***2020\u00bb.<\/p>\n\n\n\n<p>Lo primero es conocer la definici\u00f3n exacta de la funci\u00f3n sprinf, para as\u00ed crear el prototipo.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int sprintf (char *cadena, const char *formato, ...)\nEl prototipo seria typedef int(*original)(char *cadena, const char *formato, ...);<\/code><\/pre>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.pinguytaz.net\/wp-content\/uploads\/2020\/08\/image-8.png\" alt=\"\" class=\"wp-image-782\" width=\"488\" height=\"370\" srcset=\"https:\/\/www.pinguytaz.net\/wp-content\/uploads\/2020\/08\/image-8.png 622w, https:\/\/www.pinguytaz.net\/wp-content\/uploads\/2020\/08\/image-8-300x228.png 300w\" sizes=\"auto, (max-width: 488px) 100vw, 488px\" \/><\/figure><\/div>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.pinguytaz.net\/wp-content\/uploads\/2020\/08\/image-9.png\" alt=\"\" class=\"wp-image-783\" width=\"371\" height=\"72\" srcset=\"https:\/\/www.pinguytaz.net\/wp-content\/uploads\/2020\/08\/image-9.png 666w, https:\/\/www.pinguytaz.net\/wp-content\/uploads\/2020\/08\/image-9-300x58.png 300w\" sizes=\"auto, (max-width: 371px) 100vw, 371px\" \/><\/figure>\n\n\n\n<p>Con esto podemos ver  que lo que podemos hacer con <strong>LD_PRELOAD<\/strong>,  dependera de nuestra imaginaci\u00f3n: capturas para depuraci\u00f3n y an\u00e1lisis de c\u00f3digo,  interceptar datos(imagina si se define un nuevo fopen) ya sea para espiar o modificar, solucionar errores mientras el desarrollador crea una versi\u00f3n nueva, etc.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Alertas de seguridad con LD_PRELOAD<\/h2>\n\n\n\n<p>Ya hemos podido ver que se pueden realizar muchas cosas, ahora trataremos el tema de la seguridad para evitarnos problemas.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">sudo<\/h2>\n\n\n\n<p>\u00ab<a href=\"https:\/\/www.pinguytaz.net\/index.php\/2019\/08\/17\/sudo-administra-sin-ser-root\/\">sudo<\/a>\u00bb (<strong>S<\/strong>uper <strong>U<\/strong>ser <strong>Do<\/strong>) que es hacer de super usuario, o lo que es lo mismo, permitir\u00e1 ejecutar dicho comando como root sin cambiar su usuario. Linux confirmar\u00e1 si ese usuario en particular est\u00e1 en el archivo \u00ab<em>sudoers<\/em>\u00bb para saber si puede ejecutar o no.  No solo verifica el usuario sino tambi\u00e9n si puede ejecutar ese programa o no y si hereda variables de entorno.<\/p>\n\n\n\n<p>En el caso que hoy nos aplica de la variable \u00abLD_PRELOAD\u00bb, ya que las escaladas con \u00ab<a href=\"https:\/\/www.pinguytaz.net\/index.php\/2019\/08\/17\/sudo-administra-sin-ser-root\/\">sudo<\/a>\u00bb son muchas, la variable de configuraci\u00f3n de \u00ab<em>sudoers<\/em>\u00bb que debemos tener en cuenta es \u00abDefaults env_keep+=LD_PRELOAD\u00bb. Si tenemos esta opci\u00f3n habilitada la probabilidad de un ataque de escalada de privilegios esta muy garantizada, tengamos en cuenta que una ejecuci\u00f3n con sudo nos lleva a ataques similares a los de <a href=\"https:\/\/www.pinguytaz.net\/index.php\/2018\/06\/23\/escalar-privilegios-a-root-error-suid-3-3\/\">SUID<\/a>.<\/p>\n\n\n\n<p>Lo que deberemos realizar es comentar esta linea, para evitar que un usuario ejecutando \u00ab<a href=\"https:\/\/www.pinguytaz.net\/index.php\/2019\/08\/17\/sudo-administra-sin-ser-root\/\">sudo<\/a>\u00bb pueda usar la variable \u00abLD_PRELOAD\u00bb. En realizad y saliendo un poco del tema del que estamos hablando, el consejo es que se limite al m\u00e1ximo el uso en \u00ab<a href=\"https:\/\/www.pinguytaz.net\/index.php\/2019\/08\/17\/sudo-administra-sin-ser-root\/\">sudo<\/a>\u00bb por ejemplo no \u00abALL=(ALL:ALL) ALL\u00bb evitarlo y definir solo esos programas que realmente usamos muy continuamente con necesidad de root ya que de esta forma evitaremos que un simple \u00abperl\u00bb con permiso de sudo nos permitir tener un shell con los permisos de super usuario, que siempre nos pida la clave(ojo a la palabra clave NOPASSWD) as\u00ed de esta forma si se obtiene acceso al usuario sin conocimiento de la clave no se podr\u00e1 usar \u00absudo\u00bb. Es una cuesti\u00f3n de poner las m\u00e1ximas barreras y que nos permitan claro un uso amigable de nuestro sistema, en nosotros esta esa balanza,  en mi caso para un servidor publico (no mi Desktop) eliminar\u00eda el \u00ab<a href=\"https:\/\/www.pinguytaz.net\/index.php\/2019\/08\/17\/sudo-administra-sin-ser-root\/\">sudo<\/a>\u00ab.<\/p>\n\n\n\n<p>Con esto terminamos con SUDO, que dar\u00eda para otra entrada dedicada solo a sus seguridad.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Sustituci\u00f3n de librer\u00edas<\/h2>\n\n\n\n<p>Si conocemos llamadas, que est\u00e1n en librer\u00edas din\u00e1micas del ejecutable, podremos crear una librer\u00eda con esa llamada y luego cargar la nuestra con LD_PRELOAD. Por eso lo mejor en programa ya en uso es quitar informaci\u00f3n de depuraci\u00f3n para que se conozca lo m\u00ednimo de el. Ya vimos en el principio de la explicaci\u00f3n de las librer\u00edas como capturar funciones y que ademas luego se ejecutase la original de forma que no solo podemos escalar privilegios, sino que podemos dejar un esp\u00eda en un ejecutable totalmente inocente y sin necesidad de tocarlo.<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Las librerias compartidas (shared libraries) se cargan en tiempo de ejecuci\u00f3n, logrando binarios m\u00e1s peque\u00f1os, pero esto puede darnos peque\u00f1os sustos. Las maneras en que se buscan y cargas las librer\u00edas tenemos: LD_PRELOAD: Objetos compartidos que se cargaran antes de cualquier libreria. LD_LIBRARY_PATH: Camino a los directorios de librerias. \/etc\/ld.so.conf Hoy hablaremos de LD_PRELOAD, tanto [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":792,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"site-container-style":"default","site-container-layout":"default","site-sidebar-layout":"default","disable-article-header":"default","disable-site-header":"default","disable-site-footer":"default","disable-content-area-spacing":"default","footnotes":""},"categories":[19,16],"tags":[144,143,145,146,92],"class_list":["post-767","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-escalar-privilegios","category-seguridad","tag-gcc","tag-ld_preload","tag-ldd","tag-nm","tag-sudo"],"_links":{"self":[{"href":"https:\/\/www.pinguytaz.net\/index.php\/wp-json\/wp\/v2\/posts\/767","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.pinguytaz.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.pinguytaz.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.pinguytaz.net\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pinguytaz.net\/index.php\/wp-json\/wp\/v2\/comments?post=767"}],"version-history":[{"count":13,"href":"https:\/\/www.pinguytaz.net\/index.php\/wp-json\/wp\/v2\/posts\/767\/revisions"}],"predecessor-version":[{"id":791,"href":"https:\/\/www.pinguytaz.net\/index.php\/wp-json\/wp\/v2\/posts\/767\/revisions\/791"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.pinguytaz.net\/index.php\/wp-json\/wp\/v2\/media\/792"}],"wp:attachment":[{"href":"https:\/\/www.pinguytaz.net\/index.php\/wp-json\/wp\/v2\/media?parent=767"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pinguytaz.net\/index.php\/wp-json\/wp\/v2\/categories?post=767"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pinguytaz.net\/index.php\/wp-json\/wp\/v2\/tags?post=767"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}