隐藏脚本中要使用的密码

目录

  在 linux 中远程执行命令难免要输入密码,如果不希望把密码放在用户能够看到的地方该如何做呢,下面介绍一下。

条件

隐藏脚本使用的密码需要两个条件:
1.用户不是 root 用户,执行的脚本也不是 root 权限的(如果有 root 权限那么入侵的人完全可以把我们的程序拷贝出去分析,就没有意义了)
2.系统需要安装 sshpass (这个主要是对 ssh 交互的时候需要)

实现原理

  我们把密码写在 c 文件中,在 c 程序中把密码设置为一个环境变量, 然后编译为可执行文件,在这个可执行文件中调用我们要执行的脚本,并通过 sshpass -e 
从环境变量中获取密码,最后我们需要 chmod -r 去掉这个可执行文件的可读权限,然后使用 chattr +i 把这个可执行文件设置为 root 用户都不能修改。
那么这个时候,这个可执行文件既不能被读取和拷贝也不能被修改,只能执行我们的程序,而且密码在程序的环境变量中只有这个进程或这个进程的子进程能够读取到这个进程的环境变量,
所以也不能通过 ps 来查看这个进程使用的密码。

c 文件(版本 1)

#include <stdio.h>
#include <stdlib.h>





int main(int argc, const char *argv[]) {
  char cmd[3000]="./getenv.sh";
  putenv("SSHPASS=password");
  system(cmd);
  return 0;
}

shell 文件(版本 1)

#!/bin/bash


echo $SSHPASS

分析 1

# 执行效果
jimila@CDYJY-JINGML:env$ ./a.out 
password

我们可以看到程序正确的调用了 shell 脚本,并且获取到了密码,但是这个程序有个严重的问题就是密码使用字符串写入 c 文件入侵的人可以很轻松的获取到密码。
# 我们使用 strings 命令可以看到密码就可以直接看到。我们可以利用一个技巧来防范这个问题。
jimila@CDYJY-JINGML:env$ strings a.out |grep pass
SSHPASS=password

c 文件(版本 2)

#include <stdio.h>
#include <stdlib.h>





int main(int argc, const char *argv[]) {
  char cmd[3000]="./getenv.sh";

  char* password_str = ((char[]) {'S','S', 'H', 'P', 'A', 'S', 'S', '=', 'p', 'a', 's', 's', 'w', 'o', 'r', 'd' ,'\0'});
  putenv(password_str);
  system(cmd);
  return 0;
}

分析 2

# 现在同样可以执行并且 strings 看不到我们设置的密码
jimila@CDYJY-JINGML:env$ ./a.out 
password

jimila@CDYJY-JINGML:env$ strings a.out  |grep pass
jimila@CDYJY-JINGML:env$

权限设置

chmod -r a.out
chattr +i a.out

目录