Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
bypass-url-parser — 원시 curl 요청을 사용하여 40X 보호된 페이지에 대해 수백 가지 URL 우회 기법을 테스트하며, 멀티 모드 스캐닝, 헤더 스푸핑, 접근 제어 평가를 위한 JSON/HTML 결과 내보내기를 제공합니다. | Kitploit
도구/GitHubGitHub/laluka/bypass-url-parser
Vulnerability AnalysisInformation GatheringWAF BypassWeb SecurityPenetration Testing
GitHublaluka/bypass-url-parser

bypass-url-parser

원시 curl 요청을 사용하여 40X 보호된 페이지에 대해 수백 가지 URL 우회 기법을 테스트하며, 멀티 모드 스캐닝, 헤더 스푸핑, 접근 제어 평가를 위한 JSON/HTML 결과 내보내기를 제공합니다.

저장소 보기
1.1k1221년 전Kitploit 검토 완료

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유
웹사이트

Bypass Url Parser

PyPI - Version PyPI - Python Version PyPI - License pdm-managed

MANY URL 우회를 테스트하여 40X 보호 페이지에 도달하는 도구입니다.

이 코드가 단지 더러운 curl 래퍼일 뿐인 이유가 궁금하다면, 그 이유는 다음과 같습니다:

  • 대부분의 Python 요청 라이브러리는 URL/경로/매개변수 인코딩/디코딩을 수행하는데, 저는 이것을 싫어합니다.
  • 원시 문자를 제출하면, 원시 문자가 전송되기를 원합니다.
  • 이상한 경로를 보내면, 정규화되지 않은 그대로 비정상적으로 보내기를 원합니다.

이것은 파싱, SSL/TLS 캡슐화 등의 라이브러리 이점을 모두 잃지 않고 파이썬에서 달성하기가 놀랍도록 어렵습니다.
그러니 저처럼 curl을 백엔드로 사용하세요. 문제없을 것입니다.

또한, 이 도구는 라이브러리로 사용할 수 있습니다. lib_sample_usage.py를 참조하세요.

설치

이 도구를 설치하려면 pipx를 사용하는 것을 권장합니다:```bash pipx install bypass-url-parser

or for the latest dev version

pipx install git+https://github.com/laluka/bypass-url-parser

root@kitploit:~
또는, `pip`를 사용할 수 있습니다:```bash
pip install bypass-url-parser

사용법```

Bypass Url Parser, made with love by @TheLaluka A tool that tests MANY url bypasses to reach a 40X protected page.

Usage: bypass-url-parser (-u | -R ) [-m ] [-o ] [-S ] [ (-H

)...] [-r ] [-s ] [--spoofip-replace] [-p ] [--spoofport-replace] [-t ] [-T ] [--request-tls] [--jsonl] [--dump-payloads] [-x <proxy_url>] [-v | -d | -dd]

Program options: -u, --url URL (path is optional) to run bypasses against -R, --request Load HTTP raw request from a file -H, --header

Header(s) to use, format: "Cookie: can_i_haz=fire" -m, --mode Bypass modes. See 'Bypasser.BYPASS_MODES' in code [Default: all] -o, --outdir Output directory for results -x, --proxy <proxy_url> Set a proxy in the format http://proxy_ip:port. -S, --save-level Save results level. From 0 (DISABLE) to 3 (FULL) [Default: 2] -s, --spoofip IP(s) to inject in ip-specific headers -p, --spoofport Port(s) to inject in port-specific headers -r, --retry Retry attempts of failed requests. Set 0 to disable all retry tentatives [Default: 1] -t, --threads Scan with N parallel threads [Default: 1] -T, --timeout Request times out after N seconds [Default: 5]

General options: -h, --help Show help, you are here :) -v, --verbose Verbose output -d, --debug Show more details like curl commands generated by this tool -dd, --debug Print Debug level 2 (with all classes debug_class output) -V, --version Show version info

Misc options: --spoofip-replace Disable list of default internal IPs in 'http_headers_ip' bypass mode --spoofport-replace Disable list of default internal ports in 'http_headers_port' bypass mode --request-tls Force usage of TLS/HTTPS for the request load with the '-R, --request' option --dump-payloads Print all payloads (curls) generated by this tool. --jsonl Print results in JSON lines format (pipe command output)

Examples: bypass-url-parser -u "http://127.0.0.1/juicy_403_endpoint/" -s 8.8.8.8 -d bypass-url-parser -u /path/urls -t 30 -T 5 -H "Cookie: me_iz=admin" -H "User-agent: test" bypass-url-parser -R /path/request_file --request-tls -m "mid_paths, end_paths"

root@kitploit:~
## 예상 결과```bash
bypass-url-parser -u http://127.0.0.1:8000/foo/bar
2022-08-09 14:52:40 lalu-perso bup[361559] WARNING Trying to bypass 'http://127.0.0.1:8000/foo/bar' url (3213 payloads)...
2022-08-09 14:52:40 lalu-perso bup[361559] INFO Doing: 50 / 3213
[...]
2022-08-09 14:52:54 lalu-perso bup[361559] INFO Doing: 3200 / 3213
2022-08-09 14:52:54 lalu-perso bup[361559] INFO Retry (1/3) the '16' failed curl commands with 10 threads and 10s timeout
2022-08-09 14:52:54 lalu-perso bup[361559] INFO Retry (2/3) the '16' failed curl commands with 5 threads and 20s timeout
2022-08-09 14:52:54 lalu-perso bup[361559] INFO Retry (3/3) the '16' failed curl commands with 1 threads and 30s timeout
2022-08-09 14:52:55 lalu-perso bup[361559] INFO
[#####] [bypass_method] [payload] => [status_code] [content_type] [content_length] [lines_count] [word_counts] [title] [server] [redirect_url]
[GROUP (1587)] [original_request] [http://127.0.0.1:8000/foo/bar] => [404] [text/html] [469] [14] [95] [Error response] [SimpleHTTP/0.6 Python/3.8.10] []
[GROUP (10)] [http_methods] [-X CONNECT http://127.0.0.1:8000/foo/bar] => [501] [text/html] [500] [14] [96] [Error response] [SimpleHTTP/0.6 Python/3.8.10] []
[SINGLE] [mid_paths] [http://127.0.0.1:8000/???foo/bar] => [200] [text/html] [913] [26] [27] [Directory listing for /???foo/bar] [SimpleHTTP/0.6 Python/3.8.10] []
[SINGLE] [mid_paths] [http://127.0.0.1:8000//???foo/bar] => [301] [] [] [0] [0] [] [SimpleHTTP/0.6 Python/3.8.10] [/???foo/bar]
[SINGLE] [mid_paths] [http://127.0.0.1:8000/??foo/bar] => [200] [text/html] [911] [26] [27] [Directory listing for /??foo/bar] [SimpleHTTP/0.6 Python/3.8.10] []
[SINGLE] [mid_paths] [http://127.0.0.1:8000//??foo/bar] => [301] [] [] [0] [0] [] [SimpleHTTP/0.6 Python/3.8.10] [/??foo/bar]
[SINGLE] [mid_paths] [http://127.0.0.1:8000/?foo/bar] => [200] [text/html] [909] [26] [27] [Directory listing for /?foo/bar] [SimpleHTTP/0.6 Python/3.8.10] []
[SINGLE] [mid_paths] [http://127.0.0.1:8000//?foo/bar] => [301] [] [] [0] [0] [] [SimpleHTTP/0.6 Python/3.8.10] [/?foo/bar]
[SINGLE] [mid_paths] [http://127.0.0.1:8000///?anythingfoo/bar] => [200] [text/html] [929] [26] [27] [Directory listing for ///?anythingfoo/bar] [SimpleHTTP/0.6 Python/3.8.10] []
[SINGLE] [mid_paths] [http://127.0.0.1:8000////?anythingfoo/bar] => [200] [text/html] [931] [26] [27] [Directory listing for ////?anythingfoo/bar] [SimpleHTTP/0.6 Python/3.8.10] []
[GROUP (2)] [mid_paths] [http://127.0.0.1:8000/#?foo/bar] => [200] [text/html] [893] [26] [27] [Directory listing for /] [SimpleHTTP/0.6 Python/3.8.10] []
[GROUP (2)] [mid_paths] [http://127.0.0.1:8000//#?foo/bar] => [301] [] [] [0] [0] [] [SimpleHTTP/0.6 Python/3.8.10] [/]

설치

LINUX```bash

Deps

sudo apt install -y bat curl virtualenv python3

Tool

virtualenv -p python3 .py3 source .py3/bin/activate PDM_BUILD_SCM_VERSION="$(git describe --abbrev=0)-dev" pip install .

If bup installed globally, use

python src/bypass_url_parser/init.py -u https://thinkloveshare.com/juicy_403_endpoint/

Else this should work

bypass-url-parser -u https://thinkloveshare.com/juicy_403_endpoint/ cat /tmp/tmpRANDOM-bypass-url-parser/triaged-bypass.json | jq -r '.results[].request_curl_cmd' cat /tmp/tmpRANDOM-bypass-url-parser/triaged-bypass.json | jq -r '.results[].response_data'

root@kitploit:~
### 도커```bash
docker run --rm -it -v "$PWD:/host" -w /host ghcr.io/laluka/bypass-url-parser:latest bash -il
# Then bup -h, keep the docker open as the output is saved by default in /tmp
# Or specify the output to the current directory, and consult them later! :)

지원되는 인수에 대한 추가 정보

인수 구문 분석

Bypass_url_parser를 사용하면 여러 방법으로 일부 인수를 정의할 수 있습니다:

  • -m, --mode, -s, --spoofip 및 -p, --spoofport 인수는 파일 이름, 문자열, 쉼표로 구분된 문자열 목록 또는 목록(Bypasser가 라이브러리로 사용될 때)이 될 수 있습니다;
  • -u, --url 인수는 파일 이름, 문자열 또는 목록(Bypasser가 라이브러리로 사용될 때)이 될 수 있습니다;
  • 이러한 모든 인수에 대해 stdin (- 사용)이 지원됩니다.

예를 들어, 여러 대상 URL(-u, --url)을 정의하려면 다음 명령어들이 모두 동일한 결과를 생성합니다:```bash bypass-url-parser -u http://thinkloveshare.com/test bypass-url-parser -u /path/urls cat /path/urls | bypass-url-parser -u - echo 'http://thinkloveshare.com/test' | bypass-url-parser -u -

root@kitploit:~
### 대상 정의

도구가 작동하려면 대상을 정의해야 합니다. 2가지 옵션:

- `-u, --url`: URL(들), GET 방식
- `-R, --request`: 요청 파일. 파일에서 프로토콜을 추측할 수 없으므로 기본적으로 `http`이며, `--request-tls` 옵션이 있으면 `https`입니다.

### 우회 모드

`-m, --mode`가 지정되면, 원하는 우회 모드를 선택하여 특정 테스트(들)를 실행하고 도구가 보내는 요청 수를 줄일 수 있습니다.

현재 다음 우회 모드가 지원됩니다:```
all, mid_paths, end_paths, case_substitution, char_encode, http_methods, http_versions, http_headers_method, http_headers_scheme, http_headers_ip, http_headers_port, http_headers_url, user_agent

예시:```bash bypass-url-parser -u /path/urls -m "case_substitution, char_encode, http_headers_scheme"

root@kitploit:~
### Spoofip / Spoofport

우회 시도에 사용되는 IP 주소와 포트를 사용자 정의하기 위해, 이 도구는 다음 옵션을 지원합니다:

- `-s, --spoofip`을 사용하면 `ip-specific` 헤더(`X-Forwarded-For`, `X-Real-Ip` 등)에 주입할 일부 IP를 설정할 수 있습니다.
- `-p, --spoofport`를 사용하면 `port-specific` 헤더(`X-Forwarded-Port`)에 주입할 일부 포트를 설정할 수 있습니다.

기본적으로 이러한 사용자 정의 항목은 내부 IP/포트 목록에 추가됩니다. 오직 자신의 IP(들)/포트(들)만 사용하려면 `--spoofip-replace` 및/또는 `--spoofport-replace` 인수를 사용할 수 있습니다.

예제:```bash
bypass-url-parser -u /path/urls -s /path/custom_ip --spoofip-replace
bypass-url-parser -u /path/urls -p "3000, 9443, 10443"

JSON-Lines 출력 및 명령 파이핑

--jsonl 옵션을 사용하면 결과를 stdout에 JSON-Lines 형식으로 출력할 수 있습니다. 표준 도구의 출력과 결과는 stderr의 로거로 표시되므로, JSON-Line 출력 형식을 다른 도구와 파이프로 연결할 수 있습니다:```bash bypass-url-parser -u "https://thinkloveshare.com/juicy_403_endpoint/" -t 20 -S 0 -m case_substitution,char_encode --jsonl | jq

root@kitploit:~
***참고:** `-S 2` 또는 `-S 3`을 사용하면 JSON-Lines 출력에는 저장된 html 파일의 경로와 이름도 포함됩니다.*

### 결과 저장

기본적으로 대상 URL이 고유한 경우 도구는 `/tmp/tmpXXX-bypass-url-parser/` 디렉터리에 결과의 복사본을 저장합니다.

***참고:** 여러 대상 URL이 `-u`에 전달되면 URL을 디렉터리로 접두사로 사용하여 결과가 저장됩니다. (예: `/tmp/tmpXXX-bypass-url-parser/http-target-com-8080-api-users/`).*

이 동작을 사용자 정의할 수 있는 두 가지 인수가 있습니다:

- `-o, --outdir` 사용자 지정 출력 디렉터리 설정
- `-S, --save-level` 저장 수준 선택

저장 수준은 다음과 같습니다:

- `0` (NONE): 출력 저장 및 출력 디렉터리 생성을 비활성화합니다;
- `1` (MINIMAL): 결과가 포함된 프로그램 로그 파일만 저장합니다: `triaged-bypass.log`;
- `2` (PERTINENT): 프로그램 로그 파일 `triaged-bypass.log`와 **관련(결과)** curl 응답을 `triaged-bypass.json` 파일 및 별도의 html 파일에 저장합니다 (기본값);
- `3` (FULL): 프로그램 로그 파일 `triaged-bypass.log`와 **모든** curl 응답을 `triaged-bypass.json` 파일 및 별도의 html 파일에 저장합니다.

#### 예시```bash
bypass-url-parser -S 0
bypass-url-parser -S 1 -o /tmp/bypass-res
bypass-url-parser -S 2 -o /tmp/bypass-res2 -H "User-Agent: curl 7.74.0" -u http://thinkloveshare.com/juicy_403_endpoint/
tree /tmp/bypass-res2/
├── bypass-2469eecf6c38b5817d2248e911ad4382.html
├── bypass-6f7cce7caf0a0a4b440859fa189d496d.html
├── bypass-80f4ab5d32b4e74c20630c7e67f2e42f.html
├── bypass-93079abffe63d34f79ac4a511cd6b5e6.html
├── bypass-945822230d58d1ad4680d5dfbc470ecb.html
├── bypass-e6118c315eea0e5b2ebc4fcafe0559c0.html
├── triaged-bypass.json
└── triaged-bypass.log

0 directories, 8 files

결과 내보내기

MINIMAL 수준부터 프로그램에 표시된 결과는 triaged-bypass.log 파일에 저장됩니다.

JSON 내보내기

PERTINENT 및 FULL 저장 수준에서 프로그램은 모든 결과를 triaged-bypass.json 파일에 추가로 내보냅니다:

root@kitploit:~
{
  "url": "http://thinkloveshare.com/juicy_403_endpoint/",
  "bypass_modes": "all",
  "results": [
    {
      "request_curl_cmd": "/usr/bin/curl -sS -kgi -H 'User-Agent: curl 7.74.0' --path-as-is -H 'X-BlueCoat-Via: localhos[...SNIP...]",
      "request_curl_payload": "-H X-BlueCoat-Via: localhost http://thinkloveshare.com/juicy_403_endpoint/",
      "response_headers": "HTTP/1.1 301 Moved Permanently\nConnection: keep-alive\nContent-Length: 162\nServer: GitHub.c[...SNIP...]",
      "response_data": "<html>\n<head><title>301 Moved Permanently</title></head>\n<body>\n<center><h1>301 Moved Permane[...SNIP...]",
      "response_status_code": 301,
      "response_content_type": "text/html",
      "response_content_length": 162,
      "response_lines_count": 7,
      "response_words_count": 4,
      "response_title": "301 Moved Permanently",
      "response_server_type": "GitHub.com",
      "response_redirect_url": "https://thinkloveshare.com/juicy_403_endpoint/",
      "response_html_filename": "bypass-e6118c315eea0e5b2ebc4fcafe0559c0.html"
    },
    {
      "request_curl_cmd": "/usr/bin/curl -sS -kgi -H 'User-Agent: curl 7.74.0' --path-as-is -X PROPFIND http://thinklove[...SNIP...]",
      "request_curl_payload": "-X PROPFIND http://thinkloveshare.com/juicy_403_endpoint/",
      "response_headers": "HTTP/1.1 405 Method Not Allowed\nConnection: close\nContent-Length: 131\nServer: Varnish\nRet[...SNIP...]",
      "response_data": "<html>\n<head><title>405 Not Allowed</title></head>\n<body bgcolor=\"white\">\n<center><h1>405 N[...SNIP...]",
      "response_status_code": 405,
      "response_content_type": "",
      "response_content_length": 131,
      "response_lines_count": 5,
      "response_words_count": 5,
      "response_title": "405 Not Allowed",
      "response_server_type": "Varnish",
      "response_redirect_url": "",
      "response_html_filename": "bypass-945822230d58d1ad4680d5dfbc470ecb.html"
    },
    {  "...": "[...SNIP...]"},
    {
      "request_curl_cmd": "/usr/bin/curl -sS -kgi -H 'User-Agent: curl 7.74.0' --path-as-is 'http://thinkloveshare.com/j[...SNIP...]",
      "request_curl_payload": "http://thinkloveshare.com/juicy_403_endpoint/\u00b0//",
      "response_headers": "HTTP/1.1 400 Bad request\nConnection: keep-alive\nContent-Length: 90\nCache-Control: no-cache[...SNIP...]",
      "response_data": "<html><body><h1>400 Bad request</h1>\nYour browser sent an invalid request.\n</body></html>\n",
      "response_status_code": 400,
      "response_content_type": "text/html",
      "response_content_length": 90,
      "response_lines_count": 3,
      "response_words_count": 7,
      "response_title": "",
      "response_server_type": "",
      "response_redirect_url": "",
      "response_html_filename": "bypass-2469eecf6c38b5817d2248e911ad4382.html"
    }
  ]
}
```
`jq`로 더 쉽게 다룰 수 있게 만들기:```bash
$ jq -r '.results[] | [.request_curl_payload, .response_status_code, .response_content_type, .response_content_length] | join("|")' /tmp/bypass-res2/triaged-bypass.json

-H X-BlueCoat-Via: localhost http://thinkloveshare.com/juicy_403_endpoint/|301|text/html|162
-X PROPFIND http://thinkloveshare.com/juicy_403_endpoint/|405||131
http://thinkloveshare.com/%3b%2f%2e%2e%2f%2e%2e%2f%2fjuicy_403_endpoint/|400|text/html|9121
-H Host: 8.8.8.8 http://thinkloveshare.com/juicy_403_endpoint/|404|text/html|9115
-X CONNECT http://thinkloveshare.com/juicy_403_endpoint/|400|text/plain|15
http://thinkloveshare.com/juicy_403_endpoint/°//|400|text/html|90
```
#### HTML 파일

`PERTINENT` 및 `FULL` 저장 수준에서는 curl 명령과 전체 HTTP 응답도 가상의 `.html` 파일에 저장됩니다:```bash
$ echo /tmp/bypass-res2/*.html | xargs batcat
───────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
       │ File: /tmp/bypass-res2/bypass-2469eecf6c38b5817d2248e911ad4382.html
───────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
   1   │ /usr/bin/curl -sS -kgi -H 'User-Agent: curl 7.74.0' --path-as-is 'http://thinkloveshare.com/juicy_403_endpoint/°//'
   2   │
   3   │ HTTP/1.1 400 Bad request
   4   │ Connection: keep-alive
   5   │ Content-Length: 90
   6   │ Cache-Control: no-cache
   7   │ Content-Type: text/html
   8   │ Accept-Ranges: bytes
   9   │ Date: Tue, 25 Apr 2023 23:51:38 GMT
  10   │ Via: 1.1 varnish
  11   │ X-Served-By: cache-par-lfpg1960025-PAR
  12   │ X-Cache: MISS
  13   │ X-Cache-Hits: 0
  14   │ X-Timer: S1682466698.230664,VS0,VE10
  15   │ Vary: Accept-Encoding
  16   │ X-Fastly-Request-ID: b6bbb82302420db4f101a316dca39cc283a4fd44
  17   │
  18   │ <html><body><h1>400 Bad request</h1>
  19   │ Your browser sent an invalid request.
  20   │ </body></html>
───────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
───────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
       │ File: /tmp/bypass-res2/bypass-6f7cce7caf0a0a4b440859fa189d496d.html
───────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
   1   │ /usr/bin/curl -sS -kgi -H 'User-Agent: curl 7.74.0' --path-as-is -X CONNECT http://thinkloveshare.com/juicy_403_endpoint/
   2   │
   3   │ HTTP/1.1 400 Bad Request
   4   │ Connection: close
   5   │ Content-Length: 15
   6   │ content-type: text/plain; charset=utf-8
   7   │ x-served-by: cache-par-lfpg1960083
   8   │
   9   │ invalid request
───────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
───────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
       │ File: /tmp/bypass-res2/bypass-80f4ab5d32b4e74c20630c7e67f2e42f.html
───────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
   1   │ /usr/bin/curl -sS -kgi -H 'User-Agent: curl 7.74.0' --path-as-is http://thinkloveshare.com/%3b%2f%2e%2e%2f%2e%2e%2f%2fjuicy_403_endpoint/
   2   │
   3   │ HTTP/1.1 400 Bad Request
   4   │ Connection: keep-alive
   5   │ Content-Length: 9121
   6   │ Server: GitHub.com
   7   │ Content-Type: text/html; charset=utf-8
   8   │ ETag: "64417b9f-23a1"
   9   │ Content-Security-Policy: default-src 'none'; style-src 'unsafe-inline'; img-src data:; connect-src 'self'
  10   │ X-GitHub-Request-Id: 598E:F13E:26EE27D:284F5D2:64486731
  11   │ Accept-Ranges: bytes
  12   │ Date: Tue, 25 Apr 2023 23:50:11 GMT
  13   │ Via: 1.1 varnish
  14   │ X-Served-By: cache-par-lfpg1960046-PAR
  15   │ X-Cache: MISS
  16   │ X-Cache-Hits: 0
  17   │ X-Timer: S1682466611.396077,VS0,VE101
  18   │ Vary: Accept-Encoding
  19   │ X-Fastly-Request-ID: 30bd6af5892c40da130ee49bbeacd147a1a6b3c3
  20   │
  21   │ <!DOCTYPE html>
  22   │ <html>
  23   │   <head>
  24   │     <meta http-equiv="Content-type" content="text/html; charset=utf-8">
  25   │     <meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src 'unsafe-inline'; img-src data:; connect-src 'self'">
  26   │     <title>Bad request &middot; GitHub Pages</title>
  27   │     <style type="text/css" media="screen">
[...SNIP...]
```
## Contributors

- 초기 릴리스: [@TheLaluka](https://twitter.com/TheLaluka)
- 대규모 리팩토링 및 라이브러리 모드: [@jtop_fap](https://twitter.com/jtop_fap)님께 감사드립니다.
- `Docker` 및 `Pypi` 빌드 지원: [@DugnyG](https://twitter.com/DugnyG)님의 친절한 작업 덕분입니다.

## 라이선스

Copyright (C) 2022 Laluka

이 프로그램은 자유 소프트웨어입니다: 자유 소프트웨어 재단에서 발표한 GNU Affero 일반 공중 사용 허가서(GNU Affero General Public License)의 조건에 따라 재배포 및/또는 수정할 수 있습니다. (허가서의 버전 3, 또는 (선택에 따라) 이후 버전)

이 프로그램은 유용하기를 바라며 배포되지만, 어떠한 보증도 제공되지 않습니다. 상품성 또는 특정 목적에의 적합성에 대한 묵시적 보증도 포함되지 않습니다. 자세한 내용은 GNU Affero 일반 공중 사용 허가서를 참조하십시오.

이 프로그램과 함께 GNU Affero 일반 공중 사용 허가서의 사본을 받았을 것입니다. 받지 못했다면 <https://www.gnu.org/licenses/>를 참조하십시오.
도구 다운로드