requests 如何编码 multipart/form-data

requests 是用 python 处理 HTTP 请求时毋庸置疑的第一选择,其中的一个原因就是它简洁的 API 接口。那么这些接口下面隐藏的是什么样的东东呢,今天我们来分析一下 requests 是如何处理 multipart/form-data 格式的请求的。 ...

October 9, 2017

ShadowsocksX-NG 工作原理

ShadowsocksX-NG 是官方支持的 macOS 下的 shadowsocks 客户端,支持诸多 shadowsocks 协议的特性,今天我们来分析一下它的工作原理。 先看一下 ShadowsocksX-NG.app 中的内容,首先注意的是几个脚本: install 脚本是将相应的二进制文件复制到相应的目录中,start 脚本 是通过 launchctl 命令 load 相应的 plist 文件, stop 脚本是 unload 相应的 plist 文件。 其实 ShadowsocksX-NG 只是 Swift 写的一个 GUI 而已,主要的代理程序还是直接使用了 shadowsocks-libev 编译好的 ss-local 程序。ss-local 启动后监听在 1080 端口,接受 socks 协议的请求。 对于 http 协议的代理,则是集成了 privoxy 程序,监听在 1087 端口,然后转发到 1080 端口上,实现对 http 协议的代理。 另外还有集成了一个 kcptun,不过好像没有启动。 还有一个 pac server,监听在 1089 端口,用来给系统代理提供 PAC 文件,比如系统的网络配置中的 Proxy Configuration File: 这样使用系统代理的程序就可以自觉地访问本地的 1080 端口,省去了手动配置的操作。 ShadowsocksX-NG 也提供了 Manaul Mode,在此模式下,不会设置系统代理,所有的应用都需要手动配置。...

October 7, 2017

Discuz X 3.4 由任意文件删除到 Getshell

2017年9月29日,Discuz! 修复了一个安全问题用于加强安全性,这个漏洞会导致前台用户可以导致任意删除文件漏洞。并且,配合其他漏洞可以实现 GetShell。 初步分析 先下载官方托管在码云上的 Discuz X 源码: git clone https://gitee.com/ComsenzDiscuz/DiscuzX.git 查看其提交历史,发现有一个『优化 加强安全性』的 commit 比较可疑: 查看其具体内容: 它删除了5个 unlink 语句…… 这种修复方式真是简单粗暴啊… 看来我们分析的入口就在这里了。 任意文件删除 这部分的分析请参考这里:https://paper.seebug.org/411/ (别吐槽——这篇文章分析得很好,省了我很多字 :haha:) 文件删除能做什么 通过上面那篇文章,想必大家都能复现文件删除的漏洞了。那么这个漏洞能做什么呢?难道只是单纯的破坏吗? 我们知道, Discuz X 这类 CMS 软件,都会一个 install 目录,用来处理用户初次安装时的配置和数据库初始化。在安装完成后,会在 data 目录下生成一个 install.lock 文件。如果尝试再次访问 /install 来安装,检测到存在 install.lock,于是提示错误: 如果用户没有删除 install 目录,而且我们也可以利用文件删除漏洞的话,我们就可以删掉这个 instal.lock,然后重新安装 Discuz。而重装过程中一般都有写配置文件的步骤,可能会给我们写入一句话的机会。 分析重装过程 install/index.php 文件控制安装的过程,它的逻辑其实很简单。安装主要分为五个步骤: show_license 显示是否接受协议,同意后跳到 env_check env_check 检查目录是否可写和 PHP的相关检测,然后跳到 app_reg app_reg 提示是否安装 UCenter Server,POST 到 app_reg,如果 install_ucenter=yes,直接重定向至 db_init,否则显示配置 ucenter 的表单 db_init 要求填写数据库和网站信息,POST 到 db_init,这时会进行数据库连接和数据表的检查。所以填写的数据库地址等信息要求必须是目标站能够连接的真实的服务器。 …....

October 2, 2017

Composer 初试

Composer 不是一个包管理器,默认下它不会全局安装任何包,只是在一个项目的某个目录中进行安装,它只是一个依赖管理工具。 Composer 解决的问题是: 你有一个项目依赖于若干个库 其中一些库依赖于其他库 你声明你依赖的东西 Composer 会找出哪个版本的包需要安装,并安装他们(将他们下载到你的项目中) 安装 curl -sS https://getcomposer.org/installer | php installer是一个PHP脚本,用来下载真正的composer.phar,composer.phar会保存到当前目录中。可以使用 --install-dir指定保存目录。 将composer.phar移动到PATH中 mv composer.phar /usr/local/bin/composer 这样就可以直接使用composer命令 使用 composer help 非常有用 composer install 读取当前目录下的composer.lock文件,下载和安装其中提到的库和依赖。如果composer.lock不存在,则查看composer.json文件。 composer update 读取当前目录中的composer.json文件,更新、删除或者安装所有的依赖。 composer init composer require xx 添加xx依赖到composer.json中,并安装他们 修改composer 全局配置composer config -g repo.packagist composer https://packagist.phpcomposer.com 链接 Composer中文文档 Packagist/Composer中国全量镜像

January 21, 2017

PHP 使用 xdebug 调试之路

PHPStorm中调试利用的是xdebug的remote特性,使用的是 DBGp协议,PHPStorm是一个实现了DBGp协议的客户端 在php.ini中启用xdebug.remote_enable, 配置xdebug.remote_host和xdebug.remote_port, port默认是9000. 通过phpinfo()函数的输出,可以在Loaded Configuration File中看到实际加载的php.ini文件是哪一个。 sudo apt install php-xdebug之后,会自动在/etc/php/7.0/apache2/conf.d中创建一个xdebug的配置文件,可以在这个文件中修改关于xdebug的配置,而不用去改通用的php.ini. client启动之后会监听 port,等待xdebug发送的请求。 要使php解释器在运行的时候activate xdebug,有三种方式: 从命令行运行php脚本时,设置环境变量export XDEBUG_CONFIG="idekey=session_name", 同样也可以在XDEBUG_CONFIG环境变量中设置remote_host,remote_port等属性。 从一个浏览器中启动debugger,需要传递一个XDEBUG_SESSION_START=session_name参数,这个参数可以是GET,POST或者Cookie。可以使用一些浏览器的插件自动传递这个参数。 只要xdebug.remtoe_enable开启了,PHPStorm打开了 Listening for PHP Debug,也就是服务器和客户端都准备好了,然后浏览器发送请求的时候包含一个XDEBUG_SESSION_START参数(?文档中写的是XDEBUG_SESSION_START,而实际上bookmark和插件中设置的cookie都是XDEBUG_SESSION),就可以愉快地调试了。

January 21, 2017

Python 图片处理库: Pillow

Image.open() im.mode, im.size, im.format Image.save() Image.show() 性能很慢, 仅作调试用. Image.convert() 比较常用的函数 Image.crop() Image.paste() Image.split() 将图像分为不同的 band Image.getpixel() Image.putpixel() 很慢 Image.point() 可以接受一个 lookup table, 或者一个函数, 函数接受一个参数, 这个参数可以看做像素点的颜色, 返回值为像素点的新颜色 Image.thumbnail() 生成缩略图, 会直接修改原图, 如果要保留原图需要先用 Image.copy() Image.getbbox() 这个函数好像很好用的样子, 待会儿再尝试 Image.getcolors(maxcolors=256) 获取图片中用到的所有颜色, 返回 [ (count, color),… ] 如果是 RGB 等格式, color 也是一个 tuple, 所以不同的颜色会有很多, 需要传入较大的 maxcolors, 否则会返回 None Image.histogram() 获取图片的直方图, 返回一个list, 如果是灰度图像, 则 list 大小为256, 每个元素表示0-255各个灰度的像素点的个数. 如果是 RGB 图像, 则 list 大小为 256*3.

January 21, 2017

跨域相关

同源策略 origin = 协议 + 域名 + 端口号 同源策略的限制: Cookie, LocalStorage 和 IndexDB 无法读取 DOM 无法获得 AJAX 无法发送 可跨域的标签 script,img,iframe, link等 JSONP 实质是一种自己发起的XSS 无法在 https 页面发起对非https的请求,会出现 Mixed content 错误 CORS方案 发起跨域请求时,浏览器会自动设置Origin首部,无法手动改变 在服务端的响应中设置Access-Control-Allow-Origin首部 但是这个首部不支持多个 host,所以如果需要支持多个 domain,需要动态地生成这个首部。比如说: < ?php $allowedOrigins = array("http://example.com", "http://localhost:63342"); $headers = getallheaders(); if ($headers["Origin"] && in_array($headers["Origin"], $allowedOrigins)) { header("Access-Control-Allow-Origin: " . $headers["Origin"]); } ?> 是否发送凭证 客户端: var xhr = new XMLHttpRequest(); xhr.withCredentials = true; 服务端添加 Access-Control-Allow-Credentials : true首部,如果服务器端没有返回这个首部,即使当前domain是允许的,客户端也得不到响应。会有类似 XMLHttpRequest cannot load http://example....

January 20, 2017

TensorFlow 初试

安装 pip install tensorflow 如果安装GPU版本的,需要安装 Cuda Toolkit 8.0 和 cuDNN v5.1 pip install tensorflow-gpu 并且设置环境变量 LD_LIBRARY_PATH和CUDA_HOME。 运行 demo model python -m tensorflow.models.image.mnist.convolutional

January 19, 2017

127.0.1.1是什么?

Some software (e.g., GNOME) expects the system hostname to be resolvable to an IP address with a canonical fully qualified domain name. This is really improper because system hostnames and domain names are two very different things; but there you have it. In order to support that software, it is necessary to ensure that the system hostname can be resolved. Most often this is done by putting a line in /etc/hosts containing some IP address and the system hostname....

January 19, 2017

Apache 配置学习

基本 配置文件/etc/apach2/apache2.conf以及/etc/apache2/conf-enabled DirectoryIndex index.html index.php 优先级从左到右降低 包含外部配置文件 Include xxx 启动 apachectl脚本,从/etc/apache2/envavars中读取并设置一些环境变量 Rewrite 基于正则表达式的规则,动态修改 incoming URl requests。 Virtual Host 用同一个 Apache 服务器上搭建多个服务,根据用户请求中不同的 Host首部(或其他条件) 将请求转给不同的VirtualHost来处理。 Name-based vs IP-based Virtual Hosts 基于IP的虚拟主机,要求服务器有多个IP,Apache根据用户请求的IP来转发到相应的主机中 基于名字的虚拟主机,要求客户端在HTTP首部中包含主机的名字,这样多个主机就可以共享同一个IP。 基于名字(hostname)的虚拟主机,通常只需要将多个域名解析到同一个IP即可。 比如说,login.a.com和logout.a.com只想相同的IP,也使用相同的端口(即后台的web服务器是同一个),但是后台的web服务器却可以根据请求中的Host首部不同,为他们提供不同的服务。 服务器如何选择合适的 name-based virtual host? 先进行 IP-based的选择,也就是先根据请求的IP选择出为此IP服务的Virtual Host,然后再从中找出最符合的name-based virtual host。 先根据IP和端口选出一组最符合的hosts,然后根据ServerName和ServerAlias作比较。如果没有符合的ServerName和ServerAlias,则选择列出的第一个。 省略ServerName则默认使用fully qualified domain name。 参考链接

January 18, 2017