telnet 会话的客户端与服务器(C/C++代码实现)
telnet 是一种网络虚拟终端协议。是用于在远程主机上运行程序的标准 TCP/IP 协议。术语telnet也指在特定平台或系统上实现此协议的软件(客户端或服务器组件), telnet 在RFC854 中定义。Telnet 的工作原理telnet 是一个终端仿真程序,它是一个命令行界面,用于在远程计算机上发出命令。 运行 telnet 客户端软件的用户可以在运行 telnet 服务或守护程序的远程
telnet 是一种网络虚拟终端协议。是用于在远程主机上运行程序的标准 TCP/IP 协议。术语telnet也指在特定平台或系统上实现此协议的软件(客户端或服务器组件), telnet 在RFC854 中定义。
Telnet 的工作原理
telnet 是一个终端仿真程序,它是一个命令行界面,用于在远程计算机上发出命令。 运行 telnet 客户端软件的用户可以在运行 telnet 服务或守护程序的远程主机上交互地运行命令行应用程序。 用户在telnet客户端输入信息; 此信息在 telnet 服务器上进行处理,并将其输出返回给用户。
如果你使用 telnet 连接到 linux 服务器,您可以发出 linux 命令来远程在该服务器上执行操作
客户端:
服务器:
telnet 用户命令
1.cd命令
cd XxxService: 改变缺省服务,当设置了缺省服务,凡是需要输入服务名作为参数的命令,都可以省略服务参数
cd /: 取消缺省服务
2.pwd命令
pwd: 显示当前缺省服务
3.ls命令
ps: 显示服务端口列表
ps -l: 显示服务地址列表
ps 5050: 显示端口上的连接信息
ps -l 5050: 显示端口上的连接详细信
4.status命令
status: 显示汇总状态,该状态将汇总所有资源的状态,当全部 OK 时则显示 OK,只要有一个 ERROR 则显示 ERROR,只要有一个 WARN 则显示 WARN
status -l: 显示状态列表
5.clear命令
clear: 清除屏幕上的内容
clear 100: 清除屏幕上的指定行数的内
6.exit命令
exit: 退出当前 telnet 命令
7.shutdown 命令
shutdown: 关闭 dubbo 应用
shutdown -t 1000: 延迟 1000 毫秒关闭 dubbo 应用
命令太多,这里就不一一列举了。
telnet客户端与服务器C/C++代码实现
client:
int main(int argc, char *argv[])
{
if (argc == 5)
{
destination = argv[1];
portN = atoi(argv[2]);
c_username = argv[3];
c_password = argv[4];
//printf("SHA1 password: %s \n", c_password);
}
else
usage(argv[0]);
//将密码转换为sha1格式
int i = 0;
unsigned char temp[SHA_DIGEST_LENGTH];
char buf[SHA_DIGEST_LENGTH * 2];
memset(buf, 0x0, SHA_DIGEST_LENGTH * 2);
memset(temp, 0x0, SHA_DIGEST_LENGTH);
SHA1((unsigned char *) argv[4], strlen(argv[4]), temp);
for (i = 0; i < SHA_DIGEST_LENGTH; i++)
{
sprintf((char*) &(buf[i * 2]), "%02x", temp[i]);
}
//printf("SHA1 of %s is %s\n", argv[4], buf);
RemoteShell(destination, portN, c_username, buf);
return 0;
}
客户端向服务器提供用户名和密码哈希(sha1 哈希),客户端发送的用户名加密,服务器收到后解密
server:
int main(int argc, char *argv[])
{
if (argc == 3)
{
portN = atoi(argv[1]);
char buf[100];
FILE *ptr_file = fopen(argv[2], "r");
if (!ptr_file)
return 1;
int mcr = 0;
while (fgets(buf, 1000, ptr_file) != NULL)
fclose(ptr_file);
server_user = strtok(buf, ";");
server_psw = strtok(NULL, ";");
strcpy(s_uid,server_user);
strcpy(s_phash,server_psw);
} else
usage(argv[0]);
/*
printf("User_ID: %s\n", server_user);
printf("Password_Hash: %s\n", server_psw); */
msock = serverTCPsock(portN, 5, server_user, server_psw);
printf("Waiting for client to connect....\n");
(void) signal(SIGCHLD, reaper);
while (1)
{
fromAddrLen = sizeof(fromAddr);
ssock = accept(msock, (struct sockaddr *) &fromAddr, &fromAddrLen);
if (ssock < 0)
{
if (errno == EINTR)
continue;
errmesg("accept errorn");
}
read(ssock, uid, 5);
read(ssock, phash, 50);
if((strcmp(s_uid, uid) != 0) || (strcmp(s_phash, phash) != 0))
{
printf("Failed to authenticate!\n");
printf("Connection to client '%s' closed!\n\n", uid);
close(ssock);
}
else
printf("Connection to client '%s' successful!\n\n", uid);
switch (fork())
{
case 0: /* child */
close(msock);
r = RemoteShellD(ssock);
close(ssock);
exit(r);
default: /* parent */
(void) close(ssock);
break;
case -1:
errmesg("fork errorn");
}
}
close(msock);
}
服务器执行客户端发送的命令并将结果返回给客户端。打开一个端口并让多个客户端连接到该端口,将用户名和密码哈希与其密码文件中的可用值进行比较。
运行结果
client:
./client localhost <端口> <用户名> <密码>
使用原始加密,用户名的每个字符都用一个密钥值更改,密码使用 sha1 散列进行散列。
server:
./server < port > password.txt
服务器打开端口后,客户端尝试通过发送用户名和密码哈希来连接端口 。 服务器读取从客户端收到的用户名和密码,解密用户名并将收到的密码哈希与 password.txt 文件中的哈希进行比较。
只有在验证了用户名和密码之后,服务器才会接受来自客户端的任何命令。
tshark 抓包:
总结
可以使用 telnet 客户端连接到端口 80 上的 Web 服务器或端口 25 上的简单邮件传输协议 (SMTP) 邮件服务器,然后直接向服务器发出超文本传输协议 (HTTP) 或 SMTP 命令以进行故障排除。
最后,由于在开放网络上使用 telnet 时的安全问题,telnet 的使用被拒绝,而转而使用 SSH。telnet 缺乏身份验证策略和数据加密。
参考:1.RFC854
2.https://docs.oracle.com/cd/E56344_01/html/E54075/telnet-1.html
欢迎关注微信公众号【程序猿编码】,需要telnet完整源码的添加本人微信号(c17865354792)
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)