
로그에서 Log4Shell CVE-2021-44228 IOC를 찾는 PCRE 정규식
아래의 RegEx는 Log4Shell (CVE-2021-44228 및 CVE-2021-45046) 악용의 지표와 일치하도록 작성되었습니다.
2021/12/21 이전 버전을 실행 중이라면 테스트하고 업데이트하는 것이 좋습니다.
몇 가지 결함을 제거하고 성능을 향상시켰습니다.
이 Regex는 PCRE 호환을 목표로 하지만, re2 및 잠재적으로 더 많은 RegEx 엔진에서도 실행되어야 합니다.
RegEx:```regex (?im)(?:^|[\n]).?(?:[\x24]|%(?:25%?)24|\u?0(?:44|24))(?:[\x7b]|%(?:25%?)7b|\u?0(?:7b|173))[^\n]?((?:j|%(?:25%?)(?:4a|6a)|\u?0(?:112|6a|4a|152))[^\n]?(?:n|%(?:25%?)(?:4e|6e)|\u?0*(?:4e|156|116|6e))[^\n]?(?:d|%(?:25%?)(?:44|64)|\u?0*(?:44|144|104|64))[^\n]?(?:[i\x{130}\x{131}]|%(?:25%?)(?:49|69|C4%(?:25%?)B0|C4%(?:25%?)B1)|\u?0(?:111|69|49|151|130|460|131|461))[^\n]?(?:[\x3a]|%(?:25%?)3a|\u?0(?:72|3a))[^\n]?((?:l|%(?:25%?)(?:4c|6c)|\u?0*(?:154|114|6c|4c))[^\n]?(?:d|%(?:25%?)(?:44|64)|\u?0*(?:44|144|104|64))[^\n]?(?:a|%(?:25%?)(?:41|61)|\u?0*(?:101|61|41|141))[^\n]?(?:p|%(?:25%?)(?:50|70)|\u?0*(?:70|50|160|120))(?:[^\n]?(?:[s\x{17f}]|%(?:25%?)(?:53|73|C5%(?:25%?)BF)|\u?0(?:17f|123|577|73|53|163)))?|(?:r|%(?:25%?)(?:52|72)|\u?0(?:122|72|52|162))[^\n]?(?:m|%(?:25%?)(?:4d|6d)|\u?0*(?:4d|155|115|6d))[^\n]?(?:[i\x{130}\x{131}]|%(?:25%?)(?:49|69|C4%(?:25%?)B0|C4%(?:25%?)B1)|\u?0(?:111|69|49|151|130|460|131|461))|(?:d|%(?:25%?)(?:44|64)|\u?0*(?:44|144|104|64))[^\n]?(?:n|%(?:25%?)(?:4e|6e)|\u?0*(?:4e|156|116|6e))[^\n]?(?:[s\x{17f}]|%(?:25%?)(?:53|73|C5%(?:25%?)BF)|\u?0(?:17f|123|577|73|53|163))|(?:n|%(?:25%?)(?:4e|6e)|\u?0(?:4e|156|116|6e))[^\n]?(?:[i\x{130}\x{131}]|%(?:25%?)(?:49|69|C4%(?:25%?)B0|C4%(?:25%?)B1)|\u?0(?:111|69|49|151|130|460|131|461))[^\n]?(?:[s\x{17f}]|%(?:25%?)(?:53|73|C5%(?:25%?)BF)|\u?0(?:17f|123|577|73|53|163))|(?:[^\n]?(?:[i\x{130}\x{131}]|%(?:25%?)(?:49|69|C4%(?:25%?)B0|C4%(?:25%?)B1)|\u?0(?:111|69|49|151|130|460|131|461))){2}[^\n]?(?:o|%(?:25%?)(?:4f|6f)|\u?0*(?:6f|4f|157|117))[^\n]?(?:p|%(?:25%?)(?:50|70)|\u?0*(?:70|50|160|120))|(?:c|%(?:25%?)(?:43|63)|\u?0(?:143|103|63|43))[^\n]?(?:o|%(?:25%?)(?:4f|6f)|\u?0*(?:6f|4f|157|117))[^\n]?(?:r|%(?:25%?)(?:52|72)|\u?0*(?:122|72|52|162))[^\n]?(?:b|%(?:25%?)(?:42|62)|\u?0*(?:102|62|42|142))[^\n]?(?:a|%(?:25%?)(?:41|61)|\u?0*(?:101|61|41|141))|(?:n|%(?:25%?)(?:4e|6e)|\u?0(?:4e|156|116|6e))[^\n]?(?:d|%(?:25%?)(?:44|64)|\u?0*(?:44|144|104|64))[^\n]?(?:[s\x{17f}]|%(?:25%?)(?:53|73|C5%(?:25%?)BF)|\u?0(?:17f|123|577|73|53|163))|(?:h|%(?:25%?)(?:48|68)|\u?0(?:110|68|48|150))(?:[^\n]?(?:t|%(?:25%?)(?:54|74)|\u?0*(?:124|74|54|164))){2}[^\n]?(?:p|%(?:25%?)(?:50|70)|\u?0*(?:70|50|160|120))(?:[^\n]?(?:[s\x{17f}]|%(?:25%?)(?:53|73|C5%(?:25%?)BF)|\u?0(?:17f|123|577|73|53|163)))?)[^\n]?(?:[\x3a]|%(?:25%?)3a|\u?0(?:72|3a))|(?:b|%(?:25%?)(?:42|62)|\u?0*(?:102|62|42|142))[^\n]?(?:a|%(?:25%?)(?:41|61)|\u?0*(?:101|61|41|141))[^\n]?(?:[s\x{17f}]|%(?:25%?)(?:53|73|C5%(?:25%?)BF)|\u?0(?:17f|123|577|73|53|163))[^\n]?(?:e|%(?:25%?)(?:45|65)|\u?0*(?:45|145|105|65))[^\n]*?(?:[\x3a]|%(?:25%?)3a|\u?0(?:72|3a))(JH[s-v]|[\x2b\x2f-9A-Za-z][CSiy]R7|[\x2b\x2f-9A-Za-z]{2}[048AEIMQUYcgkosw]ke[\x2b\x2f-9w-z]))
## 기능
현재 이 정규식은 익스플로잇과 일치해야 합니다. 그 이유는 다음과 같습니다:
- 기록된 그대로
- 대소문자 구분 없음 (지원되는 모든 인코딩에서도)
- URL 인코딩
- 재귀적 URL 인코딩
- 유니코드 인코딩
- 8진수 인코딩
- Base64 인코딩 (기본적인)
### 배경
목표는 허용 가능한 오탐(false positive) 수준으로 최대한 많은 공격 시도를 탐지하는 합리적인 균형을 이루는 정규식을 만드는 것입니다.
APT 공격자는 필요하다면 우회 방법을 찾겠지만, 정교하지 않은 공격은 경고등을 켜놓을 것입니다.
왜 (단일) 정규식인가: 추가 도구 없이 CLI나 SIEM에서 쉽게 실행할 수 있기 때문입니다. 도구를 실행할 수 있다면 그렇게 하세요. 도구는 존재합니다.
정규식의 길이는 성능보다 덜 문제입니다. 길이에도 불구하고 정규식은 평균 로그 데이터에서 실행 가능한 수준으로 빨라야 합니다.
### 행동 촉구
실제 시나리오에서 공격을 숨기기 어렵게 만들고 싶습니다.
이 정규식이 실제 환경에서 본 것이나 악용 가능함을 보여줄 수 있는 것과 일치하지 않으면 이슈를 생성해 주세요.
Base64를 사용하여 공격 패턴의 다른 부분을 인코딩함으로써 정규식을 쉽게 우회할 수 있다는 것은 알려져 있습니다. 그러나 이것은 수용됩니다. `base64`가 아직 공식 Log4j 릴리스에 최종적으로 포함되지 않았기 때문입니다. ([LOG4J2-2446](https://issues.apache.org/jira/projects/LOG4J2/issues/LOG4J2-2446))
### 도구
- 정규식 테스트: **[regex101](https://regex101.com/r/KqGG3W/24)**
- 정규식 시각화: **[REGEXPER](https://regexper.com/#%28%3F%3A%5E%7C%5B%5Cn%5D%29.*%3F%28%3F%3A%5B%5Cx24%5D%7C%25%28%3F%3A25%25%3F%29*24%7C%5C%5Cu%3F0*%28%3F%3A44%7C24%29%29%28%3F%3A%5B%5Cx7b%5D%7C%25%28%3F%3A25%25%3F%29*7b%7C%5C%5Cu%3F0*%28%3F%3A7b%7C173%29%29%5B%5E%5Cn%5D*%3F%28%28%3F%3Aj%7C%25%28%3F%3A25%25%3F%29*%28%3F%3A4a%7C6a%29%7C%5C%5Cu%3F0*%28%3F%3A112%7C6a%7C4a%7C152%29%29%5B%5E%5Cn%5D*%3F%28%3F%3An%7C%25%28%3F%3A25%25%3F%29*%28%3F%3A4e%7C6e%29%7C%5C%5Cu%3F0*%28%3F%3A4e%7C156%7C116%7C6e%29%29%5B%5E%5Cn%5D*%3F%28%3F%3Ad%7C%25%28%3F%3A25%25%3F%29*%28%3F%3A44%7C64%29%7C%5C%5Cu%3F0*%28%3F%3A44%7C144%7C104%7C64%29%29%5B%5E%5Cn%5D*%3F%28%3F%3A%5Bi%5Cx%7B130%7D%5Cx%7B131%7D%5D%7C%25%28%3F%3A25%25%3F%29*%28%3F%3A49%7C69%7CC4%25%28%3F%3A25%25%3F%29*B0%7CC4%25%28%3F%3A25%25%3F%29*B1%29%7C%5C%5Cu%3F0*%28%3F%3A111%7C69%7C49%7C151%7C130%7C460%7C131%7C461%29%29%5B%5E%5Cn%5D*%3F%28%3F%3A%5B%5Cx3a%5D%7C%25%28%3F%3A25%25%3F%29*3a%7C%5C%5Cu%3F0*%28%3F%3A72%7C3a%29%29%5B%5E%5Cn%5D*%3F%28%28%3F%3Al%7C%25%28%3F%3A25%25%3F%29*%28%3F%3A4c%7C6c%29%7C%5C%5Cu%3F0*%28%3F%3A154%7C114%7C6c%7C4c%29%29%5B%5E%5Cn%5D*%3F%28%3F%3Ad%7C%25%28%3F%3A25%25%3F%29*%28%3F%3A44%7C64%29%7C%5C%5Cu%3F0*%28%3F%3A44%7C144%7C104%7C64%29%29%5B%5E%5Cn%5D*%3F%28%3F%3Aa%7C%25%28%3F%3A25%25%3F%29*%28%3F%3A41%7C61%29%7C%5C%5Cu%3F0*%28%3F%3A101%7C61%7C41%7C141%29%29%5B%5E%5Cn%5D*%3F%28%3F%3Ap%7C%25%28%3F%3A25%25%3F%29*%28%3F%3A50%7C70%29%7C%5C%5Cu%3F0*%28%3F%3A70%7C50%7C160%7C120%29%29%28%3F%3A%5B%5E%5Cn%5D*%3F%28%3F%3A%5Bs%5Cx%7B17f%7D%5D%7C%25%28%3F%3A25%25%3F%29*%28%3F%3A53%7C73%7CC5%25%28%3F%3A25%25%3F%29*BF%29%7C%5C%5Cu%3F0*%28%3F%3A17f%7C123%7C577%7C73%7C53%7C163%29%29%29%3F%7C%28%3F%3Ar%7C%25%28%3F%3A25%25%3F%29*%28%3F%3A52%7C72%29%7C%5C%5Cu%3F0*%28%3F%3A122%7C72%7C52%7C162%29%29%5B%5E%5Cn%5D*%3F%28%3F%3Am%7C%25%28%3F%3A25%25%3F%29*%28%3F%3A4d%7C6d%29%7C%5C%5Cu%3F0*%28%3F%3A4d%7C155%7C115%7C6d%29%29%5B%5E%5Cn%5D*%3F%28%3F%3A%5Bi%5Cx%7B130%7D%5Cx%7B131%7D%5D%7C%25%28%3F%3A25%25%3F%29*%28%3F%3A49%7C69%7CC4%25%28%3F%3A25%25%3F%29*B0%7CC4%25%28%3F%3A25%25%3F%29*B1%29%7C%5C%5Cu%3F0*%28%3F%3A111%7C69%7C49%7C151%7C130%7C460%7C131%7C461%29%29%7C%28%3F%3Ad%7C%25%28%3F%3A25%25%3F%29*%28%3F%3A44%7C64%29%7C%5C%5Cu%3F0*%28%3F%3A44%7C144%7C104%7C64%29%29%5B%5E%5Cn%5D*%3F%28%3F%3An%7C%25%28%3F%3A25%25%3F%29*%28%3F%3A4e%7C6e%29%7C%5C%5Cu%3F0*%28%3F%3A4e%7C156%7C116%7C6e%29%29%5B%5E%5Cn%5D*%3F%28%3F%3A%5Bs%5Cx%7B17f%7D%5D%7C%25%28%3F%3A25%25%3F%29*%28%3F%3A53%7C73%7CC5%25%28%3F%3A25%25%3F%29*BF%29%7C%5C%5Cu%3F0*%28%3F%3A17f%7C123%7C577%7C73%7C53%7C163%29%29%7C%28%3F%3An%7C%25%28%3F%3A25%25%3F%29*%28%3F%3A4e%7C6e%29%7C%5C%5Cu%3F0*%28%3F%3A4e%7C156%7C116%7C6e%29%29%5B%5E%5Cn%5D*%3F%28%3F%3A%5Bi%5Cx%7B130%7D%5Cx%7B131%7D%5D%7C%25%28%3F%3A25%25%3F%29*%28%3F%3A49%7C69%7CC4%25%28%3F%3A25%25%3F%29*B0%7CC4%25%28%3F%3A25%25%3F%29*B1%29%7C%5C%5Cu%3F0*%28%3F%3A111%7C69%7C49%7C151%7C130%7C460%7C131%7C461%29%29%5B%5E%5Cn%5D*%3F%28%3F%3A%5Bs%5Cx%7B17f%7D%5D%7C%25%28%3F%3A25%25%3F%29*%28%3F%3A53%7C73%7CC5%25%28%3F%3A25%25%3F%29*BF%29%7C%5C%5Cu%3F0*%28%3F%3A17f%7C123%7C577%7C73%7C53%7C163%29%29%7C%28%3F%3A%5B%5E%5Cn%5D*%3F%28%3F%3A%5Bi%5Cx%7B130%7D%5Cx%7B131%7D%5D%7C%25%28%3F%3A25%25%3F%29*%28%3F%3A49%7C69%7CC4%25%28%3F%3A25%25%3F%29*B0%7CC4%25%28%3F%3A25%25%3F%29*B1%29%7C%5C%5Cu%3F0*%28%3F%3A111%7C69%7C49%7C151%7C130%7C460%7C131%7C461%29%29%29%7B2%7D%5B%5E%5Cn%5D*%3F%28%3F%3Ao%7C%25%28%3F%3A25%25%3F%29*%28%3F%3A4f%7C6f%29%7C%5C%5Cu%3F0*%28%3F%3A6f%7C4f%7C157%7C117%29%29%5B%5E%5Cn%5D*%3F%28%3F%3Ap%7C%25%28%3F%3A25%25%3F%29*%28%3F%3A50%7C70%29%7C%5C%5Cu%3F0*%28%3F%3A70%7C50%7C160%7C120%29%29%7C%28%3F%3Ac%7C%25%28%3F%3A25%25%3F%29*%28%3F%3A43%7C63%29%7C%5C%5Cu%3F0*%28%3F%3A143%7C103%7C63%7C43%29%29%5B%5E%5Cn%5D*%3F%28%3F%3Ao%7C%25%28%3F%3A25%25%3F%29*%28%3F%3A4f%7C6f%29%7C%5C%5Cu%3F0*%28%3F%3A6f%7C4f%7C157%7C117%29%29%5B%5E%5Cn%5D*%3F%28%3F%3Ar%7C%25%28%3F%3A25%25%3F%29*%28%3F%3A52%7C72%29%7C%5C%5Cu%3F0*%28%3F%3A122%7C72%7C52%7C162%29%29%5B%5E%5Cn%5D*%3F%28%3F%3Ab%7C%25%28%3F%3A25%25%3F%29*%28%3F%3A42%7C62%29%7C%5C%5Cu%3F0*%28%3F%3A102%7C62%7C42%7C142%29%29%5B%5E%5Cn%5D*%3F%28%3F%3Aa%7C%25%28%3F%3A25%25%3F%29*%28%3F%3A41%7C61%29%7C%5C%5Cu%3F0*%28%3F%3A101%7C61%7C41%7C141%29%29%7C%28%3F%3An%7C%25%28%3F%3A25%25%3F%29*%28%3F%3A4e%7C6e%29%7C%5C%5Cu%3F0*%28%3F%3A4e%7C156%7C116%7C6e%29%29%5B%5E%5Cn%5D*%3F%28%3F%3Ad%7C%25%28%3F%3A25%25%3F%29*%28%3F%3A44%7C64%29%7C%5C%5Cu%3F0*%28%3F%3A44%7C144%7C104%7C64%29%29%5B%5E%5Cn%5D*%3F%28%3F%3A%5Bs%5Cx%7B17f%7D%5D%7C%25%28%3F%3A25%25%3F%29*%28%3F%3A53%7C73%7CC5%25%28%3F%3A25%25%3F%29*BF%29%7C%5C%5Cu%3F0*%28%3F%3A17f%7C123%7C577%7C73%7C53%7C163%29%29%7C%28%3F%3Ah%7C%25%28%3F%3A25%25%3F%29*%28%3F%3A48%7C68%29%7C%5C%5Cu%3F0*%28%3F%3A110%7C68%7C48%7C150%29%29%28%3F%3A%5B%5E%5Cn%5D*%3F%28%3F%3At%7C%25%28%3F%3A25%25%3F%29*%28%3F%3A54%7C74%29%7C%5C%5Cu%3F0*%28%3F%3A124%7C74%7C54%7C164%29%29%29%7B2%7D%5B%5E%5Cn%5D*%3F%28%3F%3Ap%7C%25%28%3F%3A25%25%3F%29*%28%3F%3A50%7C70%29%7C%5C%5Cu%3F0*%28%3F%3A70%7C50%7C160%7C120%29%29%28%3F%3A%5B%5E%5Cn%5D*%3F%28%3F%3A%5Bs%5Cx%7B17f%7D%5D%7C%25%28%3F%3A25%25%3F%29*%28%3F%3A53%7C73%7CC5%25%28%3F%3A25%25%3F%29*BF%29%7C%5C%5Cu%3F0*%28%3F%3A17f%7C123%7C577%7C73%7C53%7C163%29%29%29%3F%29%5B%5E%5Cn%5D*%3F%28%3F%3A%5B%5Cx3a%5D%7C%25%28%3F%3A25%25%3F%29*3a%7C%5C%5Cu%3F0*%28%3F%3A72%7C3a%29%29%7C%28%3F%3Ab%7C%25%28%3F%3A25%25%3F%29*%28%3F%3A42%7C62%29%7C%5C%5Cu%3F0*%28%3F%3A102%7C62%7C42%7C142%29%29%5B%5E%5Cn%5D*%3F%28%3F%3Aa%7C%25%28%3F%3A25%25%3F%29*%28%3F%3A41%7C61%29%7C%5C%5Cu%3F0*%28%3F%3A101%7C61%7C41%7C141%29%29%5B%5E%5Cn%5D*%3F%28%3F%3A%5Bs%5Cx%7B17f%7D%5D%7C%25%28%3F%3A25%25%3F%29*%28%3F%3A53%7C73%7CC5%25%28%3F%3A25%25%3F%29*BF%29%7C%5C%5Cu%3F0*%28%3F%3A17f%7C123%7C577%7C73%7C53%7C163%29%29%5B%5E%5Cn%5D*%3F%28%3F%3Ae%7C%25%28%3F%3A25%25%3F%29*%28%3F%3A45%7C65%29%7C%5C%5Cu%3F0*%28%3F%3A45%7C145%7C105%7C65%29%29%5B%5E%5Cn%5D*%3F%28%3F%3A%5B%5Cx3a%5D%7C%25%28%3F%3A25%25%3F%29*3a%7C%5C%5Cu%3F0*%28%3F%3A72%7C3a%29%29%28JH%5Bs-v%5D%7C%5B%5Cx2b%5Cx2f-9A-Za-z%5D%5BCSiy%5DR7%7C%5B%5Cx2b%5Cx2f-9A-Za-z%5D%7B2%7D%5B048AEIMQUYcgkosw%5Dke%5B%5Cx2b%5Cx2f-9w-z%5D%29%29)**
## Linux 머신에서 사냥하기
### CLI에서 `grep` 사용```bash
eval "$(./RegEx_Generator.sh)"
grep -P ${Log4ShellRex} <logfile>
그리고 모든 테스트를 자동으로 실행하는 별도의 check 모드도 있습니다. 기본적으로 편리한 단축어입니다:
./ruff check # 현재 디렉터리의 모든 파일을 린트합니다.
좋습니다. 우리의 특정 사례에 대한 ruff 명령어의 출력도 확인해 보겠습니다:
ruff check --no-cache --output-format=concise --select=B,SIM
테스트 파일에 대한 출력은 다음과 같습니다:
test.py:3:5: B006 함수 인수를 제자리에서 변경하지 마세요
|
2 | def mutate_argument(x=[]):
3 | x.append(1) # B006: 함수 인수를 제자리에서 변경하지 마세요
| ^^^^^^^^^^^^ B006
보시다시피, ruff 도구가 Python 테스트 파일에서 B006 문제(함수 인수 변경)를 발견했습니다.
이제 규칙이 정말 많다는 것을 깨달았습니다. 프로젝트에 가장 적합한 규칙을 찾기 어려울 수 있습니다. 다음에서는 실제로 유용한 규칙의 선별된 목록을 제공하겠습니다.
단일 파일을 린트하려면:
ruff check my_file.py
여러 파일을 린트하려면:
ruff check src/ tests/ --extend-select=B,SIM
일부 문제(안전한 수정이 있는 문제)를 자동으로 수정하려면:
ruff check --fix
안전하지 않은 수정도 적용하려면:
ruff check --fix --unsafe-fixes
프로젝트 루트에 pyproject.toml 또는 ruff.toml을 생성합니다. ruff.toml 예제:
[tool.ruff]
target-version = "py311"
line-length = 120
[tool.ruff.lint]
select = ["B", "SIM", "S"]
ignore = ["B905"]
[tool.ruff.format]
preview = true
그런 다음 실행:
ruff check
이렇게 하면 자동으로 구성을 읽습니다.
Ruff는 매우 빠르게 설계되었습니다. 벤치마크에서 기존 도구(예: Flake8 또는 Pylint)보다 10~100배 더 빠른 경우가 많습니다. 속도는 다음 조합에서 비롯됩니다:
Ruff는 pyproject.toml, ruff.toml, .ruff.toml 또는 명령줄 인수를 통해 구성할 수 있습니다. 구성 파일이 권장되는 방법입니다.
[tool.ruff]
# 대상 Python 버전
target-version = "py311"
# 최대 줄 길이
line-length = 88
[tool.ruff.lint]
# 규칙을 카테고리별로 활성화
select = ["B", "SIM"]
# 특정 규칙 비활성화
ignore = ["B006"]
[tool.ruff.per-file-ignores]
"__init__.py" = ["F401"]
[tool.ruff.lint.pydocstyle]
convention = "google"
[tool.ruff.format]
# 미리보기 스타일 사용
preview = true
전체 옵션 목록은 문서를 참조하세요.
Ruff는 다음을 포함한 많은 편집기에 통합될 수 있습니다:
Ruff는 플러그인을 통해 사용자 정의 규칙을 지원합니다. Rust로 자신만의 규칙을 작성하여 Ruff에 등록할 수 있습니다. 자세한 내용은 플러그인 API 문서를 참조하세요.
이제 Ruff를 CI/CD 파이프라인에 통합하는 데 초점을 맞춰야 합니다.
Ruff를 GitHub Actions에 통합하려면 다음 워크플로우를 사용할 수 있습니다:
name: CI
on: [push, pull_request]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies
run: pip install ruff
- name: Check formatting
run: ruff check --output-format=github
이렇게 하면 푸시 및 풀 리퀘스트마다 Ruff가 실행되고 결과가 GitHub UI에 주석으로 표시됩니다.
마찬가지로 다른 CI 시스템의 경우 ruff를 직접 호출할 수 있습니다.
Ruff는 Python을 위한 빠르고 확장 가능한 린터 및 포맷터입니다. 속도와 포괄적인 규칙 세트는 모든 Python 개발자에게 필수적인 도구입니다.
지금까지 Ruff의 주요 기능과 사용법을 다루었습니다. 다음 청크에서는 고급 구성 및 사용자 정의 플러그인 개발에 대해 살펴보겠습니다.```bash grep -P '(?im)(?:^|[\n]).?(?:[\x24]|%(?:25%?)24|\u?0(?:44|24))(?:[\x7b]|%(?:25%?)7b|\u?0(?:7b|173))[^\n]?((?:j|%(?:25%?)(?:4a|6a)|\u?0(?:112|6a|4a|152))[^\n]?(?:n|%(?:25%?)(?:4e|6e)|\u?0*(?:4e|156|116|6e))[^\n]?(?:d|%(?:25%?)(?:44|64)|\u?0*(?:44|144|104|64))[^\n]?(?:[i\x{130}\x{131}]|%(?:25%?)(?:49|69|C4%(?:25%?)B0|C4%(?:25%?)B1)|\u?0(?:111|69|49|151|130|460|131|461))[^\n]?(?:[\x3a]|%(?:25%?)3a|\u?0(?:72|3a))[^\n]?((?:l|%(?:25%?)(?:4c|6c)|\u?0*(?:154|114|6c|4c))[^\n]?(?:d|%(?:25%?)(?:44|64)|\u?0*(?:44|144|104|64))[^\n]?(?:a|%(?:25%?)(?:41|61)|\u?0*(?:101|61|41|141))[^\n]?(?:p|%(?:25%?)(?:50|70)|\u?0*(?:70|50|160|120))(?:[^\n]?(?:[s\x{17f}]|%(?:25%?)(?:53|73|C5%(?:25%?)BF)|\u?0(?:17f|123|577|73|53|163)))?|(?:r|%(?:25%?)(?:52|72)|\u?0(?:122|72|52|162))[^\n]?(?:m|%(?:25%?)(?:4d|6d)|\u?0*(?:4d|155|115|6d))[^\n]?(?:[i\x{130}\x{131}]|%(?:25%?)(?:49|69|C4%(?:25%?)B0|C4%(?:25%?)B1)|\u?0(?:111|69|49|151|130|460|131|461))|(?:d|%(?:25%?)(?:44|64)|\u?0*(?:44|144|104|64))[^\n]?(?:n|%(?:25%?)(?:4e|6e)|\u?0*(?:4e|156|116|6e))[^\n]?(?:[s\x{17f}]|%(?:25%?)(?:53|73|C5%(?:25%?)BF)|\u?0(?:17f|123|577|73|53|163))|(?:n|%(?:25%?)(?:4e|6e)|\u?0(?:4e|156|116|6e))[^\n]?(?:[i\x{130}\x{131}]|%(?:25%?)(?:49|69|C4%(?:25%?)B0|C4%(?:25%?)B1)|\u?0(?:111|69|49|151|130|460|131|461))[^\n]?(?:[s\x{17f}]|%(?:25%?)(?:53|73|C5%(?:25%?)BF)|\u?0(?:17f|123|577|73|53|163))|(?:[^\n]?(?:[i\x{130}\x{131}]|%(?:25%?)(?:49|69|C4%(?:25%?)B0|C4%(?:25%?)B1)|\u?0(?:111|69|49|151|130|460|131|461))){2}[^\n]?(?:o|%(?:25%?)(?:4f|6f)|\u?0*(?:6f|4f|157|117))[^\n]?(?:p|%(?:25%?)(?:50|70)|\u?0*(?:70|50|160|120))|(?:c|%(?:25%?)(?:43|63)|\u?0(?:143|103|63|43))[^\n]?(?:o|%(?:25%?)(?:4f|6f)|\u?0*(?:6f|4f|157|117))[^\n]?(?:r|%(?:25%?)(?:52|72)|\u?0*(?:122|72|52|162))[^\n]?(?:b|%(?:25%?)(?:42|62)|\u?0*(?:102|62|42|142))[^\n]?(?:a|%(?:25%?)(?:41|61)|\u?0*(?:101|61|41|141))|(?:n|%(?:25%?)(?:4e|6e)|\u?0(?:4e|156|116|6e))[^\n]?(?:d|%(?:25%?)(?:44|64)|\u?0*(?:44|144|104|64))[^\n]?(?:[s\x{17f}]|%(?:25%?)(?:53|73|C5%(?:25%?)BF)|\u?0(?:17f|123|577|73|53|163))|(?:h|%(?:25%?)(?:48|68)|\u?0(?:110|68|48|150))(?:[^\n]?(?:t|%(?:25%?)(?:54|74)|\u?0*(?:124|74|54|164))){2}[^\n](?:50|70)|\u?0*(?:70|50|160|120))(?:[^\n](?:53|73|C5%(?:25%?)(?:17f|123|577|73|53|163)))?)[^\n](?:42|62)|\u?0*(?:102|62|42|142))[^\n](?:41|61)|\u?0*(?:101|61|41|141))[^\n](?:53|73|C5%(?:25%?)(?:17f|123|577|73|53|163))[^\n](?:45|65)|\u?0*(?:45|145|105|65))[^\n]*?(?:[\x3a]|%(?:25%?)(?:72|3a))(JH[s-v]|[\x2b\x2f-9A-Za-z][CSiy]R7|[\x2b\x2f-9A-Za-z]{2}[048AEIMQUYcgkosw]ke[\x2b\x2f-9w-z]))'
### `find`와 결합하여 로그 파일의 (하위)폴더를 재귀적으로 스캔하기```bash
eval "$(./RegEx_Generator.sh)"
find /var/log -name "*.log" | xargs grep -P ${Log4ShellRex}
the output.
You can also apply terminal tags to explicitly mark the duration of a command that will run for a long period of time, for instance:

This tag can be applied by pressing <prefix>-m in a terminal session's input mode. Pressing that one more time will change the tag to Success/Failed as-per the logic mentioned above.
Note that the timing logic for marking an output execution does not depend on a command's message but rather on the timing between the start and end markers.
You can leverage the plugin's internal tags mechanism to tag your own custom events. For instance, you can add this to your zshrc file:
# The following will register a tag named "TEA" that will be triggered upon pressing Ctrl-T
zsh_sessions_add_tag "TEA" "f0" "ctrl-t"
This will create a new tag named "TEA", foreground color "f0", background color default, that will be marked when you press Ctrl-T. The tags must be registered before the plugin is loaded (or the terminal session is started, to be accurate).
Additionally, you need to bind the Ctrl-T key to the zsh_sessions_trigger_tag function, for instance by adding this to your zshrc file:
zle -N zsh_sessions_trigger_tag
bindkey '^T' zsh_sessions_trigger_tag
After registering and binding the tag, upon pressing Ctrl-T, a tag "TEA" will be added to the terminal's tag bar. The tag will be automatically removed once you press Enter.
You can also manually trigger a tag by running zsh_sessions_trigger_tag "TEA".
Tags can also be automatically added to a terminal's tag bar based on the command that is being executed. In order to do so, you must first register a trigger tag. Trigger tags are defined as follows:
zsh_sessions_register_trigger_tag <name> <pattern>
The pattern will be checked against the command that is being executed, and if the pattern is found, the trigger tag will be added to the terminal's tag bar. The trigger tag is automatically removed once the command finishes executing.
NOTE: The trigger tag for a terminal is checked every time a command is executed. The pattern provided to the zsh_sessions_register_trigger_tag function is a zsh glob pattern, and can be either a literal string or something more complex that can help you identify a command more accurately.
Example:
zsh_sessions_register_trigger_tag "EDITOR" "vim"
zsh_sessions_register_trigger_tag "EDITOR" "nvim"
zsh_sessions_register_trigger_tag "EDITOR" "nano"
zsh_sessions_register_trigger_tag "EDITOR" "emacs"
zsh_sessions_register_trigger_tag "SSH" "ssh *"
zsh_sessions_register_trigger_tag "MAN" "man *"
zsh_sessions_register_trigger_tag "TAIL" "tail *"
zsh_sessions_register_trigger_tag "WATCH" "watch *"
zsh_sessions_register_trigger_tag "KUBECTL" "kubectl *"
zsh_sessions_register_trigger_tag "TF" "terraform *"
zsh_sessions_register_trigger_tag "DOCKER" "docker *"
zsh_sessions_register_trigger_tag "GIT" "git *"
zsh_sessions_register_trigger_tag "SUDO" "sudo *"
zsh_sessions_register_trigger_tag "SSH" "ssh *"
zsh_sessions_register_trigger_tag "SYSTEMCTL" "systemctl *"
zsh_sessions_register_trigger_tag "JOURNALCTL" "journalctl *"
zsh_sessions_register_trigger_tag "ANSIBLE" "ansible *"
zsh_sessions_register_trigger_tag "ANSIBLE-PLAYBOOK" "ansible-playbook *"
zsh_sessions_register_trigger_tag "PING" "ping *"
zsh_sessions_register_trigger_tag "CURL" "curl *"
You can run the zsh_sessions_register_trigger_tag function any time you want for the changes to take effect immediately, or you can add them to your zshrc file to have them loaded upon shell start.
NOTE: For custom tags to be properly displayed, you'll need to add this plugin after any other plugins that may alter your terminal's appearance (e.g., themes).
In the above example, a "TMUX" tag also gets automatically added when inside a tmux session. This tag is added with a green background and black foreground.
You can specify foreground and background colors for the tags. The colors are defined by their ANSI color codes.
You can find a list of ANSI color codes here.
The default color for a tag added with zsh_sessions_add_tag is white foreground on black background.
However, you can optionally specify the foreground and background colors when adding a tag:
zsh_sessions_add_tag "TEA" "f0" "b1" "ctrl-t"
The first argument is the tag name, the second (optional) is the foreground color and the third (optional) is the background color, and the fourth (optional) is the key-binding.
The default colors are "f7" for foreground and "b0" for background.
Tags can also be used to send a message to the user upon successful, failed or erased command execution. The message looks as follows:

In order to utilize this, you first need to register a terminal message. A terminal message can be one of the following:
zsh_sessions_register_success_message <tag> <message>: This message will be displayed when a command tagged with completes successfullyzsh_sessions_register_failure_message <tag> <message>: This message will be displayed when a command tagged with failsTranslation: Need to keep all Markdown, links, images, code blocks, bash commands exactly. Translate surrounding text. Use appropriate Korean. Preserve italics, bold, inline code, etc. "the output" -> "출력" perhaps? But careful, "the output" appearing at the start might be a continuation from previous chunk, so just translate. Also keep "assets/terminal_tags.gif" etc. unchanged.
We'll generate Korean translation.the output.
또한 실행 시간이 긴 명령의 지속 시간을 명시적으로 표시하기 위해 터미널 태그를 적용할 수도 있습니다. 예시:

이 태그는 터미널 세션의 입력 모드에서 <prefix>-m을 눌러 적용할 수 있습니다. 한 번 더 누르면 위에서 설명한 논리에 따라 태그가 Success/Failed로 변경됩니다.
출력 실행을 표시하는 타이밍 로직은 명령의 메시지가 아니라 시작 마커와 종료 마커 사이의 타이밍에 의존한다는 점에 유의하세요.
플러그인의 내부 태그 메커니즘을 활용하여 사용자 정의 이벤트에 태그를 지정할 수 있습니다. 예를 들어, zshrc 파일에 다음과 같이 추가할 수 있습니다:
# The following will register a tag named "TEA" that will be triggered upon pressing Ctrl-T
zsh_sessions_add_tag "TEA" "f0" "ctrl-t"
이렇게 하면 "TEA"라는 이름의 태그가 생성되며, 전경색은 "f0", 배경색은 기본값으로, Ctrl-T를 누를 때 표시됩니다. 태그는 플러그인이 로드되기 전(또는 정확히 말하면 터미널 세션이 시작되기 전)에 등록되어야 합니다.
또한 Ctrl-T 키를 zsh_sessions_trigger_tag 함수에 바인딩해야 합니다. 예를 들어 zshrc 파일에 다음을 추가합니다:
zle -N zsh_sessions_trigger_tag
bindkey '^T' zsh_sessions_trigger_tag
태그를 등록하고 바인딩한 후에는 Ctrl-T를 누르면 터미널 태그 바에 "TEA" 태그가 추가됩니다. Enter 키를 누르면 태그가 자동으로 제거됩니다.
zsh_sessions_trigger_tag "TEA"를 실행하여 수동으로 태그를 트리거할 수도 있습니다.
실행 중인 명령에 따라 태그를 터미널 태그 바에 자동으로 추가할 수도 있습니다. 그러려면 먼저 트리거 태그를 등록해야 합니다. 트리거 태그는 다음과 같이 정의됩니다:
zsh_sessions_register_trigger_tag <name> <pattern>
패턴은 실행되는 명령과 비교되며, 패턴이 발견되면 트리거 태그가 터미널 태그 바에 추가됩니다. 트리거 태그는 명령 실행이 완료되면 자동으로 제거됩니다.
NOTE: 터미널의 트리거 태그는 명령이 실행될 때마다 확인됩니다. zsh_sessions_register_trigger_tag 함수에 제공되는 패턴은 zsh 글로브 패턴이며, 리터럴 문자열이거나 명령을 보다 정확하게 식별할 수 있는 더 복잡한 패턴일 수 있습니다.
Example:
zsh_sessions_register_trigger_tag "EDITOR" "vim"
zsh_sessions_register_trigger_tag "EDITOR" "nvim"
zsh_sessions_register_trigger_tag "EDITOR" "nano"
zsh_sessions_register_trigger_tag "EDITOR" "emacs"
zsh_sessions_register_trigger_tag "SSH" "ssh *"
zsh_sessions_register_trigger_tag "MAN" "man *"
zsh_sessions_register_trigger_tag "TAIL" "tail *"
zsh_sessions_register_trigger_tag "WATCH" "watch *"
zsh_sessions_register_trigger_tag "KUBECTL" "kubectl *"
zsh_sessions_register_trigger_tag "TF" "terraform *"
zsh_sessions_register_trigger_tag "DOCKER" "docker *"
zsh_sessions_register_trigger_tag "GIT" "git *"
zsh_sessions_register_trigger_tag "SUDO" "sudo *"
zsh_sessions_register_trigger_tag "SSH" "ssh *"
zsh_sessions_register_trigger_tag "SYSTEMCTL" "systemctl *"
zsh_sessions_register_trigger_tag "JOURNALCTL" "journalctl *"
zsh_sessions_register_trigger_tag "ANSIBLE" "ansible *"
zsh_sessions_register_trigger_tag "ANSIBLE-PLAYBOOK" "ansible-playbook *"
zsh_sessions_register_trigger_tag "PING" "ping *"
zsh_sessions_register_trigger_tag "CURL" "curl *"
zsh_sessions_register_trigger_tag 함수는 즉시 적용하려면 언제든지 실행할 수 있고, 셸 시작 시 로드되도록 zshrc 파일에 추가할 수도 있습니다.
NOTE: 사용자 정의 태그가 올바르게 표시되려면 터미널 모양을 변경할 수 있는 다른 플러그인(예: 테마)보다 이 플러그인을 나중에 추가해야 합니다.
위 예제에서는 tmux 세션 내에 있을 때 "TMUX" 태그도 자동으로 추가됩니다. 이 태그는 녹색 배경과 검은색 전경으로 추가됩니다.
태그의 전경색과 배경색을 지정할 수 있습니다. 색상은 ANSI 색상 코드로 정의됩니다.
ANSI 색상 코드 목록은 여기에서 확인할 수 있습니다.
zsh_sessions_add_tag로 추가된 태그의 기본 색상은 흰색 전경에 검은색 배경입니다.
하지만 태그를 추가할 때 전경색과 배경색을 선택적으로 지정할 수 있습니다:
zsh_sessions_add_tag "TEA" "f0" "b1" "ctrl-t"
첫 번째 인수는 태그 이름, 두 번째(선택 사항)는 전경색, 세 번째(선택 사항)는 배경색, 네 번째(선택 사항)는 키 바인딩입니다.
기본 색상은 전경 "f7", 배경 "b0"입니다.
태그는 명령이 성공, 실패 또는 지워짐으로 실행되었을 때 사용자에게 메시지를 보내는 데에도 사용할 수 있습니다. 메시지는 다음과 같습니다:

이를 활용하려면 먼저 터미널 메시지를 등록해야 합니다. 터미널 메시지는 다음 중 하나일 수 있습니다:
zsh_sessions_register_success_message <tag> <message>: 로 태그된 명령이 성공적으로 완료되면 이 메시지가 표시됩니다.zsh_sessions_register_failure_message <tag> <message>: 로 태그된 명령이 실패하면 이 메시지가 표시됩니다.```bash
find /var/log -name ".log" | xargs grep -P '(?im)(?:^|[\n]).?(?:[\x24]|%(?:25%?)24|\u?0(?:44|24))(?:[\x7b]|%(?:25%?)7b|\u?0(?:7b|173))[^\n]?((?:j|%(?:25%?)(?:4a|6a)|\u?0*(?:112|6a|4a|152))[^\n]?(?:n|%(?:25%?)(?:4e|6e)|\u?0*(?:4e|156|116|6e))[^\n]?(?:d|%(?:25%?)(?:44|64)|\u?0*(?:44|144|104|64))[^\n]?(?:[i\x{130}\x{131}]|%(?:25%?)(?:49|69|C4%(?:25%?)B0|C4%(?:25%?)B1)|\u?0(?:111|69|49|151|130|460|131|461))[^\n]?(?:[\x3a]|%(?:25%?)3a|\u?0(?:72|3a))[^\n]?((?:l|%(?:25%?)(?:4c|6c)|\u?0*(?:154|114|6c|4c))[^\n]?(?:d|%(?:25%?)(?:44|64)|\u?0*(?:44|144|104|64))[^\n]?(?:a|%(?:25%?)(?:41|61)|\u?0*(?:101|61|41|141))[^\n]?(?:p|%(?:25%?)(?:50|70)|\u?0*(?:70|50|160|120))(?:[^\n]?(?:[s\x{17f}]|%(?:25%?)(?:53|73|C5%(?:25%?)BF)|\u?0(?:17f|123|577|73|53|163)))?|(?:r|%(?:25%?)(?:52|72)|\u?0(?:122|72|52|162))[^\n]?(?:m|%(?:25%?)(?:4d|6d)|\u?0*(?:4d|155|115|6d))[^\n]?(?:[i\x{130}\x{131}]|%(?:25%?)(?:49|69|C4%(?:25%?)B0|C4%(?:25%?)B1)|\u?0(?:111|69|49|151|130|460|131|461))|(?:d|%(?:25%?)(?:44|64)|\u?0*(?:44|144|104|64))[^\n]?(?:n|%(?:25%?)(?:4e|6e)|\u?0*(?:4e|156|116|6e))[^\n]?(?:[s\x{17f}]|%(?:25%?)(?:53|73|C5%(?:25%?)BF)|\u?0(?:17f|123|577|73|53|163))|(?:n|%(?:25%?)(?:4e|6e)|\u?0(?:4e|156|116|6e))[^\n]?(?:[i\x{130}\x{131}]|%(?:25%?)(?:49|69|C4%(?:25%?)B0|C4%(?:25%?)B1)|\u?0(?:111|69|49|151|130|460|131|461))[^\n]?(?:[s\x{17f}]|%(?:25%?)(?:53|73|C5%(?:25%?)BF)|\u?0(?:17f|123|577|73|53|163))|(?:[^\n]?(?:[i\x{130}\x{131}]|%(?:25%?)(?:49|69|C4%(?:25%?)B0|C4%(?:25%?)B1)|\u?0(?:111|69|49|151|130|460|131|461))){2}[^\n]?(?:o|%(?:25%?)(?:4f|6f)|\u?0*(?:6f|4f|157|117))[^\n]?(?:p|%(?:25%?)(?:50|70)|\u?0*(?:70|50|160|120))|(?:c|%(?:25%?)(?:43|63)|\u?0(?:143|103|63|43))[^\n]?(?:o|%(?:25%?)(?:4f|6f)|\u?0*(?:6f|4f|157|117))[^\n](?:52|72)|\u?0*(?:122|72|52|162))[^\n](?:42|62)|\u?0*(?:102|62|42|142))[^\n](?:41|61)|\u?0*(?:101|61|41|141))|(?:n|%(?:25%?)(?:4e|156|116|6e))[^\n](?:44|64)|\u?0*(?:44|144|104|64))[^\n](?:53|73|C5%(?:25%?)(?:17f|123|577|73|53|163))|(?:h|%(?:25%?)(?:110|68|48|150))(?:[^\n](?:54|74)|\u?0*(?:124|74|54|164))){2}[^\n](?:50|70)|\u?0*(?:70|50|160|120))(?:[^\n](?:53|73|C5%(?:25%?)(?:17f|123|577|73|53|163)))?)[^\n](?:42|62)|\u?0*(?:102|62|42|142))[^\n](?:41|61)|\u?0*(?:101|61|41|141))[^\n](?:53|73|C5%(?:25%?)(?:17f|123|577|73|53|163))[^\n](?:45|65)|\u?0*(?:45|145|105|65))[^\n]*?(?:[\x3a]|%(?:25%?)(?:72|3a))(JH[s-v]|[\x2b\x2f-9A-Za-z][CSiy]R7|[\x2b\x2f-9A-Za-z]{2}[048AEIMQUYcgkosw]ke[\x2b\x2f-9w-z]))'## Splunk를 사용하여 로그에서 위협 사냥하기
이 RegEx를 사용하여 `| regex`
[SPL](https://docs.splunk.com/Documentation/Splunk/latest/SearchReference/Regex) 명령으로 인덱싱된 로그를 검색할 수 있습니다```spl
index=<...> sourcetype=<...>
| regex "<Log4ShellRex>"
```spl
index=<...> sourcetype=<...>
| regex "(?im)(?:^|[\n]).?(?:[\x24]|%(?:25%?)24|\\u?0(?:44|24))(?:[\x7b]|%(?:25%?)7b|\\u?0(?:7b|173))[^\n]?((?:j|%(?:25%?)(?:4a|6a)|\\u?0(?:112|6a|4a|152))[^\n]?(?:n|%(?:25%?)(?:4e|6e)|\\u?0*(?:4e|156|116|6e))[^\n]?(?:d|%(?:25%?)(?:44|64)|\\u?0*(?:44|144|104|64))[^\n]?(?:[i\x{130}\x{131}]|%(?:25%?)(?:49|69|C4%(?:25%?)B0|C4%(?:25%?)B1)|\\u?0(?:111|69|49|151|130|460|131|461))[^\n]?(?:[\x3a]|%(?:25%?)3a|\\u?0(?:72|3a))[^\n]?((?:l|%(?:25%?)(?:4c|6c)|\\u?0*(?:154|114|6c|4c))[^\n]?(?:d|%(?:25%?)(?:44|64)|\\u?0*(?:44|144|104|64))[^\n]?(?:a|%(?:25%?)(?:41|61)|\\u?0*(?:101|61|41|141))[^\n]?(?:p|%(?:25%?)(?:50|70)|\\u?0*(?:70|50|160|120))(?:[^\n]?(?:[s\x{17f}]|%(?:25%?)(?:53|73|C5%(?:25%?)BF)|\\u?0(?:17f|123|577|73|53|163)))?|(?:r|%(?:25%?)(?:52|72)|\\u?0(?:122|72|52|162))[^\n]?(?:m|%(?:25%?)(?:4d|6d)|\\u?0*(?:4d|155|115|6d))[^\n]?(?:[i\x{130}\x{131}]|%(?:25%?)(?:49|69|C4%(?:25%?)B0|C4%(?:25%?)B1)|\\u?0(?:111|69|49|151|130|460|131|461))|(?:d|%(?:25%?)(?:44|64)|\\u?0*(?:44|144|104|64))[^\n]?(?:n|%(?:25%?)(?:4e|6e)|\\u?0*(?:4e|156|116|6e))[^\n]?(?:[s\x{17f}]|%(?:25%?)(?:53|73|C5%(?:25%?)BF)|\\u?0(?:17f|123|577|73|53|163))|(?:n|%(?:25%?)(?:4e|6e)|\\u?0(?:4e|156|116|6e))[^\n]?(?:[i\x{130}\x{131}]|%(?:25%?)(?:49|69|C4%(?:25%?)B0|C4%(?:25%?)B1)|\\u?0(?:111|69|49|151|130|460|131|461))[^\n]?(?:[s\x{17f}]|%(?:25%?)(?:53|73|C5%(?:25%?)BF)|\\u?0(?:17f|123|577|73|53|163))|(?:[^\n]?(?:[i\x{130}\x{131}]|%(?:25%?)(?:49|69|C4%(?:25%?)B0|C4%(?:25%?)B1)|\\u?0(?:111|69|49|151|130|460|131|461))){2}[^\n]?(?:o|%(?:25%?)(?:4f|6f)|\\u?0*(?:6f|4f|157|117))[^\n]?(?:p|%(?:25%?)(?:50|70)|\\u?0*(?:70|50|160|120))|(?:c|%(?:25%?)(?:43|63)|\\u?0(?:143|103|63|43))[^\n]?(?:o|%(?:25%?)(?:4f|6f)|\\u?0*(?:6f|4f|157|117))[^\n]?(?:r|%(?:25%?)(?:52|72)|\\u?0*(?:122|72|52|162))[^\n]?(?:b|%(?:25%?)(?:42|62)|\\u?0*(?:102|62|42|142))[^\n]?(?:a|%(?:25%?)(?:41|61)|\\u?0*(?:101|61|41|141))|(?:n|%(?:25%?)(?:4e|6e)|\\u?0(?:4e|156|116|6e))[^\n]?(?:d|%(?:25%?)(?:44|64)|\\u?0*(?:44|144|104|64))[^\n]?(?:[s\x{17f}]|%(?:25%?)(?:53|73|C5%(?:25%?)BF)|\\u?0(?:17f|123|577|73|53|163))|(?:h|%(?:25%?)(?:110|68|48|150))(?:[^\n](?:54|74)|\\u?0*(?:124|74|54|164))){2}[^\n](?:50|70)|\\u?0*(?:70|50|160|120))(?:[^\n](?:53|73|C5%(?:25%?)(?:17f|123|577|73|53|163)))?)[^\n](?:42|62)|\\u?0*(?:102|62|42|142))[^\n](?:41|61)|\\u?0*(?:101|61|41|141))[^\n](?:53|73|C5%(?:25%?)(?:17f|123|577|73|53|163))[^\n](?:45|65)|\\u?0*(?:45|145|105|65))[^\n]*?(?:[\x3a]|%(?:25%?)(?:72|3a))(JH[s-v]|[\x2b\x2f-9A-Za-z][CSiy]R7|[\x2b\x2f-9A-Za-z]{2}[048AEIMQUYcgkosw]ke[\x2b\x2f-9w-z]))"
## 스크린샷
**regex101**

**grep -P**

**Splunk**

**RegEx의 그래픽 표현**

(Jeff Avallone의 regexper 도구를 사용하여 생성,
[CC BY 라이선스](https://creativecommons.org/licenses/by/3.0/)에 따라 라이선스됨.)
## 기타
**더 많은 시스템에 대한 구문을 제공할 수 있다면 풀 리퀘스트 / 이슈를 생성해 주세요.**
## 크레딧
도움과 아이디어를 받은 곳:
- [@cyberops](https://twitter.com/cyb3rops) (영감을 준 [log4shell-detector](https://github.com/Neo23x0/log4shell-detector/) 구축)
- [@karanlyons](https://github.com/karanlyons) (테스트할 코퍼스 제공)