Я написал C программу, которая прослушивает порт 443 и принимает пакеты SSL, обрабатывает их и отправляет ответ:
#include <errno.h>
#include <ctype.h>
#include <limits.h>
#include <string.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/stat.h>
#include <stdio.h>
#define MAX_SIZE 10000
struct server_hello {
//struct ssl_header hdr;
uint8_t hdr_type;
uint8_t hdr_version_1;
uint8_t hdr_version_2;
uint16_t hdr_length;
uint8_t type;
unsigned int len:24;
uint8_t ssl_version_1;
uint8_t ssl_version_2;
char random[32];
uint8_t session_id_len;
char session_id[32];
uint16_t ciphersuite;
};
int client_hello (int sock) {
struct server_hello *sh ;
sh = calloc (1, sizeof (struct server_hello));
sh->hdr_type = 22;
sh->hdr_version_1 =3;
sh->hdr_version_2 =3;
sh->hdr_length =73;
sh->type =2;
sh->len =69;
sh->ssl_version_1 =3;
sh->ssl_version_2 = 3;
strcpy(sh->random, "971bf9f29cbc9f938a20ee1237da6499b441aabf79ba2e9d271d75e11ad52ca8");
sh->session_id_len= 0 ; //if 0 , there is no session_id
//strcpy(sh->session_id, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
sh->ciphersuite=49195;
// sh->ciphersuite=0;
write (sock, sh , sizeof(struct server_hello));
return 0;
}
void *message_processing(int sockfd){
char *buff = calloc(MAX_SIZE + 1, sizeof (char));
/*struct handshake *pkt;
pkt = calloc (1, sizeof (struct handshake)); */
while (1) {
int len_of_read_data = read( sockfd, buff, MAX_SIZE);
if (len_of_read_data > 0) {
FILE* file = fopen("logfile", "a");
fprintf(file, "ssl type : %d\n", ntohl((int) buff[0]));
fprintf(file, "ssl version : %d.%d\n", ntohl((int) buff[1]), ntohl((int) buff[2]));
fprintf(file, "ssl length : %d%d\n",ntohl((int) buff[3]),ntohl((int) buff[4]));
fprintf(file, "handshake type : %d\n",ntohl ((int) buff[5]) );
fprintf(file, "handshake len : %d%d%d\n",ntohl((int)buff[6]), ntohl((int)buff[7]), ntohl((int)buff[8]) );
fprintf(file, "ssl version : %d.%d\n", ntohl((int)buff[9]), ntohl((int)buff[10]) );
int pkt_type = (int) buff[0];
if (pkt_type == 22 ) {
int handshake_type = (int)buff[5];
if (handshake_type == 1)
client_hello(sockfd);
}
}
}
}
int main () {
struct sockaddr_in serv_addr;
int sock_descriptor = socket(AF_INET, SOCK_STREAM, 0);
int trueval = 1;
setsockopt(sock_descriptor, SOL_SOCKET, SO_REUSEPORT | SO_REUSEADDR, (char *)&trueval, sizeof(trueval));
bzero((char *) &serv_addr, sizeof (serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(443);
bind(sock_descriptor, (struct sockaddr *) &serv_addr, sizeof (serv_addr));
listen(sock_descriptor, 50);
while (1) {
struct sockaddr_in cli_addr;
socklen_t clilen;
clilen = sizeof(cli_addr);
int client_socket = accept(sock_descriptor, (struct sockaddr *) &cli_addr, &clilen);
message_processing(client_socket);
//pthread_t pid;
// pthread_create(&pid, NULL, (void *) message_processing, &client_socket);
//pthread_join(pid, NULL);
}
}
Я подключаюсь к сокету, используя:
curl -I https://10.10.10.101:443 --insecure --sslv3
Я создаю структуру ответа с именем sh и записываю ее в сокет (в функции client_hello), затем использую wireshark на клиенте. в ответном пакете на клиентской машине есть некоторые дополнительные байты, которые я не установил, например, второй 00000000 перед последним байтом:
00010110 00000011 00000011 00000000 01001001 00000000 00000010
Это приводит к тому, что клиент не может правильно определить поля пакета, и я получаю это ошибка как вывод curl:
curl: (35) error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol
Кто-нибудь может помочь, как я могу удалить эти дополнительные байты из пакета?