今天比较特别,讲两个主题,主要是为了承上启下,进行补充和过渡。
躲避execve,是在原来的文章的基础上补充一个小思路,分析/proc/目录 是为了下一篇讲解内存中修改函数做准备,要让大家提前知道这回事。
本公众号以原创干货为主,原创不易,大家如果喜欢本篇文章的话,记得点在看和转发朋友圈。
在之前文章中,我讲解过各种躲避execve监控的方法,如果有朋友没看到过,可以点下面文章链接熟悉一下:
无"命令"反弹shell-逃逸基于execve的命令监控(上)
本文的思路,类似文件复制重命名,躲避execve监控的关键点在于创建软链接,通过创建软链接的方式来混淆命令执行的路径。下面以whoami命令为例:
ln -s /bin/whoami /tmp/whoami_tmp
接着使用strace调试执行/tmp/whoami_tmp,看一下execve的系统调用:
strace -f /tmp/whoami_tmp
由于execve执行软链接,会自动执行目标文件,不会对软链接进行转换,从而实现了隐藏。
不要以为这就结束了!!!
虽然最后执行的时候混淆了,但是在执行ln命令的时候,还是暴露了命令路径,暴露了关键字。
可以对目录下的文件进行批量创建软连接:
cp -s /bin/* /tmp/
然后对 /tmp下的软链接批量添加后缀名即可,就不会暴露命令了。
之前有朋友说很简单,直接将bash复制一份,重命名即可,就算执行命令也无所谓呀,反正不知道是bash执行的。
下面我来说一下,这种方式按我的猜想该怎么监控:
接下来的文章中,我要讲解一下从linux进程内存中修改函数,需要给大家提前预习一下基础知识。
proc文件系统是一个伪文件系统,它提供内核数据结构的接口。通常安装在/过程。通常,它是由系统自动安装的,但是也可以使用以下命令手动安装:
mount -t proc proc /proc
proc文件系统中的大多数文件都是只读的,但是有些文件是可写的,允许更改内核变量。/proc目录下的文件很多,我们主要讲解如下文件/文件夹,其中pid是进程号,如果是想查看自身进程中的内容,可以将pid换成self。
/proc/[pid]/auxv /proc/[pid]/cmdline /proc/[pid]/comm /proc/[pid]/cwd /proc/[pid]/environ /proc/[pid]/exe /proc/[pid]/fd /proc/[pid]/limits /proc/[pid]/maps /proc/[pid]/root /proc/[pid]/stack /proc/[pid]/statm /proc/[pid]/status /proc/[pid]/syscall /proc/[pid]/wchan
/proc/[pid]/auxv
包含传递给进程的 ELF
解释器信息,格式是每一项都是一个 unsignedlong
长度的 ID
加上一个 unsignedlong
长度的值。最后一项以连续的两个 0x00
开头。举例如下:
[root@VM_0_13_centos ~]# hexdump -x /proc/28858/auxv
0000000 0021 0000 0000 0000 e000 90bf 7ffc 0000
0000010 0010 0000 0000 0000 fbff 1f8b 0000 0000
0000020 0006 0000 0000 0000 1000 0000 0000 0000
0000030 0011 0000 0000 0000 0064 0000 0000 0000
0000040 0003 0000 0000 0000 f040 6206 7f48 0000
0000050 0004 0000 0000 0000 0038 0000 0000 0000
0000060 0005 0000 0000 0000 0009 0000 0000 0000
0000070 0007 0000 0000 0000 b000 61e4 7f48 0000
0000080 0008 0000 0000 0000 0000 0000 0000 0000
0000090 0009 0000 0000 0000 2004 6207 7f48 0000
00000a0 000b 0000 0000 0000 0000 0000 0000 0000
00000b0 000c 0000 0000 0000 0000 0000 0000 0000
00000c0 000d 0000 0000 0000 0000 0000 0000 0000
00000d0 000e 0000 0000 0000 0000 0000 0000 0000
00000e0 0017 0000 0000 0000 0000 0000 0000 0000
00000f0 0019 0000 0000 0000 4269 90bd 7ffc 0000
0000100 001f 0000 0000 0000 4fea 90bd 7ffc 0000
0000110 000f 0000 0000 0000 4279 90bd 7ffc 0000
0000120 0000 0000 0000 0000 0000 0000 0000 0000
0000130
解析这个文件可以参考这段代码(https://www.wienand.org/junkcode/linux/read-auxv.c)。
/proc/[pid]/cmdline
是一个只读文件,包含进程的完整命令行信息。举例如下:
[root@VM_0_13_centos ~]# ps -ef | grep 28858
root 28858 28568 0 22:56 pts/2 00:00:00 ping www.baidu.com
root 29047 2548 0 22:57 pts/4 00:00:00 grep --color=auto 28858
[root@VM_0_13_centos ~]# cat /proc/28858/cmdline
pingwww.baidu.com
/proc/[pid]/comm
包含进程的命令名。举例如下:
[root@VM_0_13_centos ~]# cat /proc/28858/comm
ping
/proc/[pid]/cwd
是进程当前工作目录的符号链接。举例如下:
[root@VM_0_13_centos ~]# ls -lt /proc/28858/cwd
lrwxrwxrwx 1 root root 0 Mar 29 22:58 /proc/28858/cwd -> /root
/proc/[pid]/environ
显示进程的环境变量。举例如下:
[root@VM_0_13_centos ~]# strings /proc/28858/environ
XDG_SESSION_ID=212367
rvm_bin_path=/usr/local/rvm/bin
HOSTNAME=VM_0_13_centos
PYENV_ROOT=/root/.pyenv
GEM_HOME=/usr/local/rvm/gems/ruby-2.5.5
TERM=xterm
SHELL=/bin/bash
HISTSIZE=3000
IRBRC=/usr/local/rvm/rubies/ruby-2.5.5/.irbrc
SSH_CLIENT=113.97.33.208 58836 22
MY_RUBY_HOME=/usr/local/rvm/rubies/ruby-2.5.5
SSH_TTY=/dev/pts/2
USER=root
/proc/[pid]/exe
为实际运行程序的符号链接。举例如下:
[root@VM_0_13_centos ~]# ls -lt /proc/28858/exe
lrwxrwxrwx 1 root root 0 Mar 29 22:56 /proc/28858/exe -> /usr/bin/ping
/proc/[pid]/fd
是一个目录,包含进程打开文件的情况。举例如下:
[root@VM_0_13_centos ~]# ls -lt /proc/28858/fd
total 0
lrwx------ 1 root root 64 Mar 29 23:01 0 -> /dev/pts/2
lrwx------ 1 root root 64 Mar 29 23:01 1 -> /dev/pts/2
lrwx------ 1 root root 64 Mar 29 23:01 3 -> socket:[153313413]
lrwx------ 1 root root 64 Mar 29 23:01 6 -> /dev/pts/2
lrwx------ 1 root root 64 Mar 29 22:56 2 -> /dev/pts/2
目录中的每一项都是一个符号链接,指向打开的文件,数字则代表文件描述符。
/proc/[pid]/limits
显示当前进程的资源限制。举例如下:
[root@VM_0_13_centos ~]# cat /proc/28858/limits
Limit Soft Limit Hard Limit Units
Max cpu time unlimited unlimited seconds
Max file size unlimited unlimited bytes
Max data size unlimited unlimited bytes
Max stack size 8388608 unlimited bytes
Max core file size 0 unlimited bytes
Max resident set unlimited unlimited bytes
Max processes 7282 7282 processes
Max open files 100001 100002 files
Max locked memory 65536 65536 bytes
Max address space unlimited unlimited bytes
Max file locks unlimited unlimited locks
Max pending signals 7282 7282 signals
Max msgqueue size 819200 819200 bytes
Max nice priority 0 0
Max realtime priority 0 0
Max realtime timeout unlimited unlimited us
SoftLimit
表示 kernel
设置给资源的值, HardLimit
表示 SoftLimit
的上限,而 Units
则为计量单元。
/proc/[pid]/maps
显示进程的内存区域映射信息。举例如下:
[root@VM_0_13_centos ~]# cat /proc/28858/maps
......
7f4862059000-7f486205d000 rw-p 00000000 00:00 0
7f486206a000-7f486206c000 rw-p 00000000 00:00 0
7f486206c000-7f486206d000 r--p 00021000 fd:01 139988 /usr/lib64/ld-2.17.so
7f486206d000-7f486206e000 rw-p 00022000 fd:01 139988 /usr/lib64/ld-2.17.so
7f486206e000-7f486206f000 rw-p 00000000 00:00 0
7f486206f000-7f4862079000 r-xp 00000000 fd:01 143369 /usr/bin/ping
7f4862278000-7f4862279000 r--p 00009000 fd:01 143369 /usr/bin/ping
7f4862279000-7f486227a000 rw-p 0000a000 fd:01 143369 /usr/bin/ping
7f486227a000-7f486228d000 rw-p 00000000 00:00 0
7f4863ec6000-7f4863ee7000 rw-p 00000000 00:00 0 [heap]
7ffc90bb4000-7ffc90bd5000 rw-p 00000000 00:00 0 [stack]
7ffc90bfe000-7ffc90c00000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
其中注意的一点是 [stack:<tid>]
是线程的堆栈信息,对应于 /proc/[pid]/task/[tid]/
路径。
/proc/[pid]/root
是进程根目录的符号链接。举例如下:
[root@VM_0_13_centos ~]# ls -lt /proc/28858/root
lrwxrwxrwx 1 root root 0 Mar 29 22:58 /proc/28858/root -> /
/proc/[pid]/stack
显示当前进程的内核调用栈信息,只有内核编译时打开了 CONFIG_STACKTRACE
编译选项,才会生成这个文件。举例如下:
[root@VM_0_13_centos ~]# cat /proc/28858/stack
[<ffffffff81213465>] poll_schedule_timeout+0x55/0xb0
[<ffffffff812149ed>] do_sys_poll+0x4cd/0x580
[<ffffffff81214ba4>] SyS_poll+0x74/0x110
[<ffffffff81697809>] system_call_fastpath+0x16/0x1b
[<ffffffffffffffff>] 0xffffffffffffffff
/proc/[pid]/statm
显示进程所占用内存大小的统计信息,包含七个值,度量单位是 page
( page
大小可通过 getconf PAGESIZE
得到)。举例如下:
[root@VM_0_13_centos ~]# cat /proc/28858/statm
36867 404 315 10 0 111 0
各个值含义:
a)进程占用的总的内存;
b)进程当前时刻占用的物理内存;
c)同其它进程共享的内存;
d)进程的代码段;
e)共享库(从 2.6
版本起,这个值为 0
);
f)进程的堆栈;
g) dirty pages
(从 2.6
版本起,这个值为 0
)。
/proc/[pid]/status
包含进程的状态信息。其很多内容与 /proc/[pid]/stat
和 /proc/[pid]/statm
,但是却是以一种更清晰地方式展现出来。举例如下:
[root@VM_0_13_centos ~]# cat /proc/28858/status
Name: ping
State: S (sleeping)
Tgid: 28858
Ngid: 0
Pid: 28858
PPid: 28568
TracerPid: 0
Uid: 0 0 0 0
Gid: 0 0 0 0
FDSize: 256
Groups: 0
VmPeak: 147524 kB
VmSize: 147468 kB
VmLck: 0 kB
VmPin: 0 kB
VmHWM: 1616 kB
VmRSS: 1616 kB
RssAnon: 356 kB
RssFile: 1260 kB
RssShmem: 0 kB
VmData: 312 kB
VmStk: 132 kB
VmExe: 40 kB
VmLib: 4348 kB
VmPTE: 104 kB
VmSwap: 0 kB
Threads: 1
SigQ: 0/7282
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000000000
SigCgt: 0000000180002006
CapInh: 0000000000000000
CapPrm: 0000000000003000
CapEff: 0000000000000000
CapBnd: 0000001fffffffff
CapAmb: 0000000000000000
Seccomp: 0
Cpus_allowed: 1
Cpus_allowed_list: 0
Mems_allowed: 00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000001
Mems_allowed_list: 0
voluntary_ctxt_switches: 1881
nonvoluntary_ctxt_switches: 0
关于信号( signal
)的信息: SigQ
分为两部分(例如 0/7282
),前面表示当前处在队列中的信号( 0
),后面则表示队列一共可以存储多少信号( 7282
); SigPnd
表示当前线程 pending
的信号,而 ShdPnd
则表示整个进程 pending
的信号; SigBlk
、 SigIgn
和 SigCgt
分别表示对信号的处理是阻塞,忽略,还是捕获。(关于 Unix
信号的相关知识,可以参考Unix: Dealing with signals)。
/proc/[pid]/syscall
显示当前进程正在执行的系统调用。举例如下:
[root@VM_0_13_centos ~]# cat /proc/28858/syscall
7 0x7ffc90bd2d00 0x1 0x3e3 0x5e80b9e6 0x0 0x0 0x7ffc90bd28d8 0x7f4861738bd0
第一个值是系统调用号( 7
代表 poll
),后面跟着 6
个系统调用的参数值(位于寄存器中),最后两个值依次是堆栈指针和指令计数器的值。如果当前进程虽然阻塞,但阻塞函数并不是系统调用,则系统调用号的值为 -1
,后面只有堆栈指针和指令计数器的值。如果进程没有阻塞,则这个文件只有一个“ running
”的字符串。
内核编译时打开了 CONFIG_HAVE_ARCH_TRACEHOOK
编译选项,才会生成这个文件。
/proc/[pid]/wchan
显示当进程 sleep
时, kernel
当前运行的函数。举例如下:
[root@VM_0_13_centos ~]# cat /proc/28858/wchan
poll_schedule_timeout
参考:http://man7.org/linux/man-pages/man5/proc.5.html https://github.com/NanXiao/gnu-linux-proc-pid-intro