[write up] hackim ctf – mixme – pwn5

Tesla123

VIP Members
25/03/2014
7
141 bài viết
[write up] hackim ctf – mixme – pwn5
Đánh giá sơ lược về binary:
PHP:
~/Sources/CTFs/hackim » file mixme                               peternguyen@peternguyen
mixme: ELF 32-bit LSB  executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=b93d20dd523097dd7d53a7fda265a2d977d29c30, stripped
Checksec:
ScreenShot2015-01-12at111306AM_zps163b811d.png

Chương trình có 3 lệnh chính: (store/edit/get)
[h=5]Phân tích hàm edit[/h]Đựa trên hàm store, mình có thể reverse lại được cấu trúc lưu trữ của chương trình như sau:
PHP:
struct node{
 char name[16];
 int size;
 char *data;
 struct node *next;
 struct node *prev;

size là khích cỡ vùng nhớ được malloc cho data.
Các node được lưu trữ bằng một danh sách double linked list circular
image018.jpg


Vùng nhớ tổ chức trong mem như sau (tạo 2 block với data size = 16:
ScreenShot2015-01-12at111248AM_zpsca72a939.png


Gồm 3 block: block head được khởi tạo mặc định khi chạy chương trình.
Để ý phần data của block được cấp phát là 1 đoạn đằng sau block, tôi sẽ đề cập sau ở phần khai thác lỗi.
[h=5]Phân tích hàm edit[/h]Nhập name,và size, hàm sẽ duyệt qua linked list để tìm ra block có tên tương ứng, và cập nhật lại phần data.
Để ý phần sau:
ScreenShot2015-01-12at111102AM_zpse1ead7c3.png

ScreenShot2015-01-12at111018AM_zps6288871d.png


Chương trình đọc từ stdin vào data nbytes, mà nbytes không check length.
Nếu tạo 2 block liền nihau thì, phần tiếp theo phần data của block 1 là block2 nên ta có thể overwrite được cái block 2.
[h=5]Phân tích hàm get:[/h]Nhập vào tên block và size, tìm ra block tương ứng, in phần data ra màn hình, free vùng data và block, cập nhật lại linked list. Để ý write(1,node->data,n); mình sẽ dùng nó để leak addr
ScreenShot2015-01-12at111000AM_zpsc4f6c36a.png


[h=4]Khai thác lỗi.[/h]Ở đây mình sẽ overwrite địa chỉ data bằng địa chỉ của một hàm trong bảng got bằng cách lợi dụng phần read(0,node->data,node->size)
Để ý hàm free(node->data) nhận input là phần data nhập vào, ý tưởng là overwrite free trong bảng got là system và ta có, system(node->data).
Payload của mình làm theo các bước như sau:


  1. Tạo ra 2 block peter123,lol123 với data size của mỗi block là 16 bytes
  2. edit block peter123: với size 56, ‘D’*28 + ‘x00′ * 16 + ‘CCCC’, với CCCC => địa chỉ hàm free, sở dĩ mình padd ‘x00’*16 byte để làm name của block2 = ‘DDDD’.
  3. edit block 2 (‘DDDD’) với size 4 bytes để ghi đè free trong bảng got ở đây mình ghi đè got bằng địa chỉ của lệnh ret, mục đích là để bypass qua hàm free, vì mình lợi dụng lệnh ret để leak 1 địa chỉ trong bảng GOT.
  4. get block 2(‘DDDD’) minh sẽ leak được 1 địa chỉ trong bảng GOT, từ đó tính được địa chỉ hàm system.
  5. Tạo tiếp 2 block bất kì (b1,b2) với data size của mỗi block là 16 bytes
  6. edit block1(‘b1′) ghi đè địa chỉ data của block 2 bằng địa chỉ free một lần nữa
  7. edit block2() để ghi đè free bằng system.
  8. Tạo ra block ‘shell’ với phần data=’/bin/sh’
  9. get block(‘shell’) và boom đã có được shell
ScreenShot2015-01-11at30525AM_zps9153b11c.png
 
Mời các bạn tham gia Group WhiteHat để thảo luận và cập nhật tin tức an ninh mạng hàng ngày.
Lưu ý từ WhiteHat: Kiến thức an ninh mạng để phòng chống, không làm điều xấu. Luật pháp liên quan
Bài viết liên quan
Bên trên