이경수

dynamic.html 추가

...@@ -18,14 +18,14 @@ from django.contrib import admin ...@@ -18,14 +18,14 @@ from django.contrib import admin
18 from django.contrib.auth import views 18 from django.contrib.auth import views
19 from VulnNotti.views import * 19 from VulnNotti.views import *
20 from django.conf import settings 20 from django.conf import settings
21 - 21 +from myapp.views import *
22 22
23 urlpatterns = [ 23 urlpatterns = [
24 url(r'^admin/', admin.site.urls), 24 url(r'^admin/', admin.site.urls),
25 url(r'^$', HomeView.as_view(), name='home'), 25 url(r'^$', HomeView.as_view(), name='home'),
26 url(r'^home/', HomeView.as_view(), name='home'), 26 url(r'^home/', HomeView.as_view(), name='home'),
27 url(r'^myapp/', include('myapp.urls', namespace='myapp')), 27 url(r'^myapp/', include('myapp.urls', namespace='myapp')),
28 - 28 + url(r'^myapp/static', StaticView.as_view(), name='static'),
29 url(r'^edit/', EditView.as_view(), name='edit'), 29 url(r'^edit/', EditView.as_view(), name='edit'),
30 30
31 url(r'^accounts/', include('django.contrib.auth.urls')), 31 url(r'^accounts/', include('django.contrib.auth.urls')),
......
1 -from django.contrib import admin
2 -from myapp.models import *
3 -# Register your models here.
4 -
5 -class UploadFileAdmin(admin.ModelAdmin):
6 - list_display = ('title', 'file')
7 -
8 -admin.site.register(UploadFileModel, UploadFileAdmin)
...@@ -47,15 +47,16 @@ ...@@ -47,15 +47,16 @@
47 <h1 class="text-uppercase mb-0">동적 분석 페이지입니다.</h1> 47 <h1 class="text-uppercase mb-0">동적 분석 페이지입니다.</h1>
48 <hr class="star-light"> 48 <hr class="star-light">
49 <h2 class="font-weight-light mb-0">툴을 다운로드 받은 후 결과 파일을 업로드 해주세요.</h2> 49 <h2 class="font-weight-light mb-0">툴을 다운로드 받은 후 결과 파일을 업로드 해주세요.</h2>
50 - 50 + </div>
51 - 51 + <div>
52 - <a href="{% static 'img/profile.png' %}" download> 52 + <a href="{% static 'img/linux_vuln_check_script.sh' %}" download>
53 <button class="btn btn-success">Download!</button> 53 <button class="btn btn-success">Download!</button>
54 </a> 54 </a>
55 - <button class="btn btn-warning">Upload!</button> 55 +
56 - <form method="post" enctype="multipart/form-data">{% csrf_token %} 56 + <!-- <button class="btn btn-warning">Upload!</button> -->
57 - <input type="file" name="sentFile" /> 57 + <form method="post" style="display: inline;" enctype="multipart/form-data">{% csrf_token %}
58 - <input type="submit" name="submit" value="Upload" /> 58 + <input class="btn btn-warning" style="background-color: #fcc;"value="Select File" type="file" name="sentFile" />
59 + <input class="btn btn-warning" style="color: white;" type="submit" name="submit" value="Upload!" />
59 </form> 60 </form>
60 </div> 61 </div>
61 </header> 62 </header>
...@@ -89,7 +90,7 @@ ...@@ -89,7 +90,7 @@
89 <th>분류</th> 90 <th>분류</th>
90 <th>점검항목</th> 91 <th>점검항목</th>
91 <th>항목 중요도</th> 92 <th>항목 중요도</th>
92 - <th>결과</th> 93 + <th style="width: 50%;">결과</th>
93 </tr> 94 </tr>
94 <tbody> 95 <tbody>
95 {% for object in object_list %} 96 {% for object in object_list %}
......
...@@ -24,6 +24,8 @@ ...@@ -24,6 +24,8 @@
24 <link rel="stylesheet" href="//cdn.jsdelivr.net/highlight.js/9.5.0/styles/vs2015.min.css"> 24 <link rel="stylesheet" href="//cdn.jsdelivr.net/highlight.js/9.5.0/styles/vs2015.min.css">
25 <script src="//cdn.jsdelivr.net/highlight.js/9.5.0/highlight.min.js"></script> 25 <script src="//cdn.jsdelivr.net/highlight.js/9.5.0/highlight.min.js"></script>
26 <script>hljs.initHighlightingOnLoad();</script> 26 <script>hljs.initHighlightingOnLoad();</script>
27 +
28 +
27 </head> 29 </head>
28 30
29 31
...@@ -62,14 +64,19 @@ ...@@ -62,14 +64,19 @@
62 <!-- Portfolio Grid Section --> 64 <!-- Portfolio Grid Section -->
63 65
64 <!-- <section class="portfolio" id="portfolio"> --> 66 <!-- <section class="portfolio" id="portfolio"> -->
65 - <div class="col-md-6 col-lg-6" style="float: left;"> 67 + <div class="col-lg-4" style="float: left;">
68 + <div class="container">
69 + <canvas id="barChart" width="700" height="400"></canvas>
70 + </div>
71 + </div>
72 + <div class="col-lg-4" style="float: right;">
66 <div class="container"> 73 <div class="container">
67 - <canvas id="barChart" width="700" height="200"></canvas> 74 + <canvas id="barChart2" width="700" height="400"></canvas>
68 </div> 75 </div>
69 </div> 76 </div>
70 - <div class="col-md-6 col-lg-6" style="float: right;"> 77 + <div class="col-lg-4" style="float: right;">
71 <div class="container"> 78 <div class="container">
72 - <canvas id="pieChart" width="700" height="200"></canvas> 79 + <canvas id="pieChart" width="600" height="300"></canvas>
73 </div> 80 </div>
74 </div> 81 </div>
75 82
...@@ -98,24 +105,17 @@ ...@@ -98,24 +105,17 @@
98 <th>CVE</th> 105 <th>CVE</th>
99 <th>내용</th> 106 <th>내용</th>
100 <th>이름</th> 107 <th>이름</th>
101 - <th>번호</th> 108 +
102 - <th>제목</th>
103 - <th>이름</th>
104 - <th>CVE</th>
105 - <th>내용</th>
106 </tr> 109 </tr>
107 {% for object in object_list %} 110 {% for object in object_list %}
108 <tr> 111 <tr>
109 <td>{{ forloop.counter }}</td> 112 <td>{{ forloop.counter }}</td>
110 - <td>{{ object.Language }}</td> 113 + <td>{{ object.vulnId }}</td>
111 - <td>{{ object.Length }}</td> 114 + <td>{{ object.lenBlock }}</td>
112 - <td>{{ object.PreviousFunc }}</td> 115 + <td>{{ object.cve }}</td>
113 - <td>{{ object.InputDate }}</td> 116 + <td>{{ object.funcName }}</td>
114 - <td>{{ object.Hash }}</td> 117 + <td>{{ object.numBlock }}</td>
115 - <td>{{ forloop.counter }}</td> 118 +
116 - <td>{{ object.Language }}</td>
117 - <td>{{ object.Length }}</td>
118 - <td>{{ object.PreviousFunc }}</td>
119 119
120 <td id="modal_{{ forloop.counter }}"> 120 <td id="modal_{{ forloop.counter }}">
121 <a class="portfolio-item d-block mx-auto" href="#portfolio-modal-{{ forloop.counter }}"> 121 <a class="portfolio-item d-block mx-auto" href="#portfolio-modal-{{ forloop.counter }}">
...@@ -126,6 +126,12 @@ ...@@ -126,6 +126,12 @@
126 {% endfor %} 126 {% endfor %}
127 </table> 127 </table>
128 </div> 128 </div>
129 + <div style="text-align: center;">
130 + <button id="prev" class="btn btn-primary" style="background-color: #FF0066; border: #FF0066;"><< Prev</button>
131 + <button id="next" class="btn btn-primary" style="margin-left: 200px; background-color: #FF0066; border: #FF0066;">Next >></button>
132 + </div>
133 + &nbsp;
134 + &nbsp;
129 135
130 {% for object in object_list %} 136 {% for object in object_list %}
131 <div class="portfolio-modal mfp-hide" id="portfolio-modal-{{ forloop.counter }}"> 137 <div class="portfolio-modal mfp-hide" id="portfolio-modal-{{ forloop.counter }}">
...@@ -139,41 +145,14 @@ ...@@ -139,41 +145,14 @@
139 <h2 class="text-secondary text-uppercase mb-0" style="text-align: center;">previous sourcecode</h2> 145 <h2 class="text-secondary text-uppercase mb-0" style="text-align: center;">previous sourcecode</h2>
140 <hr class="star-dark mb-5"> 146 <hr class="star-dark mb-5">
141 <pre><code> 147 <pre><code>
148 + <!-- #include <iostream>;
142 using namespace std; 149 using namespace std;
143 150
144 int main() 151 int main()
145 { 152 {
146 - int rows;
147 -
148 - cout << "Enter number of rows: ";
149 - cin >> rows;
150 -
151 - for(int i = 1; i <= rows; ++i)
152 - {
153 - for(int j = 1; j <= i; ++j)
154 - {
155 - cout << j << " ";
156 - }
157 - cout << "\n";
158 - }
159 -
160 - char input, alphabet = 'A';
161 -
162 - cout << "Enter the uppercase character you want to print in the last row: ";
163 - cin >> input;
164 -
165 - for(int i = 1; i <= (input-'A'+1); ++i)
166 - {
167 - for(int j = 1; j <= i; ++j)
168 - {
169 - cout << alphabet << " ";
170 - }
171 - ++alphabet;
172 -
173 - cout << endl;
174 - }
175 return 0; 153 return 0;
176 - } 154 +
155 + } -->
177 </code></pre> 156 </code></pre>
178 </div> 157 </div>
179 <!-- right side --> 158 <!-- right side -->
...@@ -181,41 +160,7 @@ ...@@ -181,41 +160,7 @@
181 <h2 class="text-secondary text-uppercase mb-0" style="text-align: center;">modified sourcecode</h2> 160 <h2 class="text-secondary text-uppercase mb-0" style="text-align: center;">modified sourcecode</h2>
182 <hr class="star-dark mb-5"> 161 <hr class="star-dark mb-5">
183 <pre><code> 162 <pre><code>
184 - using namespace std; 163 + {{ object.codeOriBefore }}
185 -
186 - int main()
187 - {
188 - int rows;
189 -
190 - cout << "Enter number of rows: ";
191 - cin >> rows;
192 -
193 - for(int i = 1; i <= rows; ++i)
194 - {
195 - for(int j = 1; j <= i; ++j)
196 - {
197 - cout << j << " ";
198 - }
199 - cout << "\n";
200 - }
201 -
202 - char input, alphabet = 'A';
203 -
204 - cout << "Enter the uppercase character you want to print in the last row: ";
205 - cin >> input;
206 -
207 - for(int i = 1; i <= (input-'A'+1); ++i)
208 - {
209 - for(int j = 1; j <= i; ++j)
210 - {
211 - cout << alphabet << " ";
212 - }
213 - ++alphabet;
214 -
215 - cout << endl;
216 - }
217 - return 0;
218 - }
219 </code></pre> 164 </code></pre>
220 </div> 165 </div>
221 <!-- footer --> 166 <!-- footer -->
...@@ -245,30 +190,71 @@ ...@@ -245,30 +190,71 @@
245 <script type="text/javascript" src="{% static 'js/Chart.min.js' %}"></script> 190 <script type="text/javascript" src="{% static 'js/Chart.min.js' %}"></script>
246 <script type="text/javascript"> 191 <script type="text/javascript">
247 192
193 +
194 + // $(document).on("click", "#next", function() {
195 + // $.ajax({
196 + // url: '{% url 'static' %}',
197 + // data: {
198 + // idx : $('#idx').val(),
199 + // method : 'next',
200 + // },
201 + // dataType: "json",
202 + // success: function(){
203 + // object_list = []
204 + // var tbody = document.getElementById('tbody');
205 + // tbody.innerHTML = '';
206 + // },
207 + // error: function(e){
208 + // alert("error");
209 + // },
210 + // });
211 + // });
212 +
213 +
248 // barChart 214 // barChart
215 + var level0 = {{ level0 }};
216 + var level1 = {{ level1 }};
217 + var level2 = {{ level2 }};
218 + var level3 = {{ level3 }};
219 + var level4 = {{ level4 }};
220 + var level5 = {{ level5 }};
221 + var level6 = {{ level6 }};
222 + var level7 = {{ level7 }};
223 + var level8 = {{ level8 }};
224 + var level9 = {{ level9 }};
225 +
226 +
249 var ctx = document.getElementById("barChart").getContext('2d'); 227 var ctx = document.getElementById("barChart").getContext('2d');
250 var myChart = new Chart(ctx, { 228 var myChart = new Chart(ctx, {
251 type: 'bar', 229 type: 'bar',
252 data: { 230 data: {
253 - labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"], 231 + labels: ["0-1", "1-2", "2-3", "3-4", "4-5", "5-6", "6-7", "7-8", "8-9", "9-10"],
254 datasets: [{ 232 datasets: [{
255 - label: '# of Votes', 233 + label: 'level',
256 - data: [12, 19, 3, 5, 2, 3], 234 + data: [level0, level1, level2, level3, level4, level5, level6, level7, level8, level9],
257 backgroundColor: [ 235 backgroundColor: [
258 - 'rgba(255, 99, 132, 0.2)', 236 + 'rgba(0, 196, 0, 0.4)',
259 - 'rgba(54, 162, 235, 0.2)', 237 + 'rgba(0, 224, 32, 0.4)',
260 - 'rgba(255, 206, 86, 0.2)', 238 + 'rgba(0, 240, 0, 0.4)',
261 - 'rgba(75, 192, 192, 0.2)', 239 + 'rgba(209, 255, 0, 0.4)',
262 - 'rgba(153, 102, 255, 0.2)', 240 + 'rgba(255, 224, 0, 0.4)',
263 - 'rgba(255, 159, 64, 0.2)' 241 + 'rgba(255, 204, 0, 0.4)',
242 + 'rgba(255, 188, 16, 0.4)',
243 + 'rgba(255, 156, 32, 0.4)',
244 + 'rgba(255, 128, 0, 0.4)',
245 + 'rgba(255, 0, 0, 0.4)',
264 ], 246 ],
265 borderColor: [ 247 borderColor: [
266 - 'rgba(255,99,132,1)', 248 + 'rgba(0,196,0,1)',
267 - 'rgba(54, 162, 235, 1)', 249 + 'rgba(0, 224, 32, 1)',
268 - 'rgba(255, 206, 86, 1)', 250 + 'rgba(0, 240, 0, 1)',
269 - 'rgba(75, 192, 192, 1)', 251 + 'rgba(209, 255, 0, 1)',
270 - 'rgba(153, 102, 255, 1)', 252 + 'rgba(255, 224, 0, 1)',
271 - 'rgba(255, 159, 64, 1)' 253 + 'rgba(255, 204, 0, 1)',
254 + 'rgba(255, 188, 16, 1)',
255 + 'rgba(255, 156, 32, 1)',
256 + 'rgba(255, 128, 0, 1)',
257 + 'rgba(255, 0, 0, 1)',
272 ], 258 ],
273 borderWidth: 1 259 borderWidth: 1
274 }] 260 }]
...@@ -284,32 +270,121 @@ ...@@ -284,32 +270,121 @@
284 } 270 }
285 }); 271 });
286 272
273 + var year2009 = {{ year2009 }};
274 + var year2010 = {{ year2010 }};
275 + var year2011 = {{ year2011 }};
276 + var year2012 = {{ year2012 }};
277 + var year2013 = {{ year2013 }};
278 + var year2014 = {{ year2014 }};
279 + var year2015 = {{ year2015 }};
280 + var year2016 = {{ year2016 }};
281 + var year2017 = {{ year2017 }};
282 + var year2018 = {{ year2018 }};
283 +
284 + var ctx = document.getElementById("barChart2").getContext('2d');
285 + var myChart = new Chart(ctx, {
286 + type: 'bar',
287 + data: {
288 + labels: ["2009", "2010", "2011", "2012", "2013", "2014", "2015", "2016", "2017", "2018"],
289 + datasets: [{
290 + label: '',
291 + data: [year2009, year2010, year2011, year2012, year2013, year2014, year2015, year2016, year2017, year2018],
292 + backgroundColor: [
293 + 'rgba(50, 50, 50, 0.4)',
294 + 'rgba(0, 196, 0, 0.4)',
295 + 'rgba(255, 0, 0, 0.4)',
296 + 'rgba(255, 128, 0, 0.4)',
297 + 'rgba(100, 100, 0, 0.4)',
298 + 'rgba(0, 192, 192, 0.4)',
299 + 'rgba(96, 0, 255, 0.4)',
300 + 'rgba(200, 200, 0, 0.4)',
301 + 'rgba(0, 0, 255, 0.4)',
302 + 'rgba(255, 60, 60, 0.4)',
303 + ],
304 + borderColor: [
305 + 'rgba(50, 50, 50, 1)',
306 + 'rgba(0, 196, 0, 1)',
307 + 'rgba(255, 0, 0, 1)',
308 + 'rgba(255, 128, 0, 1)',
309 + 'rgba(100, 100, 0, 1)',
310 + 'rgba(0, 192, 192, 1)',
311 + 'rgba(96, 0, 255, 1)',
312 + 'rgba(100, 200, 100, 1)',
313 + 'rgba(0, 0, 255, 1)',
314 + 'rgba(255, 60, 60, 1)',
315 + ],
316 + borderWidth: 1
317 + }]
318 + },
319 + options: {
320 + scales: {
321 + yAxes: [{
322 + ticks: {
323 + beginAtZero:true
324 + }
325 + }]
326 + }
327 + }
328 + });
287 // pieChart 329 // pieChart
288 - var red = {{ red }} 330 + // var red = {{ red }}
289 - var green = {{ green }} 331 + // var green = {{ green }}
290 - var blue = {{ blue }} 332 + // var blue = {{ blue }}
333 + // var test = 10;
334 + var Dos = {{ Dos }};
335 + var Overflow = {{ Overflow }};
336 + var XSS = {{ XSS }};
337 + var SqlInjection = {{ SqlInjection }};
338 + var CSRF = {{ CSRF }};
339 + var FileInclusion = {{ FileInclusion }};
340 + var MemoryCorruption = {{ MemoryCorruption }};
341 + var GainPrivilege = {{ GainPrivilege }};
342 + var ExecuteCode = {{ ExecuteCode }};
343 + var Bypasssomething = {{ Bypasssomething }};
291 344
292 var ctx = document.getElementById("pieChart").getContext('2d'); 345 var ctx = document.getElementById("pieChart").getContext('2d');
346 + // var ctx2 = document.getElementById("pieChart2").getContext('2d');
293 var data = { 347 var data = {
294 datasets: [{ 348 datasets: [{
295 - data: [red, green, blue], 349 + data: [Dos, Overflow, XSS, SqlInjection, CSRF, FileInclusion, MemoryCorruption, GainPrivilege, ExecuteCode, Bypasssomething],
296 backgroundColor: [ 350 backgroundColor: [
297 - 'rgba(255, 99, 132, 0.2)', 351 + 'rgba(50, 50, 50, 0.4)',
298 - 'rgba(54, 162, 235, 0.2)', 352 + 'rgba(0, 196, 0, 0.4)',
299 - 'rgba(255, 206, 86, 0.2)', 353 + 'rgba(255, 0, 0, 0.4)',
354 + 'rgba(255, 128, 0, 0.4)',
355 + 'rgba(100, 100, 0, 0.4)',
356 + 'rgba(0, 192, 192, 0.4)',
357 + 'rgba(96, 0, 255, 0.4)',
358 + 'rgba(200, 200, 0, 0.4)',
359 + 'rgba(0, 0, 255, 0.4)',
360 + 'rgba(255, 60, 60, 0.4)',
300 ], 361 ],
301 borderColor: [ 362 borderColor: [
302 - 'rgba(255,99,132,1)', 363 + 'rgba(50, 50, 50, 1)',
303 - 'rgba(54, 162, 235, 1)', 364 + 'rgba(0, 196, 0, 1)',
304 - 'rgba(255, 206, 86, 1)', 365 + 'rgba(255, 0, 0, 1)',
366 + 'rgba(255, 128, 0, 1)',
367 + 'rgba(100, 100, 0, 1)',
368 + 'rgba(0, 192, 192, 1)',
369 + 'rgba(96, 0, 255, 1)',
370 + 'rgba(100, 200, 100, 1)',
371 + 'rgba(0, 0, 255, 1)',
372 + 'rgba(255, 60, 60, 1)',
305 ], 373 ],
306 borderWidth: 1 374 borderWidth: 1
307 }], 375 }],
308 // These labels appear in the legend and in the tooltips when hovering different arcs 376 // These labels appear in the legend and in the tooltips when hovering different arcs
309 labels: [ 377 labels: [
310 - 'Red', 378 + 'DoS',
311 - 'Yellow', 379 + 'Overflow',
312 - 'Blue' 380 + 'XSS',
381 + 'Sql Injection',
382 + 'CSRF',
383 + 'File Inclusion',
384 + 'Memory Corruption',
385 + 'Gain Privilege',
386 + 'Execute Code',
387 + 'Bypass something'
313 ] 388 ]
314 }; 389 };
315 var options = { 390 var options = {
...@@ -326,5 +401,11 @@ ...@@ -326,5 +401,11 @@
326 data: data, 401 data: data,
327 options: options 402 options: options
328 }); 403 });
404 + // var myChart2 = new Chart(ctx2, {
405 + // type: 'pie',
406 + // data: data,
407 + // options: options
408 + // });
409 +
329 </script> 410 </script>
330 </html> 411 </html>
......
1 from django.conf.urls import url, include 1 from django.conf.urls import url, include
2 from myapp.views import * 2 from myapp.views import *
3 3
4 - 4 +app_name = 'myapp'
5 urlpatterns = [ 5 urlpatterns = [
6 url(r'^static/', StaticView.as_view(), name='static'), 6 url(r'^static/', StaticView.as_view(), name='static'),
7 url(r'^dynamic/', DynamicView.as_view(), name='dynamic'), 7 url(r'^dynamic/', DynamicView.as_view(), name='dynamic'),
8 -
9 ] 8 ]
......
...@@ -3,6 +3,7 @@ from django.views.generic import FormView ...@@ -3,6 +3,7 @@ from django.views.generic import FormView
3 from django.views.generic import View 3 from django.views.generic import View
4 from django.db import connection 4 from django.db import connection
5 from django.shortcuts import render 5 from django.shortcuts import render
6 +from django.http import JsonResponse
6 from django.http import HttpResponseRedirect 7 from django.http import HttpResponseRedirect
7 from .forms import UploadFileForm 8 from .forms import UploadFileForm
8 import re 9 import re
...@@ -53,7 +54,7 @@ class DynamicView(TemplateView): ...@@ -53,7 +54,7 @@ class DynamicView(TemplateView):
53 # print(str(line, 'UTF-8')) 54 # print(str(line, 'UTF-8'))
54 55
55 # r = re.compile('\@.+\@', ) 56 # r = re.compile('\@.+\@', )
56 - r = re.compile(r'\@(.+)\@', re.MULTILINE) 57 + r = re.compile(r'\@(.*?)\@', re.DOTALL)
57 results = r.findall(temp) 58 results = r.findall(temp)
58 59
59 result_list = dict(enumerate(results, 0)) 60 result_list = dict(enumerate(results, 0))
...@@ -87,10 +88,18 @@ class StaticView(TemplateView): ...@@ -87,10 +88,18 @@ class StaticView(TemplateView):
87 template_name = 'static.html' 88 template_name = 'static.html'
88 89
89 def get(self, request, *args, **kwargs): 90 def get(self, request, *args, **kwargs):
90 - context = {}
91 - context['form'] = testform
92 91
93 - query = 'SELECT * FROM vuln.vulnInfo' 92 + if request.is_ajax():
93 + data = 1
94 + idx = request.GET.get('idx')
95 + method = request.GET.get('method')
96 +
97 + print(idx)
98 + print(method)
99 + return JsonResponse(data, safe=False)
100 +
101 + context = {}
102 + query = 'SELECT * FROM vuln.vulnInfo LIMIT 50'
94 103
95 param_list = [] 104 param_list = []
96 105
...@@ -99,6 +108,8 @@ class StaticView(TemplateView): ...@@ -99,6 +108,8 @@ class StaticView(TemplateView):
99 108
100 columns = [column[0] for column in cursor.description] 109 columns = [column[0] for column in cursor.description]
101 110
111 + print(columns)
112 +
102 object_list = [] 113 object_list = []
103 114
104 for row in cursor.fetchall(): 115 for row in cursor.fetchall():
...@@ -125,27 +136,27 @@ class StaticView(TemplateView): ...@@ -125,27 +136,27 @@ class StaticView(TemplateView):
125 print(text) 136 print(text)
126 return render(self.request, self.template_name, context) 137 return render(self.request, self.template_name, context)
127 138
128 -class ServerList(View): 139 +# class ServerList(View):
129 - template_name = 'test.html' 140 +# template_name = 'test.html'
130 - 141 +#
131 - def get(self, request, *args, **kwargs): 142 +# def get(self, request, *args, **kwargs):
132 - 143 +#
133 - query = 'SELECT * FROM vuln.vulnInfo' 144 +# query = 'SELECT * FROM vuln.vulnInfo'
134 - param_list = [] 145 +# param_list = []
135 - 146 +#
136 - with connection.cursor() as cursor: 147 +# with connection.cursor() as cursor:
137 - cursor.execute(query, param_list) 148 +# cursor.execute(query, param_list)
138 - 149 +#
139 - columns = [column[0] for column in cursor.description] 150 +# columns = [column[0] for column in cursor.description]
140 - 151 +#
141 - for row in cursor.fetchall(): 152 +# for row in cursor.fetchall():
142 - object_list.append(dict(zip(columns, row))) 153 +# object_list.append(dict(zip(columns, row)))
143 - 154 +#
144 - context = {} 155 +# context = {}
145 - object_list = [] 156 +# object_list = []
146 - context['object_list'] = object_list 157 +# context['object_list'] = object_list
147 - 158 +#
148 - return render(self.request, self.template_name, context) 159 +# return render(self.request, self.template_name, context)
149 - 160 +#
150 -class TableView(TemplateView): 161 +# class TableView(TemplateView):
151 - template_name = 'myapp_table.html' 162 +# template_name = 'myapp_table.html'
......
1 +#!/bin/sh
2 +
3 +# Coded by N3wbieH4cker
4 +# bob3rdnewbie.tistory.com
5 +
6 +
7 +
8 +# check priv
9 +if [ "$EUID" -ne 0 ]
10 + then echo "root 권한으로 스크립트를 실행하여 주십시오."
11 + exit
12 +fi
13 +
14 +
15 +alias ls=ls
16 +CF=`hostname`"_scan_result_"`date +%F__%T`.txt
17 +
18 +echo > $CF 2>&1
19 +
20 +
21 +
22 +echo "**********************************************************************"
23 +echo "* 리눅스 취약점 진단 스크립트 *"
24 +echo "**********************************************************************"
25 +echo "* 항목에 따라 시간이 다른 항목에 비하여 다소 오래 걸릴수 있습니다 *"
26 +echo "* 스캔 보고서는 hostname_scan_result_시각.txt 파일로 저장 됩니다 *"
27 +echo "* 기준은 [주요 정보통신 기반 시설 취약점 분석,평가기준] 문서입니다 *"
28 +echo "**********************************************************************"
29 +echo ""
30 +
31 +sleep 3
32 +
33 +
34 +echo "**********************************************************************" >> $CF 2>&1
35 +echo "* 리눅스 스크립트 *" >> $CF 2>&1
36 +echo "**********************************************************************" >> $CF 2>&1
37 +echo "" >> $CF 2>&1
38 +
39 +
40 +echo "############################# 시작 시간 ##############################"
41 +date
42 +
43 +
44 +echo "############################# 시작 시간 ##############################" >> $CF 2>&1
45 +date >> $CF 2>&1
46 +
47 +
48 +echo "============================ 시스템 정보 ===========================" >> $CF 2>&1
49 +echo >> $CF 2>&1
50 +
51 +echo "1. 시스템 기본 정보" >> $CF 2>&1
52 +echo " 운영체제 : " `head -n 1 /etc/centos-release` >> $CF 2>&1
53 +echo " 호스트 이름 : " `uname -n` >> $CF 2>&1
54 +echo " 커널 버전 : " `uname -r` >> $CF 2>&1
55 +echo >> $CF 2>&1
56 +
57 +echo "2. 네트워크 정보" >> $CF 2>&1
58 +ifconfig -a >> $CF 2>&1
59 +echo >> $CF 2>&1
60 +
61 +echo
62 +echo
63 +echo >> $CF 2>&1
64 +echo >> $CF 2>&1
65 +
66 +echo "************************** 취약점 체크 시작 **************************"
67 +echo
68 +
69 +
70 +echo "************************** 취약점 체크 시작 **************************" >> $CF 2>&1
71 +echo >> $CF 2>&1
72 +echo >> $CF 2>&1
73 +
74 +
75 +echo "============================== 계정 관리 ============================="
76 +echo "============================== 계정 관리 =============================" >> $CF 2>&1
77 +
78 +echo "01. root 계정 원격 접속 제한"
79 +echo "01. root 계정 원격 접속 제한" >> $CF 2>&1
80 +
81 +if [ -z "`grep -v tty\? /etc/securetty`" ]
82 + then
83 + echo " ==> [안전] 콘솔 로그인만 가능합니다" >> $CF 2>&1
84 + else
85 + echo " ==> [취약] 콘솔 로그인 이외의 로그인이 가능합니다" >> $CF 2>&1
86 +fi
87 +echo >> $CF 2>&1
88 +echo
89 +
90 +echo "02. 패스워드 복합성 설정(및 정책)"
91 +echo "02. 패스워드 복합성 설정(및 정책)" >> $CF 2>&1
92 +
93 +echo " ==> 알고리즘 : `authconfig --test | grep hashing | awk '{print $5}'`" >> $CF 2>&1
94 +echo " ==> 최대 사용 기간 : `cat /etc/login.defs | grep PASS_MAX_DAYS | awk '{print $2}' | sed '1d'`일" >> $CF 2>&1
95 +echo " ==> 최소 사용 시간 : `cat /etc/login.defs | grep PASS_MIN_DAYS | awk '{print $2}' | sed '1d'`일" >> $CF 2>&1
96 +echo " ==> 최소 길이 : `cat /etc/login.defs | grep PASS_MIN_LEN | awk '{print $2}' | sed '1d'`글자" >> $CF 2>&1
97 +echo " ==> 기간 만료 경고 기간(일) : `cat /etc/login.defs | grep PASS_WARN_AGE | awk '{print $2}' | sed '1d'`일" >> $CF 2>&1
98 +
99 +echo >> $CF 2>&1
100 +echo
101 +
102 +
103 +echo "03. 계정 잠금 (임계값) 설정"
104 +echo "03. 계정 잠금 (임계값) 설정" >> $CF 2>&1
105 +
106 +TI=`grep deny= /etc/pam.d/password-auth | awk '{print $5}' | awk -F = '{print $2}'`
107 +
108 +if [ "`grep deny= /etc/pam.d/password-auth`" ]
109 + then
110 + echo " ==> [안전] "$TI"번 로그인 실패시 계정이 잠김니다" >> $CF 2>&1
111 + else
112 + echo " ==> [취약] 계정 잠금 정책이 설정되어 있지 않습니다" >> $CF 2>&1
113 +fi
114 +
115 +echo >> $CF 2>&1
116 +echo
117 +
118 +
119 +echo "04. 패스워드 파일 보호"
120 +echo "04. 패스워드 파일 보호" >> $CF 2>&1
121 +
122 +if [ "`cat /etc/passwd | grep "root" | awk -F: '{print $2}' | sed -n '1p'`" = x ]
123 + then
124 + if test -r /etc/shadow
125 + then
126 + echo " ==> [안전] Shadow 패스워드 시스템을 사용중입니다" >> $CF 2>&1
127 + else
128 + echo " ==> [취약] Passwd 패스워드 시스템을 사용중입니다" > $CF 2>&1
129 + fi
130 +fi
131 +echo >> $CF 2>&1
132 +
133 +
134 +
135 +
136 +echo " 04-1. /etc/passwd" >> $CF 2>&1
137 +
138 +PP=`ls -l /etc/passwd | awk {'print $1'}`
139 +PO=`ls -l /etc/passwd | awk {'print $3'}`
140 +PG=`ls -l /etc/passwd | awk {'print $4'}`
141 +
142 +if [ $PP = -r--r--r--. ]
143 + then
144 + echo " ==> [안전] 권한 : " $PP >> $CF 2>&1
145 +else
146 + if [ $PP = -rw-r--r--. ]
147 + then
148 + echo " ==> [안전] 권한 : " $PP >> $CF 2>&1
149 + else
150 + echo " ==> [취약] 권한 : " $PP >> $CF 2>&1
151 + fi
152 +fi
153 +
154 +if [ $PO = root ]
155 + then
156 + echo " ==> [안전] 소유자 : " $PO >> $CF 2>&1
157 + else
158 + echo " ==> [취약] 소유자 : " $PO >> $CF 2>&1
159 +fi
160 +
161 +if [ $PG = root ]
162 + then
163 + echo " ==> [안전] 그룹 : " $PO >> $CF 2>&1
164 + else
165 + echo " ==> [취약] 그룹 : " $PO >> $CF 2>&1
166 +fi
167 +
168 +echo >> $CF 2>&1
169 +
170 +
171 +
172 +
173 +
174 +echo " 04-2. /etc/shadow" >> $CF 2>&1
175 +
176 +if test `ls -l /etc/shadow | awk {'print $1'} ` = -r--------.
177 + then
178 + echo " ==> [안전] 권한 : "`ls -l /etc/shadow | awk {'print $1'}` >> $CF 2>&1
179 +else
180 + if test `ls -l /etc/shadow | awk {'print $1'} ` = ----------.
181 + then
182 + echo " ==> [안전] 권한 : "`ls -l /etc/shadow | awk {'print $1'}` >> $CF 2>&1
183 + else
184 + echo " ==> [취약] 권한 : "`ls -l /etc/shadow | awk {'print $1'}` >> $CF 2>&1
185 + fi
186 +fi
187 +
188 +
189 +
190 +if test `ls -l /etc/shadow | awk {'print $3'}` = root
191 + then
192 + echo " ==> [안전] 소유자 : " `ls -l /etc/shadow | awk {'print $3'}` >> $CF 2>&1
193 + else
194 + echo " ==> [취약] 소유자 : " `ls -l /etc/shadow | awk {'print $3'}` >> $CF 2>&1
195 +fi
196 +
197 +
198 +if test `ls -l /etc/shadow | awk {'print $4'} ` = root
199 + then
200 + echo " ==> [안전] 그룹 : "`ls -l /etc/shadow | awk {'print $4'}` >> $CF 2>&1
201 + else
202 + echo " ==> [취약] 그룹 : "`ls -l /etc/shadow | awk {'print $4'}` >> $CF 2>&1
203 +fi
204 +
205 +echo >> $CF 2>&1
206 +echo >> $CF 2>&1
207 +
208 +echo
209 +echo
210 +
211 +
212 +
213 +
214 +
215 +echo "======================= 파일 및 디렉터리 관리 ========================"
216 +echo "======================= 파일 및 디렉터리 관리=========================" >> $CF 2>&1
217 +
218 +echo "05. root홈, 패스 디렉터리 권한 및 패스 설정"
219 +echo "05. root홈, 패스 디렉터리 권한 및 패스 설정" >> $CF 2>&1
220 +echo " root 홈 디렉터리 : " `cat /etc/passwd | grep root | sed -n '1p' | awk -F: '{print $6}'` >> $CF 2>&1
221 +
222 +GRDP=`cat /etc/passwd | grep root | sed -n '1p' | awk -F: '{print$6}' | ls -l /../ | awk '{print $1$8}' | grep root | awk -F. '{print $1}'`
223 +RDP=dr-xr-x---
224 +
225 +if test $GRDP=$RDP
226 + then
227 + echo " ==> [안전] root 홈 디렉터리 권한 : " $GRDP >> $CF 2>&1
228 + else
229 + echo " ==> [취약] root 홈 권한 : " $GRDP >> $CF 2>&1
230 +fi
231 +
232 +echo " PATH 디렉터리 : " `env | grep PATH | awk -F= '{print $2}'` >> $CF 2>&1
233 +echo
234 +echo >> $CF 2>&1
235 +
236 +echo "06. 파일 및 디렉터리 소유자 설정"
237 +echo "06. 파일 및 디렉터리 소유자 설정" >> $CF 2>&1
238 +
239 +if test -f `find / \( -nouser -o -nogroup \) -xdev -ls 2>/dev/null`
240 + then
241 + echo " ==> [안전] 소유자 혹은 그룹이 없는 파일 및 디렉터리가 존재하지 않습니다" >> $CF 2>&1
242 + else
243 + echo " ==> [취약] 소유자 혹은 그룹이 없는 파일 및 디렉터리가 존재합니다" >> $CF 2>&1
244 +fi
245 +
246 +
247 +
248 +echo
249 +echo >> $CF 2>&1
250 +
251 +echo "07. /etc/passwd 파일 소유자 및 권한 설정"
252 +echo "07. /etc/passwd 파일 소유자 및 권한 설정" >> $CF 2>&1
253 +echo " 04-01 항목 참고" >> $CF 2>&1
254 +echo
255 +echo >> $CF 2>&1
256 +
257 +
258 +echo "08. /etc/shadow 파일 소유자 및 권한 설정"
259 +echo "08. /etc/shadow 파일 소유자 및 권한 설정" >> $CF 2>&1
260 +echo " 04-02 항목 참고" >> $CF 2>&1
261 +echo
262 +echo >> $CF 2>&1
263 +
264 +echo "09. /etc/hosts 파일 소유자 및 권한 설정"
265 +echo "09. /etc/hosts 파일 소유자 및 권한 설정" >> $CF 2>&1
266 +
267 +HO=`ls -l /etc/hosts | awk '{print $3}'`
268 +HP=`ls -l /etc/hosts | awk '{print $1}'`
269 +
270 +if [ $HO = root ]
271 + then
272 + echo " ==> [안전] hosts 파일 소유자 : " $HO >> $CF 2>&1
273 + else
274 + echo " ==> [취약] hosts 파일 소유자 : " $HO >> $CF 2>&1
275 +fi
276 +
277 +if [ $HP = -rw-------. ]
278 + then
279 + echo " ==> [안전] hosts 파일 권한 : " $HP >> $CF 2>&1
280 + else
281 + echo " ==> [취약] hosts 파일 권한 : " $HP >> $CF 2>&1
282 +fi
283 +
284 +echo
285 +echo >> $CF 2>&1
286 +
287 +
288 +echo "10. /etc/(x)inetd.conf 파일 소유자 및 권한 설정"
289 +echo "10. /etc/(x)inetd.conf 파일 소유자 및 권한 설정" >> $CF 2>&1
290 +
291 +if test -f /etc/inetd.conf
292 + then
293 + echo " [OOOO] inetd.conf 파일이 존재합니다" >> $CF 2>&1
294 + IO=`ls -l /etc/inetd.conf | awk '{print $3}'`
295 + IP=`ls -l /etc/inetd.conf | awk '{print $1}'`
296 +
297 + if [ $IO = root ]
298 + then
299 + echo " ==> [안전] inetd.conf 파일 소유자 : " $IO >> $CF 2>&1
300 + else
301 + echo " ==> [취약] inetd.conf 파일 소유자 : " $IO >> $CF 2>&1
302 + fi
303 +
304 + if [ $IP = -rw-------. ]
305 + then
306 + echo " ==> [안전] inetd.conf 파일 권한 : " $IP >> $CF 2>&1
307 + else
308 + echo " ==> [취약] inetd.conf 파일 권한 : " $IP >> $CF 2>&1
309 + fi
310 +
311 +else
312 + echo " [XXXX] inetd.conf 파일이 존재하지 않습니다" >> $CF 2>&1
313 + echo >> $CF 2>&1
314 +fi
315 +
316 +
317 +if test -f /etc/xinetd.conf
318 + then
319 + echo " [OOOO] xinetd.conf 파일이 존재합니다" >> $CF 2>&1
320 + XO=`ls -l /etc/xinetd.conf | awk '{print $3}'`
321 + XP=`ls -l /etc/xinetd.conf | awk '{print $1}'`
322 +
323 + if [ $XO = root ]
324 + then
325 + echo " ==> [안전] xinetd.conf 파일 소유자 : " $XO >> $CF 2>&1
326 + else
327 + echo " ==> [취약] xinetd.conf 파일 소유자 : " $XO >> $CF 2>&1
328 + fi
329 +
330 + if [ $XP = -rw-------. ]
331 + then
332 + echo " ==> [안전] xinetd.conf 파일 권한 : " $XP >> $CF 2>&1
333 + else
334 + echo " ==> [취약] xinetd.conf 파일 권한 : " $XP >> $CF 2>&1
335 + fi
336 +
337 +else
338 + echo " [XXXX] xinetd.conf 파일이 존재하지 않습니다" >> $CF 2>&1
339 +fi
340 +
341 +echo
342 +echo >> $CF 2>&1
343 +
344 +echo "11. /etc/(r)syslog.conf 파일 소유자 및 권한 설정"
345 +echo "11. /etc/(r)syslog.conf 파일 소유자 및 권한 설정" >> $CF 2>&1
346 +
347 +
348 +if test -f /etc/syslog.conf
349 + then
350 + echo " [OOOO] syslog.conf 파일이 존재합니다" >> $CF 2>&1
351 + IO=`ls -l /etc/syslog.conf | awk '{print $3}'`
352 + IP=`ls -l /etc/syslog.conf | awk '{print $1}'`
353 +
354 + if [ $IO = root ]
355 + then
356 + echo " ==> [안전] syslog.conf 파일 소유자 : " $IO >> $CF 2>&1
357 + else
358 + echo " ==> [취약] syslog.conf 파일 소유자 : " $IO >> $CF 2>&1
359 + fi
360 +
361 + if [ $IP = -rw-r--r--. ]
362 + then
363 + echo " ==> [안전] syslog.conf 파일 권한 : " $IP >> $CF 2>&1
364 + else
365 + echo " ==> [취약] syslog.conf 파일 권한 : " $IP >> $CF 2>&1
366 + fi
367 +
368 +else
369 + echo " [XXXX] syslog.conf 파일이 존재하지 않습니다" >> $CF 2>&1
370 + echo >> $CF 2>&1
371 +fi
372 +
373 +
374 +if test -f /etc/rsyslog.conf
375 + then
376 + echo " [OOOO] rsyslog.conf 파일이 존재합니다" >> $CF 2>&1
377 + XO=`ls -l /etc/rsyslog.conf | awk '{print $3}'`
378 + XP=`ls -l /etc/rsyslog.conf | awk '{print $1}'`
379 +
380 + if [ $XO = root ]
381 + then
382 + echo " ==> [안전] rsyslog.conf 파일 소유자 : " $XO >> $CF 2>&1
383 + else
384 + echo " ==> [취약] rsyslog.conf 파일 소유자 : " $XO >> $CF 2>&1
385 + fi
386 +
387 + if [ $XP = -rw-r--r--. ]
388 + then
389 + echo " ==> [안전] rsyslog.conf 파일 권한 : " $XP >> $CF 2>&1
390 + else
391 + echo " ==> [취약] rsyslog.conf 파일 권한 : " $XP >> $CF 2>&1
392 + fi
393 +
394 +else
395 + echo " [XXXX] rsyslog.conf 파일이 존재하지 않습니다" >> $CF 2>&1
396 +fi
397 +
398 +echo
399 +echo >> $CF 2>&1
400 +
401 +echo "12. /etc/services 파일 소유자 및 권한 설정"
402 +echo "12. /etc/services 파일 소유자 및 권한 설정" >> $CF 2>&1
403 +
404 +SO=`ls -l /etc/services | awk '{print $3}'`
405 +SP=`ls -l /etc/services | awk '{print $1}'`
406 +
407 +if [ $SO = root ]
408 + then
409 + echo " ==> [안전] services 파일 소유자 : " $SO >> $CF 2>&1
410 + else
411 + echo " ==> [취약] services 파일 소유자 : " $SO >> $CF 2>&1
412 +fi
413 +
414 +if [ $SP = -rw-r--r--. ]
415 + then
416 + echo " ==> [안전] services 파일 권한 : " $SP >> $CF 2>&1
417 + else
418 + echo " ==> [취약] services 파일 권한 : " $SP >> $CF 2>&1
419 +fi
420 +
421 +echo
422 +echo >> $CF 2>&1
423 +
424 +echo "13. SetUID, SetGID, Sticky Bit 설정 파일 검사"
425 +echo "13. SetUID, SetGID, Sticky Bit 설정 파일 검사" >> $CF 2>&1
426 +
427 +SF="13-1.SetUID.txt"
428 +SG="13-2.SetGID.txt"
429 +SB="13-3.Sticky_Bit.txt"
430 +
431 +find / -user root -perm -4000 2>/dev/null > $SF
432 +find / -user root -perm -2000 2>/dev/null > $SG
433 +find / -user root -perm -1000 2>/dev/null > $SB
434 +
435 +echo " 스캔 후 생성된 13-1, 13-2, 13-3.txt 파일을 참고하여 파일을 검사" >> $CF 2>&1
436 +
437 +echo
438 +echo >> $CF 2>&1
439 +
440 +echo "14. 사용자, 시스템 시작파일 및 환경파일 소유자 및 권한 설정"
441 +echo "14. 사용자, 시스템 시작파일 및 환경파일 소유자 및 권한 설정" >> $CF 2>&1
442 +
443 +echo " 서버 환경마다 파일들이 다르기 때문에 이를 스크립트로 체크할 경우 오탐 발생이 높음" >> $CF 2>&1
444 +echo " 따라서 수동적인 체크가 필요" >> $CF 2>&1
445 +echo " ==> [권장] 체크 후, 해당 파일이 root와 소유자만이 w 권한이 있도록 설정" >> $CF 2>&1
446 +echo " 수동적인 체크 후, 해당 파일이 root와 소유자 이외에도 w 권한이 있다면 [취약]하다고 판단할 수 있음" >> $CF 2>&1
447 +echo
448 +echo >> $CF 2>&1
449 +
450 +echo "15. world writable 파일 점검"
451 +echo "15. world writable 파일 점검" >> $CF 2>&1
452 +WW="15-1.World_Writable.txt"
453 +find / -perm -2 -ls 2>/dev/null | awk {'print $3, $11'} > $WW
454 +echo " 생성된 15-1.txt 및 보고서 파일 참조" >> $CF 2>&1
455 +echo " 이 또한 서버 환경마다 다르기 때문에 수동적인 체크가 필요함" >> $CF 2>&1
456 +echo " 다만 기본적으로 시스템에 설치되는 world writable 파일 자체가 상당히 많기 때문에, " >> $CF 2>&1
457 +echo " 15-1.txt 목록(혹시 모를 악의적인 파일 포함)과 기본적으로 생성되는 world writable 파일 간의 비교가 필요함" >> $CF 2>&1
458 +echo
459 +echo >> $CF 2>&1
460 +
461 +echo "16. /dev에 존재하지 않는 device 파일 점검"
462 +echo "16. /dev에 존재하지 않는 device 파일 점검" >> $CF 2>&1
463 +DF="16-1.Device_file.txt"
464 +find /dev -type f -exec ls -l {} \; | awk '{print $1, $8}' > $DF
465 +echo " 생성된 16-1.Device_file.txt 및 보고서 파일 참조" >> $CF 2>&1
466 +echo " 마찬가지로 서버의 환경마다 다르기 때문에 수동적인 체크가 필요함" >> $CF 2>&1
467 +echo
468 +echo >> $CF 2>&1
469 +
470 +echo "17. $HOME/.rhosts, hosts.equiv 사용 금지"
471 +echo "17. $HOME/.rhosts, hosts.equiv 사용 금지" >> $CF 2>&1
472 +
473 +if test -f `ls -l $HOME/.rhosts 2>/dev/null`
474 + then
475 + if test -f `ls -l hosts.equiv 2>/dev/null`
476 + then
477 + echo " ==> [안전] 해당 서비스가 활성화 되어 있지 않습니다" >> $CF 2>&1
478 + else
479 + echo " ==> [취약] 해당 서비스가 활성화 되어 있습니다" >> $CF 2>&1
480 + fi
481 + else
482 + echo " ==> [취약] 해당 서비스가 활성화 되어 있습니다" >> $CF 2>&1
483 +fi
484 +echo
485 +echo >> $CF 2>&1
486 +
487 +echo "18. 접속 IP 및 포트 제한"
488 +echo "18. 접속 IP 및 포트 제한" >> $CF 2>&1
489 +AL="18-1.hosts.allow.txt"
490 +AD="18-2.hosts.deny.txt"
491 +cat /etc/hosts.allow 2>/dev/null > $AL
492 +cat /etc/hosts.deny > $AD
493 +
494 +echo " 생성된 18-1, 18-2.txt 참조" >> $CF 2>&1
495 +echo " allow는 서버에 접속을 허용할 IP 목록 및 서비스가 들어있음" >> $CF 2>&1
496 +echo " deny는 서버에 접속을 거부할 IP 목록 및 서비스가 들어있음" >> $CF 2>&1
497 +echo " 일반적으로 deny 파일의 우선순위가 높음" >> $CF 2>&1
498 +echo
499 +echo >> $CF 2>&1
500 +echo
501 +echo >> $CF 2>&1
502 +
503 +
504 +echo "============================= 서비스 관리 ============================"
505 +echo "============================= 서비스 관리 ============================" >> $CF 2>&1
506 +
507 +echo "19. Finger 서비스 비활성화"
508 +echo "19. Finger 서비스 비활성화" >> $CF 2>&1
509 +
510 +if test -f /etc/xinetd.d/finger
511 + then
512 + if [ "`cat /etc/xinetd.d/finger | grep disable | awk '{print $3}'`" = yes ]
513 + then
514 + echo " ==> [안전] finger 서비스가 설치되어 있으나 비활성화 되어 있습니다" >> $CF 2>&1
515 + else
516 + echo " ==> [취약] finger 서비스가 설치되어 있고, 활성화 되어 있습니다" >> $CF 2>&1
517 + fi
518 + else
519 + echo " ==> [안전] finger 서비스가 설치되어 있지 않습니다" >> $CF 2>&1
520 +fi
521 +
522 +echo
523 +echo >> $CF 2>&1
524 +
525 +echo "20. Anonymous FTP 비활성화"
526 +echo "20. Anonymous FTP 비활성화" >> $CF 2>&1
527 +
528 +if test -f /etc/vsftpd/vsftpd.conf
529 + then
530 + if [ "`cat /etc/vsftpd/vsftpd.conf | grep anonymous_enable | awk -F= '{print $2}'`" = NO ]
531 + then
532 + echo " ==> [안전] FTP에 익명 접속이 불가능합니다" >> $CF 2>&1
533 + else
534 + echo " ==> [취약] FTP에 익명 접속이 가능합니다" >> $CF 2>&1
535 + fi
536 + else
537 + echo " [XXXX] FTP 서비스가 설치되어 있지 않습니다" >> $CF 2>&1
538 +fi
539 +
540 +echo
541 +echo >> $CF 2>&1
542 +
543 +echo "21. r 계열 서비스 비활성화"
544 +echo "21. r 계열 서비스 비활성화" >> $CF 2>&1
545 +
546 +echo " 스크립트 상의 진단은 rlogin만 진행" >> $CF 2>&1
547 +echo " 기타 r 계열 서비스 목록은 21-1. r services.txt 에서 확인" >> $CF 2>&1
548 +
549 +if test -f /etc/xinetd.d/rlogin
550 + then
551 + if [ "`cat /etc/xinetd.d/rlogin | grep disable | awk '{print $3}'`" = yes ]
552 + then
553 + echo " ==> [안전] rlogin 서비스가 설치되어 있으나 비활성화 되어 있습니다" >> $CF 2>&1
554 + else
555 + echo " ==> [취약] rlogin 서비스가 설치되어 있고, 활성화 되어 있습니다" >> $CF 2>&1
556 + fi
557 + else
558 + echo " ==> [안전] rlogin 서비스가 설치되어 있지 않습니다" >> $CF 2>&1
559 +fi
560 +
561 +RS="21-1.r services.txt"
562 +ls /etc/xinetd.d/r* 2>/dev/null > $RS
563 +
564 +
565 +echo
566 +echo >> $CF 2>&1
567 +
568 +echo "22. cron 파일 소유자 및 권한 설정"
569 +echo "22. cron 파일 소유자 및 권한 설정" >> $CF 2>&1
570 +
571 +if test -f /etc/cron.allow
572 + then
573 + echo " [OOOO] cron.allow 파일이 존재합니다" >> $CF 2>&1
574 + CO=`ls -l /etc/cron.allow | awk '{print $3}'`
575 + CP=`ls -l /etc/cron.allow | awk '{print $1}'`
576 +
577 + if [ $CO = root ]
578 + then
579 + echo " ==> [안전] cron.allow 파일 소유자 : " $CO >> $CF 2>&1
580 + else
581 + echo " ==> [취약] cron.allow 파일 소유자 : " $CO >> $CF 2>&1
582 + fi
583 +
584 + if [ $CP = -rw-------. ]
585 + then
586 + echo " ==> [안전] cron.allow 파일 권한 : " $CP >> $CF 2>&1
587 +
588 + else
589 + if [ $CP = -rw-r--r--. ]
590 + then
591 + echo " ==> [안전] cron.allow 파일 권한 : " $CP >> $CF 2>&1
592 + else
593 + echo " ==> [취약] cron.allow 파일 권한 : " $CP >> $CF 2>&1
594 + fi
595 + fi
596 +
597 +else
598 + echo " [XXXX] cron.allow 파일이 존재하지 않습니다" >> $CF 2>&1
599 + echo >> $CF 2>&1
600 +fi
601 +
602 +
603 +if test -f /etc/cron.deny
604 + then
605 + echo " [OOOO] cron.deny 파일이 존재합니다" >> $CF 2>&1
606 + CO=`ls -l /etc/cron.deny | awk '{print $3}'`
607 + CP=`ls -l /etc/cron.deny | awk '{print $1}'`
608 +
609 + if [ $CO = root ]
610 + then
611 + echo " ==> [안전] cron.deny 파일 소유자 : " $CO >> $CF 2>&1
612 + else
613 + echo " ==> [취약] cron.deny 파일 소유자 : " $CO >> $CF 2>&1
614 + fi
615 +
616 + if [ $CP = -rw-------. ]
617 + then
618 + echo " ==> [안전] cron.deny 파일 권한 : " $CP >> $CF 2>&1
619 +
620 + else
621 + if [ $CP = -rw-r--r--. ]
622 + then
623 + echo " ==> [안전] cron.deny 파일 권한 : " $CP >> $CF 2>&1
624 + else
625 + echo " ==> [취약] cron.deny 파일 권한 : " $CP >> $CF 2>&1
626 + fi
627 + fi
628 +
629 +else
630 + echo " [XXXX] cron.deny 파일이 존재하지 않습니다" >> $CF 2>&1
631 + echo >> $CF 2>&1
632 +fi
633 +
634 +echo
635 +echo >> $CF 2>&1
636 +
637 +
638 +echo "23. DoS 공격에 취약한 서비스 비활성화"
639 +echo "23. DoS 공격에 취약한 서비스 비활성화" >> $CF 2>&1
640 +echo " DoS 공격에 취약하다고 알려진 서비스들은 (echo, discard, daytime, chargen) 등이 있음" >> $CF 2>&1
641 +
642 +ET=`cat /etc/services | grep echo | sed -n '1p' | awk '{print $1}'`
643 +DT=`cat /etc/services | grep discard | sed -n '1p' | awk '{print $1}'`
644 +TT=`cat /etc/services | grep daytime | sed -n '1p' | awk '{print $1}'`
645 +CT=`cat /etc/services | grep chargen | sed -n '1p' | awk '{print $1}'`
646 +
647 +
648 +if [ $ET = \#echo ]
649 + then
650 + echo " ==> [안전] echo 서비스가 비활성화 되어 있습니다" >> $CF 2>&1
651 + else
652 + echo " ==> [취약] echo 서비스가 활성화 되어 있습니다" >> $CF 2>&1
653 +fi
654 +
655 +if [ $DT = \#discard ]
656 + then
657 + echo " ==> [안전] discard 서비스가 비활성화 되어 있습니다" >> $CF 2>&1
658 + else
659 + echo " ==> [취약] discard 서비스가 활성화 되어 있습니다" >> $CF 2>&1
660 +fi
661 +
662 +if [ $TT = \#daytime ]
663 + then
664 + echo " ==> [안전] daytime 서비스가 비활성화 되어 있습니다" >> $CF 2>&1
665 + else
666 + echo " ==> [취약] daytime 서비스가 활성화 되어 있습니다" >> $CF 2>&1
667 +fi
668 +
669 +
670 +if [ $ET = \#chargen ]
671 + then
672 + echo " ==> [안전] chargen 서비스가 비활성화 되어 있습니다" >> $CF 2>&1
673 + else
674 + echo " ==> [취약] chargen 서비스가 활성화 되어 있습니다" >> $CF 2>&1
675 +fi
676 +
677 +echo
678 +echo >> $CF 2>&1
679 +
680 +echo "24. NFS 서비스 비활성화"
681 +echo "24. NFS 서비스 비활성화" >> $CF 2>&1
682 +NC=`systemctl is-enabled nfs 2>/dev/null`
683 +
684 +if [[ "enable" == "$NC" ]]
685 + then
686 + echo " ==> [취약] NFS 서비스가 활성화 되어 있습니다" >> $CF 2>&1
687 +
688 +elif [[ "disable" == "$NC" ]]
689 + then
690 + echo " ==> [안전] NFS 서비스가 비활성화 되어 있습니다" >> $CF 2>&1
691 +else
692 + echo " [XXXX] NFS 서비스가 설치 되어 있지 않습니다" >> $CF 2>&1
693 +fi
694 +
695 +echo
696 +echo >> $CF 2>&1
697 +
698 +
699 +echo "25. NFS 접근통제"
700 +echo "25. NFS 접근통제" >> $CF 2>&1
701 +echo " 24번 항목에서 NFS를 비활성화 하는 것을 권장하지만 사용해야 할 경우에는 적절한 접근통제가 필요함" >> $CF 2>&1
702 +echo " 이 경우 관리자(=root)가 NFS 서비스를 설치하면서 공유 디렉터리를 임의로 지정하기 때문에 스크립트로 체크가 불가능" >> $CF 2>&1
703 +echo " ==> [권장] 해당 공유 디렉터리의 권한이 적절한지 수동으로 체크" >> $CF 2>&1
704 +echo
705 +echo >> $CF 2>&1
706 +
707 +
708 +echo "26. automountd 제거"
709 +echo "26. automountd 제거" >> $CF 2>&1
710 +echo " 본 항목은 리눅스가 아닌 유닉스에만 존재함" >> $CF 2>&1
711 +echo
712 +echo >> $CF 2>&1
713 +
714 +
715 +echo "27. RPC 서비스 확인"
716 +echo "27. RPC 서비스 확인" >> $CF 2>&1
717 +echo " 다음과 같은 서비스를 제한 (단, 플랫폼에 따라 서비스 명이 다소 다를 수 있음)" >> $CF 2>&1
718 +echo " {sadmin, rpc.*, rquotad, shell. login. exec, talk, time, discard, chargen}" >> $CF 2>&1
719 +echo " {printer, uucp, echo, daytime, dtscpt, finger}" >> $CF 2>&1
720 +echo >> $CF 2>&1
721 +echo " ==> [권장] 위싀 서비스들을 중지하거나, 최신 버전의 패치 적용" >> $CF 2>&1
722 +echo " 위의 서비스들을 중지하거나, 최신 버전의 패치를 적용했을 경우 [안전] 하다고 판단" >> $CF 2>&1
723 +echo " 위의 서비스들을 사용하거나, 최신 버전의 패치를 적용하지 않았을 경우 [취약] 하다고 판단" >> $CF 2>&1
724 +echo
725 +echo >> $CF 2>&1
726 +
727 +
728 +echo "28. NIS, NIS+ 점검"
729 +echo "28. NIS, NIS+ 점검" >> $CF 2>&1
730 +echo " 관리자의 수동적인 점검이 필요함" >> $CF 2>&1
731 +echo " ==> [권장] NIS 보다 데이터 인증이 강화된 NIS+ 사용" >> $CF 2>&1
732 +echo " 점검 후 NIS 보다 데이터 인증이 강화된 NIS+ 사용한다면 [안전] 하다고 판단" >> $CF 2>&1
733 +echo " 점검 후 기본적인 NIS를 사용한다면 [취약] 하다고 판단" >> $CF 2>&1
734 +echo
735 +echo >> $CF 2>&1
736 +
737 +
738 +echo "29. tftp, talk 서비스 비활성화"
739 +echo "29. tftp, talk 서비스 비활성화" >> $CF 2>&1
740 +
741 +
742 +TP=`cat /etc/services | grep tftp | sed -n '1p' | awk '{print $1}'`
743 +TK=`cat /etc/services | grep talk | sed -n '1p' | awk '{print $1}'`
744 +
745 +if [ $TP = \#tftp ]
746 + then
747 + echo " ==> [안전] tftp 서비스가 비활성화 되어 있습니다" >> $CF 2>&1
748 + else
749 + echo " ==> [취약] tftp 서비스가 활성화 되어 있습니다" >> $CF 2>&1
750 +fi
751 +
752 +if [ $TK = \#talk ]
753 + then
754 + echo " ==> [안전] talk 서비스가 비활성화 되어 있습니다" >> $CF 2>&1
755 + else
756 + echo " ==> [취약] talk 서비스가 활성화 되어 있습니다" >> $CF 2>&1
757 +fi
758 +
759 +echo
760 +echo >> $CF 2>&1
761 +
762 +
763 +echo "30. Sendmail 버전 점검"
764 +echo "30. Sendmail 버전 점검" >> $CF 2>&1
765 +SI=`yum list installed | grep sendmail | awk '{print $1}'`
766 +
767 +if [ $SI ]
768 + then
769 + SV=`echo \$Z | /usr/lib/sendmail -bt -d0 | sed -n '1p' | awk '{print $2}'`
770 + echo " [OOOO] 설치된 sendmail의 버전은 $SV 입니다" >> $CF 2>&1
771 + echo " ==> [권장] 최신 버전의 설치 및 업그레이드를 위해 sendmail 데몬의 중지가 필요하기 때문에 적절한 시간대에 수행해야 함" >> $CF 2>&1
772 + else
773 + echo " [XXXX] sendmail이 설치되어 있지 않습니다 " >> $CF 2>&1
774 +fi
775 +
776 +echo
777 +echo >> $CF 2>&1
778 +
779 +
780 +echo "31. 스팸 메일 릴레이 제한"
781 +echo "31. 스팸 메일 릴레이 제한" >> $CF 2>&1
782 +
783 +if [ $SI ]
784 + then
785 + SP=`ls -l /etc/mail/access | awk '{print $1}'`
786 + if [ $SP ]
787 + then
788 + SP=`ls -l /etc/mail/access | awk '{print $1}'`
789 + echo " ==> [안전] 스팸 메일 관련 설정 사항이 저장된 파일이 존재합니다" >> $CF 2>&1
790 + echo " ==> [진행] 해당 파일을 DB화 시켜 sendmail 데몬에 인식시키는 작업을 수행합니다" >> $CF 2>&1
791 + makemap hash /etc/mail/access < /etc/mail/access
792 + echo " ==> [완료] 작업을 완료하였습니다" >> $CF 2>&1
793 + else
794 + echo " ==> [취약] 스팸 메일 관련 설정 사항이 명시 된 파일이 존재하지 않습니다" >> $CF 2>&1
795 + fi
796 + else
797 + echo " [XXXX] sendmail이 설치되어 있지 않습니다" >> $CF 2>&1
798 +fi
799 +
800 +echo
801 +echo >> $CF 2>&1
802 +
803 +
804 +echo "32. 일반사용자의 Sendmail 실행 방지"
805 +echo "32. 일반사용자의 Sendmail 실행 방지" >> $CF 2>&1
806 +
807 +if [ $SI ]
808 + then
809 + SV=`cat /etc/mail/sendmail.cf | grep PrivacyOptions | awk -F= '{print $2}'`
810 +
811 + if [ $SV = authwarnings,novrfy,noexpn,restrictqrun ]
812 + then
813 + echo " ==> [안전] 일반사용자의 sendmail 실행 방지가 설정되어 있습니다" >> $CF 2>&1
814 + else
815 + echo " ==> [취약] 일반사용자의 sendmail 실행 방지가 설정되어 있지 않습니다" >> $CF 2>&1
816 + fi
817 +fi
818 +echo
819 +echo >> $CF 2>&1
820 +
821 +
822 +echo "33. DNS 보안 버전 패치"
823 +echo "33. DNS 보안 버전 패치" >> $CF 2>&1
824 +
825 +DS=`dig +short @168.126.63.1 porttest.dns-oarc.net TXT | awk -Fis '{print $2}' | awk -F: {'print $1'} | sed '1d' | awk '{print $1}'`
826 +
827 +if [ $DS=GOOD -o GREAT ]
828 + then
829 + echo " ==> [안전] DNS 보안 패치가 최신 버전입니다" >> $CF 2>&1
830 + else
831 + echo " ==> [취약] DNS 보안 패치가 구 버전입니다" >> $CF 2>&1
832 +fi
833 +
834 +echo
835 +echo >> $CF 2>&1
836 +
837 +
838 +echo "34. DNS Zone Transfer 설정"
839 +echo "34. DNS Zone Transfer 설정" >> $CF 2>&1
840 +echo " Primary Name Server에는 Zone Transfer를 허용하는 서버를 지정" >> $CF 2>&1
841 +echo " Secondary Server 에는 Zone Transfer를 허용하지 않아야 함" >> $CF 2>&1
842 +echo >> $CF 2>&1
843 +echo " ==> [권장] DNS Zone Transfer를 허가된 사용자에게만 허용해야 함" >> $CF 2>&1
844 +echo " DNS Zone Transfer를 모든 사용자에게 허용했을 경우 [취약] 하다고 판단" >> $CF 2>&1
845 +echo
846 +echo >> $CF 2>&1
847 +
848 +
849 +echo "35. Apache 디렉터리 리스팅 제거"
850 +echo "35. Apache 디렉터리 리스팅 제거" >> $CF 2>&1
851 +GV=`cat /etc/httpd/conf/httpd.conf | grep Options | sed -n '1p'`
852 +
853 +if [[ $GV == *Indexes* ]]
854 + then
855 + echo " ==> [취약] 디렉터리 리스팅이 설정되어 있습니다" >> $CF 2>&1
856 + else
857 + echo " ==> [안전] 디렉터리 리스팅이 설정되어 있지 않습니다" >> $CF 2>&1
858 +fi
859 +
860 +echo
861 +echo >> $CF 2>&1
862 +
863 +
864 +echo "36. Apache 웹 프로세스 권한 제한"
865 +echo "36. Apache 웹 프로세스 권한 제한" >> $CF 2>&1
866 +UP=`cat /etc/httpd/conf/httpd.conf | grep User | sed -n '2p' | awk '{print $2}'`
867 +GP=`cat /etc/httpd/conf/httpd.conf | grep Group | sed -n '2p' | awk '{print $2}'`
868 +
869 +if [ "$UP" != root ]
870 + then
871 + echo " ==> [안전] 현재 설정된 웹 프로세스 User 권한 :" $UP >> $CF 2>&1
872 + else
873 + echo " ==> [취약] 현재 설정된 웹 프로세스 User 권한 :" $UP >> $CF 2>&1
874 +fi
875 +
876 +if [ "$GP" != root ]
877 + then
878 + echo " ==> [안전] 현재 설정된 웹 프로세스 Group 권한 :" $GP >> $CF 2>&1
879 + else
880 + echo " ==> [취약] 현재 설정된 웹 프로세스 Group 권한 :" $GP >> $CF 2>&1
881 +fi
882 +
883 +echo
884 +echo >> $CF 2>&1
885 +
886 +
887 +echo "37. Apache 상위 디렉터리 접근 금지"
888 +echo "37. Apache 상위 디렉터리 접근 금지" >> $CF 2>&1
889 +
890 +GC=`cat /etc/httpd/conf/httpd.conf | grep AllowOverride | sed -n '1p' | awk '{print $2}'`
891 +
892 +if [ $GC = AuthConfig ]
893 + then
894 + echo " ==> [안전] 디렉터리별 사용자 인증이 설정되어 있습니다" >> $CF 2>&1
895 + echo >> $CF 2>&1
896 + echo " 사용자 인증이 필요한 디렉터리에 다음의 지시자들이 포함된 .htaccess 파일 생성" >> $CF 2>&1
897 + echo " ***************************************************************" >> $CF 2>&1
898 + echo " * 지시자 * 설명 **" >> $CF 2>&1
899 + echo " ***************************************************************" >> $CF 2>&1
900 + echo " * AuthType * 인증 형태 (Baisc / Digest) *" >> $CF 2>&1
901 + echo " * AuthName * 인증 영역 (웹 브라우저의 인증창에 표시) *" >> $CF 2>&1
902 + echo " * AuthUserFile * 사용자 패스워드 파일의 위치 *" >> $CF 2>&1
903 + echo " * AuthGroupFile * 그룹 파일의 위치 (옵션) *" >> $CF 2>&1
904 + echo " * Require * 접근을 허용할 사용자 / 그룹 정의 *" >> $CF 2>&1
905 + echo " ***************************************************************" >> $CF 2>&1
906 + echo " ***************************************************************" >> $CF 2>&1
907 +
908 + echo " .htaccess 파일의 예제는 다음과 같음" >> $CF 2>&1
909 + echo " ***************************************" >> $CF 2>&1
910 + echo " # vi .htaccess" >> $CF 2>&1
911 + echo " AuthType Basic" >> $CF 2>&1
912 + echo " AuthName \"Welcome to AnonSE Server\"" >> $CF 2>&1
913 + echo " AuthUserFile /etc/shadow" >> $CF 2>&1
914 + echo " Require valid-user " >> $CF 2>&1
915 + echo " ***************************************" >> $CF 2>&1
916 + else
917 + echo " ==> [취약] 디렉터리별 사용자 인증이 설정되어 있지 않습니다" >> $CF 2>&1
918 +fi
919 +
920 +echo
921 +echo >> $CF 2>&1
922 +
923 +
924 +echo "38. Apache 불필요한 파일 제거"
925 +echo "38. Apache 불필요한 파일 제거" >> $CF 2>&1
926 +echo " ==> [권장] 웹 서버를 정기적으로 검사하여 불필요한 파일을 제거" >> $CF 2>&1
927 +echo
928 +echo >> $CF 2>&1
929 +
930 +
931 +echo "39. Apache 링크 사용 금지"
932 +echo "39. Apache 링크 사용 금지" >> $CF 2>&1
933 +
934 +if [[ $GV == *FollowSymLinks* ]]
935 + then
936 + echo " ==> [취약] Apache 상에서 심볼릭 링크 사용이 설정되어 있습니다" >> $CF 2>&1
937 + else
938 + echo " ==> [안전] Apache 상에서 심볼릭 링크 사용이 설정되어 있지 않습니다" >> $CF 2>&1
939 +fi
940 +
941 +echo
942 +echo >> $CF 2>&1
943 +
944 +echo "40. Apache 파일 업로드 및 다운로드 제한"
945 +echo "40. Apache 파일 업로드 및 다운로드 제한" >> $CF 2>&1
946 +
947 +US=`cat /etc/php.ini 2>/dev/null | grep post_max_size | awk '{print $3}'`
948 +DS=`cat /etc/httpd/conf/httpd.conf 2>/dev/null | grep LimitRequestBody`
949 +
950 +if [ $US ]
951 + then
952 + echo " ==> [안전] 업로드 가능한 파일의 최대 용량 : "$US >> $CF 2>&1
953 + else
954 + echo " ==> [취약] 업로드 가능한 파일의 최대 용량 : 제한없음" >> $CF 2>&1
955 +fi
956 +
957 +if [ $DS ]
958 + then
959 + echo " ==> [안전] 다운로드 가능한 파일의 최대 용량 : "$DS >> $CF 2>&1
960 + else
961 + echo " ==> [취약] 다운로드 가능한 파일의 최대 용량 : 제한없음" >> $CF 2>&1
962 +fi
963 +
964 +echo
965 +echo >> $CF 2>&1
966 +
967 +echo "41. Apache 웹 서비스 영역 분리"
968 +echo "41. Apache 웹 서비스 영역 분리" >> $CF 2>&1
969 +DR=`cat /etc/httpd/conf/httpd.conf | grep DocumentRoot | sed -n '2p' | awk '{print $2}'`
970 +DD="/var/www/html"
971 +
972 +if [ $DR=$DD ]
973 + then
974 + echo " ==> [취약] DocumentRoot에 설정된 디렉터리 : $DR" >> $CF 2>&1
975 + else
976 + echo " ==> [안전] DocumentRoot에 설정된 디렉터리 : $DR" >> $CF 2>&1
977 +fi
978 +echo
979 +echo
980 +echo >> $CF 2>&1
981 +echo >> $CF 2>&1
982 +
983 +
984 +echo "============================== 패치 관리 ============================="
985 +echo "============================== 패치 관리 =============================" >> $CF 2>&1
986 +
987 +echo "42. 최신 보안패치 및 벤더 권고사항 적용"
988 +echo "42. 최신 보안패치 및 벤더 권고사항 적용" >> $CF 2>&1
989 +echo " ==> [권장] 'yum update (-y)' 명령어를 사용하여 설치된 패키지의 최신 패치를 설치" >> $CF 2>&1
990 +echo
991 +echo
992 +echo >> $CF 2>&1
993 +echo >> $CF 2>&1
994 +
995 +
996 +echo "============================== 로그 관리 ============================="
997 +echo "============================== 로그 관리 =============================" >> $CF 2>&1
998 +echo "43. 로그의 정기적 검토 및 보고"
999 +echo "43. 로그의 정기적 검토 및 보고" >> $CF 2>&1
1000 +echo " ==> [권장] 로그 기록에 대해 정기적 검토, 분석, 이에 대한 리포트 작성 및 보고" >> $CF 2>&1
1001 +echo
1002 +echo
1003 +echo >> $CF 2>&1
1004 +echo >> $CF 2>&1
1005 +
1006 +
1007 +echo "************************** 취약점 체크 종료 **************************"
1008 +echo "************************** 취약점 체크 종료 **************************" >> $CF 2>&1