PHP 反序列化与字符串逃逸

0x00 漏洞成因 该漏洞主要是因为序列化的字符串在经过过滤函数不正确的处理而导致对象注入,目前看到都是因为过滤函数放在了 serialize 函数之后 0x01 条件 相邻两个属性的值是我们可以控制的 前一个属性的 s 长度可以发生变化(变长变短都可以) 若变长则可以直接在该属性中注入对象来达到反序列化 若变短则可以吞掉后面相邻属性的值,在后面的属性中注入新的对象 0x02 题目 Bugku CTF 的题 <?php // php版本:5.4.44 header("Content-type: text/html; charset=utf-8"); // highlight_file(__FILE__); class evil{ public $hint; public function __construct($hint){ $this->hint = $hint; } public function __destruct(){ if($this->hint==="hint.php") { @$this->hint = base64_encode(file_get_contents($this->hint)); } var_dump($this->hint); } function __wakeup() { if ($this->hint != "╭(●`∀´●)╯") { //There's a hint in ./hint.php $this->hint = "╰(●’◡’●)╮"; } } } class User { public $username; public $password; public function __construct($username, $password){ $this->username = $username; $this->password = $password; } } function filter($data){ $data = str_replace('123', 'abcdef', $data); return $data; } $username = $_POST['username']; $password = $_POST['password']; $a = serialize(new User($username, $password)); if(preg_match('/flag/is', $a)) die("NoNoNo!


PHP 反序列化

0x01 php 中的魔法函数 __construct():PHP 中类的构造函数,创建对象时调用。具有构造函数的类会在每次创建新对象时先调用此方法,所以非常适合在使用对象之前做一些初始化工作。 __destruct():PHP 中类的析构函数,销毁对象时调用。PHP 5 后引入了析构函数的概念,析构函数会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行。 __toString() 当一个对象被当作一个字符串使用。 __sleep() 在对象在被序列化之前被调用。 __wakeup 将在序列化之后立即被调用。 0x02 序列化和反序列化 serialize() 会检查类中是否存在一个魔术方法 __sleep()。如果存在,该方法会在 __construct 后被调用,然后才执行序列化操作。 unserialize() 会检查类中是否存在一个 __wakeup() 方法。如果存在,则会在 __destruct 前调用 __wakeup 方法,预先准备对象需要的资源。 0x03 序列化字符串格式 在 PHP 序列化得到的字符串中,字段根据长度判断内容、以 ; 作为字段的分隔、以 } 作为结尾(字符串除外) O:3:"ctf":2:{s:11:"username";s:5:"admin";s:6:"cmd";s:2:"ls";} O 代表对象,因为我们序列化的是一个对象,序列化数组则用 A 来表示 3 代表类名长度 ctf 是类名 2 代表两个属性 s 代表字符串 11 代表属性名长度 username 是属性名 s:5:"admin" 属性值时字符串 属性值长度 属性值 0x04 序列化中的访问控制修饰符 需要注意的是当访问控制符为 private 与 protect 时,序列化时比较特殊: protected 属性被序列化的时候属性值会变成:%00*%00 属性名


通过 Sphinx 快速查询数据

0x00 Sphinx Sphinx 是一款基于 SQL 的高性能全文检索引擎,Sphinx 的性能在众多全文检索引擎中也是数一数二的,利用 Sphinx我们可以完成比数据库本身更专业的搜索功能,而且可以有很多针对性的性能优化。 快速创建索引:3 分钟左右即可创建近 100 万条记录的索引,并且采用了增量索引的方式,重建索引非常迅速。 闪电般的检索速度:尽管是 1 千万条的大数据量,查询数据的速度也在毫秒级以上,2-4G 的文本量中平均查询速度不到 0.1 秒。 为很多脚本语言设计了检索 API,如 PHP,Python,Perl,Ruby 等,因此你可以在大部分编程应用中很方便地调用 Sphinx 的相关接口。 为 MySQL 设计了一个存储引擎插件,因此如果你在 MySQL 上使用 Sphinx,那简直就方便到家了。 支持分布式搜索,可以横向扩展系统性能。 0x01 使用 Sphinx 查询的流程 通过 Sphinx 的 indexer 生成索引(需要先配置文件 sphinx.conf) 部分索引:indexer.exe -c sphinx.conf index_3pk_com_member 全部索引:C:\Apps\sphinx\bin\indexer.exe -c C:\Apps\sphinx\etc\sphinx.conf --all 若此时searchd守护进程已经启动,那么需要加上 --rotate参数: C:\Apps\sphinx\bin\indexer.exe -c C:\Apps\sphinx\etc\sphinx.conf --all --rotate Sphinx 启动一个 searchd 进行监听(调接口) C:\Apps\sphinx\bin\searchd.exe -c c:\Apps\sphinx\etc\sphinx.conf


记一次 SQL 注入简单 bypass

0x00 存在 SQL 注入 总之是遇到一个站,登录的页面,数据包大致如下: POST /jsweb/userlogin/UserLoginAction.aspx HTTP/1.1 Host: 115.xxx.xxx.xxx:8042 Content-Length: 47 Accept: */* X-Requested-With: XMLHttpRequest User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36 Content-Type: application/x-www-form-urlencoded; charset=UTF-8 Origin: http://115.xxx.xxx.xxx:8042 Referer: http://115.xxx.xxx.xxx:8042/ Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9,en;q=0.8 Cookie: ASP.NET_SessionId=bxdzehxa5mvoco1fkrjlbqbt Connection: close uname=admin*&pwd=dskfsdkf&valCode=1197&telphone= 其中验证码可以绕过,而登录名那里存在注入 使用 and 1=1、and 1=2 时,发现过滤了空格,用/**/代替 0x01 简单看一下 中间件是 IIS,存在 len 函数,确定为 SQLServer Order by 一下,看看能不能 union,发现有 10 列 尝试 union select admin 转换为 int 时出错,感觉好像能显示位,测试发现确实可以显示 可以获取数据库版本,可以确定有 union 注入了 0x02 sqlmap sqlmap跑一下:sqlmap --risk=3 --level=3 --batch --thread=1 -r 1.


目录遍历利用

0x00 目录遍历 一个同事说有一些目录遍历,想着能不能搞个脚本啥的,以后利用也方便,自己没有写出来,说让我看看 一般来说存在目录遍历的话就是翻文件,看看有没有一些敏感信息、未授权接口之类的,一个个翻的话也确实比较麻烦 而且 eWebEditor、FCKeditor 这种编辑器有些版本也存在目录遍历漏洞,能找的一些未授权访问也是好的 以前写过一个爬网站链接的脚本,感觉可以在那个脚本的基础上改一下,改过后确实大致能用 0x01 脚本 #!/usr/bin/env python # -*- coding: utf-8 -*- ''' @Author: reber @Mail: reber0ask@qq.com @Date: 2019-08-05 15:58:38 @LastEditTime: 2019-12-16 17:07:09 ''' import asyncio import aiohttp from lxml import etree from urllib.parse import urljoin from urllib.parse import urlparse from urllib.parse import urlunsplit from pybloom_live import BloomFilter bf = BloomFilter(100000, 0.01) def is_repeat(ele): if ele in bf: return True #元素不一定在集合中 else: bf.add(ele) return False #元素一定不在集合中 class GetAllLink(object): """docstring for GetAllLink""" def __init__(self, target, crawl_deepth, rate): super(GetAllLink, self).


PostgreSQL 简单使用

0x00 安装 ➜ brew install postgresql ➜ echo 'export PATH="/usr/local/Cellar/postgresql/11.4/bin:$PATH"' >> ~/.zshrc ➜ source ~/.zshrc -- 初始化数据库 ➜ initdb /usr/local/var/postgres ➜ pg_ctl -D /usr/local/var/postgres -l /usr/local/var/log/postgres.log start 0x01 简单操作 常用操作命令 reber=# \password #设置当前登录用户的密码 reber=# \password [user_name] #设置其他用户的密码 reber=# \l #列出所有数据库 reber=# \du #列出所有用户 reber=# \c [database_name] #连接数据库 reber=# \d #列出当前数据库的所有表 reber=# \d [table_name] #列出表结构 reber=# \conninfo #列出当前数据库和连接的信息 连接数据库 ➜ psql postgres #初始化数据库后会生成默认的数据库 postgres psql (11.


记一次网页 js 挂马

0x00 常见网页挂马方式 iframe 框架挂马 简单来说就是加 iframe 标签 script 挂马 通过各种办法加载 js 代码 htm 文件挂马 上传 htm 文件,然后用 script 引入 js 挂马 上传 js 文件,然后用 script 引入 图片伪装挂马 比较新颖的一种挂马隐蔽方法 等等。。。 0x01 发现被插入恶意 js 前几天在做子域名搜集,搜集完后提取 title,结果看到了一个站点的 title 不正常 网站是 tp5 的,应该是前段时候 tp5 出现命令执行时被入侵的 查看网页 html 源码发现 title 和 meta 的 description 都被改了 <title>&#25250;&#24196;&#29275;&#29275;&#28216;&#25103;&#24179;&#21488;&#44;&#30495;&#38065;&#25250;&#24196;&#29275;&#29275;&#28216;&#25103;&#44;&#25250;&#24196;&#29275;&#29275;&#25163;&#28216;&#19979;&#36733;</title> <meta name="keywords" content="&#25250;&#24196;&#29275;&#29275;&#28216;&#25103;&#24179;&#21488;&#44;&#30495;&#38065;&#25250;&#24196;&#29275;&#29275;&#28216;&#25103;&#44;&#25250;&#24196;&#29275;&#29275;&#25163;&#28216;&#19979;&#36733;"/> <meta name="description" content="&#25250;&#24196;&#29275;&#29275;&#12304;&#55;&#49;&#49;&#49;&#48;&#46;&#99;&#111;&#109;&#12305;&#29616;&#20844;&#21496;&#25317;&#26377;&#19968;&#25209;&#26377;&#20960;&#21313;&#24180;&#21644;&#22810;&#25250;&#24196;&#29275;&#29275;&#25216;&#24039;&#24180;&#40831;&#36718;&#27979;&#37327;&#20013;&#24515;&#21046;&#36896;&#32463;&#39564;&#30340;&#20154;&#21592;&#44;&#25250;&#24196;&#29275;&#29275;&#28216;&#25103;&#35268;&#21017;&#38598;&#25104;&#20102;&#22269;&#20869;&#39030;&#23574;&#40831;&#36718;&#27979;&#37327;&#25216;&#26415;"/> 解码一下 <title>抢庄牛牛游戏平台,真钱抢庄牛牛游戏,抢庄牛牛手游下载</title> <meta name="keywords" content="抢庄牛牛游戏平台,真钱抢庄牛牛游戏,抢庄牛牛手游下载"/> <meta name="description" content="抢庄牛牛【71110.com】现公司拥有一批有几十年和多抢庄牛牛技巧年齿轮测量中心制造经验的人员,抢庄牛牛游戏规则集成了国内顶尖齿轮测量技术"/> 0x02 简单分析 紧接着有一段 js 代码


FRP 内网穿透

0x00 对外提供简单的文件访问服务 服务端 ➜ frp cat frps.ini [common] ; 监听端口 bind_port = 7000 ; 那些端口允许客户端用来映射 allow_ports = 22-80,3000,33389 ➜ frp ./frps -c frps.ini 2019/07/31 00:22:31 [I] [service.go:139] frps tcp listen on 0.0.0.0:7000 2019/07/31 00:22:31 [I] [root.go:204] Start frps success 客户端 C:\Users\Administrator\Desktop\frp>type frpc.ini [common] server_addr = 66.123.35.123 server_port = 7000 [test_static_file] type = tcp ; 文件服务的端口 remote_port = 3000 ; 启用插件 plugin = static_file ; 要对外暴露的文件目录 plugin_local_path = C:\\Users\Administrator\Desktop\frp_file ; 访问 url 中会被去除的前缀,保留的内容即为要访问的文件路径 plugin_strip_prefix = myfile ; 301 认证 plugin_http_user = admin plugin_http_passwd = 123456 C:\Users\Administrator\Desktop\frp>frpc.


通过 selenium 和 flask 中转后利用 sqlmap 进行注入

0x00 先说前提 昨天某个小伙伴说有个注入没法搞 前端提交登陆表单时数据包加密了, 而且有个 sign 字符串每次都不一样用于校验, 应该是用 js 加密了 0x01 找加密的 js 文件 注入的地方是获取验证码时的手机号, 刚开始想着先找到 js 加密的函数, 然后生成 sign 再组数据包发送。 就像 记一次SQL Server报错注入 中一样, 用 selenium 或者 PhantomJS 执行 js 代码生成sign 一番查找发现了加密的 js 文件函数, 但是用的是 angular 这个前端框架, 没用过这个东西。。。。。 能看懂一般的 js 代码, 但是这个没得搞, 不懂。。。 0x02 数据中转 本来昨天我已经放弃了的, 结果今天上午小伙伴又找我了, 说还没有整好, 又看了一通 js, 仍然无解, 看不懂。。。 想起昨天有个大佬说用 PhantomJS + flask 这样、那样、再这样, 中转数据就可以用 sqlmap 跑了, emmmmm。。。 虽然很早以前用过 asp 的 Cookie 注入中转 , 但是那个是软件, 一直没有搞懂原理, 现在正好趁机学下


利用 Python 的协程进行快速端口扫描

0x00 协程的优势 协程拥有极高的执行效率,因为子程序切换不是线程切换,而是由程序自身控制,因此没有线程切换的开销。和多线程比,线程数量越多,协程的性能优势就越明显。 不需要多线程的锁机制,因为只有一个线程,也不存在同时写变量冲突,在协程中控制共享资源不加锁,只需要判断状态就好了,所以执行效率比多线程高很多 0x01 Python中的协程 协程也就是微线程,python 的 generator(生成器) 中的 yield 可以一定程度上实现协程 在 generator 中,我们不但可以通过 for 循环来迭代,还可以不断调用 next() 函数获取由 yield 语句返回的下一个值。 但是 Python 的 yield 不但可以返回一个值,它还可以接收调用者发出的参数。 0x02 使用 gevent python 中可以通过 generator 实现协程,但是不完全,第三方的 gevent 为 Python 提供了比较完善的协程支持,gevent 可以通过 monkey patch 动态的修改 Python 自带的一些标准库 由于 IO 操作(比如访问网络)非常耗时,经常使程序处于等待状态,而 gevent 可以为我们自动切换协程,再在适当的时候切换回来继续执行,这就保证总有 greenlet 在运行,而不是等待 IO 使用 gevent 可以获得极高的并发性能,但 gevent 只能在 Unix/Linux 下运行,在 Windows 下不保证正常安装和运行 下面 3 个网络操作是并发执行的,且结束顺序不同,但只有一个线程 from gevent import monkey; monkey.patch_all() import requests import gevent def get_resp_size(url): print('GET: %s' % url) html = requests.

可以返回顶部