博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Linux编程之给你的程序开后门
阅读量:5023 次
发布时间:2019-06-12

本文共 6097 字,大约阅读时间需要 20 分钟。

switch(args[0][0])  //解析指令,看每个指令对应哪些意思        {            case 'd':    //display                switch(args[1][0])                {                    case 'q':   //display queue                    show_MQ(fd);                    break;                    case 'd':   //display debug                    show_debug_level(fd);                    break;                     default:                        help_manual(fd);                        break;                }                break;             case 's':    //set                switch(args[1][0])                {                    case 'd': //set debug level                    n = atoi(args[2]);  //将字符串转化为整数                    fprintf(fd," debug level change from %d to %d",global.debug_level,n);                    global.debug_level = n;  //更改log级别                    break;                     default:                        help_manual(fd);                        break;                }                break;             default:                help_manual(fd);                break;        }

 

四、搭建debug界面
先上界面图:

我们敲的每个命令都是通过该界面传递到程序那头的,比如“d d”就表示展示出现在系统运行时的log级别,而“s d”就是设置我们想要看的log级别,这样我们就可以实现通过程序后门动态修改程序走向了。
那该如何实现这个看似简单的交互界面呢?实现该交互界面,有几个关键点:
  • 我们需将程序的打印输出重定向到一个文件里
  • 使用shell脚本读出文件的内容
  • 我们输入的命令需写入到fifo中
以上三点就是做成界面的最重要的技术问题。
  1. 重定向输出
  一开始我是打算将标准输出、标准错误都重定向到文件里的额,但是想了想,还是想直接把打印内容直接输出到文件就好了。比如这样:
fd = fopen("/vob/ljsdpoenew3/exercise/debug_log2", "w+");    if(fd == NULL)    {        MY_LOG(DEBUG, "open debug_log2 fail!\n");        pthread_exit(0);    }fprintf(fd," debug level change from %d to %d",global.debug_level,n);
  这样我们在debug center产生的打印都输出到文件debug_log2上了。

  2.利用脚本读出内容且将内容写入fifo

  要做到这点需要shell编程的简单知识,我们怎么将我们的输入放到fifo呢?我们怎么把log文件的内容读出来显示在显示屏呢?我想到首先是再写个client,进行进程间通信嘛,将命令写到fifo,同时也读出log文件的内容。但是,我发现利用shell就可以做到以上的事了,而且只需花费几行代码。
 
#!/bin/bash my_inp_fifo=/vob/ljsdpoenew3/exercise/debug_log    # 指定fifo文件stty erase ^H     while [ true ];do         read inp    #循环读入用户输入        if [ "$inp" == "quit" ];then   #quit代表结束该界面                exit 0        fi        echo $inp > $my_inp_fifo   #写入fifo        cat debug_log2.txt         #显示log的内容done

 

那看看这个命令行界面跑起来是怎么的吧!
首先我们运行server进程
 
sever进程不断产生消息并处理消息。
我们打开另一个窗口,并执行脚本./test.sh,进入界面
 
 
我们使用了d d命令看到了程序此时的debug级别,用d q看出了程序消息队列的情况。
 
 
我们使用了s d指令将debug level设置为0,此时屏幕没有任何打印输出,当我们在使用s d指令将level设置为-1(即将所有位置一),此时所有打印级别都打开了,屏幕又开始疯狂打印了。也就说,我们通过后门操控了程序,这里我们只是仅仅修改了程序的log级别,当然我们还可以做更多的事,只要依照这个框架往里面加指令,以及对应的处理操作,就可以实现了。
五、总结
所谓后门,就是一个可以操控程序的接口,这个接口仅仅用于开发者调试开发,不会开放给客户。所以这个后门的作用非常巨大,所以是开发者调试程序的一大利器。有人会想,我想用socket来代替fifo进行进程通信可以不,这样就可以做到远程主机操控程序了。我觉得是可以的,但是感觉利用telnet到目的主机再运行脚本操作比较安全。
最后给出源代码框架
1 #include 
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include "msg_def.h" 9 #include "global.h" 10 11 extern Queue_t MsgQueue; 12 extern dashboard_t global; 13 14 15 #define MAX_NUM_ARGS 20 16 #define MAX_ARGS_SIZE 56 17 18 static char args[MAX_NUM_ARGS][MAX_ARGS_SIZE]; 19 20 static int get_args(FILE *inputFile,FILE *fd) 21 { 22 char tmpBuffer[100]; 23 char tmpBuffer2[100]; 24 char *line = tmpBuffer; 25 char separator[] = " ,\n\t"; 26 char *token; 27 int i; 28 char eof; 29 30 int num = 0; 31 32 eof = !fgets(line, sizeof(tmpBuffer), inputFile); 33 if (eof) 34 return num; 35 36 memcpy(tmpBuffer2,tmpBuffer,100); 37 38 39 token = strtok(line, separator); 40 while (num < MAX_NUM_ARGS && token) 41 { 42 strcpy(args[num], token); 43 num++; 44 token = strtok(NULL, separator); 45 } 46 47 for (i = num; i < MAX_NUM_ARGS; i++) 48 args[i][0] = 0; 49 50 if(num > 0) 51 { 52 fprintf(fd, "%s", tmpBuffer2); 53 } 54 55 return num; 56 } 57 58 59 static void help_manual(FILE* fd) 60 { 61 fprintf(fd,"\nd d : display current debug level\n"); 62 fprintf(fd,"d q : display msg queue length, head and tail\n"); 63 fprintf(fd,"s d [level] : set debug [level] \n"); 64 } 65 66 static void show_MQ(FILE* fd) 67 { 68 fprintf(fd," msg queue length:%d head:%d tail:%d \n",abs(MsgQueue.head-MsgQueue.rear),MsgQueue.head,MsgQueue.rear); 69 } 70 71 static void show_debug_level(FILE* fd) 72 { 73 fprintf(fd," current debug level: %d\n", global.debug_level); 74 } 75 76 77 78 void debug_center() 79 { 80 int rc,num,n; 81 FILE* fp; 82 FILE* fd; 83 84 MY_LOG(DEBUG,"Hi,debug!\n"); 85 86 87 system("rm /vob/ljsdpoenew3/exercise/debug_log"); 88 system("rm /vob/ljsdpoenew3/exercise/debug_log2"); 89 rc = mkfifo("/vob/ljsdpoenew3/exercise/debug_log", 0666); 90 if(rc < 0) 91 { 92 MY_LOG(DEBUG, "make fifo fail!\n"); 93 pthread_exit(0); 94 } 95 96 fp = fopen("/vob/ljsdpoenew3/exercise/debug_log", "r"); 97 if(fp == NULL) 98 { 99 MY_LOG(DEBUG, "open debug_log fail!\n");100 pthread_exit(0);101 }102 103 fd = fopen("/vob/ljsdpoenew3/exercise/debug_log2", "w+");104 if(fd == NULL)105 {106 MY_LOG(DEBUG, "open debug_log2 fail!\n");107 pthread_exit(0);108 }109 //freopen("/vob/ljsdpoenew3/exercise/debug_log2.txt", "w+", fd);110 111 fprintf(fd," \n==================================================\n");112 fprintf(fd," Welcme to Debug Center!");113 fprintf(fd," \n==================================================\n\n");114 help_manual(fd);115 //fflush(fd);116 117 while(1)118 {119 fflush(fd);120 fprintf(fd,"\n\nmy_diag>");121 num = get_args(fp,fd);122 if(num < 1)123 {124 freopen("/vob/ljsdpoenew3/exercise/debug_log", "r", fp);125 fflush(fd);126 continue;127 }128 fprintf(fd,"\n\nmy_diag>");129 switch(args[0][0])130 {131 case 'd': //display132 switch(args[1][0])133 {134 case 'q': //display queue135 show_MQ(fd);136 break;137 case 'd': //display debug138 show_debug_level(fd);139 break;140 141 default:142 help_manual(fd);143 break;144 }145 break;146 147 case 's': //set148 switch(args[1][0])149 {150 case 'd': //set debug level151 n = atoi(args[2]);152 fprintf(fd," debug level change from %d to %d",global.debug_level,n);153 global.debug_level = n;154 break;155 156 default:157 help_manual(fd);158 break;159 }160 break;161 162 default:163 help_manual(fd);164 break;165 }166 167 }168 }

 

转载于:https://www.cnblogs.com/xieyulin/p/7060870.html

你可能感兴趣的文章
PLSQL如何输出字典的脚本文件.sql
查看>>
idea热部署+自动编译
查看>>
SharePoint表单和工作流 - Nintex篇(三)
查看>>
mysql调优
查看>>
AlexNet详解
查看>>
清除目录下的SVN信息
查看>>
JS 定时提交 以及 保持在网页存在的时候session不失效的小技巧
查看>>
PYTHON常用数据类型(列表,元组,字典)
查看>>
nginx负载均衡tomcat和配置ssl
查看>>
SVN 错误 Access to SVN Repository Forbidden的原因及解决方法
查看>>
[转]PHP语言的数据库操作函数的理解
查看>>
ADO.Net中DataTable的应用
查看>>
Android Studio 学习 - Activity生命周期
查看>>
[转]application.properties详解 --springBoot配置文件
查看>>
浏览无法加载控件
查看>>
ModelSim应用笔记
查看>>
Android GridView、ListView、ScrollView上下拉刷新
查看>>
Hydra的使用
查看>>
定义为HTML属性的事件句柄的作用域
查看>>
Caffe配置简明教程 ( Ubuntu 14.04 / CUDA 7.5 / cuDNN 5.1 )
查看>>