• WinSocket编程笔记(四)


    这里附上先前(三)中的实验,AS与ALICE通信时,ALICE客户端的完整代码

    #include <iostream>
    #include <stdio.h>
    #include <winsock2.h>
    #pragma comment(lib,"ws2_32.lib")
    using namespace std;
    #define BUF_SIZE 100
    const int PORT = 8000;
    int main()
    {
        WORD sockVersion = MAKEWORD(2, 2);
    
        WSADATA data;
    
        if (WSAStartup(sockVersion, &data) != 0)
    
        {
    
            return 1;
    
        }
        SOCKET clientSocket = socket(AF_INET, SOCK_STREAM,0);
            if (clientSocket == INVALID_SOCKET){
                cout << "Socket error" << endl;}
        SOCKADDR_IN ListenAddr;
        ListenAddr.sin_family=AF_INET;
        ListenAddr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");;
        ListenAddr.sin_port=htons(PORT);
    //connect
        int ret=0;
        ret=connect(clientSocket,(sockaddr*)&ListenAddr, sizeof(struct sockaddr_in));
    //send
        char name[BUF_SIZE] = {"ALICE"};
        send(clientSocket, name, BUF_SIZE, 0);
        char secret[BUF_SIZE] = {"12345"};
        send(clientSocket, secret, BUF_SIZE, 0);
    //recv
        char buffRecv[BUF_SIZE]={0};
        recv(clientSocket,buffRecv,BUF_SIZE,0);
        cout<<"KA加密以后的TGT:"<<buffRecv<<endl;
        char buffRecv2[BUF_SIZE]={0};
        recv(clientSocket,buffRecv2,BUF_SIZE,0);
        cout<<"KA加密以后的KSkey:"<<buffRecv2<<endl;
    //解密
        int key=12345;
        //char转string,buffRecv -> cipher
        string plain ="";
        string cipher=buffRecv;
        int offset = key % 26;
        for(int i = 0; i < cipher.length(); i++)
        {
            char c = cipher[i];
            if(isalpha(c))
            {
                if(c >= 'a' && c <= 'z')
                {
                    c = 'z' - (('z' - c + offset) % 26);
                    plain += c;
                }
                else
                {
                    c = 'Z' - (('Z' - c + offset) % 26);
                    plain += c;
                }
            }
            else if(isdigit(c))
                {
                    c = '9' - (('9' - c + offset) % 10);
                    plain += c;
                }
                else
                {
                    plain += c;
                }
        }
        cout<<"解密以后的TGT:"<<plain<<endl;
        string plain2 ="";
        string cipher2=buffRecv2;
        for(int i = 0; i < cipher2.length(); i++)
        {
            char c2 = cipher2[i];
            if(isalpha(c2))
            {
                if(c2 >= 'a' && c2 <= 'z')
                {
                    c2 = 'z' - (('z' - c2 + offset) % 26);
                    plain2 += c2;
                }
                else
                {
                    c2 = 'Z' - (('Z' - c2 + offset) % 26);
                    plain2 += c2;
                }
            }
            else if(isdigit(c2))
                {
                    c2 = '9' - (('9' - c2 + offset) % 10);
                    plain2 += c2;
                }
                else
                {
                    plain2 += c2;
                }
        }
        cout<<"解密以后的明文KSkey:"<<plain2<<endl;
        //不让程序结束
        while(1)
        {
    
        }
    //closesocket
        closesocket(clientSocket);
    
        return 0;
    }

    上面的代码只能实现一次通信,而且仅限于和AS通信接收TGT和KS

    关于如何实现Kerberos的完整通信

    因为Kerberos通信时AS每次生成的随机会话密钥不同,所以我们不能多次通信,必须要一次完成实验。所以可行的方法有存入文件,或者一次连接多个服务器端。我选择了后者,客户端只要做到每次通信完成以后断开服务器端就能一次性和三个服务器端进行通信。而服务器端需要先打开监听端口,不然客户端只会返回空内容。

    修改以后能一次性和多个服务器通信的ALICE客户端

    同时做到接收和发送TGT和KS,接收和发送Ticket和KAB,接收BOB服务器端加密发送的消息:

    #include <iostream>
    #include <stdio.h>
    #include <winsock2.h>
    #include<string.h>
    #pragma comment(lib,"ws2_32.lib")
    using namespace std;
    #define BUF_SIZE 100
    const int PORT = 8000;
    const int PORT2 = 8002;
    const int PORT3 = 8001;
    int main()
    {   //定义两个全局变量,之后会用来接收BOB主密钥加密的ALICE和Kab
        char RECV[BUF_SIZE]={0};
        char RECV2[BUF_SIZE]={0};
        int KKAB=0;
        WORD sockVersion = MAKEWORD(2, 2);
    
        WSADATA data;
    
        if (WSAStartup(sockVersion, &data) != 0)
    
        {
    
            return 1;
    
        }
        SOCKET clientSocket = socket(AF_INET, SOCK_STREAM,0);
            if (clientSocket == INVALID_SOCKET){
                cout << "Socket error" << endl;}
        SOCKADDR_IN ListenAddr;
        ListenAddr.sin_family=AF_INET;
        ListenAddr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");;
        ListenAddr.sin_port=htons(PORT);
    //connect
        int ret=0;
        ret=connect(clientSocket,(sockaddr*)&ListenAddr, sizeof(struct sockaddr_in));
    //send
        char name[BUF_SIZE] = {"ALICE"};
        send(clientSocket, name, BUF_SIZE, 0);
        char secret[BUF_SIZE] = {"12345"};
        send(clientSocket, secret, BUF_SIZE, 0);
    //recv
        char buffRecv[BUF_SIZE]={0};
        recv(clientSocket,buffRecv,BUF_SIZE,0);
        cout<<"接收到的加密以后的TGT:"<<buffRecv<<endl;
        char buffRecv2[BUF_SIZE]={0};
        recv(clientSocket,buffRecv2,BUF_SIZE,0);
        cout<<"接收到的加密以后的KSkey:"<<buffRecv2<<endl;
    //解密
        int key=12345;
        //char转string,buffRecv -> cipher
        string plain ="";
        string cipher=buffRecv;
        int offset = key % 26;
        for(int i = 0; i < cipher.length(); i++)
        {
            char c = cipher[i];
            if(isalpha(c))
            {
                if(c >= 'a' && c <= 'z')
                {
                    c = 'z' - (('z' - c + offset) % 26);
                    plain += c;
                }
                else
                {
                    c = 'Z' - (('Z' - c + offset) % 26);
                    plain += c;
                }
            }
            else if(isdigit(c))
                {
                    c = '9' - (('9' - c + offset) % 10);
                    plain += c;
                }
                else
                {
                    plain += c;
                }
        }
        cout<<"解密以后的TGT:"<<plain<<endl;
        string plain2 ="";
        string cipher2=buffRecv2;
        for(int i = 0; i < cipher2.length(); i++)
        {
            char c2 = cipher2[i];
            if(isalpha(c2))
            {
                if(c2 >= 'a' && c2 <= 'z')
                {
                    c2 = 'z' - (('z' - c2 + offset) % 26);
                    plain2 += c2;
                }
                else
                {
                    c2 = 'Z' - (('Z' - c2 + offset) % 26);
                    plain2 += c2;
                }
            }
            else if(isdigit(c2))
                {
                    c2 = '9' - (('9' - c2 + offset) % 10);
                    plain2 += c2;
                }
                else
                {
                    plain2 += c2;
                }
        }
        cout<<"解密以后的KSkey:"<<plain2<<endl;
        //KSkey从string转char
        //string转char,plain2 -> pp
            char pp[100];
            int i0;
            for( i0=0;i0<plain2.length();i0++)
            {
                pp[i0] = plain2[i0];
            }
            pp[i0] = '';
        //KSkey从char转成int(不能从string直接转int)
        int INTKSkey=0;
        INTKSkey=atoi(pp);
        cout<<"与AS通信完毕!"<<endl;
    //closesocket
        closesocket(clientSocket);
        WSACleanup();
    
        int U;
        cout<<"---------------------输入数字1与TGS进行连接---------------------"<<endl;
        cout<<"请输入数字:"<<endl;
        cin>>U;
        if(U==1){
    //再开启
        WORD sockVersion = MAKEWORD(2, 2);
    
        WSADATA data;
    
        if (WSAStartup(sockVersion, &data) != 0)
    
        {
    
            return 1;
    
        }
        SOCKET client2Socket = socket(AF_INET, SOCK_STREAM,0);
            if (client2Socket == INVALID_SOCKET){
                cout << "Socket error" << endl;}
        SOCKADDR_IN ListenAddr2;
        ListenAddr2.sin_family=AF_INET;
        ListenAddr2.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");;
        ListenAddr2.sin_port=htons(PORT2);
    //connect TGS
        int ret2=0;
        ret2=connect(client2Socket,(sockaddr*)&ListenAddr2, sizeof(struct sockaddr_in));
            //string转char,明文TGT-> T
            char T[100];
            int i;
            for( i=0;i<plain.length();i++)
            {
                T[i] = plain[i];
            }
            T[i] = '';
            //string转char,KSkey -> Y
    
            //send
            send(client2Socket, T, BUF_SIZE, 0);
            char sendd[BUF_SIZE] = {"BOB"};
            send(client2Socket, sendd, BUF_SIZE, 0);
            send(client2Socket, pp, BUF_SIZE, 0);
            //recv
            char buffRecv3[BUF_SIZE]={0};
            recv(client2Socket,buffRecv3,100,0);
            cout<<"BOB主密钥加密以后的ALICE:"<<buffRecv3<<endl;
            //存入全局变量,后面还要调用
            memcpy(RECV,buffRecv3, strlen(buffRecv3));
            char buffRecv4[BUF_SIZE]={0};
            recv(client2Socket,buffRecv4,100,0);
            cout<<"BOB主密钥加密以后的Kab:"<<buffRecv4<<endl;
            //存入全局变量,后面还要调用
            memcpy(RECV2,buffRecv4, strlen(buffRecv4));
            char buffRecv5[BUF_SIZE]={0};
            recv(client2Socket,buffRecv5,100,0);
            cout<<"KS加密以后的BOB:"<<buffRecv5<<endl;
            char buffRecv6[BUF_SIZE]={0};
            recv(client2Socket,buffRecv6,100,0);
            cout<<"KS加密以后的Kab:"<<buffRecv6<<endl;
    
            //KS解密Kab
            string plain4 ="";
            string cipher4=buffRecv6;
            int offset4 = INTKSkey % 26;
            int i4;
            for( i4 = 0; i4 < cipher4.length(); i4++)
            {
                char c4 = cipher4[i4];
                if(isalpha(c4))
                {
                if(c4 >= 'a' && c4 <= 'z')
                {
                    c4 = 'z' - (('z' - c4 + offset4) % 26);
                    plain4 += c4;
                }
                else
                {
                    c4 = 'Z' - (('Z' - c4 + offset4) % 26);
                    plain4 += c4;
                }
                }
                else if(isdigit(c4))
                {
                    c4 = '9' - (('9' - c4 + offset4) % 10);
                    plain4 += c4;
                }
                else
                {
                    plain4 += c4;
                }
            }
            cout<<"解密以后的明文KAB:"<<plain4<<endl;
            //string转int,并存入全局变量
            //先转char
            //plain4转char,plain4 -> p4
            char p4[100];
            int i5;
            for( i5=0;i5<plain4.length();i5++)
            {
                p4[i5] = plain4[i5];
            }
            p4[i5] = '';
            //KAB从char转成int(不能从string直接转int)
            int INTKAB=0;
            INTKAB=atoi(p4);
            KKAB=INTKAB;
    
            //KS解密BOB
            string plain3 ="";
            string cipher3=buffRecv5;
            int offset3 = INTKSkey % 26;
            int i3;
            for( i3 = 0; i3 < cipher3.length(); i3++)
            {
                char c3 = cipher3[i3];
                if(isalpha(c3))
                {
                if(c3 >= 'a' && c3 <= 'z')
                {
                    c3 = 'z' - (('z' - c3 + offset3) % 26);
                    plain3 += c3;
                }
                else
                {
                    c3 = 'Z' - (('Z' - c3 + offset3) % 26);
                    plain3 += c3;
                }
                }
                else if(isdigit(c3))
                {
                    c3 = '9' - (('9' - c3 + offset3) % 10);
                    plain3 += c3;
                }
                else
                {
                    plain3 += c3;
                }
            }
            cout<<"解密以后的BOB:"<<plain3<<endl;
            if(plain3=="BOB")
            {
                cout<<"与TGS传输成功!"<<endl;
            }
            closesocket(client2Socket);
            WSACleanup();
        }
    
        int U2;
        cout<<"---------------------输入数字1与BOB进行连接---------------------"<<endl;
        cout<<"请输入数字:"<<endl;
        cin>>U2;
        if(U2==1){
    //再开启
        WORD sockVersion = MAKEWORD(2, 2);
    
        WSADATA data;
    
        if (WSAStartup(sockVersion, &data) != 0)
    
        {
    
            return 1;
    
        }
        SOCKET client3Socket = socket(AF_INET, SOCK_STREAM,0);
            if (client3Socket == INVALID_SOCKET){
                cout << "Socket error" << endl;}
        SOCKADDR_IN ListenAddr3;
        ListenAddr3.sin_family=AF_INET;
        ListenAddr3.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");;
        ListenAddr3.sin_port=htons(PORT3);
    //connect TGS
        int ret3=0;
        ret3=connect(client3Socket,(sockaddr*)&ListenAddr3, sizeof(struct sockaddr_in));
    //send
        send(client3Socket, RECV, BUF_SIZE, 0);
        Sleep(1000);
        send(client3Socket, RECV2, BUF_SIZE, 0);
    //recv
        char buffRecv8[BUF_SIZE]={0};
        recv(client3Socket,buffRecv8,100,0);
        cout<<"接收到的信息:"<<buffRecv8<<endl;
    //KAB解密消息
        string plain8 ="";
        string cipher8=buffRecv8;
        int offset8 = KKAB % 26;
        for(int i8 = 0; i8 < cipher8.length(); i8++)
        {
            char c8 = cipher8[i8];
            if(isalpha(c8))
            {
                if(c8 >= 'a' && c8 <= 'z')
                {
                    c8 = 'z' - (('z' - c8 + offset8) % 26);
                    plain8 += c8;
                }
                else
                {
                    c8 = 'Z' - (('Z' - c8 + offset8) % 26);
                    plain8 += c8;
                }
            }
            else if(isdigit(c8))
                {
                    c8 = '9' - (('9' - c8 + offset8) % 10);
                    plain8 += c8;
                }
                else
                {
                    plain8 += c8;
                }
        }
        cout<<"接收成功!"<<endl;
        cout<<"解密以后的消息:"<<plain8<<endl;
        closesocket(client3Socket);
        WSACleanup();
        }
    
    
    
        //程序不退出
        while(1)
        {
    
        }
        return 0;
    }

    (待续)

    [Sign]做不出ctf题的时候很痛苦,你只能眼睁睁看着其他人领先你
  • 相关阅读:
    BZOJ 1036 树的统计
    codevs 4712 gcd与lcm问题
    codevs 1574 矩阵乘法
    Python定时任务框架APScheduler
    PHP集成支付宝快速实现充值功能
    玩转Web之easyui(二)-----easy ui 异步加载生成树节点(Tree),点击树生成tab(选项卡)
    玩转Web之easyui(一)-----easy ui datagird 分页
    Android访问服务器(TOMCAT)乱码引发的问题
    工厂方法模式--结合具体例子学习工厂方法模式
    简单工厂模式--结合实例学习简单工厂模式
  • 原文地址:https://www.cnblogs.com/echoDetected/p/12699419.html
Copyright © 2020-2023  润新知