数据库信息被篡改一例

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

数据库信息

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

主机层面查看当前会话

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[postgres@db](mailto: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 在执行,猜想可能是这个会话有问题。

查看 15207 会话详细信息

1
2
3
4
5
6
7
8
9
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 条件的,应该只更新一条记录,为什么执行了这么久还没跑完呢?觉得非常奇怪, 接下来想进一步分析,但业务因为部分用户登陆不了系统,项目经理建议先重启业务,回头再查原因。

出现转机

业务重启后,应用恢复正常,接着开发人员在测试环境上进行了测试,幸运的是他们带来了意外的发现,他们发现在修改字段值时,加上单引号,再加上注释符 – 后,表上所有的记录都被更新了,正如上面的 signature 字段值全被更新成 sunlei 了,后来了解了下情况,目前业务上基本上没有对客户端用户输入的信息做处理,没对特殊字符做转义。接下来详细测试下。

模拟测试

创建测试表并插入数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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)

更新数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
skytf=> update test_66 set name='aaa '--' where id=1;    
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 条件的更新,却全表更新了表数据,原因是注释符 “–” 后面的语句被注释掉了,如果此时程序发送分号,那么语句被执行,全表数据被更新。

测试结论

上面证实了本文的问题属于软件问题,没对对客户端输入的文字进行合法性检查,也没有对特殊字符进行转义处理,同时这也给 SQL 注入带来了很大的隐患。

对特殊字符进行转义处理

举例如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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)

解决方法

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

参考文档

原创文章,作者:506227337,如若转载,请注明出处:https://blog.ytso.com/237808.html

(0)
上一篇 2022年1月29日
下一篇 2022年1月29日

相关推荐

发表回复

登录后才能评论