黑客攻击-深入理解socket

左手的ㄟ右手 2023-02-22 05:15 150阅读 0赞

声明:谢绝一切形式的转载

socket套接字

socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,都可以用“打开open –> 读写write/read –> 关闭close”模式来操作。Socket就是该模式的一个实现, socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO、打开、关闭). 说白了Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议
在这里插入图片描述

TCP/IP

TCP三次握手

tcp的三次握手如下所示。
在这里插入图片描述
有很多面试官很特别容易问为什么两次不行?个人感觉,两次也不是不行。只是在有些情况下会产生无效的连接。
比如客户端发起连接,由于网络阻塞,服务器一直没有收到连接请求,客户端没有收到任何回应,启动重传机制,又发起了一次连接,这次很顺利,然后服务端正常返回信息,第二次的连接成功了。可是,万万没想到,那个阻塞的连接经过跋山涉水终于到了服务器端,此时服务器作何处理那
服务器端认为你咋又发了个请求呀,于是再次进行确认,客户端收到一条服务器端的一个确认,不予理会。可服务器却坚持认为连接已经成功,等待客户端传输数据,于是服务器的许多资源就浪费了。

抓包分析

个人认为,涉及到tcp/ip原理讲解的,空讲理论略显不足,甚至有点”耍流氓”的感觉。”三次握手,四次挥手”这种理论书本中讲述的很清楚了,下面以WireShark工具见证一下这个理论。

三次握手

在这里插入图片描述通过上面可以看出三次握手的流程

  1. 客户端向服务器端发送[SYN],seq=0
  2. 服务端向客户端返回[SYN,ACK] Ack=1 seq=0
  3. 客户端向服务器端返回[ACK] Ack=1
四次挥手

在这里插入图片描述在这里插入图片描述

tcp状态变迁图

在这里插入图片描述

基本的socket函数

使用socket编程用到的函数和基本流程如下:
在这里插入图片描述
注意:还有两个函数send和recieve。这两个函数比较容易望文生义,认为是send把数据发送出去。其实不是这样子的,只有当send把socket的发送缓冲区填满的时候数据才进行发送,通过TCP/IP协议进行发送。进行数据传输的是协议。

简单聊天系统

前面的理论知识还是很有必要了解的。之后开发程序就简单多了。先看以下效果:
在这里插入图片描述

服务器端代码

  1. /************************************************************************* > File Name: server.c > Author: 无情剑客 > Mail: 2250911301@qq.com > Created Time: 2020年7月1日21时43分10秒 ************************************************************************/
  2. #include<stdio.h>
  3. #include<stdlib.h>
  4. #include<string.h>
  5. #include<sys/types.h>
  6. #include<sys/socket.h>
  7. #include<unistd.h>
  8. #include<netinet/in.h>
  9. #include<arpa/inet.h>
  10. #define PORT 6666
  11. #define BACKLOG 10
  12. #define MAXDATASIZE 2048
  13. int main(int argc, char *argv[])
  14. {
  15. int listenfd;
  16. //创建一个socket描述符,此描述符仅是本主机上的一个普通文件描述符而已
  17. listenfd = socket(AF_INET, SOCK_STREAM, 0);
  18. //定义一个结构体变量servaddr,用来记录给定的IP和port信息,为bind函数做准备
  19. struct sockaddr_in serveraddr;
  20. bzero(&serveraddr, sizeof(serveraddr));
  21. serveraddr.sin_family = AF_INET;
  22. serveraddr.sin_port = htons(PORT); //把端口转化为网络字节序,即大端模式
  23. serveraddr.sin_addr.s_addr = INADDR_ANY;
  24. //把“本地含义的描述符”绑定到一个IP和Port上,此时这个socket才具备对外连接的能力
  25. bind(listenfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr));
  26. //创建一个监听队列,用来保存用户的请求连接信息(ip、port、protocol)
  27. listen(listenfd, BACKLOG);
  28. printf("======端口绑定成功,等待客户端的连接======\n");
  29. //让操作系统回填client的连接信息(ip、port、protocol)
  30. struct sockaddr_in peeraddr;
  31. socklen_t peer_len = sizeof(peeraddr);
  32. int connfd;
  33. while(1)
  34. {
  35. //accept函数从listen函数维护的监听队列里取一个客户连接请求处理
  36. connfd = accept(listenfd, (struct sockaddr*)&peeraddr, &peer_len);
  37. printf("\n=====================客户端链接成功=====================\n");
  38. printf("IP = %s:PORT = %d\n", inet_ntoa(peeraddr.sin_addr), ntohs(peeraddr.sin_port));
  39. char buf[MAXDATASIZE];
  40. while(1)
  41. {
  42. memset(buf, '\0', MAXDATASIZE/sizeof (char));
  43. int recv_length = recv(connfd, buf, MAXDATASIZE/sizeof (char), 0);
  44. if(recv_length == 0)
  45. {
  46. printf("客户端已经关闭!\n");
  47. break;
  48. }
  49. char vul_buffer[64] ;
  50. strcpy(vul_buffer,buf);
  51. printf("客户端说: ");
  52. fputs(vul_buffer, stdout);
  53. memset(buf, '\0', MAXDATASIZE/sizeof (char));
  54. printf("请输入: ");
  55. fgets(buf, sizeof(buf), stdin);
  56. send(connfd, buf, recv_length, 0);
  57. }
  58. close(connfd);
  59. close(listenfd);
  60. return 0;
  61. }
  62. }

这里使用了strcpy这个危险函数,后续文章会针对这个漏洞进行攻击。

客户端代码

  1. /************************************************************************* > File Name: client.c > Author: 无情剑客 > Mail: 2250911301@qq.com > Created Time: 2020年07月01日 星期三 21时44分37秒 ************************************************************************/
  2. #include<stdio.h>
  3. #include<stdlib.h>
  4. #include<string.h>
  5. #include<sys/types.h>
  6. #include<sys/socket.h>
  7. #include<unistd.h>
  8. #include<netinet/in.h>
  9. #define PORT 6666
  10. #define MAXDATASIZE 2048
  11. int main(int argc, char *argv[])
  12. {
  13. if(argc != 2)
  14. {
  15. fprintf(stderr, "请您输入ip地址!\n");
  16. exit(1);
  17. }
  18. int sockfd;
  19. sockfd = socket(AF_INET, SOCK_STREAM, 0);
  20. const char *server_ip = argv[1]; //从命令行获取输入的ip地址,此处没有对ip地址进行检验
  21. struct sockaddr_in serveraddr;
  22. bzero(&serveraddr, sizeof(serveraddr));
  23. serveraddr.sin_family = AF_INET;
  24. serveraddr.sin_port = htons(PORT);
  25. inet_pton(AF_INET, server_ip, &serveraddr.sin_addr);
  26. connect(sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr));
  27. printf("=====================服务器链接成功=====================\n");
  28. char buf[MAXDATASIZE];
  29. memset(buf, 0 , sizeof(buf));
  30. printf("请输入: ");
  31. //判断输入的内容是否是quit,如果输入quit,则关闭连接
  32. while(fgets(buf, sizeof(buf), stdin) != NULL && (strncmp(buf, "quit", 4)))
  33. {
  34. send(sockfd, buf, sizeof(buf), 0);
  35. memset(buf, 0, sizeof(buf));
  36. recv(sockfd, buf, sizeof(buf), 0);
  37. printf("服务器说: ");
  38. fputs(buf, stdout);
  39. memset(buf, 0, sizeof(buf));
  40. printf("请输入: ");
  41. }
  42. printf("客户端将要被关闭,下次再见\n");
  43. close(sockfd);
  44. return 0;
  45. }

使用如下命令进行编译

  1. gcc -o client client.c && gcc -o server server.c

注意:在判断是否是”quit”的时候,应该使用strncmp而不是strcmp

公众号

了解更多网络安全内容,欢迎关注我的公众号:无情剑客
在这里插入图片描述

发表评论

表情:
评论列表 (有 0 条评论,150人围观)

还没有评论,来说两句吧...

相关阅读

    相关 黑客攻击-木马程序(3)

    声明:禁止用作非法目的,谢绝一切形式的转载。 当你在登陆某个网站的时候,当你在用ftp登陆传输文件的时候,你的密码可能已经被嗅探到了。黑客利用网络嗅探可以获取大量有用的信息。

    相关 黑客攻击-木马程序(2)

    声明:本篇内容禁止用作非法目的,谢绝一切形式的转载 当你在登陆电脑的时候,当你在登陆淘宝的时候,当你在登陆微信的时候,你的输入可能正在被记录,然后电脑的登陆密码、微信帐号密码

    相关 黑客攻击-木马程序(1)

    声明:禁止用作非法目的,谢绝一切形式的转载。 当你在无意间点击一个链接后,当你在不明情况安装一个程序时,当你忍不住点击一个美女图片的时候,你的设备可能就此沦陷了,成为了黑客眼

    相关 终极社会工程黑客攻击

    虽然我们主要关注技术黑客,但社交工程有时可能特别有效。 这个需要一些技术技能,但不是太多。 此外,它受限于您可以选择的具体目标 - 但它会起作用。 什么是社会工程?