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] = '\0'; //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] = '\0'; //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] = '\0'; //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题的时候很痛苦,你只能眼睁睁看着其他人领先你