app.py (7628B)
1 import geoip2.database
2 import socket
3 import re
4 import urllib.parse
5 import requests
6 import os
7 import shodan as shodan_lib
8 import ipaddress
9 from flask_paginate import Pagination, get_page_args
10 from datetime import datetime, timedelta
11 from flask import Flask, render_template, request
12 from modules.County_Codes import country_code_to_korean
13 from dateutil.parser import parse
14 from bs4 import BeautifulSoup
15 from datetime import datetime, timedelta
16 from pytz import timezone
17
18 def get_unique_words(title):
19 # 여기서는 제목을 공백으로 분리하여 단어를 추출하였습니다.
20 # 필요에 따라 더 복잡한 토큰화 도구를 사용할 수 있습니다.
21 return set(title.split(' '))
22
23 # 국가 코드를 한국어 국가 이름으로 변환하는 함수
24 def get_korean_country_name(country_code):
25 return country_code_to_korean.get(country_code, 'None')
26
27 app = Flask(__name__)
28
29 # GeoLite2 데이터베이스 파일의 경로를 지정합니다.
30 reader = geoip2.database.Reader('GeoLite2-Country.mmdb')
31
32 def get_ip_address(input_value):
33 try:
34 if not input_value.replace(".", "").isnumeric(): # If it's a domain name
35 ip_address = socket.gethostbyname(input_value)
36 return ip_address
37 else: # If it's an IP address
38 return input_value
39 except socket.gaierror:
40 return None
41
42 @app.route('/', methods=['GET', 'POST'])
43 def index():
44 ip_data = []
45
46 if request.method == 'POST':
47 input_list = request.form['ip_list'].splitlines()
48
49 for input_value in input_list:
50 ip_address = get_ip_address(input_value)
51 if ip_address is None:
52 ip_data.append({
53 'ip': 'Invalid IP or Domain',
54 'country': 'Invalid IP or Domain'
55 })
56 else:
57 try:
58 response = reader.country(ip_address)
59 ip_data.append({
60 'ip': input_value,
61 'country': get_korean_country_name(response.country.iso_code) # 수정된 부분
62 })
63 except:
64 ip_data.append({
65 'ip': input_value,
66 'country': 'Invalid IP'
67 })
68
69 return render_template('index.html', ip_data=ip_data)
70
71 @app.route('/ascii_to_char', methods=['GET', 'POST'])
72 def ascii_to_char():
73 characters = ''
74 if request.method == 'POST':
75 ascii_string = request.form.get('ascii_string')
76 ascii_codes = re.findall(r'\d+', ascii_string)
77 for ascii_code in ascii_codes:
78 ascii_code = int(ascii_code)
79 if ascii_code >= 0 and ascii_code <= 127:
80 characters += chr(ascii_code)
81 return render_template('ascii_to_char.html', characters=characters)
82
83 @app.route('/utf8_decoder', methods=['GET', 'POST'])
84 def utf8_decoder():
85 decoded_string = ''
86 if request.method == 'POST':
87 encoded_string = request.form.get('encoded_string')
88 decoded_string = urllib.parse.unquote(encoded_string)
89 return render_template('utf8_decoder.html', decoded_string=decoded_string)
90
91 @app.route('/news', methods=['GET'])
92 def news():
93 # Get page info from request
94 page, per_page, offset = get_page_args(page_parameter='page',
95 per_page_parameter='per_page')
96
97 # Bing Search v7 API endpoint
98 subscription_key = os.environ['BING_SEARCH_V7_SUBSCRIPTION_KEY']
99 url = 'https://api.bing.microsoft.com/v7.0/news/search'
100 headers = {"Ocp-Apim-Subscription-Key": subscription_key}
101 days = request.args.get('days', default='Day')
102
103 # Get the topics from the form
104 topics = request.args.getlist('topics')
105 days = request.args.get('days', default='Day')
106
107 # If no topics selected, set a default
108 if not topics:
109 topics = ["보안"]
110
111 # Generate the query string
112 query = " OR ".join(topics)
113
114 params = {
115 "q": query,
116 "mkt": "ko-KR",
117 "count": 100,
118 "freshness": days,
119 "textFormat": "Raw",
120 "safeSearch": "Off"
121 }
122
123 response = requests.get(url, headers=headers, params=params)
124 response.raise_for_status()
125 news_data = response.json()["value"]
126
127 def get_unique_words(title):
128 return set(title.split(' '))
129
130 unique_news_data = []
131 for news in news_data:
132 title = news['name']
133 unique_words = get_unique_words(title)
134
135 if any(sum(word in get_unique_words(existing_news['name']) for word in unique_words) >= 2 for existing_news in unique_news_data):
136 continue
137
138 unique_news_data.append(news)
139
140 # Convert published time to datetime object
141 for news in unique_news_data:
142 # Convert the 'datePublished' string to a datetime object
143 date_published = parse(news["datePublished"])
144 # Format the datetime object to a string with only the date
145 news["datePublished"] = date_published.strftime('%Y-%m-%d')
146
147 # Paginate news
148 total = len(unique_news_data)
149 pagination_news = unique_news_data[offset: offset + per_page]
150 pagination = Pagination(page=page, per_page=per_page, total=total,
151 css_framework='bootstrap4')
152
153 return render_template('news.html', news=pagination_news, page=page,
154 per_page=per_page, pagination=pagination, selected_topics=topics, days=days)
155
156 @app.route('/shodan', methods=['GET', 'POST'])
157 def shodan():
158 results = None
159 template_name = 'shodan.html'
160
161 if request.method == 'POST':
162 query = request.form.get('query')
163 if not query:
164 results = "Please enter an IP address or a domain name."
165 else:
166 shodan_api_key = os.environ['shodanAPI_key'] # Replace with your Shodan API Key
167 api = shodan_lib.Shodan(shodan_api_key)
168
169 try:
170 ipaddress.ip_address(query)
171 # If the above line of code doesn't raise an exception, it means that the input is a valid IP address
172 try:
173 results = api.host(query)
174 except shodan_lib.APIError as e:
175 results = f"No information available for that IP: {query}"
176 except ValueError:
177 # If the input is not a valid IP address, it might be a domain name
178 try:
179 results = api.search(query)
180 template_name = 'shodan_domain.html' # Use a different template for domain names
181 except shodan_lib.APIError as e:
182 results = f"Error: {e}"
183 except shodan_lib.APIError as e:
184 results = f"Error: {e}"
185
186
187 return render_template(template_name, results=results)
188
189 @app.route('/krcert')
190 def krcert():
191 url = 'https://www.krcert.or.kr/kr/bbs/list.do?bbsId=B0000133&menuNo=205020'
192 response = requests.get(url)
193 soup = BeautifulSoup(response.text, 'html.parser')
194 table = soup.find('table')
195 rows = table.find_all('tr')
196 posts = []
197 now = datetime.now()
198
199 for row in rows:
200 cols = row.find_all('td')
201 if len(cols) > 0:
202 date_str = cols[4].text.strip()
203 post_date = datetime.strptime(date_str, "%Y-%m-%d")
204 if (now - post_date).days <= 2:
205 title = cols[1].text.strip()
206 link = "https://www.krcert.or.kr" + cols[1].find('a')['href']
207 posts.append({'title': title, 'date': date_str, 'link': link})
208
209 return render_template('krcert.html', posts=posts)
210
211
212 if __name__ == '__main__':
213 app.run()