Wappalyzer란?
- Wappalyzer(와팔라이저)는 웹 페이지를 분석해서 웹 사이트가 어떤 기술스택을 사용해서 만들어졌는지를 알려주는 오픈 소스 툴이다.
- 웹 서버 종류나 버전, 사용중인 웹 프레임워크나 자바 스크립트 라이브러리 버전 등을 알려준다.
- 크롬 확장 프로그램으로 설치하는 방법과 PC에 설치해서 쓰는 방법이 있다.
- 크롬 확장 프로그램이 사용하기는 쉽지만 매번 웹 사이트를 방문해서 확장 프로그램을 실시해야 하는 번거로움이 있다.
- 설치형은 설치 과정이 번거롭지만 스크립트와 연동해서 많은 수의 사이트를 한번에 돌릴 수 있는 장점이 있다.
- 이 포스트에서는 설치형을 정리한다.
- Wappalyzer는 Node.js로 개발되었다. npm이나 yarn을 통해 설치가 가능하다.
장점(어디에 쓸 것인가?)
- 여러 가지 방면에서 사용할 수 있겠지만, 내 경우에는 취약점 대응 범위를 특정하는데 사용할 수 있다고 본다.
- 예를들어, 어떤 CMS(wordpress등)에만 존재하는 취약점이 있다고 할 때, 미리 사용기술을 분석해두면, wordpress를 사용하고 있는 서버만 추려서 취약점 테스트를 해볼 수 있다.
사용 기술을 알아내는 원리
- 내부적으로 웹 페이지에 접근하는 브라우저로 chromium을 사용하는 것 같다.
- 미리 정의된 시그니쳐 같은 것을 가지고 있다. (https://github.com/wappalyzer/wappalyzer/tree/master/src/technologies)
- 웹 페이지를 크롤링해서 매치되는 것을 찾으면 해당 기술을 사용해서 구축하고 있다고 판단하는 것 같다.
예를들면, 다음과 같은 식이다. 특정 경로에 특정 파일이 존재하는 것으로 판단한다.
"WP Maintenance Mode": {
"cats": [
87
],
"description": "WP Maintenance Mode is a WordPress plugin which add a maintenance page to your blog.",
"icon": "WP Maintenance Mode.png",
"js": {
"wpmm_vars": ""
},
"oss": true,
"requires": "WordPress",
"scriptSrc": "/wp-content/plugins/wp-maintenance-mode/.+wpmm\\.js(?:\\?ver=(\\d+(?:\\.\\d+)+))?\\;version:\\1",
"website": "https://github.com/andrianvaleanu/WP-Maintenance-Mode"
}
또는 다음과 같은 식으로 특정 메타태그가 존재하는지 여부로 판단하기도 한다.
"WebGUI": {
"cats": [
1
],
"cookies": {
"wgSession": ""
},
"icon": "WebGUI.png",
"implies": "Perl",
"meta": {
"generator": "^WebGUI ([\\d.]+)\\;version:\\1"
},
"website": "http://www.webgui.org"
},
그리고 각 기술의 아이콘을 가지고 있다. 크롬 확장 프로그램에서는 이 아이콘을 사용해서 사용기술목록을 출력해준다. (https://github.com/wappalyzer/wappalyzer/tree/master/src/drivers/webextension/images/icons)
설치방법
npm 으로 설치
- npm을 통한 설치가 가장 간편했다.
npm i wappalyzer
사용법
커맨드 라인으로 사용
다음과 같이 커맨드 라인으로 사용가능하다.
wappalyzer
Usage:
wappalyzer <url> [options]
Examples:
wappalyzer https://www.example.com
node cli.js https://www.example.com -r -D 3 -m 50 -H "Cookie: username=admin"
docker wappalyzer/cli https://www.example.com --pretty
Options:
-b, --batch-size=... Process links in batches
-d, --debug Output debug messages
-t, --delay=ms Wait for ms milliseconds between requests
-h, --help This text
-H, --header Extra header to send with requests
--html-max-cols=... Limit the number of HTML characters per line processed
--html-max-rows=... Limit the number of HTML lines processed
-D, --max-depth=... Don't analyse pages more than num levels deep
-m, --max-urls=... Exit when num URLs have been analysed
-w, --max-wait=... Wait no more than ms milliseconds for page resources to load
-p, --probe=[basic|full] Perform a deeper scan by performing additional requests and inspecting DNS records
-P, --pretty Pretty-print JSON output
--proxy=... Proxy URL, e.g. 'http://user:pass@proxy:8080'
-r, --recursive Follow links on pages (crawler)
-a, --user-agent=... Set the user agent string
-n, --no-scripts Disabled JavaScript on web pages
-N, --no-redirect Disable cross-domain redirects
-e, --extended Output additional information
--local-storage=... JSON object to use as local storage
--session-storage=... JSON object to use as session storage
Node.js 라이브러리로 사용
- Node.js 프로그램에서 wappalyzer라이브러리를 호출해서 사용할 수도 있다.
- 추가로 프로그래밍을 해서 사용한다면 이 방법이 좋을 수도 있다.
- 다음 링크에 Node.js 프로그램에서 라이브러리로 사용하는 경우의 샘플이 실려있다.
- https://www.npmjs.com/package/wappalyzer
const Wappalyzer = require('wappalyzer');
const url = 'https://www.some-url.com';
const options = {
debug: false,
delay: 500,
headers: {},
maxDepth: 3,
maxUrls: 10,
maxWait: 5000,
recursive: true,
probe: true,
proxy: false,
userAgent: 'Wappalyzer',
htmlMaxCols: 2000,
htmlMaxRows: 2000,
noScripts: false,
noRedirect: false,
};
const wappalyzer = new Wappalyzer(options)
;(async function() {
try {
await wappalyzer.init()
// Optionally set additional request headers
const headers = {}
const site = await wappalyzer.open(url, headers)
// Optionally capture and output errors
site.on('error', console.error)
const results = await site.analyze()
console.log(JSON.stringify(results, null, 2))
} catch (error) {
console.error(error)
}
await wappalyzer.destroy()
})()
결과 포맷
- 결과는 json 형식으로 출력된다.
- 스펙은 여기에서 확인할 수 있다.
- 몇 가지 특징적인 것을 정리해둔다.
cpe
CPE(Common Platform Enumeration)
는, IT제품이나 플랫폼을 구분하기 위한, 컴퓨터가 읽기 쉬운 식별자이다.- https://cpe.mitre.org/about/
트러블슈팅
실행시 크롬 관련 에러가 발생하는 경우
다음과 같은 에러가 발생했다.
node_modules/puppeteer/.local-chromium/linux-991974/chrome-linux/chrome: error while loading shared libraries: libatk-1.0.so.0: cannot open shared object file: No such file or directory
TROUBLESHOOTING: https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md
원인분석
- wappalyer는 의존 라이브러리로 Puppeteer를 사용하는데, Puppeteer를 구동하는데 필요한 libatk라이브러리가 설치되지 않은 것 같다.
- node_modules/puppeteer/ 경로로 이동해서 확인해보니 아예 .local-chromium 경로자체가 존재하지 않았다. (로컬 PC에 설치한 puppeteer에는 존재했다.)
- 리눅스 서버에 설치된 Puppeteer 버전은 최신버전인 19.7.2였고, PC에 설치된 버전은 14.1.2였다. PC설치버전이 더 오래된 버전이었다.
수동으로 chromium 설치
- https://stackoverflow.com/questions/48480143/installing-chromium-on-amazon-linux
- https://cloud.google.com/looker/docs/best-practices/how-to-install-chromium-for-amazon-linux
- 의존라이브러리 설치를 위해서는
amazon-linux-extras
가 필요한데 아마존 리눅스1에서는 동작하지 않는 것 같다. 아마존 리눅스 2에서 사용가능하다고 한다.
참고
- https://github.com/wappalyzer/wappalyzer
- https://www.npmjs.com/package/wappalyzer