请mysql高手赐教:关于mysql的注入式攻击的一个问题
有一PHP页面,其ID未经检验就放入了SQL语句中。
现在无法得知其表名,列名只知道一个。
如何取得表名?
不要告诉我慢慢猜。
我对MYSQL不熟,不过知道不能用子查询,有没有方法可以跟MSSQL一样这样取得系统对像:
select * from sysobjects where xtype='u'
另外,如果不能这样取得,可否用union,但是我不知道这个PHP页面所用的recordset有几列。那么怎么构造union的列名?
请mysql高手赐教。
问题点数:100、回复次数:33Top
1 楼yechat(点尘不惊[QQ: 675475127]--可以讨论问题,禁止聊天打屁)回复于 2004-05-02 09:50:24 得分 0
偶自己来顶一顶。Top
2 楼52juanjuan(Fibona)回复于 2004-05-02 10:20:09 得分 0
mysql不太清楚Top
3 楼yechat(点尘不惊[QQ: 675475127]--可以讨论问题,禁止聊天打屁)回复于 2004-05-02 10:28:09 得分 0
看到有回复,我满怀期望的打开贴子。
FT!Top
4 楼yechat(点尘不惊[QQ: 675475127]--可以讨论问题,禁止聊天打屁)回复于 2004-05-02 10:45:21 得分 0
我再顶。Top
5 楼syre(神仙)回复于 2004-05-02 17:18:59 得分 0
知道mysql_list_fields吗?Top
6 楼WapWeb(大白菜芯)回复于 2004-05-02 18:15:46 得分 0
关注中!!!!!!Top
7 楼feel8(Max.H)回复于 2004-05-02 19:43:07 得分 20
没有过滤id,可不可以注入建一个mysql的帐号,然后用该帐号连接数据库?Top
8 楼blazingSnow(月光飞闪刀剑吻)回复于 2004-05-02 23:05:08 得分 0
你不知道这个PHP页面所用的recordset有几列
那么你可以自己动态的生成sql 查询啊Top
9 楼waterpub(风)回复于 2004-05-03 12:29:26 得分 50
可能性不大,除非是一些小型的个人发布的程序偶尔被你找到。
一般网上流行的系统都对表单变量做过检测。
mysql好像不同于mssql,没听说过有系统表。
如果要攻击的话,还是象 feel8(准备早起的鸟) 建立帐号可能性大些
hohoTop
10 楼yechat(点尘不惊[QQ: 675475127]--可以讨论问题,禁止聊天打屁)回复于 2004-05-03 20:20:01 得分 0
to:syre(北冥有鱼)
我对mysql不了解,能否说清楚点,怎么用mysql_list_fields得到表名和列名?
还有一点这是sql注入,好像不可以在SQL语句中直接调用mysqlAPI吧?
to:feel8(准备早起的鸟)
mysql可以用多语句吗?好像不行吧。
我的意思是有一样一条语句会被执行吗:select * from table1;update table2 set fields=values;#
在mssql中是可以的,但是在mysql中可行吗?
即使可行,那么怎么得到数据表的名称?比如用户账号表,我猜过了,猜不出来。
在mssql中可以这样得到表名:select name from sysobjects where xtype='u',那么在mysql中有没有等效的方法?
还有一点:即使我能用sql injection 创建一个账户信息,我如何远程连接? mysql有远程连接的端口吗?端口号是多少?用mysql自身就可以远程连接吗?需要用其它工具吗?
很不好意思,我对mysql只是十窍通了九窍,也就是一窍不通:)
谢谢!
Top
11 楼yechat(点尘不惊[QQ: 675475127]--可以讨论问题,禁止聊天打屁)回复于 2004-05-03 20:23:25 得分 0
to:blazingSnow(常常想起初恋时喜欢的女孩)
我已经用union猜出了列名,是这样的 union select 1,1,1,1,1,1,1,1,1 #
这样就可以猜密码了,不过我不知道账户信息放在哪个表,现在这是最头痛的问题,如果是MS SQL Server,那就很好办了。不过mysql怎么得知当前数据库中的表名呢???
Top
12 楼yechat(点尘不惊[QQ: 675475127]--可以讨论问题,禁止聊天打屁)回复于 2004-05-03 23:41:15 得分 0
最新进展:
我已经拿到了Administrator的密码,不过是md5加密的,我倒~!
mysql的root密码也拿到了,不过也是用password()函数加过密的,555555~~
现在我已经知道users的表名和username、password的列名。
现在两条路在偶面前:
1、暴力破解md5码(成功的机会很小)
2、用自己的string得到的md5码更新administrator的password。
那么现在的问题是:php+mysql能不能在注入时使用多条语句:
select * from users;update users set password='d41d8cd98f00b204e9800998ecf8427e' where userid=1;
我知道php的注入时不能有引号,这个好解决,关键是能不能执行多语句???
高手教我啊~Top
13 楼feixuehenshui(飞雪恨水)回复于 2004-05-04 16:52:00 得分 0
6.4.3.1 INSERT ... SELECT 句法
INSERT [LOW_PRIORITY] [IGNORE] [INTO] tbl_name [(column list)] SELECT ...
使用 INSERT ... SELECT 语句,你可以从一个或多个表中读取多个记录行,并将其快速地插入到一个表中。
INSERT INTO tblTemp2 (fldID) SELECT tblTemp1.fldOrder_ID FROM tblTemp1 WHERE
tblTemp1.fldOrder_ID > 100;
一个 INSERT ... SELECT 语句有下列条件的限止:
INSERT 语句中的目标表不能在 SELECT 查询部分的 FROM 子句中出现,因为在 ANSI SQL 中,禁止你从正在插入的表中 SELECT。(问题是因为,SELECT 可能会发现在同一运行期内先前被插入的记录。当使用子选择子句时,这种情况将会更容易混淆!)
AUTO_INCREMENT 列像平常一样工作。
你可以使用 C API 函数 mysql_info() 得到查询的信息。查看章节 6.4.3 INSERT 句法。
为了确保二进制日志可以被用于重建最初的表,MySQL 将不允许在 INSERT ... SELECT 期间并发的插入。
你当然也可以使用 REPLACE 代替 INSERT 来盖写老的记录行。
*******
看清上面的最后一句Top
14 楼xylegend(pal)回复于 2004-05-04 19:43:57 得分 0
up
有意思,我的小站点就有这个问题,不过我懒得去改动了
反正我是没有打算放到外边去(没有免费的空间)^_^Top
15 楼xylegend(pal)回复于 2004-05-04 19:47:06 得分 0
想问一个问题,对于表单只是用JS做了非空判断,是否会有此注入漏洞?(MySQL)
虽然我的是用了session验证,但还是可以重复提交而且没有过滤'等Top
16 楼yechat(点尘不惊[QQ: 675475127]--可以讨论问题,禁止聊天打屁)回复于 2004-05-06 10:01:55 得分 0
楼上的,当然有注入的漏洞咯。
如果你是用PHP那么,且Request回的变量是字符串,那么直接放入sql语句是没问题的,因为PHP的magic_quotes_gpc选项会把所有引号转义为"\'",那么是不存在漏洞的。这也是我厌恶PHP的地方。
但如果你Request回来的是数值,并且直接放入了Sql语句,那么这就是注入漏洞。Top
17 楼xuzuning(唠叨)回复于 2004-05-06 10:16:14 得分 30
一PHP页面,其ID未经检验就放入了SQL语句中。
现在无法得知其表名,列名只知道一个。
如何取得表名?
show tables
不知你想干什么?
Top
18 楼yechat(点尘不惊[QQ: 675475127]--可以讨论问题,禁止聊天打屁)回复于 2004-05-06 10:25:06 得分 0
楼上的,在sql injection时,能用show tables???怀疑
原语句形如:
$var=1;
&strSql="select * from t1 where id=".$var;
我当然是想SQL注入咯~
Top
19 楼feixuehenshui(飞雪恨水)回复于 2004-05-06 10:25:49 得分 0
to yechat(点尘不惊
数植怎么会引起注入漏洞?Top
20 楼countstars(深空)回复于 2004-05-06 10:28:18 得分 0
加上单引号就可以了,id = '$id'
当然,SQL要转意,默认已经转了,除非你修改了php配置Top
21 楼yechat(点尘不惊[QQ: 675475127]--可以讨论问题,禁止聊天打屁)回复于 2004-05-06 10:30:13 得分 0
请版主:xuzuning(唠叨) 指教:
问题是我现在注入只能这样:
比如URL是:http://hostname/index.php?id=1
PHP语句如:
$var=1;
&strSql="select * from t1 where id=".$var;
那么我可以这样:
http://hostname/index.php?id=1 or 1=1 #
但是我还想update数据(当前连接的用户在表t1上有update的权限):
那么我想构造形如:
http://hostname/index.php?id=1;update t1 set password=0 where id=1#
这样的语句在mysql命令行是没有问题的,
但是在用在这个URL SQL注入时mysql报错:在;update t1 set password=0 where id=1#附近参数错误。
这是什么原因??
谢谢!
Top
22 楼yechat(点尘不惊[QQ: 675475127]--可以讨论问题,禁止聊天打屁)回复于 2004-05-06 10:32:53 得分 0
to:feixuehenshui(飞雪恨水)
当然会!
在PHP中字符串才不会。因为magic_quotes_gpc。
这是PHP+MYSQL与ASP+MSSQL的差别。
ASP+MSSQL的数值也会有注入漏洞,但一般程序员都会用Cint(Request.Form("Var"))进行强制转换,所以相对而言ASP对字符串下手进行注入比较容易。Top
23 楼yechat(点尘不惊[QQ: 675475127]--可以讨论问题,禁止聊天打屁)回复于 2004-05-06 10:35:49 得分 0
to:countstars(深空)
请看清楚我的问题,谢谢。Top
24 楼feixuehenshui(飞雪恨水)回复于 2004-05-06 10:37:18 得分 0
HOHO
反正我的ID 有用了 INTVALTop
25 楼xuzuning(唠叨)回复于 2004-05-06 10:47:31 得分 0
这是很正常的,php已经在防止象您这样的攻击者了。
当php发现查询串中有";"时将对查询串做特殊处理,以防止注入式攻击
所以通过php访问数据库是比较安全的。
Top
26 楼syre(神仙)回复于 2004-05-06 10:54:34 得分 0
但是这是要在php.ini里设置的
function slash($str,$tran=0){
$t=trim($str);
if (get_magic_quotes_gpc() && !$tran)
$t=stripslashes($t);
elseif (!get_magic_quotes_gpc() && $tran)
$t=addslashes($t);
return $t;
}
这个更保险一点
$trans=0:强制不转换
$trans=1:强制转换
另外,如果id是整数的话可以用(int)$id
这样就可以杜绝注入攻击Top
27 楼yechat(点尘不惊[QQ: 675475127]--可以讨论问题,禁止聊天打屁)回复于 2004-05-06 11:33:47 得分 0
to:xuzuning(唠叨)
我觉得问题不在PHP里边。
get_magic_quotes_gpc:
设为 1 时,所有的 ' (单引号), " (双引号), \ (反斜线) and 空字符会自动转为含有反斜线的溢出字符。
这其中未包含;(分号)。
而且,当用'(单引号)时,页面返回的错误信息是:
You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '\'' at line 1
很明显,这是因为PHP对单引号进行了转义。
而使用;(分号)时,页面返回的错误信息是:
You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near ';select 1 from t1' at line 1
也就是说分号没有被PHP转义。
问题出在MYSQL身上。
请版主及各位同志再帮忙看看问题出来哪。为什么不能用多条语句。
谢谢!
Top
28 楼yechat(点尘不惊[QQ: 675475127]--可以讨论问题,禁止聊天打屁)回复于 2004-05-06 11:39:41 得分 0
另外补充一点:服务器上mysql的版本是4.0.17-standard。
在shell下是可以用;(分号)分隔多条语句的。
Top
29 楼syre(神仙)回复于 2004-05-06 11:45:56 得分 0
mysql_list_fields
(PHP 3, PHP 4 )
mysql_list_fields -- 列出 MySQL 表中的字段
说明
resource mysql_list_fields ( string database_name, string table_name [, resource link_identifier])
mysql_list_fields() 取得给定表名的信息。参数是数据库名和表名。返回一个结果指针,可以用于 mysql_field_flags(),mysql_field_len(),mysql_field_name() 和 mysql_field_type()。
例子 1. mysql_list_fields() 例子
<?php
$link = mysql_connect('localhost', 'mysql_user', 'mysql_password');
$fields = mysql_list_fields("database1", "table1", $link);
$columns = mysql_num_fields($fields);
for ($i = 0; $i < $columns; $i++) {
echo mysql_field_name($fields, $i) . "\n";
}
以上例子将产生如下输出: field1
field2
field3
...
mysql_list_tables
(PHP 3, PHP 4 )
mysql_list_tables -- 列出 MySQL 数据库中的表
说明
resource mysql_list_tables ( string database [, resource link_identifier])
mysql_list_tables() 接受一个数据库名并返回和 mysql_query() 函数很相似的一个结果指针。用 mysql_tablename() 函数来遍历此结果指针,或者任何使用结果表的函数,例如 mysql_fetch_array()。
database 参数是需要被取得其中的的表名的数据库名。如果失败 mysql_list_tables() 返回 FALSE。
为向下兼容仍然可以使用本函数的别名 mysql_listtables(),但反对这样做。
注: 该函数已经被删除了,请不要再使用该函数。您可以用命令 SHOW TABLES FROM DATABASE 来实现该函数的功能。
例子 1. mysql_list_tables() 例子
<?php
$dbname = 'mysql_dbname';
if (!mysql_connect('mysql_host', 'mysql_user', 'mysql_password')) {
print 'Could not connect to mysql';
exit;
}
$result = mysql_list_tables($dbname);
if (!$result) {
print "DB Error, could not list tables\n";
print 'MySQL Error: ' . mysql_error();
exit;
}
while ($row = mysql_fetch_row($result)) {
print "Table: $row[0]\n";
}
mysql_free_result($result);
?>
这些东西php手册都有的Top
30 楼yechat(点尘不惊[QQ: 675475127]--可以讨论问题,禁止聊天打屁)回复于 2004-05-06 11:51:23 得分 0
to:syre(北冥有鱼)
谢谢。
不过请看清楚我的问题。
谢谢Top
31 楼waterpub(风)回复于 2004-05-12 23:55:35 得分 0
some data:http://www.manyi100.com/view.asp?id=859Top
32 楼zzhhll003(笨鸟后飞)回复于 2004-05-13 10:34:23 得分 0
up
Top
33 楼yechat(点尘不惊[QQ: 675475127]--可以讨论问题,禁止聊天打屁)回复于 2004-09-09 04:42:36 得分 0
To: waterpub(一夜听雨)
Tks.Top




