需求
实现攻击及修复网页的功能
代码总览(最后有完整代码)
#include <iostream>
#include <Windows.h>
#include <string>
#include <conio.h>
#include "hacker.h"
#define WIDTH 40
#define HIGH 15
int flag=1;
using namespace std;
void input(char password[]){...}//输入处理函数
void login(void){...}//登录函数
void menu_load(void){...}//菜单加载函数
int menucho(void){...}//菜单选择函数
void init(void){...}//初始化函数
void attack(void){...}//攻击函数
int main(void){
init();
login();
while(flag){
attack();
system("pause");
}
return 0;
}
主函数:调用初始化函数,调用登录函数,调用攻击函数.将代码封装在函数内能清晰的看出程序的结构.
接下来我们以主函数的视角讲解其他函数.
1.init()
void init(void){
char cmd[128];
sprintf_s(cmd,"mode con cols=%d lines=%d",WIDTH,HIGH);
system(cmd);
}
"mode con cols=? lines=?"是控制台的一条更改控制台宽度和高度的命令,在实际的需求中,高度和宽度可能会修改,所以我们这里不能写死了,用宏定义代替数字.然后是熟悉的sprintf,但我在这里使用了sprintf_s,因为发现了用sprintf会报警告,警告虽然不会影响程序的运行,但是可能会掩盖真正的错误!!! 所以尽量让你的程序没有警告.用sprintf_s将更改控制台宽度和高度的命令(字符串)写入定义好的字符数组cmd中,然后在system()里使用.
2.login()
void login(void){
string name;
char password[64];
while(1){
cout <<"请输入账号:";
cin >>name;
cout <<"请输入密码:";
input(password);
if(name=="54hk"&&!strcmp(password,"123456"))return;
else cout << "账号或密码错误!" << endl;
system("pause");
system("cls");
}
}
输出提示信息,输入账号密码,input()函数是对输入的密码的处理,如果账号密码都正确,就返回,如果错误就暂停system("pause");用户按下任意键后清屏system("cls");然后重新输入.
strcmp()是对比字符串的函数,如果相同就返回0,所以这里也可以写成if(name=="54hk"&&strcmp(password,"123456")==0)return;因为!0即真,所以!x作为条件时等同于x==0成立
3.input()
此函数实现了对密码输入的显示处理.大家在输入QQ密码的时候有没有注意到你写的密码并不会直接显示,而是只会显示一个*号,这里实现了这个功能.
void input(char password[]){
int i=0;
char ch;
while(1){
ch=getch();
if(ch=='\b'){
if(i>0){
i--;
cout <<'\b' <<" " <<'\b';
}
}
else if(ch!='\r'){
password[i++]=ch;
cout <<"*";
}
else {
password[i++]='\0';
cout <<endl;
return;
}
}
}
这里将数组作为参数传入,其本质是传入了一个指针,以后会详细讲解,这里不过多阐述.使用getch() 接收用户通过键盘输入的字符,与一般的输入不同,通过这个函数接收是没有回显的,也就是你在控制台上是看不到你输入的字符的.接收到的字符用ch变量储存.
判断输入是否结束的依据就是用户是否输入回车键,这里要注意一下:在不同平台,输入回车,getch()将返回不同数值.
- windows平台下回车键会产生两个转义字符 \r\n,因此getch返回13(\r).
- unix、 linux系统中回车键只产生 \n ,因此getch返回10(\n).
- MAC OS中回车键将产生 \r ,因此getch返回13(\r).
如果没有接收到回车和退格键(为什么有退格下面会讲解),将字符存入字符数组,输出一个*,如果接收到回车键,将\0(表示一个字符串结束的标志)存入字符数组中.
如果你在输入密码的时候输错了,按"Backspace"试图删除的时候却发现系统把"Backspace"当成了一个密码你会不会很抓狂?这会使用户体验很差,所以接收到"Backspace"(退格)的时候要另做处理,处理方法是输出退格\b和空格和退格\b,为什么要这样输出呢?事实上,输出退格\b只会让控制台上的光标前移一位,而不会覆盖光标前输出的字符,所以我们要输出空格清理掉一位输出,再将光标前移.i–的作用是清理掉一位字符数组里的密码,避免字符数组里存储错误的密码.i>0用于防止误删控制台上打印的提示信息.
4.文件hark.h
这是自定义文件hark.h的代码.#pragma once表示头文件只被编译一次.里面提供了攻击时使用的接口.
#pragma once
#include <iostream>
#define MAXSIZE 4096
//不指定编码,使用时可能导致乱码
//#pragma execution_character_set("utf-8")
//id指对应网站的端口号
// 服务器返回的结果是utf-8编码格式
int hk_404(char *id, char *response) ;
//恢复网站
int hk_restore(char *id, char *response);
//网页篡改攻击,para表示填充内容
int hk_tamper(char *id, char *para, char *response);
//查看攻击记录
int hk_record(char *id, char *response);
// 检查攻击是否成功
bool check_response(const char *response);
std::string UTF8ToGBK(const char* strUTF8);
void GBKToUTF8(std::string &strGBK);
我们还需导入一个.lib文件,它完成了hark.h中函数的具体实现,导入方法


关于.lib文件,在下一篇文章中会讲到.
5.attack()
从hark.h的注释可以知道进行攻击的需要传两个参数,一个是攻击的端口,一个是攻击返回的结果,attack()函数根据输入的选项进行不同的攻击.
void attack(void){
char id[64],response[4096],padding[64];
int cho=menucho();
switch(cho){
case 1:
cout <<"请输入要攻击的网站ID" <<endl;
scanf_s("%s",id,sizeof(id));
cout <<"404攻击开始..." <<endl;
hk_404(id,response);
cout <<UTF8ToGBK(response) <<endl;//返回结果
break;
case 2:
cout <<"请输入要篡改的网站ID" <<endl;
scanf_s("%s",&id,sizeof(id));
cout <<"请输入要篡改的内容" <<endl;
scanf_s("%s",padding,sizeof(padding));
cout <<"网站篡改攻击开始..." <<endl;
UTF8ToGBK(padding);
hk_tamper(id,padding,response);
cout <<UTF8ToGBK(response) <<endl;//返回结果
break;
case 3:
cout <<"请输入要恢复的网站ID" <<endl;
scanf_s("%s",&id,sizeof(id));
cout <<"开始恢复网站..." <<endl;
hk_restore(id,response);
cout <<UTF8ToGBK(response) <<endl;//返回结果
break;
case 4:
cout <<"请输入要查看的网站ID" <<endl;
scanf_s("%s",&id,sizeof(id));
hk_record(id,response);
cout <<UTF8ToGBK(response) <<endl;//返回结果
break;
case 5:flag=0;break;
default:
cout <<"无该选项!!!" <<endl;
break;
}
}
6.menucho()
这段代码很简单,不做过多解释,如果输入非法就清屏等待重新输入.
int menucho(void){
int cho=0;
while(1){
menu_load();
cin >> cho;
if(cin.fail()){
cin.clear();
fflush(stdin);
cout <<"非法输入!" <<endl;
}
else
break;
system("pause");
}
return cho;
}
7.menu_load()
void menu_load(void){
int maxlength=0;
system("cls");
string title="----攻击菜单----";
string str[]={
"1.网站404攻击",
"2.网站篡改攻击",
"3.网站攻击修复",
"4.查看攻击记录",
"5.退出"
};
for(int i=0;i<sizeof(str)/sizeof(str[0]);i++){
if(maxlength<(int)str[i].length())maxlength=str[i].length();
}
for(int i=0;i<(WIDTH-(int)title.length())/2;i++)cout <<" ";
cout << title <<endl;
for(int i=0;i<sizeof(str)/sizeof(str[0]);i++){//菜单居中显示
for(int j=0;j<(WIDTH-maxlength)/2;j++)cout <<" ";//打印空格
cout <<str[i] <<endl;
}
cout <<"请输入选项:";
}
此函数用于菜单的居中打印,计算居中需要多少空格,然后打印空格和菜单信息.
str[i].length()的意思是计算字符串str[i]的长度,其返回值是一个整数.string类中提供length()方法取得string的长度
效果
看完了全部代码的分析,是不是很想看效果?
攻击的页面:

项目登录界面:

开始!



(这个用的是谷歌)


完整代码
#include <iostream>
#include <Windows.h>
#include <string>
#include <conio.h>
#include "hacker.h"
#define WIDTH 40
#define HIGH 15
int flag=1;
using namespace std;
void input(char password[]){
int i=0;
char ch;
while(1){
ch=getch();
if(ch=='\b'){
if(i>0){
i--;
cout <<'\b' <<" " <<'\b';
}
}
else if(ch!='\r'){
password[i++]=ch;
cout <<"*";
}
else {
password[i++]='\0';
cout <<endl;
return;
}
}
}
void login(void){
string name;
char password[64];
while(1){
cout <<"请输入账号:";
cin >>name;
cout <<"请输入密码:";
input(password);
if(name=="54hk"&&!strcmp(password,"123456"))return;
else cout << "账号或密码错误!" << endl;
system("pause");
system("cls");
}
}
void menu_load(void){
int maxlength=0;
system("cls");
string title="----攻击菜单----";
string str[]={
"1.网站404攻击",
"2.网站篡改攻击",
"3.网站攻击修复",
"4.查看攻击记录",
"5.退出"
};
for(int i=0;i<sizeof(str)/sizeof(str[0]);i++){
if(maxlength<(int)str[i].length())maxlength=str[i].length();
}
for(int i=0;i<(WIDTH-(int)title.length())/2;i++)cout <<" ";
cout << title <<endl;
for(int i=0;i<sizeof(str)/sizeof(str[0]);i++){//菜单居中显示
for(int j=0;j<(WIDTH-maxlength)/2;j++)cout <<" ";//打印空格
cout <<str[i] <<endl;
}
cout <<"请输入选项:";
}
int menucho(void){
int cho=0;
while(1){
menu_load();
cin >> cho;
if(cin.fail()){
cin.clear();
fflush(stdin);
cout <<"非法输入!" <<endl;
}
else
break;
system("pause");
}
return cho;
}
void init(void){
char cmd[128];
sprintf_s(cmd,"mode con cols=%d lines=%d",WIDTH,HIGH);
system(cmd);
}
void attack(void){
char id[64],response[4096],padding[64];
int cho=menucho();
switch(cho){
case 1:
cout <<"请输入要攻击的网站ID" <<endl;
scanf_s("%s",id,sizeof(id));
cout <<"404攻击开始..." <<endl;
hk_404(id,response);
cout <<UTF8ToGBK(response) <<endl;//返回结果
break;
case 2:
cout <<"请输入要篡改的网站ID" <<endl;
scanf_s("%s",&id,sizeof(id));
cout <<"请输入要篡改的内容" <<endl;
scanf_s("%s",padding,sizeof(padding));
cout <<"网站篡改攻击开始..." <<endl;
UTF8ToGBK(padding);
hk_tamper(id,padding,response);
cout <<UTF8ToGBK(response) <<endl;//返回结果
break;
case 3:
cout <<"请输入要恢复的网站ID" <<endl;
scanf_s("%s",&id,sizeof(id));
cout <<"开始恢复网站..." <<endl;
hk_restore(id,response);
cout <<UTF8ToGBK(response) <<endl;//返回结果
break;
case 4:
cout <<"请输入要查看的网站ID" <<endl;
scanf_s("%s",&id,sizeof(id));
hk_record(id,response);
cout <<UTF8ToGBK(response) <<endl;//返回结果
break;
case 5:flag=0;break;
default:
cout <<"无该选项!!!" <<endl;
break;
}
}
int main(void){
init();
login();
while(flag){
attack();
system("pause");
}
return 0;
}
后记
到这里为止黑客攻击系统已经结束了,从整体来看,它和我们在学校里写的学生信息管理系统难度上并无差别.现在是使用别人提供的静态链接库,相信将来我也能自己做出一个强大的静态链接库.现在虽然只学了一些基础,但也算是走上了c++的路,前面会有什么等着我?类与对象?STL?c++流?线程?我不得而知…
该博客围绕用C++实现攻击及修复网页的功能展开。介绍了主函数调用的初始化、登录、攻击等函数,如init()更改控制台宽高,login()处理账号密码输入,input()实现密码显示处理等。还提及自定义文件hark.h及攻击函数attack()等,最后给出完整代码。
256

被折叠的 条评论
为什么被折叠?



