Skip to content

Commit a977dc9

Browse files
author
SI9INT
committed
first
0 parents  commit a977dc9

File tree

11 files changed

+359
-0
lines changed

11 files changed

+359
-0
lines changed

.flaskenv

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
FLASK_APP=app.py
2+
FLASK_ENV=development

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Subra

app.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import wrapper
2+
from flask import Flask, render_template, request, redirect, Response
3+
4+
app = Flask(__name__, template_folder='templates', static_folder='static')
5+
app.config['SECRET_KEY'] = 'xxx'
6+
7+
@app.route('/')
8+
def index():
9+
scans = wrapper.load_scans()
10+
return render_template('index.html', title='Index', scans=scans, idle=wrapper.get_idle())
11+
12+
@app.route('/new')
13+
def new_scan():
14+
return render_template('new_scan.html', title='New Scan')
15+
16+
@app.route('/new', methods=['POST'])
17+
def run_scan():
18+
wrapper.run_subfinder(request.form['domain'], request.form['args'])
19+
return redirect('/')
20+
21+
@app.route('/options')
22+
def options():
23+
return render_template('options.html', title='Options', config=wrapper.read_config())
24+
25+
@app.route('/options', methods=['POST'])
26+
def save_options():
27+
wrapper.save_config(request.form['config'])
28+
return redirect('/options')
29+
30+
@app.route('/result/<domain>')
31+
def result(domain):
32+
return render_template('result.html', title='Result: {}'.format(domain), result=wrapper.get_result(domain))
33+
34+
@app.route('/remove/<domain>')
35+
def delete(domain):
36+
wrapper.delete_target(domain)
37+
return redirect('/')
38+
39+
@app.route('/export/<domain>/<type>')
40+
def export(domain, type):
41+
data = wrapper.get_text(domain, type)
42+
return Response(data, mimetype='text/plain', headers={'Content-disposition' : 'attachment; filename={}.txt'.format(domain)})

static/bulma.min.css

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

static/style.css

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
main {
2+
padding: 3rem;
3+
}
4+
5+
h3 {
6+
margin: 1.1428em 0 !important;
7+
text-align: center;
8+
}
9+
10+
textarea {
11+
min-height: 400px !important;
12+
}
13+
14+
footer {
15+
bottom: 0;
16+
left: 0;
17+
position: fixed;
18+
right: 0;
19+
z-index: 30;
20+
padding: 2rem 1.5rem 2rem !important;
21+
}
22+
23+
.material-icons {
24+
font-size: 18px !important;
25+
}
26+
27+
.box {
28+
box-shadow: none !important;
29+
border: 2px solid #eee;
30+
}

templates/global/layout.html

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>Subra | {{ title }}</title>
5+
<link rel="stylesheet" href="/static/bulma.min.css">
6+
<link rel="stylesheet" href="/static/style.css">
7+
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
8+
rel="stylesheet">
9+
</head>
10+
11+
<body>
12+
<header>
13+
<nav class="navbar has-shadow is-dark" role="navigation">
14+
<div class="container">
15+
<div class="navbar-brand">
16+
<a class="navbar-item" href="/" title="Return to overview ..">
17+
<strong>$ Subra</strong>
18+
</a>
19+
</div>
20+
</div>
21+
</nav>
22+
</header>
23+
<main>
24+
<div class="container">
25+
{% block main %}{% endblock %}
26+
</div>
27+
</main>
28+
<footer class="footer">
29+
<div class="content has-text-centered">
30+
<p>
31+
v.0.1 | <b>Made by</b>
32+
<a href="https://twitter.com/si9int" target="_blank">@SI9INT</a>
33+
</p>
34+
</div>
35+
</footer>
36+
</body>
37+
</html>

templates/index.html

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{% extends 'global/layout.html' %}
2+
{% block main %}
3+
<div class="content">
4+
<div class="level">
5+
<div class="level-left">
6+
<a class="button level-item" href="/new">New Scan</a>
7+
<a class="button level-item" href="/options">
8+
<span class="material-icons">settings</span>
9+
</a>
10+
</div>
11+
{% if idle %}
12+
<div class="level-right">
13+
<button class="button is-warning is-light">
14+
<u>Scanning</u>&nbsp;
15+
{{ ','.join(idle) }}
16+
</button>
17+
</div>
18+
{% endif %}
19+
</div><hr>
20+
<h3>Results</h3>
21+
<div class="box">
22+
<table class="table">
23+
<tr>
24+
<th>Domain</th>
25+
{% for scan in scans %}
26+
<tr>
27+
<td>
28+
<a href="/result/{{ scan }}">{{ scan }}</a>
29+
<div class="is-pulled-right">
30+
<a href="/remove/{{ scan }}" style="color: #000;" onclick="return confirm('Sure?');" title="Remove">
31+
<span class="material-icons">delete_outline</span>
32+
</a>
33+
</div>
34+
</td>
35+
</tr>
36+
{% endfor %}
37+
</table>
38+
</div>
39+
</div>
40+
{% endblock %}

templates/new_scan.html

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
{% extends 'global/layout.html' %}
2+
{% block main %}
3+
<div class="content">
4+
<div class="level">
5+
<div class="level-left">
6+
<a class="button level-item" href="/new" disabled>New Scan</a>
7+
<a class="button level-item" href="/options">
8+
<span class="material-icons">settings</span>
9+
</a>
10+
</div>
11+
</div><hr>
12+
<h3>New Scan</h3>
13+
<div class="box">
14+
<div class="columns">
15+
<div class="column">
16+
<form method="post">
17+
<div class="field">
18+
<label class="label">Domain</label>
19+
<div class="control">
20+
<input name="domain" class="input" type="text" placeholder="Domain .." required>
21+
</div>
22+
</div>
23+
<div class="field">
24+
<label class="label">Arguments</label>
25+
<div class="control">
26+
<input name="args" class="input" type="text" placeholder="-t 100 ..">
27+
<p class="help">You can choose optional arguments from the right</p>
28+
</div>
29+
</div>
30+
<div class="field">
31+
<div class="control">
32+
<button class="button" type="submit">Schedule</button>
33+
</div>
34+
</div>
35+
</form>
36+
</div>
37+
<div class="column">
38+
<div class="content">
39+
<b>Possible Arguments</b>
40+
<table>
41+
<tr>
42+
<td>
43+
<code>-r 1.1.1.1</code>
44+
</td>
45+
<td>Comma-separated list of resolvers to use</td>
46+
</tr>
47+
<tr>
48+
<td>
49+
<code>-t 100</code>
50+
</td>
51+
<td>Number of concurrent goroutines for resolving (default 10)</td>
52+
</tr>
53+
<tr>
54+
<td>
55+
<code>-sources censys</code>
56+
</td>
57+
<td>Comma separated list of sources to use</td>
58+
</tr>
59+
</table>
60+
</div>
61+
</div>
62+
</div>
63+
</div>
64+
</div>
65+
{% endblock %}

templates/options.html

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{% extends 'global/layout.html' %}
2+
{% block main %}
3+
<div class="content">
4+
<div class="level">
5+
<div class="level-left">
6+
<a class="button level-item" href="/new">New Scan</a>
7+
<a class="button level-item" href="/options" disabled>
8+
<span class="material-icons">settings</span>
9+
</a>
10+
</div>
11+
</div><hr>
12+
<h3>Options</h3>
13+
<div class="box">
14+
<div class="columns">
15+
<div class="column">
16+
<form method="post">
17+
<div class="field">
18+
<label class="label">Configuration</label>
19+
<div class="control">
20+
<textarea name="config" class="textarea" placeholder="Textarea">{{ config[1] }}</textarea>
21+
<p class="help">
22+
This file is located under
23+
<code>{{ config[0]+ '/.config/subfinder/config.yaml' }}</code>
24+
</p>
25+
</div>
26+
</div>
27+
<div class="field">
28+
<div class="control">
29+
<button class="button" type="submit">Save</button>
30+
</div>
31+
</div>
32+
</form>
33+
</div>
34+
</div>
35+
</div>
36+
</div>
37+
{% endblock %}

templates/result.html

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{% extends 'global/layout.html' %}
2+
{% block main %}
3+
<div class="content">
4+
<div class="level">
5+
<div class="level-left">
6+
<a class="button level-item" href="/new">New Scan</a>
7+
<a class="button level-item" href="/options">
8+
<span class="material-icons">settings</span>
9+
</a>
10+
<a class="button level-item" href="/export/{{ title.split(': ')[1] }}/sub">Subdomains as .txt</a>
11+
<a class="button level-item" href="/export/{{ title.split(': ')[1] }}/ip">IP Addresses as .txt</a>
12+
</div>
13+
</div><hr>
14+
<h3>{{ title.split(': ')[1] }}</h3>
15+
<div class="box">
16+
<table class="table">
17+
<tr>
18+
<th>Subdomain</th>
19+
<th>IP Address</th>
20+
</tr>
21+
{% for r in result %}
22+
<tr>
23+
<td>
24+
<a href="https://{{ r[0] }}" target="_blank">{{ r[0] }}</a>
25+
</td>
26+
<td>
27+
<a href="https://api.iptoasn.com/v1/as/ip/{{ r[1] }}" target="_blank">{{ r[1] }}</a>
28+
</td>
29+
</tr>
30+
{% endfor %}
31+
</table>
32+
</div>
33+
</div>
34+
{% endblock %}

0 commit comments

Comments
 (0)