在过滤union,table,information和各种库名时查询列名

2 篇文章 0 订阅

被血虐的一场比赛的记录,主要考点是如何在过滤了各种关键词的情况下查询一个复杂列名(极长也无法爆破)
题目过滤了information,innodb_index_stats,table等关键词,无法从库中直接查询列名
同时过滤了union,无法通过无列名注入来获取flag

了解到了一种新的注入姿势
使用这个数据库,假设我们不知道password这个列名
在这里插入图片描述
payload:

select * from(select * from testtable a join testtable b using(id,usename))c;

接下来分析一下结构:
首先是使用的SQL join连接和using简化连接

select * from testtable a join testtable b using(id,usename);

意思是testtable连接testtable,以id和usename列为属性列

在这里插入图片描述

testtable后面的a和b是别名,如果不使用别名会出现报错,估计是mysql不允许两个名字完全相同的数据库连接,如果一样就没法在后面加on a.id=b.id and a.usename=b.usename;这种了

select * from testtable join testtable using(id,usename);

在这里插入图片描述

之后是一个派生表和别名
SQL的别名很神奇,跟在后面就行

select * from testtable a;
等同于
select * from testtable as a;

而派生表就是把查询结果作为一个表来处理,而派生表必须有一个别名
当派生表没有别名直接使用时

select * from (select * from testtable);

在这里插入图片描述

正确的用法:

select * from (select * from testtable)a;
select * from (select * from testtable)as a;

在这里插入图片描述
而派生表还有个特性就是不允许有重复的列,如果有则会报错并告知是哪个列重复了,方便修改语句,所以利用这个特性,我们可以得到数据库的列名
由上面可知我们在执行

select * from testtable a join testtable b using(id,usename);

后得到的派生表password列是重复的,为它设置别名时会有

select * from(select * from testtable a join testtable b using(id,usename))c;

在这里插入图片描述
得到列名password

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
很抱歉,我并不是一个可以执行代码的程序,我只能给你提供一些思路和参考代码。 首先,你需要在 web.xml 中配置一个 servlet,用于处理用户提交的请求。具体配置如下: ```xml <servlet> <servlet-name>DatabaseServlet</servlet-name> <servlet-class>com.example.DatabaseServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>DatabaseServlet</servlet-name> <url-pattern>/database</url-pattern> </servlet-mapping> ``` 然后,你需要编写一个 DatabaseServlet 类,处理用户提交的请求。具体代码如下: ```java package com.example; import java.io.IOException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class DatabaseServlet extends HttpServlet { // 数据库连接信息 private static final String DB_DRIVER = "com.mysql.jdbc.Driver"; private static final String DB_URL = "jdbc:mysql://localhost:3306/"; private static final String DB_USERNAME = "root"; private static final String DB_PASSWORD = "password"; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 获取用户请求参数 String dbName = req.getParameter("dbName"); String tableName = req.getParameter("tableName"); String columnName = req.getParameter("columnName"); // 连接数据库 Connection conn = null; Statement stmt = null; ResultSet rs = null; try { Class.forName(DB_DRIVER); conn = DriverManager.getConnection(DB_URL + dbName, DB_USERNAME, DB_PASSWORD); stmt = conn.createStatement(); // 查询数据库 rs = stmt.executeQuery("SELECT " + columnName + " FROM " + tableName); // 构造 HTML 响应 StringBuilder sb = new StringBuilder(); sb.append("<html><body>"); sb.append("<table>"); while (rs.next()) { sb.append("<tr>"); sb.append("<td>" + rs.getString(columnName) + "</td>"); sb.append("</tr>"); } sb.append("</table>"); sb.append("</body></html>"); // 发送响应 resp.getWriter().write(sb.toString()); } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); } finally { // 关闭数据库连接 try { if (rs != null) { rs.close(); } if (stmt != null) { stmt.close(); } if (conn != null) { conn.close(); } } catch (SQLException e) { e.printStackTrace(); } } } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 获取用户请求参数 String dbName = req.getParameter("dbName"); String tableName = req.getParameter("tableName"); String columnName = req.getParameter("columnName"); String id = req.getParameter("id"); String newValue = req.getParameter("newValue"); // 更新数据库 Connection conn = null; Statement stmt = null; try { Class.forName(DB_DRIVER); conn = DriverManager.getConnection(DB_URL + dbName, DB_USERNAME, DB_PASSWORD); stmt = conn.createStatement(); stmt.executeUpdate( "UPDATE " + tableName + " SET " + columnName + "='" + newValue + "' WHERE id=" + id); } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); } finally { // 关闭数据库连接 try { if (stmt != null) { stmt.close(); } if (conn != null) { conn.close(); } } catch (SQLException e) { e.printStackTrace(); } } // 重定向到 GET 请求 resp.sendRedirect(req.getRequestURI() + "?dbName=" + dbName + "&tableName=" + tableName + "&columnName=" + columnName); } } ``` 接下来,你需要编写一个 JSP 页面,用于展示用户查询的结果和更新数据库。具体代码如下: ```html <html> <body> <form method="get" action="/database"> <label>数据库:</label> <input type="text" name="dbName"> <br> <label>表名:</label> <input type="text" name="tableName"> <br> <label>列名:</label> <input type="text" name="columnName"> <br> <input type="submit" value="查询"> </form> <hr> <% if (request.getParameter("dbName") != null && request.getParameter("tableName") != null && request.getParameter("columnName") != null) { %> <table> <thead> <tr> <th>ID</th> <th><%= request.getParameter("columnName") %></th> <th>操作</th> </tr> </thead> <tbody> <% // 连接数据库 Connection conn = null; Statement stmt = null; ResultSet rs = null; try { Class.forName(DB_DRIVER); conn = DriverManager.getConnection(DB_URL + request.getParameter("dbName"), DB_USERNAME, DB_PASSWORD); stmt = conn.createStatement(); // 查询数据库 rs = stmt.executeQuery( "SELECT id, " + request.getParameter("columnName") + " FROM " + request.getParameter("tableName")); // 构造 HTML 响应 while (rs.next()) { %> <tr> <td><%= rs.getInt("id") %></td> <td><%= rs.getString(request.getParameter("columnName")) %></td> <td> <form method="post" action="/database"> <input type="hidden" name="dbName" value="<%= request.getParameter("dbName") %>"> <input type="hidden" name="tableName" value="<%= request.getParameter("tableName") %>"> <input type="hidden" name="columnName" value="<%= request.getParameter("columnName") %>"> <input type="hidden" name="id" value="<%= rs.getInt("id") %>"> <input type="text" name="newValue" value="<%= rs.getString(request.getParameter("columnName")) %>"> <input type="submit" value="更新"> </form> </td> </tr> <% } } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); } finally { // 关闭数据库连接 try { if (rs != null) { rs.close(); } if (stmt != null) { stmt.close(); } if (conn != null) { conn.close(); } } catch (SQLException e) { e.printStackTrace(); } } %> </tbody> </table> <% } %> </body> </html> ``` 最后,你需要将上述代码放到一个 Web 项目中,然后运行该项目,访问 http://localhost:8080/your-project-name/database 即可使用该功能。注意,你需要将代码中的数据库连接信息替换为你自己的连接信息,同需要在你的数据库中创建相应的表格和数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值