badtouch 是一个可编写脚本的网络身份验证破解程序. 虽然如今市面上关于常见服务爆破的程序已经接近 于饱和的状态 https://github.com/vanhauser-thc/thc-hydra , 但在实际 web 应用凭据测试时, 你仍可能最终会自己手动来编写自己的 Python 脚本.
badtouch 的范围是定制服务破解. 这是通过编写被加载到 lua 运行的脚本来完成的. 这些脚本代表单个服务, 并提供返回 true 或 false 的 verify(user, password)功能. badtouch 运行当中会为我们提供并发性, 进度指示和报告信息.
视频演示:
base64_decode
解码 base64 字符串.
- base64_decode("ww==")
- base64_encode
用 base64 编码一个二进制数组.
- base64_encode("\x00\xff")
- execve
执行一个外部程序. 返回退出代码.
- execve("myprog", {"arg1", "arg2", "--arg", "3"})
- hex
十六进制编码一个字节列表.
hex("\x6F\x68\x61\x69\x0A\x00")
hmac_md5
用 md5 计算 hmac. 返回一个二进制数组.
- hmac_md5("secret", "my authenticated message")
- hmac_sha1
用 sha1 计算 hmac. 返回一个二进制数组.
- hmac_sha1("secret", "my authenticated message")
- hmac_sha2_256
用 sha2_256 计算 hmac. 返回一个二进制数组.
- hmac_sha2_256("secret", "my authenticated message")
- hmac_sha2_512
用 sha2_512 计算 hmac. 返回一个二进制数组.
- hmac_sha2_512("secret", "my authenticated message")
- hmac_sha3_256
用 sha3_256 计算 hmac. 返回一个二进制数组.
- hmac_sha3_256("secret", "my authenticated message")
- hmac_sha3_512
用 sha3_512 计算 hmac. 返回一个二进制数组.
- hmac_sha3_512("secret", "my authenticated message")
- html_select
解析一个 html 文档并返回匹配 CSS 选择器的第一个元素. 返回值是一个表格, 其中 text 为内部文本, attrs 是元素属性的表格.
- csrf = html_select(html, 'input[name="csrf"]')
- token = csrf["attrs"]["value"]
- html_select_list
与 html_select 相同, 但返回所有匹配, 而不是第一个匹配.
- html_select_list(html, 'input[name="csrf"]')
- http_basic_auth
使用基本身份验证发送 GET 请求. 如果没有设置 WWW-Authenticate 头并且状态码不是 401, 则返回 true.
- http_basic_auth("https://httpbin.org/basic-auth/foo/buzz", user, password)
- http_mksession
创建一个 session 对象. 这与 python-request 中的 requests.Session 类似, 并且会跟踪 cookie.
- session = http_mksession()
- http_request
准备一个 http 请求. 第一个参数是从该会话被复制到请求中的会话引用和 cookies. 发送请求后, 响应中的 cookie 将被复制回会话中.
下一个参数是 method,url 和其他选项. 请注意, 即使没有设置选项, 你仍然需要指定一个空表{}. 有以下选项可用:
query - 应该在 url 上设置的查询参数的映射
headers - 应该设置的头映射
basic_auth - (未实现)使用 {"user,"password"} 配置基本 auth 标头}
user_agent - 用字符串覆盖默认的用户代理
json - 应该被 json 编码的请求体
form - 应该进行表单编码的请求体
body - 作为字符串的原始请求体
- req = http_request(session, 'POST', 'https://httpbin.org/post', {
- json={
- user=user,
- password=password,
- }
- })
- resp = http_send(req)
- if last_err() then return end
- if resp["status"] ~= 200 then return "invalid status code" end
- http_send
发送使用 http_request 构建的请求. 使用以下键返回表格:
status - http 状态码
headers - 表格头
text - 响应体作为字符串
- req = http_request(session, 'POST', 'https://httpbin.org/post', {
- json={
- user=user,
- password=password,
- }
- })
- resp = http_send(req)
- if last_err() then return end
- if resp["status"] ~= 200 then return "invalid status code" end
- json_decode
从 json 字符串解码 lua 值.
- json_decode("{\"data\":{\"password\":\"fizz\",\"user\":\"bar\"},\"list\":[1,3,3,7]}")
- json_encode
将 lua 值编码为 json 字符串. 请注意, 空表格被编码为空对象 {} 而不是空列表[].
- x = json_encode({
- hello="world",
- almost_one=0.9999,
- list={1,3,3,7},
- data={
- user=user,
- password=password,
- empty=nil
- }
- })
- last_err
如果未记录错误, 则返回 nil, 否则返回字符串.
- if last_err() then return end
- ldap_bind
连接到 ldap 服务器并尝试使用给定的用户进行身份验证.
- ldap_bind("ldaps://ldap.example.com/",
- "cn=\"" .. ldap_escape(user) .. "\",ou=users,dc=example,dc=com", password)
- ldap_escape
以相对专有名称转义属性值.
- ldap_escape(user)
- ldap_search_bind
连接到 ldap 服务器, 登录到用户搜索, 搜索目标用户并尝试使用搜索返回的第一个 DN 进行身份验证.
ldap_search_bind("ldaps://ldap.example.com/",
-- the user we use to find the correct DN
"cn=search_user,ou=users,dc=example,dc=com", "searchpw",
-- base DN we search in
- "dc=example,dc=com",
- -- the user we test
- user, password)
- md5
使用 md5 对字节数组哈希, 并将返回结果作为字节.
- hex(md5("\x00\xff"))
- mysql_connect
连接到一个 MySQL 数据库, 并尝试使用提供的凭据进行身份验证. 成功时返回 true.
- mysql_connect("127.0.0.1", 3306, user, password)
打印一个变量的值. 请注意为了避免带来不必要的麻烦, 建议仅在调试时使用.
- print({
- data={
- user=user,
- password=password
- }
- })
- rand
返回具有最小和最大约束的随机 u32. 返回值可以大于或等于最小边界, 并始终低于最大边界. 此功能尚未经过密码安全审查.
- rand(0, 256)
- randombytes
生成指定数量的随机字节.
- randombytes(16)
- sha1
使用 sha1 对一个字节数组哈希, 并将返回结果作为字节.
- hex(sha1("\x00\xff"))
- sha2_256
使用 sha2_256 对一个字节数组哈希, 并将返回结果作为字节.
- hex(sha2_256("\x00\xff"))
- sha2_512
使用 sha2_512 对一个字节数组哈希, 并将返回结果作为字节.
- hex(sha2_512("\x00\xff"))
- sha3_256
使用 sha3_256 对一个字节数组哈希, 并将返回结果作为字节.
- hex(sha3_256("\x00\xff"))
- sha3_512
使用 sha3_512 对一个字节数组哈希, 并将返回结果作为字节.
- hex(sha3_512("\x00\xff"))
- sleep
暂停该线程指定秒数. 这主要用于调试并发性.
sleep(3)
配置
你可以在~/.config/badtouch.toml 中放置一个配置文件来设置一些默认值.
- Global user agent
- [runtime]
- user_agent = "w3m/0.5.3+git20180125"
- RLIMIT_NOFILE
- [runtime]
- # requires CAP_SYS_RESOURCE
- # sudo setcap 'CAP_SYS_RESOURCE=+ep' /usr/bin/badtouch
- rlimit_nofile = 64000
编译 python 脚本
badtouch 运行时仍然非常的简陋, 因此你可能需要对常规 Python 脚本进行编译. 你的 wrapper 可能是这样的:
- descr = "example.com"
- function verify(user, password)
- ret = execve("./docs/test.sh", {user, password})
- if last_err() then return end
- if ret == 2 then
- return "script signaled an exception"
- end
- return ret == 0
- end
你的 python 脚本可能是这样的:
- import sys
- try:
- if sys.argv[1] == "foo" and sys.argv[2] == "bar":
- # correct credentials
- exit(0)
- else:
- # incorrect credentials
- exit(1)
- except:
- # signal an exception
- # this requeues the attempt instead of discarding it
- exit(2)
来源: http://www.tuicool.com/articles/BvmYfqF