팀지도 명 :교수 : 양환석 WeST교수님 팀 장 : 박의명 팀 원 : 심명섭 오경준 송요섭 강보경 조예림
웹 취약점 진단 시스템 개발 (OWASP TOP 10 기반)
팀 지도 | 명 : xx : | xxx | WeST 교수님 |
팀 | 장 : | xxx | |
팀 | 원 : | xxx | |
xxx | |||
xxx | |||
xxx | |||
xxx |
2019. 10.
중부대학교 xxxx학과
목 차
1. 서론
1.1 xx 목적 및 필요성 2
1.2 xx xxx정 이유 2
2. xxxx
2.1 Python 3
2.2 Ubuntu 3
2.3 Apache 3
2.4 MySQL 4
2.5 Php 4
2.6 Html 4
3. 본론
3.1 xxx xx 4
3.2 취약점 진단 xx 제작 및 실행 5
3.3 리포팅 시스템 개발 10
4. 결론
4.1 결론 및 기대효과 12
5. 참고자료 12
6. 별첨
6.1 발표 PPT 13
6.2 소스코드 26
1. 서 론
1.1 xx 목적 및 필요성
웹은 접근의 용이성 때문에 xx사고의 대부분을 차지할 정도로 집중적인 공격 xx이 되고 있어 그 범위와 피해가 날이 갈수록 증가하고 있다. 그래프(출처 : verizon data breach investigations report)를 보면 웹 어플리케이션을 공격하는 xx이 가장 많은 공 격 xx을 차지한다는 것을 알 수 있다. 이에 OWASP TOP 10을 xx으로 하여 웹 취약 점을 진단하고 xx 방안까지 알려주는 xx 시스템을 개발하려고 한다.
<xx 1 : Verizon 데이터 침해 조사 보고서 >
1.2 xx xx xx 이유
xx에 사용되고 있는 취약점 진단 서비스는 면담을 통해 xx로 이루어 지거나 직접 고객사와 만나며 이루어져야 한다는 제한성을 가지고 있다.
그에 비해 WeST팀은 직접 웹 취약점 진단 사이트를 구축함으로써 사용자의 인증 절차 를 통해 접근을 편리성을 xx 웹 사이트와 발견된 취약점에 xx xx 방안을 볼 수 있 는 리포팅 시스템을 개발한다.
2. xxxx
2.1 Python
python은 1991년 프로그래머인 Xxxxx xxx Xxxxxx이 발표한 고급 프로그래밍 언어로 플랫폼 독립적이며 인터프리터식, 객체지향적, 동적 타이핑 xx형 언어이다. Python은 비영리의 Python 소프트웨어 xx이 xx하는 개방형, 공동체 기반 개발 모델을 가지고 있다 C언어로 xx된 C파이썬 xx 사실상의 표준이다.
< xx 2-1 : 파이썬 로고 >
2.2 Ubuntu
우분투는 컴퓨터에서 프로그램과 주xxx를 사용할 수 있도록 해주는 운영체제 중 하 나이다. 안드로이드 운영체제처럼 리눅스 커널에 기반한 운영체제로 모바일과 데스크톱 PC, 서버에도 우분투 운영체제를 설치해 사용할 수 있다. 리눅스는 리누스 토발즈라는 개 발자가 어셈블리어라는 프로그래밍 언어로 유닉스를 모델 xx 개발한 오픈소스 xx체 제이다. 우분투는 리눅스 OS의 배포판 중 하나로 특히 데스크톱 PC에서 사용할 수 있게 특화된 운영체제이다.
< xx 2-2 : Ubuntu >
2.3 Apache
Apache HTTP 서버는 아파치 소프트웨어 xx에서 xx하는 HTTP 웹 서버이다. BSD, 리눅스 등 유닉스 xx 뿐 아니라 마이크로소프트 윈도우나 xx 넷웨어 같은 xx에서
도 xx할 수 있다. 아파치 프로젝트는 xxx작과 합의에 기반한개발 프로세스와 오픈 되고 실용적인 소프트웨어 라이선스라는 특징으로 xx된다.
2.4 MySQL
MYSQL은 xx에서 가장 많이 쓰이는 오픈 소스의 관계형 데이터 베이스 xx 시스템 이다. RDBMS라고도 불린다. xx 스레드, xx 사용자의 xx의 구조질의어 xx의 xx 터베이스 xx 시스템으로써 MYSQL AB가 xx 및 xx하고 있으며 Qt처럼 xx 라이선 스가 적용된다. xx의 옵션은 GPL이며 GPL이외의 라이선스로 적용시키려는 xx 전통적 인 지적재산권 라이선스의 적용을 받는다.
2.5 Php
php는 C언어를 기반으로 만들어진 서버 측에서 실행되는 서버 사이드 스크립트 언어 이다. 동적 웹 페이지를 만들기 위해 설계되었으며 이를 xxx기 위해 php로 작성된 코 드를 html 소스 문서 안에 넣으면 php 처리 기능이 있는 웹 서버에서 해당 코드를 xx 하여 작성자가 원하는 웹 페이지를 생성한다. xx에는 PHP 코드와 HTML을 별도 xx로 분리하여 작성하는 xx가 일반적이며, PHP 또한 웹서버가 아닌 php-fpm(PHP FastCGI Process Manager)을 통해 실행하는 xx가 늘어나고 있다. 또한 PHP는 xx 줄 인터페 이스 xx의 자체 인터프리터를 제공하여 이를 통해 xx 프로그래밍 언어로도 사용할 수 있으며 그래픽 애플리케이션을 제작할 수도 있다.
2.6 Html
하이퍼 본문 표식 xx 언어라는 xx의 웹 페이지를 위한 지배적인 마크업 언어다. HTML은 xx, 단락, 목록 등과 같은 본문을 위한 구조적 xx를 나타내는 것뿐만 아니 라 링크, xx과 그 밖의 xx으로 구조적 문서를 만들 수 있는 방법을 제공한다. 그리고 이미지와 객체를 내장하고 xx형 xx을 생성하는 데 사용될 수 있다.
3. 본론
3.1 xxx xx
< xx 3-1 : xxx >
3.2 취약점 진단 xx 제작 및 실행
OWASP Top 10과 KISA에서 발간한 xxx보통신기반xx 기술적 취약점 분석·평가 방법 xx가이드를 토대로 해당 취약점 진단 xx를 개발하였다.
< xx 3-2 : OWASP Top 10 - 2017 >
먼저 비회원이 인증절차를 통하여 xx가입을 하고, 로그인 및 진단 xx을 하게 되면 취약점 진단 xx를 통해 해당 웹 사이트에 xx 취약점을 진단한다.
이후 리포팅 시스템을 통해 취약점 진단 보고서를 작성해 데이터베이스에 저장하고, 사용자에게 보고서를 전달해준다.
< xx 3-3 : Web 취약점 분석·평가 xx >
< xx 3-4 : SQL INJECTION 취약점 xx 소스 일부 >
< xx 3-5 : XSS 취약점 xx 소스 일부 >
<xx 3-6 : 디렉토리 리스팅 취약점 xx 소스 일부 >
<xx 3-7 : 알려진 취약점 xx 소스 일부 >
< xx 3-8 : 관리자 페이지 xx 취약점 xx 소스 일부 >
< xx 3-9 : 데이터 xx 전송 취약점 xx 소스 일부 >
웹 사이트를 개발하여 웹 상에서 취약점 진단을 할 수 있도록 하였다.
< xx 3-10 : 웹 사이트 메인 화면 >
< xx 3-11: 취약점 진단 화면 >
3.3 리포팅 시스템 개발
취약점 진단 이후 사용자에게 보고서를 제공하기 위하여 xx 쉽게 PDFxx로 생성하여 가독성을 높였다.
< xx 3-12 : 리포팅 시스템 소스 일부 >
< xx 3 – 13 : 진단 결과 화면 >
< xx 3 – 14 : 리퍼팅 시스템으로 만든 PDF xx >
4. 결론
웹 취약점 진단 시스템을 만들어 XSS과 SQL Injection등의 취약점을 xxx 웹 공격에 xx 진단 시스템을 xx하는 것으로 목표로 xxx고 서비스를 제공하기 위해 인가된 사용자만 xx 가능 xxx 웹사이트를 개발하였다.
진단 이후 리포팅 시스템을 통해 관리자에게 xx 방안과 취약점들을 제공해 안정적이고 효율적으로 웹 사이트를 xx할 수 있도록 xx을 한다.
기대효과로는 웹 서비스를 xx하기 xxx 후에 취약점 진단 xx를 xxx여 관리자에 게 xx 방안과 취약한 부분에 xx 보고서를 제공하고 온라인에서 자동으로 웹 사이트 취약점 진단을 xx하여 빠르고 간결하게 웹 취약점진단을 할 수 있다.
5. 참고자료
[1] verizon data breach investigations report
[2] KISA – xxx보통신기반xx 취약점 진단 가이드 2014
[3] KISA – 홈페이지 취약점 진단 제거 가이드
6. 별첨
6.1 발표 PPT
6.2 소스코드
6.1 발표 PPT
6.2 소스코드
<db.php>
<?php
$host = 'localhost';
$username = 'root';
$password = 'song0401';
$dbname = 'WeST';
$options = array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'); try {
$con = new PDO("mysql:host={$host};dbname={$dbname};charset=utf8",$username,
$password);
} catch(PDOException $e) {
die("Failed to connect to the database: " . $e->getMessage());
}
$con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$con->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
if(function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) { function undo_magic_quotes_gpc(&$array) {
foreach($array as &$value) { if(is_array($value)) {
undo_magic_quotes_gpc($value);
}
else {
$value = stripslashes($value);
}
}
}
undo_magic_quotes_gpc($_POST); undo_magic_quotes_gpc($_GET); undo_magic_quotes_gpc($_COOKIE);
}
header('Content-Type: text/html; charset=utf-8'); session_start();
?>
<dbinit.php>
<?php error_reporting(E_ALL); ini_set('display_errors',1); include('check.php');
$databaseName = 'WeST';
$databaseUser = 'root';
$databasePassword = 'song0401';
데이터베이스 생성
$pdoDatabase = new PDO('mysql:host=localhost', $databaseUser, $databasePassword);
$pdoDatabase->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdoDatabase->exec('DROP DATABASE IF EXISTS WeST;');
$pdoDatabase->exec('CREATE DATABASE IF NOT EXISTS WeST DEFAULT CHARSET=utf8
COLLATE=utf8_general_ci');
테이블생성
$pdo =
new
PDO('mysql:host=localhost;dbname='.$databaseName,
$databaseUser,
$databasePassword);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->exec('DROP TABLE IF EXISTS yo;');
$pdo->exec('CREATE TABLE `yo` (
`uid` int(11) NOT NULL AUTO_INCREMENT,
`username` VARCHAR(255) NOT NULL,
`password` VARCHAR(255) NOT NULL,
`email` VARCHAR(255),
`domain` VARCHAR(255),
`salt` VARCHAR(255) NOT NULL,
`regtime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`uid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci')
echo "데이터베이스 초기화에 성공했습니다.\n";
<check.php>
<?php
error_reporting(E_ALL); ini_set('display_errors',1);
function is_login(){ global $con;
if (isset($_SESSION['user_id']) && !empty($_SESSION['user_id']) ){
$stmt = $con->prepare("select username from yo where username=:username");
$stmt->bindParam(':username', $_SESSION['user_id']);
$stmt->execute();
$count = $stmt->rowcount(); if ($count == 1){
return true; //로그인 xx
}else{
//사용자 테이블에 없는 사람 return false;
}
}else{
return false; //로그인 안된 xx
}
}
//xxxxx://xxxxxxxxxxxxx.xxx/x/00000000
function encrypt($plaintext, $salt) {
$method = "AES-256-CBC";
$key = hash('sha256', $salt, true);
$iv = openssl_random_pseudo_bytes(16);
$ciphertext = openssl_encrypt($plaintext, $method, $key, OPENSSL_RAW_DATA, $iv);
$hash = hash_hmac('sha256', $ciphertext, $key, true);
return $iv . $hash . $ciphertext;
}
function decrypt($ivHashCiphertext, $salt) {
$method = "AES-256-CBC";
$iv = substr($ivHashCiphertext, 0, 16);
$hash = substr($ivHashCiphertext, 16, 32);
$ciphertext = substr($ivHashCiphertext, 48);
$key = hash('sha256', $salt, true);
if (hash_hmac('sha256', $ciphertext, $key, true) !== $hash) return null;
return openssl_decrypt($ciphertext, $method, $key, OPENSSL_RAW_DATA, $iv);
}
?>
< main.php >
<?php include('db.php');
include('check.php'); if(is_login()){
if(isset($_SESSION['user_id'])) { header("Location: welcome.php");
}
}
?>
<!DOCTYPE HTML>
<html>
<head>
<title>WEST</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta name="description" content="" />
<meta name="keywords" content="" />
<script src="js/jquery.min.js"></script>
<script src="js/skel.min.js"></script>
<script src="js/skel-layers.min.js"></script>
<script src="js/init.js"></script>
</head>
<script >
function check() {
alert(' 로그인 먼저하세요.')
}
</script>
<body id="top">
<header id="header" class="skel-layers-fixed">
<h1><a href="#">WeST</a></h1>
<nav id="nav">
<ul>
<li><a href="#" class="button special" onclick="check()">진단하기</a></li>
</ul>
</nav>
</header>
<section id="banner">
<div class="inner">
<h2>WeST</h2>
<p><b>중부대학교 3조 졸업작품</b> <a href="#">WeST Team</a></p>
<ul class="actions">
<li><a href="#two" class="button big special">login</a></li>
<li><a href="#one" class="button big alt">vulnerabilities</a></li>
</ul>
</div>
</section>
<section id="one" class="wrapper style1">
<header class="major">
<h2>Kind Of Vulnerabilities</h2>
<p>XSS, Adminstrator Page, Known Vulnerabilities, Port Scan, SQL, Directory Listing</p>
</header>
<div class="container">
<div class="row">
<div class="4u">
<section class="special box">
<i class="icon fa-area-chart major"></i>
<h3>XSS</h3>
<p>Xss(Cross Site Script)는 웹 상에서 가장 xx적인 취약점 공격 방법의
xx으로, 악의적인 xx자기 공격하려는 사이트에 스크립트를 넣는 기법을 말합니다. 공격에 성 공하면 사이트에 접속한 사용자는 삽입된 코드를 실행하게 되며, 보통 의도치 않는 행동을 xx시 키거나 쿠키나 세션 토큰 등의 민감한 xx를 탈취합니다.</p>
</section
</div>
<div class="4u">
<section class="special box">
<i class="icon fa-refresh major"></i>
<h3>Adminstrator Page</h3>
<p>admin, adminstartor등 관리자페이지가 인터넷을 통해 추측성 접근이
가능할 xx, 공격자x x 타겟이 될 수 있으며, 이는 공격자의 SQL 인젝션, Brute-Force공격 등 다양한 xx의 공격의 빌미를 제공하는 취약점입니다.</p>
</section>
</div>
<div class="4u">
<section class="special box">
<i class="icon fa-cog major"></i>
<h3>Known Vulnerabilities</h3>
<p>대게 라이브러리, 프레임워크 및 다른 소프트웨어 모듈 같은 컴포넌 트는 애플리케이션과 같은 권한으로 실행됩니다. 알려진 취약점이 있는 컴포넌트를 사용한 애플리 케이션과 API는 애플리케이션 방어를 xx시키거나 다양한 공격과 xx을 주는 취약점입니다.
</p>
</section>
</div>
</div>
</div>
</section>
<section id="one" class="wrapper style1_2">
<div class="container">
<div class="row">
<div class="4u">
<section class="special box">
<i class="icon fa-area-chart major1"></i>
<h3>Port Scan</h3>
<p>포트 스캔xx, xx의 어떤 포트가 열려 있는지 확인하는 작업으로 침입 전 취약점을 분석하 기 위한 사전 작업이라 볼 수 있다, 스캐닝을 통해 xx의 네트워크 xx장비 xx xx, 우회 가 능 네트워크 구조, 해당 네트워크 내의 시스템 플랫폼 xx, 시스템 운영체제의 커널 버전, 제xx 는 서비스 등에 xx xx를 알 수 있어 포트가 열려 있을 시 취약할수 있는 취약점이다.</p>
</section>
</div>
<div class="4u">
<section class="special box">
<i class="icon fa-refresh major1"></i>
<h3>SQL</h3>
<p>SQL Injectionxx, 대표적인 웹 어플리케이션 취약점 중 xx입니다. 애플리케이션에서 서버로 전달되는 xx, 쿼리, 스크립트등의 값을 변도하여 비정상적인 방법으로 시스템에 접근하는 공격기법입니다. 또한 웹 어플리케이션에서만 국한되지 않고 데이터베이스와 연결된 모든 어플리케이션에서 고려해 볼 수 있는 공격 기법입니다. </p>
</section>
</div>
<div class="4u">
<section class="special box">
<i class="icon fa-cog major1"></i>
<h3>Directory Listing</h3>
<p>Directorying 취약점은 브라우징 하는 모든 xx을 보여줍니다. xx의 모적 은 문서의 공유로 xx 탐색기처럼 원하는 문서로 바로 찾아갈 수 있게 하는 xx였지만 xx에 는 문서의 저장 및 열람이 가능하다면 문서의 취약점(백업xx 및 소스 코드, 스크립트 xx의 유 출로 인한 xx xx xx 등)을 xxx 악의적인 목적을 갖고 있는 사람들에게 탈취 및 웹 서버
공격이 이루어질 수 있는 취약접입니다.</p>
</section>
</div>
</div>
</section>
<!-- Two -->
<section id="two" class="wrapper style2">
<header class="major">
<h2>login</h2>
</header>
<div class="content">
<div class="signin-cont cont">
<form method="post">
<input id="login username" name="user_name" type="text" class="inpt" placeholder="Username"required autocomplete="off" readonly onfocus="this.removeAttribute('readonly');" />
<input id="login password" name="user_password" type="password" class="inpt" placeholder="Password" required autocomplete="off" readonly onfocus="this.removeAttribute('readonly');" />
<div class="submit-wrap">
<input type="submit" name="login" class="submit" value="Login">
<a href="new_login.php" class="more">New_Login</a>
</div>
</form>
</div>
</div>
</section>
</body>
</html>
<?php
$login_ok = false;
if ( ($_SERVER['REQUEST_METHOD'] == 'POST') and isset($_POST['login']) )
{
$username=$_POST['user_name'];
$userpassowrd=$_POST['user_password'];
if(empty($username)){
$errMSG = "아이디를 입력하세요.";
}else if(empty($userpassowrd)){
$errMSG = "패스워드를 입력하세요.";
}else{
try {
$stmt = $con->prepare('select * from yo where
username=:username');
$stmt->bindParam(':username', $username);
$stmt->execute();
} catch(PDOException $e) {
die("Database error. " . $e->getMessage());
}
$row = $stmt->fetch();
$salt = $row['salt'];
$password = $row['password'];
$decrypted_password = decrypt(base64_decode($password), $salt); if ( $userpassowrd == $decrypted_password) {
$login_ok = true;
}
}
if(isset($errMSG)
echo "<script>alert('$errMSG')</script>";
if ($login_ok){
$_SESSION['user_id'] = $username; header('Location:welcome.php'); session_write_close();
}else{
echo "<script>alert('$username 인증 오류')</script>";
}
}
?>
<New_login.php>
<?php
include('db.php'); include('check.php');
function validatePassword($password){
if(strlen($password) < 8 || empty($password)) { return 0;
}
if((strlen($password) > 48)) { return 0;
}
if(preg_match('/[A-Z]/',$password) == (0 || false)){ return 1;
}
if(!preg_match('/[\d]/',$password) != (0 || false)){ return 2;
}
if(preg_match('/[\W]/',$password) == (0 || false)){ return 3;
}
return true;
}
if( ($_SERVER['REQUEST_METHOD'] == 'POST') && isset($_POST['submit']))
{
foreach ($_POST as $key => $val)
{
if(preg_match('#^ autocomplete_fix_#', $key) === 1){
$n = substr($key, 19); if(isset($_POST[$n])) {
$_POST[$val] = $_POST[$n];
}
}
}
$username=$_POST['newusername'];
$password=$_POST['newpassword'];
$confirmpassword=$_POST['newconfirmpassword'];
$email=$_POST['newemail'];
$domain=$_POST['newdomain'];
if ($_POST['newpassword'] != $_POST['newconfirmpassword']) {
$errMSG = "<script>alert('패스워드가 일치하지 않습니다.')</script>";
}
if(empty($username)){
$errMSG = "<script>alert('아이디를 입력하세요')</script>";
}
else if(empty($password)){
$errMSG = "<script>alert('패스워드을 입력하세요.')</script>";
}
else if(empty($email)){
$errMSG = "<script>alert('email을 입력하세요.')</script>";
}
else if(empty($domain)){
$errMSG = "<script>alert('domain을 입력하세요.')</script>";
}
try {
$stmt = $con->prepare('select * from yo where username=:username');
$stmt->bindParam(':username', $username);
$stmt->execute();
} catch(PDOException $e) {
die("Database error: " . $e->getMessage());
}
$row = $stmt->fetch(); if ($row){
$errMSG = "<script>alert('xx 존재하는 아이디입니다')</script>";
}
if(!isset($errMSG))
{
try{
$stmt = $con->prepare('INSERT INTO yo(username, password, email, salt, domain) VALUES(:username, :password, :email, :salt, :domain)');
$stmt->bindParam(':username',$username);
$salt = bin2hex(openssl_random_pseudo_bytes(32));
$encrypted_password = base64_encode(encrypt($password, $salt));
$stmt->bindParam(':password', $encrypted_password);
$stmt->bindParam(':email',$email);
$stmt->bindParam(':salt',$salt);
$stmt->bindParam(':domain',$domain);
if($stmt->execute())
{
}
else
{
$successMSG = "<script>alert('새로운 사용자를 추가했습니다.')</script>"; header("refresh:1;west.php");
$errMSG = "사용자 추가 에러";
}
} catch(PDOException $e) {
die("Database error: " . $e->getMessage());
}
}
}
?>
<!DOCTYPE HTML>
<html>
<head>
<title>WEST</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta name="description" content="" />
</head>
<script >
<meta name="keywords" content="" />
<script src="js/jquery.min.js"></script>
<script src="js/skel.min.js"></script>
<script src="js/skel-layers.min.js"></script>
<script src="js/init.js"></script>
function email_ck(){
var email = document.getElementById("em").value; var domain = document.getElementById("dom").value;
url = "email_ck.php?domain="+domain+"&email="+email;
xxxxxx.xxxx(url, "window_name",'width=800,height=500,location=no,status=no,scrollbars=no, resizable=no');
}
function check(){
var ck = document.getElementById("aa").value; che = "email_ok.php";
xxxxxx.xxxx(url, "window_name",'width=800,height=500,location=no,status=no,scrollbars=no, resizable=no');
}
function check1() {
alert(' 로그인 먼저하세요.')
}
</script>
<body id="top">
<!-- Header -->
<header id="header" class="skel-layers-fixed">
<h1><a href="#">WeST</a></h1>
<nav id="nav">
<ul>
<li><a href="#" class="button special" onclick="check1()">진단하기</a></li>
</ul>
</nav>
</header>
<section id="two" class="wrapper style2">
<header class="major">
<h2>새로운 사용자 추가</h2>
</header>
<div class=“tabs”>
<span class="tab signin active"><a href="west.php"><b>Back</b></a></span>
</div>
<?php if(isset($errMSG)){
?>
<div class="alert alert-danger">
<span class="glyphicon glyphicon-info-sign"></span>
<strong><?php echo $errMSG; ?></strong>
</div>
<?php
}
else if(isset($successMSG)){
?>
<div class="alert alert-success">
<strong><span class="glyphicon glyphicon-info-sign"></span>
<?php echo $successMSG; ?></strong>
</div>
<?php
}
?>
<div class="content">
<div class="signin-cont cont">
<form method="post" enctype="multipart/form-data">
<? $r1 = rmd5(rand().mocrotime(TRUE)); ?>
<input type="text" name="<? echo $r1; ?>" class="inpt" placeholder="아 이디를 입력하세요." autocomplete="off" readonly onfocus="this.removeAttribute('readonly');" />
<input type="hidden" name=" autocomplete_fix_<? echo $r1; ?>" value="newusername" />
<? $r2 = rmd5(rand().mocrotime(TRUE)); ?>
<input type="password" name="<? echo $r2; ?>" class="inpt" placeholder="패스워드를 입력하 세요" autocomplete="off" readonly onfocus="this.removeAttribute('readonly');" />
<input type="hidden" name=" autocomplete_fix_<? echo $r2; ?>" value="newpassword" />
<? $r3 = rmd5(rand().mocrotime(TRUE)); ?>
<input type="password" name="<? echo $r3; ?>" class="inpt" placeholder="패스워드를 다시 한 번 입력하세요" autocomplete="off" readonly onfocus="this.removeAttribute('readonly');" />
<input type="hidden" name=" autocomplete_fix_<? echo $r3; ?>" value="newconfirmpassword"
/>
<? $r4 = rmd5(rand().mocrotime(TRUE)); ?>
<input type="text" id="em" name="newemail" name="<? echo $r4; ?>" class="inpt" placeholder="이메일를 입력하세요" autocomplete="off" readonly onfocus="this.removeAttribute('readonly');" />
<input type="hidden" name=" autocomplete_fix_<? echo $r4; ?>" value="newemail" />
<? $r5 = rmd5(rand().mocrotime(TRUE)); ?>
<input type="text" id="dom" name="newdomain" name="<? echo $r5; ?>" class="inpt" placeholder="도메인을 입력하세요" autocomplete="off" readonly onfocus="this.removeAttribute('readonly');" />
<input type="hidden" name=" autocomplete_fix_<? echo $r5; ?>" value="newdomain" />
<div class="do">
<input type="submit" name="submit" value="Register" onclick="check()">
<input type="submit" name="aa" value="진단하기" onclick="email_ck()“>
</div>
</div>
</form>
</div>
</section>
<welcome.php>
<?php
include('db.php'); include('check.php');
if (is_login()){
;
}else
header("Location: west.php");
?>
<?php
$user_id = $_SESSION['user_id'];
try {
$stmt = $con->prepare('select * from yo where username=:username');
$stmt->bindParam(':username', $user_id);
$stmt->execute();
} catch(PDOException $e) {
die("Database error: " . $e->getMessage());
}
$row = $stmt->fetch();
?>
<!DOCTYPE HTML>
<html>
<head>
<title>WeST <?php echo($row['username']);?>님</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
</head>
<body id="top">
<!-- Header -->
<header id="header" class="skel-layers-fixed">
<h1><a href="#"><?php echo $user_id; ?>님</a></h1>
<nav id="nav">
<ul>
<li><a href="logout.php" class="button special">logout</a></li>
</ul>
</nav>
</header>
<!-- Banner -->
<section id="banner">
<div class="inner">
<h2>WeST</h2>
<p><b>중부대학교 3조 Team</a></p>
졸업작품</b>
<a
href="xxxx://xxxxxxxxx.xx">WeST
<ul class="actions">
<li> <input type="submit" value="<?php echo($row['email']);?> 진단하기" class="button big special"
onclick="xxxxxx.xxxx('./song/ppp.php','window_name','width=800,height=500,location=no,status= no,scrollbars=no');"></li>
<li><input type="submit" value="<?php echo($row['email']);?> 조회하기" class="button big alt"
onclick="xxxxxx.xxxx('look.php','window_name','width=800,height=500,location=no,status=no,scr ollbars=no');"></li>
</ul>
</div>
</section>
<result.php>
<?php
include('/var/www/html/WeST/db.php'); include('/var/www/html/WeST/check.php');
?>
<?php
$user_id = $_SESSION['user_id'];
try {
$stmt = $con->prepare('select * from yo where username=:username');
$stmt->bindParam(':username', $user_id);
$stmt->execute();
} catch(PDOException $e) {
die("Database error: " . $e->getMessage());
}
$row = $stmt->fetch();
?>
<!DOCTYPE html>
<html>
<head>
<title>Result</title>
</head>
<table class="table" border="1" >
<caption>Starting
Web
scan....
<a><?php
echo($row['email']);
?></a> <?php
echo($row['regtime']); ?></caption>
<tr><th> No. </th><th> 진단 xx </th><th> </th></tr>
<tr><td> 1/6 </td><td> 데이터 xx 전송</td><td> <div ><img id="l05" src="song.gif" width="20px" height="20px"></td></tr>
<tr><td> 2/6 </td><td> 관리자 페이지 xx</td><td > <div id ="l06" > <img id="l01" src="song.gif" width="20px" height="20px ">
</td></tr>
<tr><td> 3/6 </td><td> 알려진 취약점</td><td><div ><img id="l02" src="song.gif" width="20px" height="20px"></div>
</td></tr>
<tr><td> 4/6 </td><td> 디렉토리 리스팅</td><td> <div ><img id="l03" src="song.gif" width="20px" height="20px" ></td></tr>
<tr><td> 5/6 </td><td> XSS</td><td ><div ><img id="l04" src="song.gif" width="20px" height="20px" ></div><div id="l06">
</div></td></tr>
<tr><td> 6/6 </td><td> SQL INJECTION</td><td> <div ><img id="loading2" src="a.jpg" width="20px" height="20px"><img id="loading" src="song.gif" width="20px" height="20px "></div>
<iframe src="result.php" id="iframe100"></iframe>
</td></tr>
<script>
var ld= document.getElementById("loading"); window.addEventListener("load", function(){
ld.style.display="none";
});
</script>
</table>
</div>
<input type='button' value=" 창닫기" onclick='self.close()'>
</body>
</html>
<lnquiry.php>
<?php
include('db.php'); include('check.php');
if (is_login()){
;
}else
header("Location: west.php");
?>
<?php
$user_id = $_SESSION['user_id'];
try {
$stmt = $con->prepare('select * from yo where username=:username');
$stmt->bindParam(':username', $user_id);
$stmt->execute();
} catch(PDOException $e) {
die("Database error: " . $e->getMessage());
}
$row = $stmt->fetch();
?>
<!doctype html>
<html lang="kr">
<head>
<meta charset="UTF-8">
<title>WeST</title>
</head>
<body>
<p>진단 결과</p>
<table class="table" border="1">
<tr> <th>번호</th><th>xx</th><th>날짜</th><th>Download</th> </tr>
<tbody>
<tr> <td>1</td>
<td><?php echo $row['username']?>의 진단 결과</td>
<td><?php echo $row['regtime']?></td>
<td><a href="download.php">download</a></td> </tr>
</tbody>
</table>
</body>
</html>
<download.php>
<?php
include('db.php'); include('check.php');
if (is_login()){
;
}else
header("Location: west.php");
?>
<?php
$user_id = $_SESSION['user_id'];
try {
$stmt = $con->prepare('select * from yo where username=:username');
$stmt->bindParam(':username', $user_id);
$stmt->execute();
} catch(PDOException $e) {
die("Database error: " . $e->getMessage());
}
$row = $stmt->fetch();
?>
<?php
$user = $_SESSION['user_id'];
$filename = "cve_log_$user.pdf";
$file = "./song/" . $filename; if (is_file($file)) {
if (preg_match("/MSIE*/", $_SERVER['HTTP_USER_AGENT'])) { header("Content-type: application/octet-stream"); header("Content-Length: ".filesize("$file"));
header("Content-Disposition: attachment; filename=$filename"); // 다운로드되는 파일명 (실제 파일명과 별개로 xx 가능)
header("Content-Transfer-Encoding: binary");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Pragma: public");
header("Expires: 0");
}
else {
header("Content-type: file/unknown"); header("Content-Length: ".filesize("$file"));
header("Content-Disposition: attachment; filename=$filename"); // 다운로드되는 파일명 (실제 파일명과 별개로 xx 가능)
header("Content-Description: PHP3 Generated Data"); header("Pragma: no-cache");
header("Expires: 0");
}
$fp = fopen($file, "rb"); fpassthru($fp); fclose($fp);
}
else {
echo "해당 xx이 없습니다.";
}
?>
<Vulnerability.py>
# -*- coding: utf-8 -*- import socket
import datetime import urllib.request import requests
from bs4 import BeautifulSoup import re
import sys
from urllib import parse
from urllib.request import urlopen import time
import os
from fpdf import FPDF
def scan(domain):
module_name = "Port Scan" contents = ""
is_cve = "Safe"
comport = {"FTP":21, "SMTP":25,"HTTP":80}
ad = domain
adip = socket.gethostbyname(ad) for PN, port in comport.items():
try:
s= socket.socket(xxxxxx.XX_INET, socket.SOCK_STREAM) result = s.connect_ex((adip, port))
banner = s.recv(1024) if result == 0:
contents += str(port)+"/tcp("+str(PN)+") Open " is_cve = "Risk"
elif banner==b'':
contents += str(port)+"/tcp("+str(PN)+") noservice\n" s.close()
except:
continue
return (module_name, contents.strip(), is_cve)
def adpage(domain):
module_name = "Admin Page" contents = ""
is_cve = "Safe"
page= ["/admin",
"/manager", "/master", "/system", "/administart"]
url = "http://"+domain for pages in page:
try:
req = urllib.request.urlopen(url+ pages) contents += (pages + " server exist\n") is_cve = "Risk"
except :
continue
if is_cve == "Safe":
contents += "no admin page found" return (module_name, contents.strip(), is_cve)
def get_header(domain):
global req, header, dic, cve
req = requests.get('http://'+domain) header = req.headers
dic = {'server' : 'hidden', 'os' : 'hidden', 'lang' : 'hidden'} cve = {'server' : '', 'lang' : ''}
if 'Server' in header: server=header['Server'] s = server.split(' ')
for i, a in enumerate(dic.keys()): dic[a] = s[i]
if (len(s) < len(dic)): break
else:
pass
def check_cve(get_header): module_name = "Check CVE" contents = ""
is_cve = "Safe"
def cve1(key, contents, is_cve):
r = requests.get('xxxxx://xxx.xxxxx.xxx/xxx-xxx/xxxxxx.xxx?xxxxxxxx'xxxx(xxx[xxx])) soup = BeautifulSoup(r.text, 'html.parser')
count_target = soup.find(class_="smaller") cve[key] = count_target.find("b").text
list_result = str(xxxx.xxxxxx("#TableWithRules")) list_result = re.sub('<.+?>','',list_result,0).strip() if len(list_result) > 26:
contents += 'xxxxx://xxx.xxxxx.xxx/xxx-xxx/xxxxxx.xxx?xxxxxxxx'xxxx(xxx[xxx]) is_cve = "Risk"
return contents, is_cve if dic['server'] != 'hidden':
contents, is_cve = cve1('server', contents, is_cve) if dic['lang'] != 'hidden':
contents, is_cve = cve1('lang', contents, is_cve) if contents == "":
contents = "no cve found"
return (module_name, contents.strip(), is_cve)
def help():
print('Usage: ./main url') sys.exit(1)
def sqlinjection():
sqlinjection_mysql = ['or 1=1--',
'\' or 1=1--',
'\" or 1=1--',
'\' or \'1\'=\'1',
'\" or \"1\"=\"1']
sqlinjection_oracle = ['\' or 1=1#',
'\" or 1=1#',
'or 1=1#',
'\' or \'1\'=\'1',
'\" or \"1\"=\"1'] return sqlinjection_mysql[1]
def send_post(data, next_url): is_cve = "Safe"
header = {
'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:66.0) Gecko/20100101 Firefox/66.0',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Language': 'en-US,en;q=0.5',
'Accept-Encoding': 'gzip, deflate',
}
resp = xxxxxxxx.xxxx(next_url, data=data, headers=header) if "Sign Off" in resp.text:
is_cve = "Risk" return (is_cve)
def get_domain(url):
domainp = '^(https?:\/\/)?([\da-z\.-]+)' domain = re.compile(domainp).match(url).group() return domain
def sqltest(url):
module_name = "SQL Injection" is_cve = "Safe"
url = "http://"+ url + "/login.jsp" r = requests.get(url).text
soup = BeautifulSoup(r, 'html.parser') tags = xxxx.xxxxxx("form input")
idp = re.compile("id=\"[a-zA-Z]*id[a-z]*\"") for tag in tags:
try:
result = xxx.xxxxxx(str(tag)).group()
id_value = result.replace("id=", "").replace("\"", "")
break
except AttributeError: result = None
pw_value = xxxx.xxxxxx('form input[type=password]')[0]['name'] submit = xxxx.xxxxxx('form input[type=submit]')
submitp = re.compile("\"[a-zA-Z]*[L|l]ogin[a-zA-Z]*\"") subnetname = xxxxxxx.xxxxxx(str(submit)).group().replace("\"", "") tags = xxxx.xxxxxx("form")
formp = re.compile("<form action=\"[a-zA-Z]*[L|l]ogin\"") actionvaluep = re.compile("\"[a-zA-Z]*\"")
for tag in tags:
result = xxxxx.xxxxxx(str(tag)) if result != None:
action_value = xxxxxxxxxxxx.xxxxxx(xxxxxx.xxxxx()).group().replace("\"", "")
domain = get_domain(url)
next_url = domain + "/" + action_value
data = {id_value:sqlinjection(), pw_value:'donecare'}
contents = str(data) send_post(data, next_url)
is_cve = send_post(data, next_url)
return (module_name, contents.strip(), is_cve)
pages = set()
def getLinks(pageUrl): global pages
html = urlopen(pageUrl)
soup = BeautifulSoup(html, "html.parser") for link in soup.findAll("a"):
if 'href' in link.attrs: pages.add(link.attrs['href'])
if link.attrs['href'] not in pages: newPage = link.attrs['href']
pages.add(newPage) getLinks(newPage)
def dicxss(url):
module_name = "XSS" contents = ""
is_cve = "Safe"
url = "http://"+url getLinks(url)
lst = list(pages)
dic ={} d=0
for i in lst:
check = parse.urlparse(lst[int(d)]) check.geturl()
if check.query:
dic.update(parse.parse_qs(check.query)) d+=1
fname = "payloads.txt" with open(fname) as f:
content = f.readlines()
payloads = [x.strip() for x in content] vuln = []
for payload in payloads: for t in dic.keys():
payload = payload
xss_url = url+"?"+t+"="+payload r = requests.get(xss_url)
if payload.lower() in r.text.lower(): if(payload not in vuln):
vuln.append(payload)
if vuln:
else:
continue
tmp_contents = "\n".join(vuln) contents += str(tmp_contents) is_cve = "Risk"
return (module_name, contents.strip(), is_cve)
def get_urldirectorypath(url):
current_pagep = '\/[a-zA-Z0-9]*\.[a-zA-Z0-9]*$' path = re.sub(current_pagep, "", url)
return path
def return_souporhtml(url, str): r = requests.get(url).text
soup = BeautifulSoup(r, 'html.parser') if(str=="soup"):
return soup elif(str=="html"):
return soup.text
def regex_search(regex, str): p = re.compile(regex)
s = x.xxxxxx(str) return s
def dicrec(url):
module_name = "Directory Listing" contents = ""
is_cve = "Safe" c=0
url = "http://"+url getLinks(url)
lst = list(pages) for i in lst:
toryurl = url+"/"+lst[int(c)]
path = get_urldirectorypath(toryurl) html = return_souporhtml(path, "html")
s = regex_search('Index of /', html) if s == None:
contents = "This website is \"SAFE\" from Directory listing"
else:
contents = path is_cve = "Risk" c+=1
return (module_name, contents.strip(), is_cve)
start = xxxxxxxx.xxxxxxxx.xxx()
def Westall(domain): results = []
results.append(scan(domain)) results.append(adpage(domain)) get_header(domain) results.append(check_cve(get_header)) results.append(dicrec(domain)) results.append(dicxss(domain)) results.append(sqltest(domain))
return results data = []
url = str(sys.argv[1]) uid = str(sys.argv[2]) data.extend(Westall(url))
filename = "cve_log_"+uid+".pdf" title = 'Web Scan Report'
finish = xxxxxxxx.xxxxxxxx.xxx() duration = finish - start
class PDF(FPDF):
def header(self):
self.set_font("Arial", size=24)
self.cell(200, 20, txt="Website Vulnerability Scanner Report", ln=1, align="C") self.set_text_color(46,138,204)
self.cell(20, 20, txt="Scan Information", ln=1) self.set_line_width(1)
self.set_draw_color(255, 0, 0)
self.line(10, 45, 200, 45) self.set_line_width(0) xxxx.xxx_xxxx_xxxxx(0, 0, 0) xxxx.xxx_xxxx_xxxxx(0,0,0) self.set_font("Arial", size=11)
self.cell(20, 5, txt="Website URL = "+url, ln=1) self.cell(10,5,txt="Start Time = "+str(start), ln=1) self.cell(10,5,txt="Finish Time = "+str(finish), ln=1) self.cell(10,5,txt="Scan duration = "+str(duration), ln=1)
def footer(self):
self.set_y(-15) self.set_font('Arial', 'I', 8) self.set_text_color(128)
self.cell(0, 10, 'Page ' + str(xxxx.xxxx_no()), 0, 0, 'C') def chapter_title(self, num, label):
self.set_font('Arial', '', 12)
self.set_fill_color(200, 220, 255)
self.cell(0, 6, 'Chapter %d : %s' % (num, label), 0, 1, 'L', 1) self.ln(4)
def chapter_body(self, spacing=2):
global data
self.cell(10, 20, ln=1, align="c") self.set_font("Arial", 'B', size=24)
self.cell(10, 20, txt="List of tests performed (6/6)",ln=1 ,align="L") self.set_font("Arial", 'B', size=15)
self.set_draw_color(0, 0, 0) self.set_line_width(0.5) col_width = self.w / 3.3 row_height = self.font_size
header = ('Type', 'Contents', 'Resulte')
cellwidth =110
cellHeight= 5
self.cell(40, cellHeight*3, txt=header[0], border=1, align="C") self.cell(cellwidth, cellHeight*3, txt=header[1], border=1, align="C") self.cell(40, cellHeight*3, txt=header[2], border=1, ln=1, align="C") self.set_font("Arial", size=10)
for i in range(6):
line =1
if self.get_string_width(data[i][1]) < cellwidth: line =1
else:
textLength=len(data[i][1]) errMargin = 44
startChar = 0
maxChar = 0 textArray = [] tmpString="" st = data[i][1]
while (startChar < textLength):
while (self.get_string_width(tmpString) < (cellwidth - errMargin) and (startChar+maxChar) < textLength):
maxChar +=1
tmpString = st[startChar : maxChar] startChar= startChar + maxChar textArray.append(tmpString)
line +=1 maxChar=0 tmpString=""
self.cell(40, line*cellHeight, txt=data[i][0], border=1, ln=0,align = "C") x = self.get_x()
y = self.get_y()
self.multi_cell(cellwidth, cellHeight, txt=data[i][1], border=1) self.set_xy(x+cellwidth, y)
self.cell(40, line*cellHeight, txt=data[i][2], border=1, ln=1,align = "C")
def print_chapter(self, num, title, name): self.add_page() self.chapter_title(num, title) self.chapter_body(name)
pdf = PDF() pdf.set_title(title) pdf.add_page() pdf.chapter_body() pdf.output(filename, 'F')