Moonfish's blog


  • Startseite

  • Archiv

webpack带来的安全风险

Veröffentlicht am 2019-01-30

最近在资产收集过程中,发现越来越多的vue应用,大部分会使用webpack进行打包,如果没有正确配置,就会导致vue源码泄露。

webpack是一个JavaScript应用程序的静态资源打包器(module bundler)。它会递归构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个bundle。

可以直接使用浏览器的调试模式进行查看,我们对vue的源码泄露并没有什么兴趣,感兴趣的是泄露的各种信息如API、加密算法、管理员邮箱、内部功能等等。下图泄露了全部的API。

image

很多vue应用都是先渲染页面再判断是否登陆,根据这个小缺陷,我们首先可以查看相关功能,或者利用Burpsuite修改验证用户的返回包,然后爬虫爬一下API,分析一下参数,偶尔会遇到没有权限验证的接口,或者会有注入、XSS之类的漏洞。

image

其他的文件也可以多留意一下

image

拼接URL,这个报错一看就是个thinkphp

image

构造一下请求:thinkphp5

image

最近的thinkphp代码执行

image

漏洞案例,大家根据文章和漏洞名称猜测一下思路:

某碑分站权限控制不当进入运维管理系统

某陌分站webpack配置不当进入后台

其他的由于还未修复,就不说了。

ref:

https://www.webpackjs.com/concepts/

https://segmentfault.com/a/1190000008961395

https://www.cnblogs.com/liemei/p/7826202.html(修复建议)

DedeCMS V57 SQL注入

Veröffentlicht am 2018-10-30

六月份提交给先知的漏洞,不过重复了
版本信息:
image
注入点:http://localhost/dedecms/v57/dede/co_do.php?clshash=true&dopost=clear&ids=*
根据我们hook的函数发现payload直接进入查询语句
image
sleep(1)
image
sleep(5)
image
sqlmap测试
image
定位到.\dede\co_do.php文件中当$ids和$clshash不为空时,$ids直接拼接到查询语句执行
image
IAST是个有趣的工具,还是需要不断研究的。

PocScan 无法加载bugscan插件的解决办法

Veröffentlicht am 2018-07-05

最近想写一个插件式扫描器,顺便研究了一下PocScan

https://github.com/erevus-cn/pocscan/

这个扫描器刚开源的时候很火,记得之前众测的时候还有公司将它部署到生产环境上,开了Debug信息。

在项目的Issues多次提到不兼容问题,但是一直没有修复,所以就看一下问题出在哪里。

加载bugscan插件后扫了一下自己的VPS,查看日志之后发现payload是发过来了,说明是结果存储反馈的过程除了问题。

文件 /pocscan/blob/master/pocscan/plugins/bugscan/dummy/__init__.py

def _problem(*args, **kwargs):
    # 从栈里取poc名字
    import inspect
    poc_name =  inspect.stack()[1][1]
    log = kwargs['log']

  • 这里传入的参数用*args就可以了
  • 作者的本意是获取log中的url,事实上在旧版的插件中并不返回log,log 是新插件中hackhttp函数返回的

简单粗暴直接将38行修改成

def _problem(*args):
    # 从栈里取poc名字
    import inspect
    poc_name = inspect.stack()[1][1]
    result = ['note', 'info', 'warning', 'hole'][args[0]]
    save_result(args[1], poc_name, result + ': '+poc_name)

扫描一下看结果:

总结:这个扫描器从学习的角度来讲具有借鉴意义,但并不适合部署使用。

后续我会写一下我的插件式扫描器的开发过程,在此立个flag。

SEACMS最新版(V6.61)后台SQL注入[CNVD-2018-12347]

Veröffentlicht am 2018-06-08

后台注入,需要登录

注入点在order by 后面

正常访问时:

http://localhost/seacmsv6.61/meet/admin_news.php?n_commend=&order=n_id--#&page=0&type=

倒序时:

http://localhost/seacmsv6.61/meet/admin_news.php?n_commend=&order=n_id+desc--#&page=0&type=

使用updatexml进行报错注入

http://localhost/seacmsv6.61/meet/admin_news.php?n_commend=&order=n_id+and(updatexml(1,concat(0x7e,(select%20user())),0))--#&page=0&type=

源码分析:

漏洞文件:

\seacmsV6.61\admin\templets\admin_news.htm

admin_news.php 中使用include包含该文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?php
$numPerPage=20;
if(empty($order)) $order="n_addtime"; //$order的值不为空
$orderStr= " order by d.$order desc"; // d拼接$order
$page = isset($page) ? intval($page) : 1;
if($page==0) $page=1;
$whereStr=" ";
if ($action=="nullpic") $whereStr.=" and d.v_pic=''";
if ($n_recycled=="ok") $whereStr.=" and d.n_recycled=1";
if (!empty($type)) $whereStr.=" and d.tid in (".getTypeId($type).")";
if (!empty($keyword)) $whereStr.=" and d.n_title like '%".$keyword."%'";
$whereorder = str_replace("where order","order",str_replace("where and","and",$whereStr.$orderStr)); //$whereorder 即为" order by d.$order desc"
$csqlStr="select count(*) as dd from `sea_news` d where d.n_recycled=0 ".$whereorder; //第一处拼接查询语句
if ($n_recycled=="ok")$csqlStr="select count(*) as dd from `sea_news` d where d.n_recycled=1 ".$whereorder;
$row = $dsql->GetOne($csqlStr); 进入GetOne()
if(is_array($row)){
$TotalResult = $row['dd'];
}else{
$TotalResult = 0;
}
$TotalPage = ceil($TotalResult/$numPerPage);
if ($page>$TotalPage) $page=$TotalPage;
$limitstart = ($page-1) * $numPerPage;
if($limitstart<0) $limitstart=0;
$sqlStr="select d.n_id,d.n_title,d.n_hit,0,d.tid,d.n_addtime,d.n_commend,t.tname from sea_news d left join `sea_type` t on t.tid=d.tid where d.n_recycled=0 ".$whereorder." limit $limitstart,$numPerPage"; //第二处拼接查询语句
if ($n_recycled=="ok") $sqlStr="select d.n_id,d.n_title,d.n_hit,0,d.tid,d.n_addtime,d.n_commend,t.tname from sea_news d left join `sea_type` t on t.tid=d.tid where 1=1 ".$whereorder." limit $limitstart,$numPerPage";
//echo $sqlStr;die();
?>

跟进GetOne()

seacmsV6.61\include\sql.class.php

主要是看Execute()

数据在进入mysql_query()之前会进行SQL语句安全检查,重点在这

这里的$this->safeCheck前面赋值为true,但是我们的payload没有进入SQL语句安全检测,为什么呢

1
2
3
4
5
  if($this->safeCheck)
        {
            
            CheckSql($this->queryString);
        }

admin_news.php 中包含seacmsV6.61\admin\config.php

config.php中的$dsql->safeCheck=false,所以就跳过了CheckSql()这个检查函数,SQL注入因此产生

看到有人用这个洞申请CVE,想想也没什么意思。

好记性不如烂笔头

Veröffentlicht am 2018-06-01

最近暴露了许多问题:理论基础不牢固,心态容易失衡,这种情况下表达能力会降低,做过的项目很容易忘记。

如何解决:

  1. 多读书,同时做笔记
  2. 早读,将一些笔记内容熟读
  3. 整理做过的事情或者项目,系统化理论化
  4. 摆正心态,不管在哪里,不能消沉放弃
  5. 提高用语言表达技术、用文档表达技术的能力

关于工作、生活

Veröffentlicht am 2018-05-11

最近看到一个前辈说,优秀的人思想都是独立的,深以为然。循规蹈矩的人很难有什么创造力,最敏锐的心思,往往是从磨炼中来的。

离职之后轻松许多,大多数时间都在独处。独处是窥视内心最好的时候,如果感到空虚,必然会带来散漫,进一步就是消极。

有时候计划无法完成时往往会感到焦虑,然而达到目标的最好做法就是按部就班的做下去,过程比结果重要。

想了一些事情以后用来提升核心竞争力:

  1. 保持代码量,从开发的角度理解漏洞
  2. 技能的熟练度
  3. 前瞻性,掌握某一领域未来发展方向
  4. 多付出一点、多承担、多学习

Host Header欺骗在密码找回中的利用

Veröffentlicht am 2017-12-16

看到了一篇国外的blog,分享了一个找回密码功能中利用$_SERVER['HTTP_HOST']窃取token的姿势,本来我以为是email header injection,后来发现不是。雨神在他的blog 为什么$_SERVER['HTTP_HOST']有时是不可控的 中就提到$_SERVER['HTTP_HOST']是可控的:
一些同学会以为HTTP的联机就是靠包里的HOST header来连接的,所以会认为如果修改掉包里的HOST, 那么就连接不到目标服务器,所以是不可控的。 其实HTTP的联机与包里的HOST并没有啥关系, HTTP的联机是TCP/IP建立的, 所以修改掉HOST HEADER并不会把包丢到另外一个服务器上。
方便理解,这里要介绍一下HTTP_HOST和SERVER_NAME的区别: HTTP_HOST是从客户端获取的,用户可控,SERVER_NAME是从服务器配置文件获取的,如:
<?php echo $_SERVER['SCRIPT_NAME'].PHP_EOL; echo $_SERVER['HTTP_HOST'].PHP_EOL; echo $_SERVER['SERVER_NAME']; ?>
我服务器上的server_name是bugbountychina.com
image
image
当应用使用$_SERVER['HTTP_HOST']获取网站URL并拼接到找回密码的链接当中,就会产生漏洞。
当你使用网站密码重置功能,网站URL可能在将来会改变,所以要动态地生成一个邮箱找回密码的链接来匹配服务器的URL。这个时候可能就会使用$_SERVER['HTTP_HOST']
Host header 是客户端提供的,意味着攻击者可以将他们自己的网址写到重置密码的邮件当中,威胁任意用户的账户安全。下面是一个攻击场景:

  1. 攻击者确认目标用户邮箱地址
  2. 攻击者将重置密码请求中的host header设置成他们自己的网址
  3. 目标用户会接收到如下的邮件
    image
  4. 目标用户出于对公司的信任,点击了这个重置链接。由于这个链接是由host header生成的,会指向攻击者的网站。当目标用户访问了这个网站,他们的密码重置token也会被发给攻击者。
  5. 此时攻击者可以使用目标用户的token重置他们的密码

案例 - Mavenlink

Mavenlink上项目地址是public HackerOne program

  • Mavenlink允许用户注册一个mavenlink.com的子域名去展示他们的内容,所以他们需要一个方法去动态地决定公司的子域名。
  • host header 可以设置为mavenlink.com的任意子域名,但是从mavenlink.com更改域名将会返回一个错误,而不是发送一个邮件。
  • 添加一个随机的mavenlink.com的子域名,但是这会被定向到正确的页面,没办法插入自己的域名。
  • 测试特殊字符。服务器接受host header中的一个问号,生成下面的链接
    Host: example.com?.mavenlink.com
  • 这样就可以从用户邮件中盗取密码重置token
    image

报告:
https://hackerone.com/reports/281575
结论:
发送密码重置邮件时,不要信任host header,在任何情况下也不要信任它。相反,如果需要对一个动态的URL进行解析,最好的方法是将host作为一个服务端变量储存。

原文:
https://lightningsecurity.io/blog/host-header-injection/
参考:
https://stackoverflow.com/questions/2297403/what-is-the-difference-between-http-host-and-server-name-in-php/2297421#2297421
http://www.yulegeyu.com/2017/04/24/%E4%B8%BA%E4%BB%80%E4%B9%88$_SERVER['HTTP_HOST']%E6%9C%89%E6%97%B6%E6%98%AF%E4%B8%8D%E5%8F%AF%E6%8E%A7%E7%9A%84%E3%80%82/
https://stackoverflow.com/questions/2297403/what-is-the-difference-between-http-host-and-server-name-in-php/2297421#2297421

moonfish

7 Artikel
© 2019 moonfish
Erstellt mit Hexo
|
Theme — NexT.Muse v5.1.3