Skip to content

Commit

Permalink
docs: update development docs.
Browse files Browse the repository at this point in the history
  • Loading branch information
TuuuNya committed Mar 12, 2019
1 parent 8cbd0d3 commit 6f621ef
Showing 1 changed file with 108 additions and 110 deletions.
218 changes: 108 additions & 110 deletions docs/framework/development.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,77 +9,92 @@

我会长期坚持维护该模块库,欢迎大家加入。共勉。

模块基本结构
概述
-------------

在 WebPocket 中撰写一个完整的模块,需要符合如下要求:

* 模块必须为一个 ``class`` 且类名为 ``Exploit``
* ``Exploit`` 类必须继承自 ``BaseExploit`` (通过 ``from lib.BaseExploit import BaseExploit`` 引入 )
* 模块必须包含 ``__init__`` 方法,必须调用父类的 ``__init__`` 方法,(通过 ``super(Exploit, self).__init__()`` 调用)
* 模块必须填写相关信息,使用 ``self.update_info()`` 方法
* POC的目标目前主要分为 ``http`` 和 ``tcp`` 类型,使用 ``self.register_tcp_target()`` 注册tcp类型的目标。 使用 ``self.register_tcp_target()`` 注册http类型的目标。
* 注册以后的目标可以使用 ``self.options.get_option`` 获取其中的参数。
* ``check`` 方法用来实现检测漏洞,不可存在攻击行为。
* ``exploit`` 方法用来实现攻击行为,但也不可进行影响服务器正常运行的操作。
* 在 ``check`` 和 ``exploit`` 方法中,如果测试成功,调用 ``self.results.success()`` 方法保存结果。失败调用 ``self.results.failure()`` 保存结果。
* 不管 ``check/exploit`` 成功与否,都要最后返回 ``self.results`` (将来可能会移除该要求,但目前暂时还是需要返回。)。

在写模块的过程中,如果使用 ``pycharm`` 可以跟进上述的方法查看代码,方便大家理解,如有任何疑问或者建议,欢迎联系我。

微信:StrikerSb
邮箱:[email protected]

案例:redis未授权检测模块
----------------------------

基本代码: ::

import requests
# 请求redis需要socket 故引入socket
import socket
from lib.BaseExploit import BaseExploit
from lib.ExploitOption import ExploitOption


class Exploit(BaseExploit):

def __init__(self):
super(Exploit, self).__init__()
self.update_info(info={
"name": "模块名称 可用于检索",
"description": "模块描述 可用于检索",
"author": ["作者, 可以填写多个"],
self.update_info({
"name": "redis unauthorized",
"description": "redis unauthorized",
"author": ["unknown"],
"references": [
"参考资料/漏洞来源网址,可填写多个",
"https://www.freebuf.com/column/158065.html",
],
"disclosure_date": "漏洞发现时间",
"service_name": "服务名称,如:phpcms、zabbix、php、apache",
"service_version": "服务版本",
"disclosure_date": "2019-02-28",
"service_name": "redis",
"service_version": "*",
})
# 因为redis只需要提供ip和端口,所以这里注册tcp的目标。
self.register_tcp_target(port_value=6379)

# 注册模块所需的参数, required为True的模块,默认值请设置为None
self.register_options([
ExploitOption(
name="host",
required=True,
description="The target domain",
value=None
),
ExploitOption(
name="password",
required=True,
description="webshell password",
value=None
),
])

# check 方法仅做漏洞检测,不可进行攻击
# 测试存在漏洞调用 self.results.success方法,传入结果
# 测试不存在漏洞调用 self.results.failure 传入错误信息
def check(self):
webshell = "http://www.hackersb.cn/shell.php"
if len(webshell):
self.results.success(
message="Target {} has vul".format(self.options.get_option("host"))
)
else:
self.results.failure(error_message="Target {} no vulnerability".format(self.options.get_option("host")))
# 这三个参数都是self.register_tcp_target方法注册的,这里可以直接调用
host = self.options.get_option("HOST")
port = int(self.options.get_option("PORT"))
timeout = int(self.options.get_option("TIMEOUT"))

# 执行测试的整个过程最好放进try里面,然后在except里面捕获错误直接调用self.results.failure打印出报错。
try:
socket.setdefaulttimeout(timeout)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
s.send(bytes("INFO\r\n", encoding="utf-8"))
result = s.recv(1024)
if bytes("redis_version", encoding="utf-8") in result:
# 存在漏洞 调用该方法 data可传入一个字典,目前没有什么用,也可以不传。
self.results.success(
data={
"host": host,
"port": port,
},
# 由于可能会执行多个目标,所以结果里面最好写上目标和端口,方便辨认。
message="Host {host}:{port} exists redis unauthorized vulnerability".format(host=host, port=port)
)
else:
# 不存在漏洞 调用self.results.failure方法传入错误信息。
self.results.failure(
error_message="Host {host}:{port} does not exists redis unauthorized vulnerability".format(
host=host,
port=port
)
)
except Exception as e:
# 执行错误,使用self.results.failure传入错误信息。
self.results.failure(error_message="Host {host}:{port}: {error}".format(host=host, port=port, error=e))
return self.results

# exploit方法为攻击模块 结果同check方法一样处理
# 注意:不要写可以导致系统崩溃的Exploit方法。
def exploit(self):
requests.get(self.options.get_option("host"))
webshell = "http://www.hackersb.cn/shell.php"
if len(webshell):
self.results.success(
data={
"target": self.options.get_option("host"),
"webshell": webshell
},
message="Webshell: {}".format(webshell)
)
else:
self.results.failure(error_message="No vulnerability")
return self.results
return self.check()

撰写模块
---------
Expand Down Expand Up @@ -122,26 +137,7 @@
"service_name": "redis",
"service_version": "*",
})
self.register_options([
ExploitOption(
name="host",
required=True,
description="The IP of the machine to be tested",
value=None
),
ExploitOption(
name="timeout",
required=False,
description="The timeout for connecting to redis",
value=10,
),
ExploitOption(
name="port",
required=False,
description="redis port",
value=6379
)
])
self.register_tcp_target(port_value=6379)

这里来解释一下,首先看 ``__init__`` 方法的第一行: ::

Expand All @@ -163,44 +159,31 @@
"service_version": "*",
})

然后使用 ``self.register_options`` 方法注册三个参数,分别是 ``host``, ``timeout``, ``port``,

* host 表示需要测试漏洞的主机ip
* timeout 表示连接redis超时时间
* port 表示redis端口

代码如下: ::

self.register_options([
ExploitOption(
name="host",
required=True,
description="The IP of the machine to be tested",
value=None
),
ExploitOption(
name="timeout",
required=False,
description="The timeout for connecting to redis",
value=10,
),
ExploitOption(
name="port",
required=False,
description="redis port",
value=6379
)
])
然后使用 ``self.register_tcp_target`` 方法注册了一个tcp类型的目标,这个方法自动为我们注册了如下参数: ::

self.register_options([
ExploitOption(name="HOST", required=True, description="The IP address to be tested"),
ExploitOption(name="PORT", required=True, description="The port to be tested", value=port_value),
ExploitOption(name="TIMEOUT", required=True, description="Connection timeout", value=timeout_value),
ExploitOption(name="THREADS", required=True, description="The number of threads", value=threads_value)
])

对于我们redis未授权的漏洞,需要HOST和PORT已经够了,所以不需要再注册多余的参数。

如果需要额外注册参数,可以调用 ``self.register_options`` 方法,传入一个list,list包含 ``ExploitOption`` 对象。

``ExploitOption`` 引入方法:``from lib.ExploitOption import ExploitOption``

完成check方法
--------------

check方法主要写检测漏洞是否存在,不可存在攻击行为。 代码如下: ::

def check(self):
host = self.options.get_option("host")
port = int(self.options.get_option("port"))
timeout = self.options.get_option("timeout")
host = self.options.get_option("HOST")
port = int(self.options.get_option("PORT"))
timeout = int(self.options.get_option("TIMEOUT"))

try:
socket.setdefaulttimeout(timeout)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
Expand All @@ -213,14 +196,17 @@ check方法主要写检测漏洞是否存在,不可存在攻击行为。 代
"host": host,
"port": port,
},
message="Host {} exists redis unauthorized vulnerability".format(host)
message="Host {host}:{port} exists redis unauthorized vulnerability".format(host=host, port=port)
)
else:
self.results.failure(
error_message="Host {} does not exists redis unauthorized vulnerability".format(host)
error_message="Host {host}:{port} does not exists redis unauthorized vulnerability".format(
host=host,
port=port
)
)
except Exception as e:
self.results.failure(error_message=e)
self.results.failure(error_message="Host {host}:{port}: {error}".format(host=host, port=port, error=e))
return self.results

首先前三行使用 ``self.options.get_option()`` 方法获取模块参数。
Expand All @@ -234,16 +220,19 @@ check方法主要写检测漏洞是否存在,不可存在攻击行为。 代
"host": host,
"port": port,
},
message="Host {} exists redis unauthorized vulnerability".format(host)
message="Host {host}:{port} exists redis unauthorized vulnerability".format(host=host, port=port)
)

漏洞不存在则执行了 ``self.results.failure`` 方法,传入失败信息: ::

self.results.failure(
error_message="Host {} does not exists redis unauthorized vulnerability".format(host)
error_message="Host {host}:{port} does not exists redis unauthorized vulnerability".format(
host=host,
port=port
)
)

check方法最后一行一定要返回 ``self.results`` 出来。 ::
check方法一定要返回 ``self.results`` 出来。 ::

return self.results

Expand All @@ -257,3 +246,12 @@ check方法最后一行一定要返回 ``self.results`` 出来。 ::
return self.check()

exploit方法也一定要返回 ``self.results`` 出来, 因为check方法也是返回 ``self.results`` ,所以这里可以直接调用 ``self.check()`` 。

更多案例
--------------

现在框架大部分功能已经完成了,我自己会开始写一些模块。

大家可以参考我已经写好的模块,来完成自己的模块。

所有模块都在github仓库中modules目录下。

0 comments on commit 6f621ef

Please sign in to comment.