
웹 셸 스캐너 및 분석기.
웹 셸 분석기는 웹 셸로 의심되는 파일을 식별, 디코딩 및 태깅하는 목적으로만 제작된 크로스 플랫폼 독립 실행형 바이너리입니다. 웹 셸 분석기는 웹 셸 스캐너 프로젝트(http://github.com/tstillz/webshell-scan)의 상위 버전으로, 해당 프로젝트는 정규식으로만 파일을 스캔하며 디코딩이나 속성 분석은 수행하지 않습니다.
스캐너에 포함된 정규식과 내장 디코딩 루틴은 디스크에 있는 모든 웹 셸을 찾을 것을 보장하지 않으며 일부 오탐지(false positive)를 식별할 수 있습니다. 또한 프로덕션 시스템에서 실행하기 전에 분석기를 테스트하고 그 영향을 평가하는 것이 좋습니다. 이 분석기는 어떠한 보증도 없으며, 사용에 따른 책임은 사용자에게 있습니다.
PHP, ASP/X 웹 셸을 지원합니다. JSP/X, CFM 및 기타 유형은 개발 중입니다.스캔되는 모든 파일은 PRE 및/또는 POST 액션을 거칠 수 있습니다:
PreDecodeActions 함수의 개념은 정규식을 사용하여 일치하는 문자열이나 패턴을 식별하고, 원시 일치 내용을 가져온 후 정의된 디코딩/정리 단계를 수행하고 최종 출력을 분석 엔진으로 다시 보내 재스캔/처리하는 것입니다.
이에 대한 매우 간단한 예는 Base64 디코딩입니다. base64로 인코딩된 웹 셸에 대한 탐지 로직을 확인하려면 먼저 base64의 모든 계층을 제거해야 합니다. 이를 위해 다음 PreDecodeAction을 사용할 수 있습니다:
{
Name: "PHP_Base64Decode",
Regex: *regexp.MustCompile(`(?i)(?:=|\s+)(base64_decode\('('?\"?[A-Za-z0-9+\/=]+'?\"?))`),
DataCapture: *regexp.MustCompile(`(?i)((?:'|")[A-Za-z0-9+\/=]+(?:'|"))`),
PreDecodeActions: []cm.Action{
{Function: cm.StringReplace, Arguments: []interface{}{"\"", "", -1}},
{Function: cm.StringReplace, Arguments: []interface{}{"'", "", -1}},
},
Functions: []cm.Base_Func{cm.DecodeBase64},
},
위 블록을 보면, 먼저 함수의 이름, 매칭에 사용되는 정규식, 데이터 캡처 정규식(때로는 매칭되는 것과 캡처할 것을 조정하고 싶을 수 있음), 그리고 PreDecodeActions가 있습니다. 이 경우, 함수 cm.DecodeBase64가 일치하는 텍스트에 적용되기 전에 시스템이 먼저 "와 '를 제거합니다.
PostDecodeActions는 반대 방식으로 작동하며, 디코딩이 수행된 후 출력이 검사됩니다. 이 모델을 사용하면 무한한 PRE/POST 및 디코딩 함수를 가진 여러 사용자 지정 디코더를 만들어 대부분의 웹 셸 분석 요구를 처리할 수 있습니다.
탐지는 이름과 설명이 포함된 정규식입니다. 이 모델의 아이디어는 탐지를 모듈화하고 확장 가능하게 만들며 실제 탐지와 컨텍스트를 유지하는 것입니다. 탐지는 속성과 동일한 형식을 공유하지만, 속성은 탐지를 생성할 수 없으며 기존 탐지에 컨텍스트만 추가할 수 있습니다. 아래 예시 탐지 로직 블록을 살펴보겠습니다:
{
Name: "Generic_Embedded_Executable",
Description: "Looks for magic bytes associated with a PE file",
Regex: *regexp.MustCompile(`(?i)(?:(?:0x)?4d5a)`),
},
정규식을 보면 매직 헤더 바이트 4D 5A를 기반으로 포함된 Windows PE 파일을 찾고 있음을 알 수 있습니다. 발견되면 이는 탐지로 이어지며 파일에 대한 JSON 보고서가 생성됩니다.
현재 탐지는 파일 확장자에 따라 적용되거나 모든 파일 형식에 일반적으로 적용됩니다. 예를 들어, PHP용 디코딩 루틴은 cm.GlobalMap.Function_Php 아래에 정의되고, 속성 태그는 cm.GlobalMap.Tags_Php 아래에 정의됩니다.
cm.GlobalMap.Function_Generics 함수와 cm.GlobalMap.Tags_Generics 아래의 태그는 모든 웹 셸 확장자에 포괄적으로 적용됩니다.
속성 태깅은 기존 웹 셸 탐지에 "컨텍스트"를 추가하기 위해 제가 만든 새로운 개념입니다. 속성만으로는 현재 자체적으로 탐지를 생성할 수 없습니다. 전통적인 스캔 엔진에서는 스캐너가 웹 셸이 탐지된 경우에만 알림을 보내지만, 웹 셸이 잠재적으로 가진 기능(속성)에 대한 추가 컨텍스트는 거의 제공하지 않습니다. 속성 태그는 탐지 로직과 동일하게 작동하지만, 탐지가 확인된 후에만 표시되며 자체적으로 탐지를 생성할 수 없습니다. 아래 예시 로직을 살펴보겠습니다:
cm.GlobalMap.Tags_Php = []cm.TagDef{
{
Name: "PHP_Database_Operations",
Description: "Looks for common PHP functions used for interacting with a database.",
Regex: *regexp.MustCompile(`(?i)(?:'mssql_connect\|mysql_exec\()`),
Attribute: true,
},
}
Tags_Php 구조체 아래에 새로운 PHP 태그를 생성한 것을 볼 수 있습니다. 스캔 중 일치 항목이 발견되면 Attribute 플래그가 확인되고 True로 설정된 경우 탐지된 웹 셸은 JSON 보고서에 PHP_Database_Operations 태그가 빈도 및 일치 텍스트 블록과 함께 추가됩니다. 아래 예시 출력을 참조하십시오:
{
"filePath": "/testers/1.php",
"size": 66109,
"md5": "6793d8ebab93e5a0f91e5a331221f331",
"timestamps": {
"birth": "2019-02-03 02:02:22",
"created": "2020-07-29 02:50:15",
"modified": "2019-02-03 02:02:22",
"accessed": "2020-07-29 02:51:07"
},
"matches": {
"FilesMAn": 5,
"FilesMan": 29,
"cmd": 20,
"eval(": 4,
"exec(": 2,
"ipconfig": 1,
"netstat": 2,
"passthru(": 1,
"shell_exec(": 1
},
"decodes": {
"Generic_Base64Decode": 40,
"Generic_Multiline_Base64Decode": 165
},
"tags": {
"Generic_Embedding_Code_C": {
"bind(": 2,
"listen(": 2
},
"PHP_Banned_Function": {
"exec(": 3,
"get_current_user(": 1,
"getmyuid(": 1,
"link(": 7,
"listen(": 2,
"passthru(": 1,
"realpath(": 1,
"set_time_limit(": 1
},
"PHP_Database_Operations": {
"mysql_query(": 1
},
"PHP_Disk_Operations": {
"@chmod(": 1,
"@filegroup(": 4,
"@fileowner(": 4,
"@rename(": 2,
"fopen(": 7,
"fwrite(": 6
}
}
}
이러한 태그는 웹 셸이 무엇을 할 수 있는지 정의하는 데 도움이 될 뿐만 아니라, IR 컨설턴트와 같은 팀이 라이브 대응 업무 중에 다음에 어디를 살펴봐야 할지에 대한 피벗 포인트를 제공합니다.
없음! OS에 맞는 바이너리를 다운로드하고 스캔할 디렉터리를 지정한 후(다른 인수는 선택 사항) 실행하기만 하면 됩니다.
인수 없이 wsa를 실행하면 다음 옵션이 표시됩니다:
/Users/beastmode$ ./wsa
Options:
-dir string
Directory to scan for web shells
-pretty
If set to true, the analyzer will output the results in a json indented form
-raw_contents
If a match is found, grab the raw contents and base64 + gzip compress the file into the JSON object.
-size int
Specify max file size to scan (default is 10 MB) (default 10)
-verbose
If set to true, the analyzer will print all files analyzer, not just matches
유일한 필수 인수는 dir입니다. 원하는 경우 다른 프로그램 기본값을 재정의할 수 있습니다.
분석기의 출력은 콘솔(표준 출력)에 기록됩니다. 아래 예시 참조(최상의 결과를 위해 stdout을 json 파일로 리디렉션하고 오프라인에서 검토/후처리):
Linux: ./wsa -dir /opt/www
Windows: wsa.exe -dir C:\Windows\Inetput\wwwroot
### STDOUT 및 전체 웹 셸 파일 인코딩 및 압축 사용:
Linux: ./wsa -dir /opt/www -raw_contents=true > scan_results.json
분석기가 완료되면 아래 예시와 같이 전체 스캔 메트릭을 STDOUT에 출력합니다:
{"scanned":311,"matches":122,"noMatches":189,"directory":"/webshell-master/php","scanDuration":1.4757737378333333,"systemInfo":{"hostname":"Beast","envVars":[""],"username":"beastmode","userID":"501","realName":"The Beast","userHomeDir":"/Users/beastmode"}}