자동화 도구 개발 전에 수동 진단표를 먼저 만들어야 합니다.
왜냐하면 나중에 Streamlit에서 비교하려면 수동 결과와 자동 결과의 기준이 같아야 하기 때문입니다.
manual_results.csvcheck_id,category,item,manual_result,manual_evidence,tester,elapsed_time
WEB-001,웹서버 설정,보안 헤더 미설정,취약,X-Frame-Options와 CSP 헤더 없음,준희,3
WEB-002,웹서버 설정,서버 정보 노출,취약,Server 헤더에서 Tomcat 정보 확인,준희,2
WEB-003,웹앱 취약점,SQL Injection,취약,admin'-- 입력 시 로그인 성공,세권,5
WEB-004,웹앱 취약점,XSS,취약,script 태그가 응답에 반사됨,하연,4
WEB-005,웹앱 취약점,민감정보 노출,취약,debug.jsp에서 db_password와 api_key 확인,병헌,2
WEB-006,웹앱 취약점,관리자 페이지 노출,취약,로그인 없이 admin.jsp 접근 가능,채윤,2
자동 진단 도구는 Python으로 만들면 됩니다.
대상 URL 입력
↓
각 진단 모듈 실행
↓
HTTP 요청 전송
↓
응답 코드 / 헤더 / 본문 분석
↓
취약 / 양호 / N/A 판단
↓
evidence 저장
↓
GPT로 reason / recommendation 생성
↓
auto_results.json 생성
이렇게 구성하면 깔끔합니다.
scanner/
├── scanner.py
├── config.py
├── checks/
│ ├── header_check.py
│ ├── server_info_check.py
│ ├── sqli_check.py
│ ├── xss_check.py
│ ├── sensitive_info_check.py
│ └── admin_exposure_check.py
├── gpt_reporter.py
└── auto_results.json
파이썬 코드
import requests
resp = requests.post(
"<http://15.164.60.79:8000/scan>",
json={
"target": "<http://15.164.60.79>" # 이 주소는 사용자 입력 받아 동적으로 할당
},
stream=True,
timeout=600,
)
print("status:", resp.status_code)
print("content-type:", resp.headers.get("Content-Type"))
print("content-disposition:", resp.headers.get("Content-Disposition"))
resp.raise_for_status()
content_type = resp.headers.get("Content-Type", "")
if "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" not in content_type:
body = resp.text
raise RuntimeError(f"엑셀 파일 응답이 아닙니다:\\n{body}")
filename = "자동진단.xlsx"
content_disposition = resp.headers.get("Content-Disposition", "")
if "filename=" in content_disposition:
filename = content_disposition.split("filename=")[-1].strip().strip('"')
with open(filename, "wb") as f:
for chunk in resp.iter_content(chunk_size=8192):
if chunk:
f.write(chunk)
print("saved:", filename)
이거 실행하면 data/자동진단.xlsx 파일 리턴해줍니다!