注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

PostgreSQL 中文网

 
 
 

日志

 
 

数据库信息被篡改一例  

2011-11-14 23:27:11|  分类: PG案例分析 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |


            这几天有套应用发生了匪夷所思的现象,数据库信息频繁被篡改,一开始我们怀疑可能是应用被攻击了,
但依然没有可靠的证据,接连几天找不到原因,今天下午应用人员告诉我说很多用户都登陆不了系统了,数据库
是不是出问题了,下面是今天的分析过程。


--1 首先查看数据库负载等信息
   数据库负载为 2 左右,对于 8 核的机器来说还不算高,IO,CPU使用率在合理范围之内。
  

--2 主机层面查看当前会话
postgres@db> ps -ef | grep UPDATE
postgres   393  3708  0 Nov12 ?        00:01:24 postgres: mpc_db_account mpc_db_account 192.168.104.50(38165) UPDATE waiting
postgres   403  3708  0 Nov12 ?        00:01:23 postgres: mpc_db_account mpc_db_account 192.168.104.50(38172) UPDATE waiting
postgres   465  3708  0 Nov12 ?        00:01:24 postgres: mpc_db_account mpc_db_account 192.168.104.50(45733) UPDATE waiting
postgres   478  3708  0 Nov12 ?        00:01:30 postgres: mpc_db_account mpc_db_account 192.168.104.50(45740) UPDATE waiting
postgres   516  3708  0 Nov12 ?        00:01:29 postgres: mpc_db_account mpc_db_account 192.168.104.50(45747) UPDATE waiting
postgres  8114  3708  0 15:06 ?        00:00:00 postgres: mpc_db_account mpc_db_account xxx.xxx.xxx.xx(40477) UPDATE waiting
postgres  8236  3708  0 15:08 ?        00:00:00 postgres: mpc_db_account mpc_db_account xxx.xxx.xxx.xx(51622) UPDATE waiting
postgres  8781  8319  0 15:19 pts/0    00:00:00 grep UPDATE
postgres 15199  3708  0 Nov13 ?        00:00:46 postgres: mpc_db_account mpc_db_account xxx.xxx.xxx.xx(50177) UPDATE waiting
postgres 15207  3708  0 Nov13 ?        00:05:28 postgres: mpc_db_account mpc_db_account xxx.xxx.xxx.xx(50184) UPDATE
postgres 15215  3708  0 Nov13 ?        00:00:59 postgres: mpc_db_account mpc_db_account xxx.xxx.xxx.xx(50190) UPDATE waiting
postgres 15223  3708  0 Nov13 ?        00:00:48 postgres: mpc_db_account mpc_db_account xxx.xxx.xxx.xx(50197) UPDATE waiting
postgres 23476  3708  0 Nov12 ?        00:01:13 postgres: mpc_db_account mpc_db_account xxx.xxx.xxx.xx(43681) UPDATE waiting

       备注:这里发现有十几个 update 会话处于等待状态,只有会话 15207 在执行,猜想可能是这个会话有问题。


--3 查看 15207 会话详细信息
postgres=# select datname,current_query,query_start,client_a from pg_stat_activity where current_query !='<IDLE>' and procpid=15207;
    datname     |         current_query                                                                                                                 |          query_start          |  client_addr   | client_port
----------------+-------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------
------------+-------------------------------+----------------+-------------
 mpc_db_account | update tmp_table set                          column1 = '[?au]..v..<<kool-boy>>...',                  
              sex = 1,                                birthday = '1994-11-24',                                mobile = '',         
                  province = '',                          city = '',                              signature = 'sunlei '--',        
                      head_icon = 30,                                 country_code = 286                              where user_id
= 139957561 | 2011-11-14 14:51:07.147826+08 | xxx.xxx.xxx.xx |       50184
(1 row)

    备注:根据执行时间( query_start )来看,这个会话跑了有 30 分钟左右了还没跑完,这个 update 语句是带
              where 条件的,应该只更新一条记录,为什么执行了这么久还没跑完呢?觉得非常奇怪, 接下来想进一步分析,
              但业务因为部分用户登陆不了系统,项目经理建议先重启业务,回头再查原因。
         

--4 出现转机
      业务重启后,应用恢复正常,接着开发人员在测试环境上进行了测试,幸运的是他们带来了意外的发现,他们发现
   在修改字段值时,加上单引号,再加上注释符 -- 后,表上所有的记录都被更新了,正如上面的 signature 字段值全
   被更新成 sunlei 了,后来了解了下情况,目前业务上基本上没有对客户端用户输入的信息做处理,没对特殊字符做
   转义。接下来详细测试下。
   
           
5 测试
--5.1 创建测试表并插入数据
skytf=> create table test_66 (id integer, name varchar(32));
CREATE TABLE

skytf=> insert into test_66 select generate_series(1,10),'a';
INSERT 0 10

skytf=> select * from test_66;
 id | name
----+------
  1 | a
  2 | a
  3 | a
  4 | a
  5 | a
  6 | a
  7 | a
  8 | a
  9 | a
 10 | a
(10 rows)


--5.2 更新数据
skytf=>  update test_66 set name='aaa '--' where id=1;
skytf-> ;
UPDATE 10

skytf=> select  * from test_66;
 id | name
----+------
  1 | aaa
  2 | aaa
  3 | aaa
  4 | aaa
  5 | aaa
  6 | aaa
  7 | aaa
  8 | aaa
  9 | aaa
 10 | aaa
(10 rows)

      备注:虽然带有 where 条件的更新,却全表更新了表数据,原因是注释符 "--" 后面的语句被注释掉了,
                如果此时程序发送分号,那么语句被执行,全表数据被更新。
  
 
--6 结论
  
         上面证实了本文的问题属于软件问题,没对对客户端输入的文字进行合法性检查,也没有对特殊字符进行
   转义处理,同时这也给 SQL 注入带来了很大的隐患。
    
    
--7 对特殊字符进行转义处理举例
skytf=> update test_66 set name=E'bbb\'bbb' where id=1;
UPDATE 1

skytf=> select * from test_66;
 id |  name  
----+---------
  2 | aaa
  3 | aaa
  4 | aaa
  5 | aaa
  6 | aaa
  7 | aaa
  8 | aaa
  9 | aaa
 10 | aaa
  1 | bbb'bbb
(10 rows)    

skytf=> update test_66 set name=E'bbb\'\-\-' where id=2;
UPDATE 1

skytf=> select * from test_66;
 id |  name  
----+---------
  3 | aaa
  4 | aaa
  5 | aaa
  6 | aaa
  7 | aaa
  8 | aaa
  9 | aaa
 10 | aaa
  1 | bbb'bbb
  2 | bbb'--
(10 rows)


--8 解决方法
     为了减少此类情况和 SQL 注入的情况,建议程序里对客户端输入的文字进行合法性检查,对特殊字符进行转义处理;
   同时也要增加应用程序的安全性,例如权限, 不使用动态SQL,以及密码需加密等。   
    

--9 参考文档
http://technet.microsoft.com/zh-cn/cc562985.aspx  
 

  评论这张
 
阅读(26469)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2016