Un cop d'ull a l'explotació de vulnerabilitats

Com em vaig quedar amb ganes de seguir tractant sobre aquest tema, permetin-me explicar una mica d'història, teoria i pràctica sobre les vulnerabilidaes. Tots hem sentit a hores d'ara que les fallades de seguretat poden costar molt, tots sabem que hem de mantenir el nostre programari actualitzat, tots sabem que moltes actualitzacions es produeixen per errors de seguretat. Però avui els explicaré una mica sobre com és que es troben i s'exploten aquests errors 🙂 Però abans d'això anem a aclarir uns quants detalls per poder tenir un millor panorama.

Abans de començar

Primer vull dir-los que ens centrarem en la primera vulnerabilitat que vaig aprendre a explotar, els coneguts buffer overflows, En aquesta vulnerabilitat vam aprofitar una falta de verificació en la memòria per fer coses divertides 🙂 Però anem a aclarir una mica més a l'respecte.

Això no serà un escenari de el món real

No puc donar-me el luxe de ensenyar-los a trencar qualsevol programa que vegin 🙂 primer perquè és perillós per als seus ordinadors, segon perquè això em prendria més de la meva acostumada quota de paraules.

Ens anem de viatge als 80s

Això que els vaig a mostrar el puc fer en el meu portàtil, però no vol dir que es pugui fer avui per avui de manera senzilla 🙂 molts d'aquests conceptes ja han estat explotats tantes vegades que han sorgit nous mètodes de protecció i nous mètodes per evadir 😛 però això ens torna a al mateix lloc, falta espai per poder explicar tot això 🙂

Potser no funcioni en el teu processador

Encara vaig a utilitzar un exemple molt simple, vull que des del principi quedi prou clar que els detalls d'això són tants i tan variats que així com pot sortir-te igual que a mi, si desitges intentar-ho, també pot ser que no s'aconsegueixi l'efecte desitjat 🙂 Però ja s'imaginaran que això no puc explicar-ho en aquest espai, sobretot perquè amb aquesta introducció ja em vaig endur més de 300 paraules, així que directe a la nostra.

Què és un buffer Overflow

Per respondre això primer hem de comprendre la primera meitat d'aquesta combinació.

Buffers

Com tot es tracta de memòria en un equip computacional, és lògic que hi ha d'haver algun tipus de contenidor d'informació. Quan parlem de entrades sortides, Arribem directament a l'concepte de tampons. Per fer-ho curt, XNUMX esmorteir és un espai de memòria de mida definit en el qual anem a emmagatzemar una quantitat d'informació, simple 🙂

Els overflow ocorren, com el seu nom indica, quan un buffer s'omple amb més informació de la que pot aguantar. Però, per què és això important?

Apilar

També conegut com piles, són un tipus de dades abstracte en el qual podem apilar informació, la seva principal característica és que compten amb un ordenament LIFO (Last In First Out). Pensem per un segon en una pila de plats, nosaltres els posem per sobre un a un, i després els traiem XNUMX-XNUMX des de dalt, això fa que l'últim plat que hàgim posat (el qual es troba fins a dalt) sigui el primer plat que traurem, evidentment si només podem treure un plat a la vegada i vam decidir fer-ho en aquest ordre: P.

Ara que ja coneixen aquests dos conceptes, hem de ordenar-los. Les piles són importants perquè cada programa que executem té la seva pròpia pila d'execució. Però aquesta pila té una característica particularcreix cap avall. L'única cosa que han de saber d'això és que mentre un programa s'executa, quan una funció és cridada, la pila passa d'un nombre X de memòria a un nombre (Xn). Però per poder seguir hem de comprendre un concepte més.

punters

Aquest és un concepte que torna boig a molts programadors quan comencen en el món de C, francament la gran potència de la programació en C es deu en part a l'ús de punters. Per fer-ho simple, un punter apunta a una adreça de memòria. Això sona complex, però no ho és tant, tots tenim RAM en les nostres màquines cert? Doncs aquesta pot definir com un arranjament consecutiu de blocs, Normalment aquestes ubicacions s'expressen en nombres hexadecimals (de el 0 a 9 i després d'això de A a F, com ara 0x0, 0x1, 0x6, 0XA, 0xF, 0x10). Aquí com a nota curiosa, 0x10 NO és igual a 10 😛 si ho convertim a l'ordre decimal seria el mateix que dir 15. Això és una cosa que també confon més d'un a del principi, però anem a la nostra.

Inscripció i registre al càmping

Els processadors treballen amb una sèrie de registres, Els quals funcionen per transmetre ubicacioines des de la memòria física a l'processador, per a arquitectures que fan servir 64-bits, la quantitat de registres és gran i difícil de descriure aquí, però per fer-nos a la idea, els registres són com punters, indiquen entre altres coses, un espai en memòria (ubicació).

Ara la pràctica

Sé que ha estat molta informació per processar fins ara, però en realitat són temes una mica complexos que intento explicar de manera molt simple, anem a veure un petit programa que fa servir buffers i ho anem a trencar per entendre això dels overflows, evidentment aquest no és un programa real, i anem a «evadir» moltes de les contramesures que es fan servir avui dia, només per mostrar com es feien les coses abans 🙂 i perquè alguns d'aquests principis són necessaris per poder aprendre coses més complexes 😉

BGF

Un gran programa que és sens dubte un dels més usats per programadors en C. Entre les seves múltiples virtuts tenim el fet que ens permet veure tot això que hem estat conversant fins ara, registres, la pila, buffers, etc 🙂 Anem a veure el programa que farem servir per al nostre exemple.

retinput.c

Disseny propi. Christopher Díaz Riveros

Aquest és un programa bastant simple, farem servir la llibreria stdio.h per poder obtenir informació i mostrar-la en un terminal. Podem veure una funció anomenada return_input la qual genera un esmorteir anomenat formació, Que té una longitud de 30 octets (El tipus de dada char és d'1 byte de llarg).

la funció gets(array); sol·licita informació per consola i la funció printf() retorna el contingut d'array i el mostra en pantalla.

Tot programa escrit en C comença per la funció main(), Aquesta només es va a encarregar de cridar a return_input, ara anem a compilar el programa.

Disseny propi. Christopher Díaz Riveros

Anem a desprendre una mica del que acabo de fer. l'opció -ggdb li indica a gcc que ha de compilar el programa amb informació perquè gdb sigui capaç de realitzar un debug adequat. -fno-stack-protector és una opció que evidentment no hauríem d'estar fent servir, però que farem servir perquè en cas contrari ens seria possible genererar el buffer overflow al stack. A la fin he provat el resultat. ./a.out només executa el que acabo de compilar, em demana informació i la devuele. funcionant 🙂

Advertències

Una altra nota aquí. Poden veure les advertències? clarament és una cosa a tenir en compte quan treballem amb codi o compilem, aquesta és una mica òbvia i són pocs els programes que avui dia tenen la funció gets() en el codi. Un avantatge de Gentoo és que a l'compilar cada programa, puc veure el que pot estar malament, un programa «ideal» no hauria de tenir-les, però els sorprendria quants programes grans tenen aquestes advertències perquè simplement són MOLT grans i és difícil mantenir el rastre de les funcions perilloses quan són moltes advertències a el mateix temps. Ara si seguim

Depurant el programa

Disseny propi. Christopher Díaz Riveros

Ara, aquesta part pot ser una mica confusa, però com ja he escrit prou, no puc donar-me el luxe de explicar-ho tot, així que perdó si veuen que vaig molt ràpid 🙂

Desarmant el codi

Anem a començar veient el nostre programa compilat en llenguatge màquina.

Disseny propi. Christopher Díaz Riveros

Aquest és el codi de la nostra funció main en Muntatge, Això és el que entén el nostre processador, la línia de l'esquerra és l'adreça física en memòria, el <+ N> es coneix com offset, Bàsicament la distància des del principi de la funció (main) fins a aquesta instrucció (conegut com codi d'operació). Després veiem el tipus d'instrucció (push / mov / callq ...) i un o més registres. Resumit podem dir que és la indicació seguida de la font / origen i la destinació. <return_input> fa referència a la nostra segona funció, anem a donar-li un cop d'ull.

Return_input

Disseny propi. Christopher Díaz Riveros

Aquesta és una mica més complexa, però només vull que revisin un parell de coses, hi ha un label anomenat <gets@plt> i un últim opcode anomenat retq que indica el final de la funció. Anem a posar un parell de breakpoints, un a la funció gets i un altre al retq.

Disseny propi. Christopher Díaz Riveros

Correr

Ara anem a córrer el programa per veure com comença a començar l'acció.

Disseny propi. Christopher Díaz Riveros

Podem veure que apareix una petita fletxa que indica el opcode on ens trobem, vull que tinguin en compte la direcció 0x000055555555469b, Aquesta és l'adreça que es troba després de la crida a return_input en la funció main , Això és important ja que aquí és on hauria de tornar el programa quan acabi de rebre el entrada, Entrarem en la funció. Ara anem a revisar la memòria abans d'entrar a la funció gets.

Disseny propi. Christopher Díaz Riveros

Els he tornat a posar la funció main dalt, i he ressaltat el codi a què em referia, com poden veure, a causa de l' Endianness s'ha separat en dos segments, vull que tinguin en compte la direcció 0x7fffffffdbf0 (La primera de l'esquerra després del commando x/20x $rsp) Ja que aquesta és la ubicació que hem de fer servir per revisar el resultat de gets, seguim:

Trencant el programa

Disseny propi. Christopher Díaz Riveros

He ressaltat aquests 0x44444444perquè són la representació de les nostres Ds 🙂 ara hem començat a afegir entrada a el programa, i com poden apreciar, estem a només dos línies de la nostra direcció desitjada, anem a omplir-fins a estar just abans de les adreces que ressaltem en el pas anterior.

Canviant la ruta de retorn

Ara que hem aconseguit entrar en aquesta secció de el codi on indica el retorn de la funció, anem a veure què passa si canviem la direacción 🙂 en lloc d'anar a la ubicació de l'opcode que segueix a què teníem fa un moment, què els sembla si regreamos a return_input? Però per això, cal escriure en binari la direacción que desitgem, ho farem amb la funció printf de bash 🙂

Disseny propi. Christopher Díaz Riveros

Ara hem rebut dues vegades la informació 😀 segurament el programa no estava fet per a això, però hem aconseguit trencar el codi i fer que repeteixi alguna cosa que no se suposava que faci.

reflexions

Aquest simple canvi pot considerar-se un explotar molt bàsic 🙂 ha aconseguit trencar el programa i fer alguna cosa que nosaltres desitgem que faci.

Aquest és només el primer pas en una quasi infinita llista de coses per veure i afegir, hi ha formes d'afegir més coses que simplement repetir una ordre, però aquesta vegada he escrit molt i tot el relacionat a shellcoding és un tema per escriure més que articles, llibres complets diria jo. Disculpin si no he pogut aprofundir una mica més en temes que m'haguessin agradat, però segur ja hi haurà oportunitat 🙂 Salutacions i gràcies per arribar fins aquí.


Deixa el teu comentari

La seva adreça de correu electrònic no es publicarà. Els camps obligatoris estan marcats amb *

*

*

  1. Responsable de les dades: Miguel Ángel Gatón
  2. Finalitat de les dades: Controlar l'SPAM, gestió de comentaris.
  3. Legitimació: El teu consentiment
  4. Comunicació de les dades: No es comunicaran les dades a tercers excepte per obligació legal.
  5. Emmagatzematge de les dades: Base de dades allotjada en Occentus Networks (UE)
  6. Drets: En qualsevol moment pots limitar, recuperar i esborrar la teva informació.

  1.   2p2 va dir

    Sigues més directe. Escriu menys i centra't en l'important

    1.    ChrisADR va dir

      Hola, gràcies pel comentari.

      Francament he retallat una bona part d'idees, però tot i així em semblava que deixi el mínim com perquè algú que no tingui coneixements de programació es pugui donar una idea.

      Salutacions

      1.    anònim va dir

        El problema és que qui no té coneixements de programació no es va a assabentar de res perquè és massa complex per començar, però qui sap programar agraeix que se sigui més directe.

        Suposo que no es pot arribar a tot el món, cal triar, i en aquest cas has pecat de voler abastar molt.

        Per cert, t'ho dic com a crítica constructiva, m'encanten aquests temes i m'agradaria que seguissis escrivint articles, enhorabona!

    2.    anònim va dir

      Opino el mateix.

      1.    ChrisADR va dir

        Moltes gràcies a tots dos !! certament és difícil entendre com arribar a el públic objectiu quan la veritat és que el nombre de persones amb un nivell avançat de programació que llegeixen aquests articles és poc (al menys això es pot inferir en base als comentaris)

        Certament he pecat de voler simplificar una cosa que requereix una àmplia base de coneixements per a poder entendre. Espero que entenguin que com acabat estic començant en això dels blocs encara no he descobert el punt exacte on els meus lectors coneixen i entenen el que dic. Això ho faria molt més fàcil francament 🙂

        Intentaré ser més breu quan mereixi sense despersonalitzar el format, ja que deslligar la forma d'escriure de l'contingut és una mica més complicat del que un podria imaginar, jo al menys els tinc bastant lligats, però suposo que en última instància podré afegir línies en lloc de tallar contingut.

        Salutacions

  2.   Mario va dir

    On es podria saber més del tema? Algun llibre recomanat?

    1.    ChrisADR va dir

      L'exemple el vaig treure de The Shellcoder 's Handbook de Chris Anley, John Heasman, Felix Linder i Gerardo Richarte, però per poder fer la traducció a 64 bits vaig haver d'aprendre sobre la meva arquitectura, el manual d'developer d'intel, toms 2 i 3 són una font bastant fiable per això. També és bo llegir la documentació de GDB, que ve amb el comandament 'info gdb', Per aprendre Assembly i C hi ha molts llibres molt bons, excepte que els de Assembly són una mica antics pel que hi ha una bretxa que omplir amb un altre tipus de documentació.

      El shellcode mateix ja no és tan efectiu en aquests dies per diversos motius, però no deixa de ser interessant per a aprendre noves tècniques.

      Espero que ajudi una mica 🙂 Salutacions

  3.   Franz va dir

    Bon article, el vell bloc desdelinux ha tornat a renéixer =)
    Quan dius que el Shell remot no és tan efectiu, et refereixes a la contramesures dissenyades per mitigar atacs, en diuen seguretat ofensiva.
    Salutacions i segueix aixi

    1.    ChrisADR va dir

      Moltes gràcies Franz 🙂 molt amables paraules, en realitat em referia al fet que el Shellcoding ara per ara és molt més complex que això que veiem aquí. Tenim el ASLR (generador d'ubicacions de memòria random) el protector de stack, les diverses mesures i contramesures que limiten la quantitat de opcodes que es poden injectar en un programa, i només és el principi.

      Salutacions,

  4.   programari Lliure va dir

    Hola, faràs altra banda expandint el tema? és interessant

    1.    ChrisADR va dir

      Hola, certament és força interessant el tema, però el nivell de complexitat que prendríem es tornaria molt elevat, probablement implicant una gran quantitat de posts per explicar els diversos pre-requisits per entendre l'altre. Probablement escrigui a l'respecte, però no seran els següents posts, vull escriure uns quants temes abans de continuar amb aquest.

      Salutacions, i graicas per compartir

  5.   cactus va dir

    Molt bo xe! Aquestes aportant grans posts! Una pregunta, estic començant això de Seguretat IT llegint un llibre que es diu «Assuring security by pen testing». És recomanat aquest llibre? Com em suggeriu que comenci a indagar sobre aquests temes?

    1.    ChrisADR va dir

      Hola cactus, ja que és un univers sencer això de les vulnerabilitats, i altres, francament depèn molt del que et cridi l'atenció, i les necessitats que tinguis, un gerent de TI no requereix saber el mateix que un pen-tester, o un investigador de vulnerabilitats, o un analista forense, un equip de recuperació davant de desastres té un altre joc de skills molt diferent. Evidentment cada un d'ells requereix un nivell diferent a nivell tècnic de coneixements, jo et recomano que comencis descobrint exactament què t'agrada, i comencis a devorar llibres, articles, i altres, i el més important pràctica tot el que llegeixis, així estigui desactualitzat , això marcarà la diferència a la fin.
      Salutacions,

  6.   No va dir

    Hola.
    Moltíssimes gràcies per explicar aquest tema, a més de comentar que per a informació extra tenim «The Shellcoder s Handbook». Ja tinc una lectura pendent 😉