password-analyzer/README.md
2023-11-05 16:01:55 +08:00

208 lines
7.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# password-analyzer
## Description
实现了以下的分析功能:
- [x] 密码长度分析 [source](./stat_length.cpp)
- [x] 密码结构分析 [source](./stat_struct.cpp)
- [x] 密码键位分析 [source](./stat_keystroke.cpp)
- [x] 密码日期分析 [source](./stat_date.cpp)
- [x] 密码单词分析 [source](./stat_word.cpp)
## Compile and Run
### Prerequisites
项目使用了 C++23 标准进行编写,需要使用支持 C++23 的编译器进行编译
经过测试的编译器:
```
# g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/13.2.1/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /build/gcc/src/gcc/configure --enable-languages=ada,c,c++,d,fortran,go,lto,objc,obj-c++ --enable-bootstrap --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/ --with-build-config=bootstrap-lto --with-linker-hash-style=gnu --with-system-zlib --enable-__cxa_atexit --enable-cet=auto --enable-checking=release --enable-clocale=gnu --enable-default-pie --enable-default-ssp --enable-gnu-indirect-function --enable-gnu-unique-object --enable-libstdcxx-backtrace --enable-link-serialization=1 --enable-linker-build-id --enable-lto --enable-multilib --enable-plugin --enable-shared --enable-threads=posix --disable-libssp --disable-libstdcxx-pch --disable-werror
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 13.2.1 20230801 (GCC)
```
如果使用 `clang++` 编译器,需要修改 `CMakeLists.txt`,强制使用 `libc++``patch` 如下:
```diff
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2ca65a4..5129602 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -12,6 +12,9 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fmacro-prefix-map=${CMAKE_SOURCE_DIR}=.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fuse-ld=mold -Wno-unused-command-line-argument")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=address,undefined")
+set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++ -lc++abi")
+gset(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
+
message(STATUS "[DEPS] Processing spdlog")
FetchContent_Declare(
spdlog
```
其它依赖:
1. `cmake >= 3.12`
2. `make` or `ninja`
3. `git`
4. `mold`: 可选,若不需要使用 `mold` 进行链接,请在 `CMakeLists.txt` 中删除 `-fuse-ld=mold` 选项
### Compile
编译:
```bash
mkdir build
pushd
cmake ..
cmake --build . -j
popd
```
### Run
**项目根目录** 下运行:
```
# ./build/password-analyzer
[2023-11-05 14:45:17.980] [info] [stat_length(YAHOO)] start...
[2023-11-05 14:45:18.174] [info] 8: 119134
[2023-11-05 14:45:18.174] [info] 6: 79628
[2023-11-05 14:45:18.174] [info] 9: 65963
...
```
## Details
图标详见 [result.xlsx](./data/result.xlsx)
### 密码长度分析
在 YAHOO 的数据集中
- 密码长度从 1 位到 30 位不等
- 主要集中在 6 - 10 位
- 其中 8 位的密码最多,占比达 27%
在 CSDN 的数据集中
- 密码长度从 1 位到 40 位不等
- 主要集中在 8 - 12 位
- 其中 8 位的密码最多,占比达 36%
### 密码结构分析
在 YAHOO 的数据集中
- 排名前 3 位的均为全字母型密码
- 在前 15 种类型中仅有一种全数字型的密码D6排名第 7
在 CSDN 的数据集中
- 在前 15 种类型中
- 全数字密码占 6 个
- 全字母密码占 3 个
- 其余为字母数字混合型
- 排名第一的类型为 D8
- 从结构上来看符合 YYYYMMDD 日期类型或者 12345678简单密码
- 其出现频率约为第二名(D9)的两倍
在这两个数据集中,前 15 中模式中均未发现特殊符号
### 密码键位分析
在 YAHOO 的数据集中
- 前 3 位的键位类型为123456, qwerty, 123456789
- 键位连续型的密码出现频次较低
在 CSDN 的数据集中
- 前 3 位的键位类型为123456, 123456789, 1234567
- 键位连续型的密码出现频次较高
- 前 4 位的键位类型均为纯数字型,与密码结构中常见全数字型密码的结论相符
- YAHOO 中常见的 qwerty 键位类型在 CSDN 中出现在第 10 位
- CSDN 中首个常见的连续字母型键位位 zxcvbnm出现在第 5 位
### 密码日期分析
采用正则表达式匹配日期类型,将日期分为以下几种类型:
```cpp
// YYYY MM DD
0: std::regex(R"((?:19|20)\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[1-2][0-9]|3[0-1]))"),
1: std::regex(R"((?:19|20)\d{2}\.(?:0[1-9]|1[0-2])\.(?:0[1-9]|[1-2][0-9]|3[0-1]))"),
2: std::regex(R"((?:19|20)\d{2}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[1-2][0-9]|3[0-1]))"),
3: std::regex(R"((?:19|20)\d{2}/(?:0[1-9]|1[0-2])/(?:0[1-9]|[1-2][0-9]|3[0-1]))"),
// MM DD YYYY
4: std::regex(R"((?:0[1-9]|1[0-2])(?:0[1-9]|[1-2][0-9]|3[0-1])(?:19|20)\d{2})"),
5: std::regex(R"((?:0[1-9]|1[0-2])\.(?:0[1-9]|[1-2][0-9]|3[0-1])\.(?:19|20)\d{2})"),
6: std::regex(R"((?:0[1-9]|1[0-2])-(?:0[1-9]|[1-2][0-9]|3[0-1])-(?:19|20)\d{2})"),
7: std::regex(R"((?:0[1-9]|1[0-2])/(?:0[1-9]|[1-2][0-9]|3[0-1])/(?:19|20)\d{2})"),
// YY MM DD
8: std::regex(R"(\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[1-2][0-9]|3[0-1]))"),
9: std::regex(R"(\d{2}\.(?:0[1-9]|1[0-2])\.(?:0[1-9]|[1-2][0-9]|3[0-1]))"),
10: std::regex(R"(\d{2}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[1-2][0-9]|3[0-1]))"),
11: std::regex(R"(\d{2}/(?:0[1-9]|1[0-2])/(?:0[1-9]|[1-2][0-9]|3[0-1]))"),
// MM DD YY
12: std::regex(R"((?:0[1-9]|1[0-2])(?:0[1-9]|[1-2][0-9]|3[0-1])\d{2})"),
13: std::regex(R"((?:0[1-9]|1[0-2])\.(?:0[1-9]|[1-2][0-9]|3[0-1])\.\d{2})"),
14: std::regex(R"((?:0[1-9]|1[0-2])-(?:0[1-9]|[1-2][0-9]|3[0-1])-\d{2})"),
15: std::regex(R"((?:0[1-9]|1[0-2])/(?:0[1-9]|[1-2][0-9]|3[0-1])/\d{2})"),
// MM DD
16: std::regex(R"((?:0[1-9]|1[0-2])(?:0[1-9]|[1-2][0-9]|3[0-1]))"),
17: std::regex(R"((?:0[1-9]|1[0-2])\.(?:0[1-9]|[1-2][0-9]|3[0-1]))"),
18: std::regex(R"((?:0[1-9]|1[0-2])-(?:0[1-9]|[1-2][0-9]|3[0-1]))"),
19: std::regex(R"((?:0[1-9]|1[0-2])/(?:0[1-9]|[1-2][0-9]|3[0-1]))"),
```
在 YAHOO 的数据集中
- 类型 16, 12, 8 占据前三位
- 类型16形如 MMDD 的日期类型
- 类型12形如 MMDDYY 的日期类型
- 类型8形如 YYMMDD 的日期类型
- 其余类型出现频次较低,可忽略不计
在 CSDN 的数据集中
- 类型 8, 0, 12, 16
- 类型8形如 YYMMDD 的日期类型
- 类型0形如 YYYYMMDD 的日期类型
- 类型12形如 MMDDYY 的日期类型
- 类型16形如 MMDD 的日期类型
- 其余类型出现频次较低,可忽略不计
需要注意的是MMDD, MMDDYY 等类型的日期由于长度较短,在密码串中可能并不表示日期,而是具备其他的含义
由此筛选下来,只有在 CSDN 数据集中出现了常见的日期类型密码YYYYMMDD
### 密码单词分析
单词表来源于 Google 发布的 Top10000 English words
在 YAHOO 的数据集中
- Top20 单词为sword, password, write, money, angel, jesus, chris, writer, content, black, monkey, green, super,
associate, welcome, associated, prince, sweet, dragon, christ
- 其中 sword 与 password 互为包含关系sword 频次主要来源于 password
- 出现了 angel, jesus, chris 等具有宗教色彩的单词
在 CSDN 的数据集中
- Top20 单词为sword, happy, password, admin, china, hello, angel, angle, super, apple, window, windows, forever, dream,
loves, shine, lover, kevin, tiger, dragon
- 一样的出现了 sword 与 password 的包含关系
- 出现了 password, admin 等经典口令