Осалдықтарды пайдалану туралы көзқарас

Мен осы тақырыпты талқылауды жалғастыруды асыға күткен кезде, мен сізге осалдықтар туралы біраз тарих, теория және тәжірибе айтып берейін. Біз қазірге дейін қауіпсіздік ақаулары үлкен шығындарға әкелуі мүмкін дегенді естідік, біз бағдарламалық жасақтаманы жаңартып отыруымыз керек екенін білеміз, көптеген жаңартулар қауіпсіздік қателерінен туындайтынын білеміз. Бірақ бүгін мен сізге осы қателіктер қалай табылатыны және пайдаланылатыны туралы аздап айтып беремін 🙂 Бірақ бұған дейін біз шолу жасау үшін бірнеше егжей-тегжейлерді нақтылаймыз.

Бастамас бұрын

Алдымен мен сіздерге белгілі, мен пайдалануды үйренген алғашқы осалдыққа назар аударатынымызды айтқым келеді Буфер толып кетті, осалдық кезінде біз көңілді істер жасау үшін жадыны тексерудің жетіспеушілігін пайдаланамыз 🙂 Бірақ бұл туралы аздап түсіндірейік.

Бұл нақты әлемдік сценарий болмайды

Мен оларға кез-келген бағдарламаны бұзуға үйрете алмаймын - біріншіден, бұл олардың компьютерлері үшін қауіпті, екіншіден, бұл менің әдеттегі сөздер квотасынан көп алады.

Біз 80-ші жылдарға саяхатқа барамыз

Мен саған көрсететін нәрсені ноутбукта жасай аламын, бірақ бұл оны бүгінде қарапайым түрде жасауға болады дегенді білдірмейді 🙂 бұл ұғымдардың көпшілігі бірнеше рет пайдаланылып келгендіктен, қорғау әдістері мен оларды болдырмаудың жаңа әдістері пайда болды. 😛 бірақ бұл бізді бір жерге қайтарады, мұның бәрін айтуға орын жоқ 🙂

Бұл сіздің процессорыңызда жұмыс істемеуі мүмкін

Мен өте қарапайым мысал келтіретін болсам да, мұның детальдары соншалықты көп және әртүрлі болғанын, менімен бірдей шығуы мүмкін болғандықтан, егер сіз оны байқап көргіңіз келсе, қалаған эффектке қол жеткізілмеуі де мүмкін екенін басынан-ақ білгім келеді. 🙂 Бірақ сіз бұл кеңістікте мен түсіндіре алмайтынымды елестете аласыз, әсіресе осы кіріспемен мен 300-ден астам сөз қабылдадым, сондықтан біз өз ойымызға тура жеттік.

А Буфердің толуы

Бұған жауап беру үшін алдымен осы комбинацияның бірінші жартысын түсінуіміз керек.

Буферлер

Бәрі компьютердегі жадқа байланысты болғандықтан, ақпарат контейнерінің қандай да бір түрі болуы керек. Біз туралы сөйлескенде кірістер Шығу, біз тікелей тұжырымдамасына келеміз буферлер. Қысқаша болуы үшін, а буфер Бұл белгілі бір көлемдегі жад кеңістігі, онда біз қарапайым ақпаратты сақтаймыз

Толып кету, аты айтып тұрғандай, буфер өзі басқара алатыннан көбірек ақпаратты толтырғанда пайда болады. Бірақ бұл неге маңызды?

үйме

Сондай-ақ, стектер деп аталады, олар деректердің дерексіз түрі болып табылады, оларда біз жасай аламыз стек ақпарат, олардың басты сипаттамасы - олардың тапсырыс беруі LIFO (соңғы шыққан бірінші). Бір секундқа тақтайшалар туралы ойланайық, оларды бір-бірлеп үстіне қоямыз, содан кейін оларды жоғарыдан бір-бірлеп шығарамыз, осылайша біз салған соңғы табақ (үстіңгі жағында) бірінші табақ болады егер біз бір уақытта тек бір тәрелкені шығарып алсақ және оны сол тәртіппен жасауды шешсек, оны шығаратын боламыз: П.

Енді сіз осы екі ұғымды білетін болсаңыз, оларды ретке келтіруіміз керек. Стектердің маңызы зор, өйткені біз іске қосатын әрбір бағдарламаның өз бағдарламасы бар орындау стегі. Бірақ бұл стектің а ерекше сипаттамаөседі. Бұл туралы білуіңіз керек жалғыз нәрсе - бағдарлама жұмыс істеп тұрған кезде, функция шақырылған кезде стек жадтағы Х санынан (Xn) санға ауысады. Жалғастыру үшін тағы бір ұғымды түсіну керек.

Пунтерос

Бұл С бағдарламасында көптеген бағдарламашыларды есінен адастыратын тұжырымдама, шын мәнінде С бағдарламалаудың үлкен күші ішінара көрсеткіштерді қолданумен байланысты. Қарапайым болу үшін көрсеткіш жад мекенжайын көрсетеді. Бұл күрделі болып көрінеді, бірақ онша күрделі емес, бәріміздің машинамызда жедел жады бар емес пе? Мұны a ретінде анықтауға болады блоктардың бірізді орналасуы, бұл орындар әдетте он алтылық сандармен көрсетіледі (0-ден 9-ға дейін, содан кейін А-дан F-ге дейін, мысалы 0x0, 0x1, 0x6, 0xA, 0xF, 0x10). Мұнда 0x10 қызықты ескерту ретінде ЖОҚ 10 😛-ге тең, егер оны ондық тәртіпке ауыстыратын болсақ, бұл 15-тің айтқанымен бірдей болар еді. Бұл алдымен бірнешеуін шатастыратын нәрсе, бірақ оған жетейік.

Регистростар

Процессорлар бірқатармен жұмыс істейді жазбалар, физикалық жадтан процессорға орналасқан жерлерді беру үшін жұмыс істейтін, 64 битті пайдаланатын архитектуралар үшін регистрлердің саны үлкен және мұнда сипаттау қиын, бірақ идеяны алу үшін регистрлер көрсеткіштерге ұқсас, олар басқалармен бірге көрсетіледі заттар, жад кеңістігі (орналасуы).

Енді жаттығу жаса

Мен осы уақытқа дейін өңдеу үшін көп ақпарат болғанын білемін, бірақ іс жүзінде олар өте күрделі мәселелер, мен оларды өте қарапайым түрде түсіндіруге тырысамын, біз буферлерді қолданатын шағын бағдарламаны көреміз және оны толып кету туралы түсіну үшін оны бұзамыз, анық, бұл олай емес Бұл нақты бағдарлама, және біз қазіргі кезде қолданылып жатқан көптеген қарсы шаралардан «жалтаруға» тырысамыз, тек заттардың бұрын қалай жасалынғанын көрсету үшін 🙂 және осы принциптердің кейбіреулері күрделі нәрселерді үйрену үшін қажет are

GDB

С бағдарламашылары қолданатын бағдарламаның бірі екендігі сөзсіз, оның көптеген ізгіліктерінің арасында біз осы уақытқа дейін айтып келген барлық нәрселерді, регистрлерді, стектерді, буферлерді және т.б. көруге мүмкіндік беретіндігімізге назар аударамыз. біз өз мысалымыз үшін қолданғалы отырған бағдарлама.

retinput.c

Меншікті. Кристофер Диас Риверос

Бұл өте қарапайым бағдарлама, біз кітапхананы қолданамыз stdio.h ақпарат алу және оны терминалда көрсету мүмкіндігі. Деп аталатын функцияны көре аламыз return_input а тудырады буфер шақырылды массив, оның ұзындығы 30 байттар (char деректер түрі 1 байттан тұрады).

Функция gets(array); ақпаратты консолі мен функциясы бойынша сұрау printf() массивтің мазмұнын қайтарады және оны экранға шығарады.

С тілінде жазылған барлық программа функциясынан басталады main(), бұл тек return_input қоңырауына жауап береді, енді біз бағдарламаны құрастырамыз.

Меншікті. Кристофер Диас Риверос

Жаңа ғана жасаған істерімнің біразын алайық. Опция -ggdb gcc-ге gdb-ді дұрыс түзетуге мүмкіндік беретін ақпаратпен бірге бағдарламаны құрастыруды айтады. -fno-stack-protector Бұл біз қолданбауымыз керек, бірақ қолданамыз, өйткені әйтпесе стек ішіндегі буферлік толып кетуді жасауға болатын еді. Соңында мен нәтижені тексердім. ./a.out ол жай ғана мен құрастырған нәрсені іске қосады, ол менен ақпарат сұрайды және оны қайтарады. Жүгіру 🙂

Ескерту

Мұнда тағы бір ескерту. Сіз ескертулерді көре аласыз ба? біз оны кодпен немесе компиляциямен жұмыс жасағанда ескеруіміз керек, бұл біршама айқын және бүгінде функциясы бар бағдарламалар аз gets() Кодта. Gentoo-дің бір артықшылығы - әр бағдарламаны құрастыру арқылы мен оның ненің дұрыс еместігін көре аламын, «идеалды» бағдарламада ол болмауы керек, бірақ сізде қанша үлкен бағдарламада осындай ескертулер бар екеніне таң қаласыз, өйткені олар өте үлкен және оларды қадағалау қиын. бір уақытта көптеген ескертулер болған кезде қауіпті функциялар. Енді жалғастырсақ

Бағдарламаны жөндеу

Меншікті. Кристофер Диас Риверос

Енді бұл бөлім біраз түсініксіз болуы мүмкін, бірақ мен біраз жазып үлгергендіктен, бәрін түсіндіруге шамам жетпейді, сондықтан менің тым жылдам жүріп бара жатқанымды көрсеңіз sorry

Кодты қарусыздандыру

Құрастырылған машиналық тілдік бағдарламаны қарастырудан бастайық.

Меншікті. Кристофер Диас Риверос

Бұл біздің негізгі функцияларымыздың коды жиналыс, бұл біздің процессор түсінетін нәрсе, сол жақта орналасқан жадтағы физикалық адрес, <+ n> ретінде белгілі офсет, негізінен функцияның басынан (негізгі) сол тұжырымға дейінгі арақашықтық (белгілі opcode). Содан кейін біз нұсқаулық түрін (push / mov / callq…) және бір немесе бірнеше регистрді көреміз. Қорытындылай келе, бұл дереккөз / шығу тегі мен баратын жері бар көрсеткіш деп айта аламыз. <return_input> біздің екінші функциямызға қатысты, қарастырайық.

Қайтару_кірісі

Меншікті. Кристофер Диас Риверос

Бұл сәл күрделі, бірақ мен сізден бірнеше нәрсені тексергеніңізді қалаймын, бұл жерде тег бар <gets@plt> және соңғы опкод шақырылды retq функцияның аяқталуын көрсетеді. Біз бірнеше функционалды тоқтату нүктелерін қоямыз gets және басқа retq.

Меншікті. Кристофер Диас Риверос

жүгіру

Енді біз іс-әрекеттің қалай басталатынын көру үшін бағдарламаны іске қосамыз.

Меншікті. Кристофер Диас Риверос

Біз орналасқан жердегі опкодты көрсететін кішкентай көрсеткі пайда болатынын көреміз, олардың бағытын ескергенін қалаймын 0x000055555555469b, бұл қоңырау шалғаннан кейінгі мекен-жай return_input функциясы бойынша main , бұл өте маңызды, өйткені бағдарламаны алғаннан кейін қайту керек енгізу, функцияға кірісейік. Енді біз функцияны енгізбес бұрын жадыны тексереміз gets.

Меншікті. Кристофер Диас Риверос

Мен сізге негізгі функцияны қайтардым, және сіз айтып отырған кодты бөліп алдым. енді екі сегментке бөлінді, олардың бағытын ескергенін қалаймын 0x7fffffffdbf0 (командодан кейін сол жақтан бірінші x/20x $rsp) бұл нәтижені тексеру үшін пайдалануымыз керек болғандықтан, жалғастырайық:

Бағдарламаны бұзу

Меншікті. Кристофер Диас Риверос

Мен соларды бөліп көрсеттім 0x44444444өйткені олар біздің Ds-дің өкілі болып табылады 🙂 енді біз қосуды бастадық енгізу бағдарламаға, және сіз өзіңіз көріп отырғаныңыздай, біз қалаған мекен-жайымыздан екі жол ғана, оны алдыңғы қадамда бөліп көрсеткен мекен-жайлардың алдында тұрғанға дейін толтырамыз.

Қайту жолын өзгерту

Енді біз кодтың осы бөліміне функцияның қайтып келетінін көрсете алдық, енді осыдан біраз бұрын болған опкод орналасқан жерге бармай, 🙂 адресін өзгерткенде не болатынын көрейік, сіз қалай ойлайсыз егер біз қайтып оралсақ return_input? Бірақ ол үшін адресті екілік жүйеге жазу керек, біз оны функциясымен жасаймыз printf bash 🙂

Меншікті. Кристофер Диас Риверос

Енді біз екі рет ақпарат алдық 😀 бағдарлама ол үшін жасалмаған, бірақ біз кодты бұзып, оны орындауға болмайтын нәрсені қайталай алдық.

Рефлексиялар

Бұл қарапайым өзгерісті а деп санауға болады пайдалану өте қарапайым 🙂 ол бағдарламаны бұзып, біз қалаған нәрсені істей алды.

Бұл көруге және қосуға болатын заттардың шексіз тізіміндегі алғашқы қадам, тек тапсырысты қайталаудан гөрі көп нәрсені қосудың жолдары бар, бірақ мен бұл жолы көп нәрсені жаздым қабықшалау Мен мақалалардан, толық кітаптардан гөрі көп нәрсе жазамын. Кешіріңіз, мен өзіме ұнайтын тақырыптарды аздап тереңдете алмадым, бірақ мүмкіндіктің болатындығы сөзсіз 🙂 Сәлемдесу және осында келгеніңізге рахмет.


Мақаланың мазмұны біздің ұстанымдарымызды ұстанады редакторлық этика. Қате туралы хабарлау үшін нұқыңыз Мұнда.

14 пікір, өз пікіріңізді қалдырыңыз

Пікіріңізді қалдырыңыз

Сіздің электрондық пошта мекен-жайы емес жарияланады. Міндетті өрістер таңбаланған *

*

*

  1. Деректерге жауапты: Мигель Анхель Гатан
  2. Деректердің мақсаты: СПАМ-ны басқару, түсініктемелерді басқару.
  3. Заңдылық: Сіздің келісіміңіз
  4. Деректер туралы ақпарат: заңды міндеттемелерді қоспағанда, деректер үшінші тұлғаларға жіберілмейді.
  5. Деректерді сақтау: Occentus Networks (ЕО) орналастырған мәліметтер базасы
  6. Құқықтар: Сіз кез-келген уақытта ақпаратты шектей, қалпына келтіре және жоя аласыз.

  1.   2п2 дижо

    Тікелей болыңыз. Аз жазып, маңызды нәрсеге назар аударыңыз

    1.    ChrisADR дижо

      Сәлем, түсініктеме үшін рақмет.

      Шынымды айтсам, мен идеялардың жақсы бөлігін қысқарттым, бірақ менің ойымша, бұл бағдарламалық білімі жоқ адам идеяны алуы үшін минималды деңгейге жеткендей болды.

      тілекпен

      1.    аноним дижо

        Мәселе мынада: бағдарламалау туралы білімдері жоқтар ештеңе біле алмайды, өйткені оны бастау өте қиын, бірақ бағдарламалауды білетіндер тікелей болуды бағалайды.

        Менің ойымша, сіз бәріне жете алмайсыз, сіз таңдауыңыз керек және бұл жағдайда сіз көп нәрсені жапқыңыз келетін күнә жасадыңыз.

        Айтпақшы, мен сізге сындарлы сын ретінде айтамын, мен бұл тақырыптарды жақсы көремін және мақала жазуды жалғастырғаныңызды қалаймын, құттықтаймын!

    2.    аноним дижо

      Менің ойымша, дәл осындай нәрсе.

      1.    ChrisADR дижо

        Екеуіне де үлкен рахмет !! Мақсатты аудиторияға қалай жетуге болатынын түсіну қиын, егер шынымен де осы мақалаларды оқитын бағдарламалау деңгейі жоғары адамдардың саны аз болса (түсініктемелерге сүйене отырып, оларды шығаруға болады)

        Мен кең білім базасын түсінуді қажет ететін нәрсені жеңілдеткім келіп, күнә жасадым. Блог жүргізуге жаңадан кірісіп жатқандықтан, менің оқырмандарымның менің айтқанымды білетін және түсінетін нақты нүктесін әлі таба алмадым деп үміттенемін. Бұл шындықты айтуды едәуір жеңілдетер еді 🙂

        Форматты иесіздендірусіз лайықты болғанда, мен қысқаша болуға тырысамын, өйткені мазмұнды жазу тәсілін бөлу елестеткеннен гөрі біршама күрделі, мен, ең болмағанда, оларды бір-бірімен байланыстырдым, бірақ, сайып келгенде, мен жолдарды қоса аламын деп ойлаймын мазмұнды кесудің орнына.

        тілекпен

  2.   Марио дижо

    Сіз бұл тақырып туралы қайдан көбірек біле аласыз? Ұсынылған кітап бар ма?

    1.    ChrisADR дижо

      Мысал «Shellcoder's анықтамалығынан» Крис Анли, Джон Хизман, Феликс Линдер және Джерардо Ричарттен алынды, бірақ 64-биттік аударма жасау үшін менің архитектурам туралы, интеллектуалды әзірлеушілерге арналған нұсқаулықтың 2 және 3 томдары бұл үшін сенімді ақпарат көзі. 'Info gdb' командасымен бірге келетін GDB құжаттамасын оқыған жақсы, Ассемблер мен С-ны үйрену үшін өте жақсы кітаптар өте көп, тек Ассамблея кітаптары біраз ескіргендіктен, басқа кітаптармен толтыруға бос орын бар. құжаттама түрі.

      Шелкодтың өзі қазіргі кезде әртүрлі себептермен тиімді емес, бірақ жаңа техниканы үйрену әлі де қызықты.

      Бұл аздап көмектеседі деп үміттенемін 🙂 Сәлемдесу

  3.   Франц дижо

    Жақсы мақала, desdelinux ескі блогы қайта туылды =)
    Қашықтағы қабық онша тиімді емес деген кезде, сіз шабуылдарды жеңілдетуге бағытталған қарсы шараларды түсінесіз, олар мұны шабуыл қауіпсіздігі деп атайды.
    Сәлемдесу және оны жалғастыру

    1.    ChrisADR дижо

      Францке көп рахмет 🙂 жылы сөздер, шынында мен Shellcoding қазіргі кездегіден гөрі әлдеқайда күрделі екенін айтқым келді. Бізде ASLR (кездейсоқ жадының орналасу генераторы) стек қорғағышы, бағдарламаға енгізуге болатын опкодтардың санын шектейтін түрлі шаралар мен қарсы шаралар бар және бұл тек бастамасы.

      Рахмет,

  4.   Тегін бағдарламалық қамтамасыз ету дижо

    Сәлеметсіз бе, сіз тақырыпты кеңейтетін тағы бір бөлім жасайсыз ба? Бұл қызықты

    1.    ChrisADR дижо

      Сәлеметсіз бе, тақырып әрине өте қызықты, бірақ біз күрделілік деңгейі өте жоғары болады, мүмкін басқаларын түсіну үшін әр түрлі алғышарттарды түсіндіру үшін көптеген посттар керек. Мен бұл туралы жазатын шығармын, бірақ ол келесі жазбалар болмайды, мен осы тақырыпты жалғастырмас бұрын бірнеше тақырып жазғым келеді.

      Сәлемдесу және бөліскеніңіз үшін рақмет

  5.   Кактус дижо

    Өте жақсы! Сіз керемет жазбалар қосып жатырсыз! Бір сұрақ, мен бұл IT қауіпсіздігін «Қаламды сынау арқылы қауіпсіздікті қамтамасыз ету» атты кітапты оқудан бастаймын. Бұл кітап ұсынылған ба? Осы мәселелер туралы сұрай бастауды қалай ұсынасыз?

    1.    ChrisADR дижо

      Сәлеметсіз бе, кактус, бұл осалдықтар туралы бүкіл әлем және басқалары, шындықты айту, бұл сіздің назарыңызды аударатын нәрсеге байланысты, ал сіздің қажеттіліктеріңіз үшін IT-менеджер қалам тексеруші сияқты білуі қажет емес, Немесе осалдықтарды зерттеуші немесе сот сарапшысы, апаттарды қалпына келтіру тобының дағдылары мүлдем басқаша. Әрине, олардың әрқайсысы әртүрлі деңгейдегі техникалық білімді қажет етеді, мен сізге өзіңізге ұнайтын нәрсені ашуға, кітаптарды, мақалаларды және басқаларын жеуге кірісуге кеңес беремін, ең бастысы, ескірген болса да, оқығаныңыздың барлығымен машықтаныңыз. , бұл түбінде өзгеріс әкеледі.
      Рахмет,

  6.   Эйзен дижо

    Сәлеметсіз бе!
    Осы тақырыпты түсіндіргеніңіз үшін, сондай-ақ қосымша ақпарат алу үшін бізде «Shellcoder анықтамалығы» бар екеніне түсініктеме бергеніңізге көп рахмет. Менде оқуды күтуде 😉