본문 바로가기
Security Project

14. Nmap NSE 스크립트 개발 기초

by 귀멸 2022. 9. 3.

1. NSE 기본 포맷 - Hello world 출력

포맷 항목 설명
description field 스크립트에 대한 전체적인 설명
categories field 스크립트 용도에 따른 카테고리 표시
author field 스크립트 제작자
license field 라이센스 표시
dependencies field 스크립트 실행에 다른 스크립트 필요 시 표시
Rules 스크립트의 Action을 결정하는 Lua 메소드
Action port rule이 일치가 되었을 때 메인함수라고 할 수 있는 action=function이 실행

기본적으로 Hello world를 출력하는 스크립트를 통해 포맷 구성을 파악한다.

-- The Head Section --

local shortport = require "shortport"
local http = require "http"

description = [[
Show Test
]]

categories = {"safe"}

-- The Rule Section --  (조건을 지정)

portrule = function(host, port)
	return port.protocol == "tcp"
    		and port.number == 80
            and port.state == "open"
end

-- The Action Section -- (실제 실행되는 코드)

action = function(host, post)
	return "Hello World!"
end

위의 스크립트를 vim으로 hello.nse라는 이름으로 저장

저장한 파일을 스크립트들이 있는 폴더로 복사

nmap 스크립트 db 업데이트

만약 스크립트에 문법적 오류가 있으면 업데이트 시 오류가 발생함

nmap으로 스크립트를 실행해 보면 조건에 해당하는 80포트 / tcp / http 에 Hello world가 출력된 것을 볼 수 있다.

 


2. NSE 스크립트  -  서비스 응답/요청 테스트

http 서비스에 대해서 http 상태 코드가 200 ok (정상 페이지)에 대한 html 소스코드 body 값을 응답으로 출력

local shortport = require "shortport"
local http = require "http"
description = [[
Service Test Page
]]
categories = {"safe"}
-- The Rule Section --
portrule = shortport.http
-- The Action Section --
action = function(host, port)
		local uri = "/twiki/TWikiDocumentation.html"
        local response = http.get(host, port, uri)
     if(response.status == 200) then
     	return response.body
     end
end

vim으로 파일 만들고 위와 같이 db 업데이트 까지 실행

스크립트를 80 포트 지정해서 돌려보면 html body를 긁어 온다. (크롤링)

이중에서 <타이틀>만 가져오고 싶다면?

가져올 때 원하는 값만 출력해 오도록 스크립트 수정

local shortport = require "shortport"
local http = require "http"
description = [[
Service Test Page
]]
categories = {"safe"}
-- The Rule Section --
portrule = shortport.http
-- The Action Section --
action = function(host, port)
		local uri = "/twiki/TWikiDocumentation.html"
        local response = http.get(host, port, uri)
     if(response.status == 200) then
     	local title = string.match(response.body, "<[Tt][Ii][Tt][Ll][Ee][^>]*>([^<]*)</[Tt][Ii][Tt][Ll][Ee]>")
        return title
     end
end

string.match 함수를 사용하고  <title>T~~~~n</title> 이 안에 값을 가져오기 위한 정규표현식

스크립트 저장해서 nmap 돌리면 

title만 긁어 오는 것을 볼 수 있다.

댓글