{"id":82,"date":"2017-12-03T19:07:57","date_gmt":"2017-12-04T00:07:57","guid":{"rendered":"http:\/\/blogs.gentoo.org\/chrisadr\/?p=82"},"modified":"2019-11-01T03:35:27","modified_gmt":"2019-11-01T08:35:27","slug":"un-vistazo-a-la-explotacion-de-vulnerabilidades","status":"publish","type":"post","link":"https:\/\/blogs.gentoo.org\/chrisadr\/2017\/12\/03\/un-vistazo-a-la-explotacion-de-vulnerabilidades\/","title":{"rendered":"Un vistazo a la explotaci\u00f3n de vulnerabilidades"},"content":{"rendered":"<p>Como me qued\u00e9 con ganas de seguir tratando de este tema, perm\u00edtanme contarles un poco de historia, teor\u00eda y pr\u00e1ctica sobre las vulnerabilidaes. Todos hemos o\u00eddo a estas alturas que\u00a0 los fallos de seguridad pueden costar mucho, todos sabemos que debemos mantener nuestro software actualizado, todos sabemos que muchas actualizaciones se producen por errores de seguridad. Pero hoy les contar\u00e9 un poco sobre c\u00f3mo es que se encuentran y se explotan dichos errores :) Pero antes de esto vamos a aclarar unos cuantos detalles para poder tener un mejor panorama.<\/p>\n<h3>Antes de empezar<\/h3>\n<p>Primero quiero decirles que nos vamos a centrar en la primer vulnerabilidad que aprend\u00ed a explotar, los conocidos <em>Buffer\u00a0Overflows<\/em>, en esta vulnerabilidad aprovechamos una falta de verificaci\u00f3n en la memoria para hacer cosas divertidas :) Pero vamos a aclarar un poco m\u00e1s al respecto.<\/p>\n<h4>Esto no va a ser un escenario del mundo real<\/h4>\n<p>No puedo darme el lujo de ense\u00f1arles a romper cualquier programa que vean :) primero porque es peligroso para sus computadoras, segundo porque eso me tomar\u00eda m\u00e1s de mi acostumbrada cuota de palabras.<\/p>\n<h4>Nos vamos de viaje a los 80s<\/h4>\n<p>Esto que les voy a mostrar lo puedo hacer en mi laptop, pero no quiere decir que se pueda realizar hoy por hoy de manera sencilla :) muchos de estos conceptos ya han sido explotados tantas veces que han surgido nuevos m\u00e9todos de protecci\u00f3n y nuevos m\u00e9todos para evadirlos :P pero eso nos regresa al mismo lugar, falta espacio para poder contar todo eso :)<\/p>\n<h4>Tal vez no funcione en tu procesador<\/h4>\n<p>Aunque voy a usar un ejemplo muy simple, quiero que desde el principio quede bastante claro que los pormenores de esto son tantos y tan variados que as\u00ed como puede salirte igual que a m\u00ed, si deseas intentarlo, tambi\u00e9n puede que no se consiga el efecto deseado :) Pero ya se imaginar\u00e1n que eso no puedo explicarlo en este espacio, sobre todo porque con esta introducci\u00f3n ya me llev\u00e9 m\u00e1s de 300 palabras, as\u00ed que directo a lo nuestro.<\/p>\n<h3>Qu\u00e9 es un <em>Buffer Overflow<\/em><\/h3>\n<p>Para responder esto primero tenemos que comprender la primera mitad de esta combinaci\u00f3n.<\/p>\n<h4>Buffers<\/h4>\n<p>Como todo se trata de memoria en un equipo computacional, es l\u00f3gico que debe existir alg\u00fan tipo de contenedor de informaci\u00f3n. Cuando hablamos de\u00a0<strong>inputs\u00a0<\/strong>o\u00a0<strong>outputs<\/strong>, llegamos directamente al concepto de\u00a0<strong>buffers<\/strong>. Para hacerlo corto, un\u00a0<strong>buffer<\/strong> es un espacio de memoria de tama\u00f1o definido en el que vamos a almacenar una cantidad de informaci\u00f3n, simple :)<\/p>\n<p>Los overflow ocurren, como su nombre lo indica, cuando un buffer se llena con m\u00e1s informaci\u00f3n de la que puede aguantar. Pero, \u00bfpor qu\u00e9 es esto importante?<\/p>\n<h3>Stack<\/h3>\n<p>Tambi\u00e9n conocido como pilas, son un tipo de datos abstracto en el que podemos <strong>apilar\u00a0<\/strong>informaci\u00f3n, su principal caracter\u00edstica es que cuentan con un ordenamiento <strong>LIFO (Last In First Out)<\/strong>. Pensemos por un segundo en una pila de platos, nosotros los ponemos por encima uno a uno, y luego los sacamos uno a uno desde arriba, esto hace que el \u00faltimo plato que hayamos puesto (el que se encuentra hasta arriba) sea el primer plato que vamos a sacar, evidentemente si solo podemos sacar un plato a la vez y decidimos hacerlo en ese orden :P.<\/p>\n<p>Ahora que ya conocen estos dos conceptos, tenemos que ordenarlos. Las pilas son importantes porque cada programa que ejecutamos tiene su propia <strong>pila de ejecuci\u00f3n<\/strong>. Pero esta pila tiene una <em>caracter\u00edstica particular<\/em>,\u00a0<strong>crece hacia abajo<\/strong>. Lo \u00fanico que deben saber de esto es que mientras un programa se ejecuta, cuando una funci\u00f3n es llamada, la pila pasa de un n\u00famero X de memoria a un n\u00famero (X-n). Pero para poder seguir debemos comprender un concepto m\u00e1s.<\/p>\n<h3>Punteros<\/h3>\n<p>Este es un concepto que vuelve loco a muchos programadores cuando empiezan en el mundo de C, a decir verdad la gran potencia de la programaci\u00f3n en C se debe en parte al uso de punteros. Para hacerlo simple, un puntero\u00a0<strong>apunta a una direcci\u00f3n de memoria.<\/strong> Esto suena complejo, pero no lo es tanto, todos tenemos RAM en nuestras m\u00e1quinas \u00bfcierto? Pues esta puede definirse como un <strong>arreglo consecutivo de bloques<\/strong>, normalmente dichas ubicaciones se expresan en n\u00fameros hexadecimales ( del 0 a 9 y luego de eso de A a F, como por ejemplo 0x0, 0x1, 0x6, 0xA, 0xF, 0x10). Aqu\u00ed como nota curiosa, 0x10 <strong>NO\u00a0<\/strong>es igual a 10 :P si lo convertimos al orden decimal ser\u00eda lo mismo que decir 15. Esto es algo que tambi\u00e9n confunde a m\u00e1s de uno al principio, pero vamos a lo nuestro.<\/p>\n<h3>Registros<\/h3>\n<p>Los procesadores trabajan con una serie de <strong>registros<\/strong>, los cuales funcionan para transmitir ubicacioines desde la memoria f\u00edsica al procesador, para arquitecturas que usan 64-bits, la cantidad de registros es grande y dif\u00edcil de describir aqu\u00ed, pero para hacernos a la idea, los registros son como punteros, indican entre otras cosas, un espacio en memoria (ubicaci\u00f3n).<\/p>\n<h3>Ahora la pr\u00e1ctica<\/h3>\n<p>S\u00e9 que ha sido mucha informaci\u00f3n para procesar hasta ahora, pero en realidad son temas algo complejos que intento explicar de manera muy simple, vamos a ver un peque\u00f1o programa que usa buffers y lo vamos a romper para entender esto de los overflows, evidentemente este no es un programa real, y vamos a &#8220;evadir&#8221; muchas de las contramedidas que se usan hoy en d\u00eda, solo para mostrar c\u00f3mo se hac\u00edan las cosas antes :) y porque algunos de estos principios son necesarios para poder aprender cosas m\u00e1s complejas ;)<\/p>\n<h3>GDB<\/h3>\n<p>Un gran programa que es sin duda uno de los m\u00e1s usados por programadores en\u00a0 C. Entre sus m\u00faltiples virtudes tenemos el hecho de que nos permite ver todo esto que hemos estado conversando hasta ahora, registros, la pila, buffers, etc :) Vamos a ver el programa que vamos a usar para nuestro ejemplo.<\/p>\n<h4>retinput.c<\/h4>\n<figure id=\"attachment_77851\" aria-describedby=\"caption-attachment-77851\" style=\"width: 357px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"size-full wp-image-77851\" src=\"https:\/\/blog.desdelinux.net\/wp-content\/uploads\/2017\/12\/Captura-de-pantalla-de-2017-12-03-17-25-45.png\" alt=\"\" width=\"357\" height=\"337\" \/><figcaption id=\"caption-attachment-77851\" class=\"wp-caption-text\">Dise\u00f1o propio. Christopher D\u00edaz Riveros<\/figcaption><\/figure>\n<p>Este es un programa bastante simple, vamos a usar la librer\u00eda <code>stdio.h<\/code>\u00a0para poder obtener informaci\u00f3n y mostrarla en un terminal. Podemos ver una funci\u00f3n llamada <code>return_input<\/code>\u00a0la cual genera un <strong>buffer\u00a0<\/strong>llamado\u00a0<em>array<\/em>, que tiene una longitud de 30 <strong>bytes\u00a0<\/strong>(el tipo de dato char es de 1 byte de largo).<\/p>\n<p>La funci\u00f3n <code>gets(array);<\/code>\u00a0solicita informaci\u00f3n por consola y la funci\u00f3n\u00a0<code>printf()<\/code>\u00a0devuelve el contenido de array y lo muestra en pantalla.<\/p>\n<p>Todo programa escrito en C comienza por la funci\u00f3n\u00a0<code>main()<\/code>, esta solo se va a encargar de llamar a return_input, ahora vamos a compilar el programa.<\/p>\n<figure id=\"attachment_77864\" aria-describedby=\"caption-attachment-77864\" style=\"width: 420px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"size-medium wp-image-77864\" src=\"https:\/\/blog.desdelinux.net\/wp-content\/uploads\/2017\/12\/Captura-de-pantalla-de-2017-12-03-18-24-26-420x81.png\" alt=\"\" width=\"420\" height=\"81\" \/><figcaption id=\"caption-attachment-77864\" class=\"wp-caption-text\">Dise\u00f1o propio. Christopher D\u00edaz Riveros<\/figcaption><\/figure>\n<p>Vamos a desprender un poco de lo que acabo de hacer. La opci\u00f3n\u00a0<code>-ggdb<\/code>\u00a0le indica a gcc que tiene que compilar el programa con informaci\u00f3n para que gdb sea capaz de realizar un debug adecuado.\u00a0<code>-fno-stack-protector<\/code>\u00a0es una opci\u00f3n que evidentemente no deber\u00edamos estar usando, pero que vamos a usar porque en caso contrario nos ser\u00eda posible genererar el buffer overflow en el stack. Al final he probado el resultado.\u00a0<code>.\/a.out<\/code>\u00a0solo ejecuta lo que acabo de compilar, me pide informaci\u00f3n y la devuele. Funcionando :)<\/p>\n<h4>Advertencias<\/h4>\n<p>Otra nota aqu\u00ed. \u00bfPueden ver las advertencias? claramente es algo a tener en cuenta cuando trabajamos con c\u00f3digo o compilamos, esta es un poco obvia y son pocos los programas que hoy en d\u00eda tienen la funci\u00f3n\u00a0<code>gets()<\/code>\u00a0en el c\u00f3digo. Una ventaja de Gentoo es que al compilar cada programa, puedo ver lo que puede estar mal, un programa &#8220;ideal&#8221; no deber\u00eda tenerlas, pero les sorprender\u00eda cu\u00e1ntos programas grandes tienen estas advertencias porque simplemente son MUY grandes y es dif\u00edcil mantener el rastro de las funciones peligrosas cuando son muchas advertencias al mismo tiempo. Ahora si sigamos<\/p>\n<h4>Depurando el programa<\/h4>\n<figure id=\"attachment_77853\" aria-describedby=\"caption-attachment-77853\" style=\"width: 420px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"size-medium wp-image-77853\" src=\"https:\/\/blog.desdelinux.net\/wp-content\/uploads\/2017\/12\/Captura-de-pantalla-de-2017-12-03-17-40-39-420x186.png\" alt=\"\" width=\"420\" height=\"186\" \/><figcaption id=\"caption-attachment-77853\" class=\"wp-caption-text\">Dise\u00f1o propio. Christopher D\u00edaz Riveros<\/figcaption><\/figure>\n<p>Ahora, esta parte puede ser un poco confusa, pero como ya he escrito bastante, no puedo darme el lujo de explicarlo todo, as\u00ed que perd\u00f3n si ven que voy muy r\u00e1pido :)<\/p>\n<h4>Desarmando el c\u00f3digo<\/h4>\n<p>Vamos a empezar viendo nuestro programa compilado en lenguaje m\u00e1quina.<\/p>\n<figure id=\"attachment_77866\" aria-describedby=\"caption-attachment-77866\" style=\"width: 420px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"size-medium wp-image-77866\" src=\"https:\/\/blog.desdelinux.net\/wp-content\/uploads\/2017\/12\/Captura-de-pantalla-de-2017-12-03-18-45-23-420x124.png\" alt=\"\" width=\"420\" height=\"124\" \/><figcaption id=\"caption-attachment-77866\" class=\"wp-caption-text\">Dise\u00f1o propio. Christopher D\u00edaz Riveros<\/figcaption><\/figure>\n<p>Este es el c\u00f3digo de nuestra funci\u00f3n main en <strong>Assembly<\/strong>, esto es lo que entiende nuestro procesador, la l\u00ednea de la izquierda es la direcci\u00f3n f\u00edsica en memoria, el <em>&lt;+n&gt;\u00a0<\/em>se conoce como\u00a0<strong>offset<\/strong>, b\u00e1sicamente la distancia desde el principio de la funci\u00f3n (main) hasta esa instrucci\u00f3n (conocido como\u00a0<strong>opcode<\/strong>). Luego vemos el tipo de instrucci\u00f3n (push\/mov\/callq&#8230;) y uno o m\u00e1s registros. Resumido podemos decir que es la indicaci\u00f3n seguida de la fuente\/origen y el destino. <code>&lt;return_input&gt;<\/code>\u00a0hace referencia a nuestra segunda funci\u00f3n, vamos a darle un vistazo.<\/p>\n<h4>Return_input<\/h4>\n<figure id=\"attachment_77867\" aria-describedby=\"caption-attachment-77867\" style=\"width: 420px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"size-medium wp-image-77867\" src=\"https:\/\/blog.desdelinux.net\/wp-content\/uploads\/2017\/12\/Captura-de-pantalla-de-2017-12-03-18-46-25-420x218.png\" alt=\"\" width=\"420\" height=\"218\" \/><figcaption id=\"caption-attachment-77867\" class=\"wp-caption-text\">Dise\u00f1o propio. Christopher D\u00edaz Riveros<\/figcaption><\/figure>\n<p>Esta es un poco m\u00e1s compleja, pero solo quiero que revisen un par de cosas, existe un label llamado\u00a0<code>&lt;gets@plt&gt;<\/code>\u00a0y un \u00faltimo opcode llamado <code>retq<\/code>\u00a0que indica el final de la funci\u00f3n. Vamos a poner un par de breakpoints, uno en la funci\u00f3n <code>gets<\/code> y otro en el <code>retq<\/code>.<\/p>\n<figure id=\"attachment_77868\" aria-describedby=\"caption-attachment-77868\" style=\"width: 420px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"size-medium wp-image-77868\" src=\"https:\/\/blog.desdelinux.net\/wp-content\/uploads\/2017\/12\/Captura-de-pantalla-de-2017-12-03-18-47-26-420x83.png\" alt=\"\" width=\"420\" height=\"83\" \/><figcaption id=\"caption-attachment-77868\" class=\"wp-caption-text\">Dise\u00f1o propio. Christopher D\u00edaz Riveros<\/figcaption><\/figure>\n<h4>Run<\/h4>\n<p>Ahora vamos a correr el programa para ver c\u00f3mo empieza a comenzar la acci\u00f3n.<\/p>\n<figure id=\"attachment_77869\" aria-describedby=\"caption-attachment-77869\" style=\"width: 420px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"size-medium wp-image-77869\" src=\"https:\/\/blog.desdelinux.net\/wp-content\/uploads\/2017\/12\/Captura-de-pantalla-de-2017-12-03-18-48-28-420x274.png\" alt=\"\" width=\"420\" height=\"274\" \/><figcaption id=\"caption-attachment-77869\" class=\"wp-caption-text\">Dise\u00f1o propio. Christopher D\u00edaz Riveros<\/figcaption><\/figure>\n<p>Podemos ver que aparece una peque\u00f1a flecha que indica el opcode donde nos encontramos, quiero que tengan en cuenta la direcci\u00f3n <code>0x000055555555469b<\/code>, esta es la direcci\u00f3n que se encuentra tras la llamada a <code>return_input<\/code>\u00a0en la funci\u00f3n <code>main<\/code> , esto es importante puesto que ah\u00ed es donde deber\u00eda regresar el programa cuando acabe de recibir el <strong>input<\/strong>, vamos a entrar en la funci\u00f3n. Ahora vamos a revisar la memoria antes de entrar a la funci\u00f3n\u00a0<code>gets<\/code>.<\/p>\n<figure id=\"attachment_77870\" aria-describedby=\"caption-attachment-77870\" style=\"width: 420px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"size-medium wp-image-77870\" src=\"https:\/\/blog.desdelinux.net\/wp-content\/uploads\/2017\/12\/Captura-de-pantalla-de-2017-12-03-18-51-50-420x184.png\" alt=\"\" width=\"420\" height=\"184\" \/><figcaption id=\"caption-attachment-77870\" class=\"wp-caption-text\">Dise\u00f1o propio. Christopher D\u00edaz Riveros<\/figcaption><\/figure>\n<p>Les he vuelto a poner la funci\u00f3n main arriba, y he resaltado el c\u00f3digo al que me refer\u00eda, como pueden ver, debido al <strong>endianess\u00a0<\/strong>se ha separado en dos segmentos, quiero que tengan en cuenta la direcci\u00f3n\u00a0<code>0x7fffffffdbf0<\/code>\u00a0(la primera de la izquierda tras el commando <code>x\/20x $rsp<\/code>) puesto que esta es la ubicaci\u00f3n que tenemos que usar para revisar el resultado de gets, sigamos:<\/p>\n<h4>Rompiendo el programa<\/h4>\n<figure id=\"attachment_77871\" aria-describedby=\"caption-attachment-77871\" style=\"width: 420px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"size-medium wp-image-77871\" src=\"https:\/\/blog.desdelinux.net\/wp-content\/uploads\/2017\/12\/Captura-de-pantalla-de-2017-12-03-18-53-27-420x160.png\" alt=\"\" width=\"420\" height=\"160\" \/><figcaption id=\"caption-attachment-77871\" class=\"wp-caption-text\">Dise\u00f1o propio. Christopher D\u00edaz Riveros<\/figcaption><\/figure>\n<p>He resaltado esos <code>0x44444444<\/code>porque son la representaci\u00f3n de nuestras Ds :) ahora hemos empezado a agregar\u00a0<strong>input<\/strong> al programa, y como pueden apreciar, estamos a solo dos l\u00edneas de nuestra direcci\u00f3n deseada, vamos a llenarlo hasta estar justo antes de las direcciones que resaltamos en el paso anterior.<\/p>\n<h4>Cambiando la ruta de retorno<\/h4>\n<p>Ahora que hemos logrado entrar en esta secci\u00f3n del c\u00f3digo donde indica el retorno de la funci\u00f3n, vamos a ver qu\u00e9 sucede si cambiamos la direacci\u00f3n :) en lugar de ir a la ubicaci\u00f3n del opcode que sigue al que ten\u00edamos hace un momento, \u00bfqu\u00e9 les parece si regreamos a <code>return_input<\/code>? Pero para esto, es necesario escribir en binario la direacci\u00f3n que deseamos, vamos a hacerlo con la funci\u00f3n <code>printf<\/code>\u00a0de bash :)<\/p>\n<figure id=\"attachment_77865\" aria-describedby=\"caption-attachment-77865\" style=\"width: 420px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"size-medium wp-image-77865\" src=\"https:\/\/blog.desdelinux.net\/wp-content\/uploads\/2017\/12\/Captura-de-pantalla-de-2017-12-03-18-39-15-420x27.png\" alt=\"\" width=\"420\" height=\"27\" \/><figcaption id=\"caption-attachment-77865\" class=\"wp-caption-text\">Dise\u00f1o propio. Christopher D\u00edaz Riveros<\/figcaption><\/figure>\n<p>Ahora hemos recibido dos veces la informaci\u00f3n :D seguramente el programa no estaba hecho para eso, pero hemos conseguido romper el c\u00f3digo y hacer que repita algo que no se supon\u00eda que haga.<\/p>\n<h3>Reflexiones<\/h3>\n<p>Este simple cambio puede considerarse un <em>exploit\u00a0<\/em>muy b\u00e1sico :) ha logrado romper el programa y hacer algo que nosotros deseamos que haga.<\/p>\n<p>Este es solo el primer paso en una casi infinita lista de cosas por ver y agregar, existen formas de agregar m\u00e1s cosas que simplemente repetir una orden, pero esta vez he escrito mucho y todo lo relacionado a\u00a0<em>shellcoding<\/em> es un tema para escribir m\u00e1s que art\u00edculos, libros completos dir\u00eda yo. Disculpen si no he podido ahondar un poco m\u00e1s en temas que me hubieran gustado, pero seguro ya habr\u00e1 oportunidad :) Saludos y gracias por llegar hasta aqu\u00ed.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Como me qued\u00e9 con ganas de seguir tratando de este tema, perm\u00edtanme contarles un poco de historia, teor\u00eda y pr\u00e1ctica sobre las vulnerabilidaes. Todos hemos o\u00eddo a estas alturas que\u00a0 los fallos de seguridad pueden costar mucho, todos sabemos que debemos mantener nuestro software actualizado, todos sabemos que muchas actualizaciones se producen por errores de &hellip; <a href=\"https:\/\/blogs.gentoo.org\/chrisadr\/2017\/12\/03\/un-vistazo-a-la-explotacion-de-vulnerabilidades\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Un vistazo a la explotaci\u00f3n de vulnerabilidades<\/span><\/a><\/p>\n","protected":false},"author":169,"featured_media":83,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[6],"tags":[3],"jetpack_featured_media_url":"https:\/\/blogs.gentoo.org\/chrisadr\/files\/2017\/12\/virus.jpg","_links":{"self":[{"href":"https:\/\/blogs.gentoo.org\/chrisadr\/wp-json\/wp\/v2\/posts\/82"}],"collection":[{"href":"https:\/\/blogs.gentoo.org\/chrisadr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.gentoo.org\/chrisadr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.gentoo.org\/chrisadr\/wp-json\/wp\/v2\/users\/169"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.gentoo.org\/chrisadr\/wp-json\/wp\/v2\/comments?post=82"}],"version-history":[{"count":1,"href":"https:\/\/blogs.gentoo.org\/chrisadr\/wp-json\/wp\/v2\/posts\/82\/revisions"}],"predecessor-version":[{"id":84,"href":"https:\/\/blogs.gentoo.org\/chrisadr\/wp-json\/wp\/v2\/posts\/82\/revisions\/84"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blogs.gentoo.org\/chrisadr\/wp-json\/wp\/v2\/media\/83"}],"wp:attachment":[{"href":"https:\/\/blogs.gentoo.org\/chrisadr\/wp-json\/wp\/v2\/media?parent=82"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.gentoo.org\/chrisadr\/wp-json\/wp\/v2\/categories?post=82"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.gentoo.org\/chrisadr\/wp-json\/wp\/v2\/tags?post=82"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}