| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | |||||
| 3 | 4 | 5 | 6 | 7 | 8 | 9 |
| 10 | 11 | 12 | 13 | 14 | 15 | 16 |
| 17 | 18 | 19 | 20 | 21 | 22 | 23 |
| 24 | 25 | 26 | 27 | 28 | 29 | 30 |
| 31 |
- TryHackMe
- 모의해킹
- 보안 스터디
- cert
- OverTheWire
- write-up
- 사이버 보안
- CTF
- 해킹
- 해커
- 정보보안
- 보안 관제
- Web
- THM
- linux
- SoC
- http
- XSS
- Blue Team
- 정보보호
- 블루팀
- web hacking
- 리눅스 기초
- Bandit
- 해킹 스터디
- 리눅스
- Cyber Security
- Cross-Site Scripting
- IR
- 워게임
- Today
- Total
AnbyMata의 해킹 노트
[THM] SQL Injection - EP.1 (Task 1~3) 본문
TryHackMe - "SQL Injection". Task 1~3. Write-up + Extra Study!

출처: https://tryhackme.com/room/sqlinjectionlm
SQL Injection
Learn how to detect and exploit SQL Injection vulnerabilities
tryhackme.com
[1] Brief
SQL Injection
- SQL (Structured Query Lanuage) Injection, 줄여서 "SQLi" 라고도 함
- Web Application의 데이터베이스 서버를 대상으로 악의적인 쿼리를 실행하게 만드는 공격
- 공격자는 개인 정보나 데이터를 탈취, 삭제, 변조 할 수 있음
- 로그인 등의 인증을 우회하여 마이페이지나 관리자 페이지 같이 보호된 영역에 접근할 수 있음
- 매우 오래된 취약점으로 현재도 자주 발생하는 취약점
- 데이터베이스 (DB) 전체가 털릴 수도 있어 피해 규모가 큼
배우는 내용들
- 데이터베이스와 SQL이란?
- SQL의 기본 명령어들
- SQL 취약점 탐지 및 사용법
- 개발자 관점에서 SQL Injection을 방어하는 법
[2] What is Database?
Database (DB)
- 데이터들을 전자적이고 체계적으로 저장하는 방법
- 데이터베이스는 DBMS (Database Management System)에 의해 관리됨
- DBMS는 크게 Relational(관계형), Non-Relational(비관계형) 두 가지로 나뉨
- 이 룸에선 Relational(관계형) DB를 중심으로 함
- 대표적인 Relational DB = MySQL, Microsoft SQL Server, Acess, PostgreSQL, SQLite
[2-1] DBMS (Database Management System)
DBMS = 여러 개의 Database를 관리하는 소프트웨어
Database = 특정 목적으로 묶인 서로 연관된 데이터 집합
Tables = 데이터베이스 내부에서 데이터를 저장하는 단위

| [보충 설명] 레스토랑의 데이터를 관리하는 DBMS를 예시로 구성했습니다. 하나의 서버에 3개의 데이터베이스 (DB)가 관리되고 있는 모습입니다. Menu DB는 레스토랑의 메뉴 정보가 저장된 데이터베이스입니다. 메뉴 정보는 Starter, Main, Dessert로 구분하여 Table 단위로 분리되어 저장된 상태입니다. Staff DB는 레스토랑의 직원 정보가 저장된 데이터베이스입니다. 직원 정보는 Kitchen담당과 Service 담당으로 구분하여 Table 단위로 분리해 저장된 상태입니다. Customer DB는 레스토랑의 손님 정보가 저장된 데이터베이스입니다. 손님 정보는 점심과 저녁 손님을 각각 Lunch Table, Dinner Table로 분리해 저장된 상태입니다. 이렇듯, 서버에 설치된 DBMS가 여러 개의 데이터베이스를 관리하고, 각 데이터베이스에 데이터들을 Table 단위로 저장해둡니다. |
[2-2] Tables
Table = DB에서 데이터를 저장하는 기본 단위
- Table은 Column(열)과 Row(행)으로 구성된 표 형태의 데이터 저장 구조

Column (Field) (열)
- Column은 "Field"라고도 불림
- 데이터의 속성 (= 데이터 타입과 역할)
- 하나의 테이블 안에서 고유한 이름을 가짐
- 데이터의 타입 지정은 필수!
- auto-increment 기능
+ 정수형 column에서 설정 가능
+ 각 행마다 자동으로 증가하는 고유한 숫자를 부여
+ 이렇게 생성된 column은 보통 'key field'로 사용
+ 'key field'는 보통 Primary Key로서 각 행들을 식별하는데에 사용됨
| [보충 설명] 데이터 타입이라 하면, "정수형 (integers)", "문자열 (strings)", "날짜 (dates)" 등을 말합니다. 예시를 보면, Columns을 통해서 이 정보가 id인지, username인지, password인지, type인지를 통해 어떤 역할을 가지는지 알려주고, 각 정보가 어떤 데이터 타입인지도 나타낸다고 할 수 있습니다. auto-increment 기능은 각 행들을 구분해주는 역할을 한다고 할 수 있습니다. 자동으로 증가하는 고유한 숫자이기 때문에 정수형 데이터에만 사용할 수 있습니다. 이 기능으로 개발자가 직접 값을 지정하지 않아도 DBMS가 자동으로 관리해줄 수 있습니다. 'key field'는 각 Row(행)을 유일하게 식별하기 위해 사용되는 Column입니다. 즉, 모든 Column이 key field는 아닙니다. key field는 식별하는 역할을 위해 중복이 불가능하며 NULL을 허용하지 않습니다. auto-increment가 설정된 column이 key field로 주로 사용되며, Primary Key 역할을 수행합니다. Primary Key는 테이블의 각 행을 유일하게 구분하기 위한 식별자 정도로 이해하시면 됩니다. |
Row (행)
- Row는 "Record"라고도 불림
- 하나의 데이터 묶음 (= 실질적인 데이터)
- 즉, 데이터가 추가 → 새로운 행 생성 / 데이터가 삭제 → 해당 행 제거
[2-3] Relational DB vs. Non-Relational DB
Relational(관계형) Databases
- Table 형태로 정보를 저장
- Table들 간에 서로 데이터를 공유하는 일이 많음
- Column(열) = 데이터 정의 / Row(행) = 실제 데이터 값 저장
- 보통 식별을 위한 고유한 값을 가지는 Primary Key역할을 하는 Column 존재
- Primary Key를 통해 다른 테이블에서 참조되어 테이블 간의 관계를 형성함
- 대표 예시) MySQL, Microsoft SQL Server, Acess, PostgreSQL, SQLite
Non-Relational(비관계형) Databases
- Table 구조를 사용하지 않음 (= Row, Column 사용하지 않음)
- 고정된 데이터 구조가 없기에 각 데이터가 서로 다른 형태를 가질 수 있음
- Relational DB보다 높은 유연성을 제공함
- 대표 예시) MongoDB, Cassandra, ElasticSearch
| [보충 설명] Relational DB에서 "사용자명", "사용자번호"를 데이터 구조로 가지는 DB라고 하면, {Anby, 123}, {Mata, 777} 같이 동일한 형식의 데이터만을 가질수 있습니다. Non-Relational DB에서는 정해진 데이터 구조가 없기에 같은 데이터베이스 내에서 {Anby, 123}, {11, Python, 26-01-30} 과 같이 구조가 전혀 다른 데이터들이 같이 존재할 수 있습니다. |
[3] What is SQL?
SQL (Structurec Query Lanuage)
- 데이터베이스와 대화하기 위한 언어 (= DB를 query(조회))
- 데이터의 조회, 조작, 관리를 목적으로 함
- SQL 문장 (퀴리)는 보통 'statement'라 불림
- 데이터의 조회, 수정, 삽입, 삭제가 핵심 기능
- DB 서버마다 기본 개념은 동일함
- 문법, 동작 방식 등 세부적으론 DBMS마다 약간의 차이가 존재함
- SQL 문법은 대소문자 구분을 안함
| [보충 설명] MySQL이나 SQLite 같이 다양한 DBMS들이 존재합니다. 이 모든 데이터베이스들은 SQL을 사용하여 조작됩니다. SELECT(조회), INSERT(삽입), UPDATE(수정), DELETE(삭제) 같은 기본적인 개념들은 MySQL이든, SQLite든 모두 동일하게 적용됩니다. 약간의 차이만이 존재하기에 하나를 익혀두면 다른 DB 서버를 사용해도 금방 적용할 수 있습니다. SQL은 대소문자 구분을 하지 않아서 "INSERT" = "insert" = "Insert" 모두 동일하게 인식됩니다. |
연습을 위해 "menu"라는 이름의 Table 하나를 만들겠습니다.
| number | id | name |
| 1 | 101 | Cabernet Sauvignon |
| 2 | 102 | Chardonnay |
| 3 | 103 | Champagne Brut |
| 4 | 201 | Bread |
| 5 | 301 | Pomodoro pasta |
| 6 | 302 | Carbonara pasta |
| 7 | 303 | Vongole pasta |
| 8 | 304 | Lasagna |
| 9 | 401 | Tiramisu |
컨셉은 파스타 레스토랑의 메뉴들을 담고있는 데이터베이스입니다.
이 "menu" Table을 사용해 MySQL 기준으로 기본적인 명령어들을 다뤄보겠습니다.
[3-1] SELECT (조회)
1. SELECT * from menu;
= menu 테이블에 저장된 모든 Column(열)과 모든 Row(행) 조회
- SELECT : 데이터를 조회
- * : 모든 Column(열)을 의미
- from menu : "menu"라는 Table에서 데이터를 가져옴
| number | id | name |
| 1 | 101 | Cabernet Sauvignon |
| 2 | 102 | Chardonnay |
| 3 | 103 | Champagne Brut |
| 4 | 201 | Bread |
| 5 | 301 | Pomodoro pasta |
| 6 | 302 | Carbonara pasta |
| 7 | 303 | Vongole pasta |
| 8 | 304 | Lasagna |
| 9 | 401 | Tiramisu |
2. SELECT id, name from menu;
= menu 테이블에서 id와 name column(열)만 조회
- SELECT : 데이터를 조회
- id, name : 조회할 Column(열) 'id'와 'name' 지정
- from menu : "menu"라는 Table에서 데이터를 가져옴
| id | name |
| 101 | Cabernet Sauvignon |
| 102 | Chardonnay |
| 103 | Champagne Brut |
| 201 | Bread |
| 301 | Pomodoro pasta |
| 302 | Carbonara pasta |
| 303 | Vongole pasta |
| 304 | Lasagna |
| 401 | Tiramisu |
3. SELECT * from menu LIMIT 2;
= menu 테이블에서 모든 column을 조회한 다음, 2개의 Row(행)만 결과로 출력
- SELECT : 데이터를 조회
- * : 모든 Column을 의미
- from menu : "menu"라는 Table에서 데이터를 가져옴
- LIMIT 2 : 결과로 출력할 Row(행)을 2개로 제한
| number | id | name |
| 1 | 101 | Cabernet Sauvignon |
| 2 | 102 | Chardonnay |
| [보충 설명] LIMIT은 SQL 조회 결과의 개수를 제한하는 기능입니다. 조회할 행들의 개수를 제한하는 것이 아닙니다. 그래서 위의 예시는 우선은 'SELECT * from menu'에 해당되는 결과를 조회한 다음, 그 결과에서 'LIMIT 2'에 따라 결과중 2개의 행들만 출력한 것입니다. |
4. SELECT * from menu where name='Carbonara pasta';
= menu 테이블에서 name이 'Carbonara past'인 데이터만 조회
- SELECT : 데이터를 조회
- * : 모든 Column을 의미
- from menu : "menu"라는 Table에서 데이터를 가져옴
- where name='Carbonara pasta' : name 값이 "Carbonara pasta"인 Row(행)만 선택
| number | id | name |
| 6 | 302 | Carbonara pasta |
| [보충 설명] where은 조회할 행들을 조건으로 필터링하는 기능입니다. where의 조건을 만족하는 행들만이 조회 대상이 됩니다. 조회 이후에 결과를 제한하는 LIMIT과 다르게 조회 이전에 필터링을 하는 것입니다. |
5. SELECT * from menu where id != '201';
= menu 테이블에서 id가 '201'이 아닌 모든 데이터 조회
- SELECT : 데이터를 조회
- * : 모든 Column을 의미
- from menu : "menu"라는 Table에서 데이터를 가져옴
- where id != '201' : id 값이 "201"이 아닌 Row(행)만 선택
| number | id | name |
| 1 | 101 | Cabernet Sauvignon |
| 2 | 102 | Chardonnay |
| 3 | 103 | Champagne Brut |
| 5 | 301 | Pomodoro pasta |
| 6 | 302 | Carbonara pasta |
| 7 | 303 | Vongole pasta |
| 8 | 304 | Lasagna |
| 9 | 401 | Tiramisu |
| [보충 설명] ' ! '는 아시다시피 컴공에서 부정 (not)을 의미합니다. 그래서 id != '201'은 id가 201인 행을 선택하는 id='201'을 부정하여 id가 201이 아닌 행들을 선택하는 조건이 됩니다. |
6. SELECT * from menu where name='Bread' or name='Tiramisu';
= menu 테이블에서 name이 'Bread'이거나 'Tiramisu'인 데이터만 조회
- SELECT * : 모든 Column 조회
- from menu : "menu"라는 Table에서 데이터를 가져옴
- where name='Bread' or name='Tiramisu' : name 값이 "Bread"이거나 "Tiramisu"인 Row(행)만 선택
| number | id | name |
| 4 | 201 | Bread |
| 9 | 401 | Tiramisu |
| [보충 설명] OR은 컴공에서 "또는"을 의미합니다. 즉, 'A or B' 라는 조건이 있다면 A나 B 둘 중 하나의 조건만을 만족하면 됩니다. 'A or B or C'의 경우 셋 중 하나만 만족해도 됩니다. 그래서 위의 예시에서 name이 "Bread"인 행과 "Tiramisu"인 행 둘 다 조회됩니다. |
7. SELECT * from menu where name='Lasagna' and id='304';
= menu 테이블에서 name이 'Lasagna'이고 id가 '304'인 데이터만 조회
- SELECT * : 모든 Column 조회
- from menu : "menu"라는 Table에서 데이터를 가져옴
- where name='Lasagna' or id='304' : name 값이 "Lasagna"이면서 id 값이 "304"인 Row(행)만 선택
| number | id | name |
| 8 | 304 | Lasagna |
| [보충 설명] AND는 컴공에서 "그리고"를 의미합니다. 즉, 'A and B'라는 조건이 있다면 A와 B 둘 다 만족해야 합니다. 'A and B and C'의 경우 세가지 조건을 모두 만족해야 됩니다. 그래서 위의 예시에서 id가 "304"면서 name이 "Lasagna"인 행만이 조회됩니다. |
8. SELECT * from menu where name like 'C%';
= menu 테이블에서 name이 'C'로 시작하는 모든 데이터 조회
- SELECT * : 모든 Column 조회
- from menu : "menu"라는 Table에서 데이터를 가져옴
- where name like 'C%' : name 값이 'C'로 시작하는 Row(행)만 선택
| number | id | name |
| 1 | 101 | Cabernet Sauvignon |
| 2 | 102 | Chardonnay |
| 3 | 103 | Champagne Brut |
| 6 | 302 | Carbonara pasta |
| [보충 설명] name like 'Ca%' 조건의 경우, name이 "Ca"로 시작하는 행들만 조회됩니다. 이런식으로 한 글자가 아닌 여러 글자를 접두어 조건으로 지정할 수 있습니다. |
9. SELECT * from menu where name like '%a';
= menu 테이블에서 name이 't'로 끝나는 모든 데이터 조회
- SELECT * : 모든 Column 조회
- from menu : "menu"라는 Table에서 데이터를 가져옴
- where name like '%a' : name 값이 'a'로 끝나는 Row(행)만 선택
| number | id | name |
| 5 | 301 | Pomodoro pasta |
| 6 | 302 | Carbonara pasta |
| 7 | 303 | Vongole pasta |
| 8 | 304 | Lasagna |
| [보충 설명] name like '%ta' 조건의 경우, name이 "ta"로 끝나는 행들만 조회됩니다. 이런식으로 한 글자가 아닌 여러 글자를 접미어 조건으로 지정할 수 있습니다. |
10. SELECT * from menu where name like '%as%';
= menu 테이블에서 name에 'as'가 포함된 모든 데이터 조회
- SELECT * : 모든 Column 조회
- from menu : "menu"라는 Table에서 데이터를 가져옴
- where name like '%as%' : name 값이 'a'로 끝나는 Row(행)만 선택
| number | id | name |
| 5 | 301 | Pomodoro pasta |
| 6 | 302 | Carbonara pasta |
| 7 | 303 | Vongole pasta |
| 8 | 304 | Lasagna |
| [보충 설명] name like '%as%' 조건의 경우, 'a'와 's'가 붙어있는 'as'가 name에 포함되어야 조회됩니다. name에 'a'나 's'가 포함된 조건을 만들고 싶다면, name like '%a%' OR name like '%s%' name에 'a'와 's'가 포함된 조건을 만들고 싶다면, name like '%a%' AND name like '%s%' 를 사용해야 됩니다. or와 and를 대문자로 쓴건 가독성때문입니다. 위에서 말했다시피 SQL은 대소문자를 구분하지 않습니다. |
[3-2] INSERT (삽입)
1. INSERT into menu (id,name) values ('402','Icecream');
= menu 테이블의 id와 name Column(열)에 각각 '402', 'Icecream' 값을 가지는 새로운 Row(행)을 추가
- INSERT into menu : menu 테이블에 새 데이터 삽입
- (id, name) : 값을 넣은 Column(열) 'id'와 'name' 지정
- values ('402', 'Icecream') : 각 Column(열)에 들어갈 실제 값 '402'와 'Icecream'
| number | id | name |
| 1 | 101 | Cabernet Sauvignon |
| 2 | 102 | Chardonnay |
| 3 | 103 | Champagne Brut |
| 4 | 201 | Bread |
| 5 | 301 | Pomodoro pasta |
| 6 | 302 | Carbonara pasta |
| 7 | 303 | Vongole pasta |
| 8 | 304 | Lasagna |
| 9 | 401 | Tiramisu |
| 10 | 402 | Icecream |
| [보충 설명] number Column이 auto-increment (Primary Key)라고 가정한 예시입니다. 그래서 직접 INSERT하지 않아도 자동으로 "10"이라는 번호를 부여합니다. INSERT의 경우 마지막 줄에 새로운 Row 하나가 생성되는 것입니다. 그래서 number 값도 9에 1을 더한 10이 자동으로 할당됩니다. |
[3-3] UPDATE (수정)
1. UPDATE menu SET name='Baguette' where id='201';
= menu 테이블에서 id가 '201'인 Row(행)의 name 값을 'Baguette'로 수정
- UPDATE menu : menu 테이블의 데이터를 수정
- SET name='Baguette' : name 값을 'Baguette'로 변경
- where id='201' : id 값이 '201'인 Row(행)만 수정 대상
| number | id | name |
| 1 | 101 | Cabernet Sauvignon |
| 2 | 102 | Chardonnay |
| 3 | 103 | Champagne Brut |
| 4 | 201 | Baguette |
| 5 | 301 | Pomodoro pasta |
| 6 | 302 | Carbonara pasta |
| 7 | 303 | Vongole pasta |
| 8 | 304 | Lasagna |
| 9 | 401 | Tiramisu |
| 10 | 402 | Icecream |
| [보충 설명] 위의 예시의 경우, id 값이 '201'인 행들의 name 값을 전부 'Baguette'로 바꾸는 것입니다. 즉, id 값이 '201'인 행이 여러 개인 경우 그 모든 행들의 name 값이 'Baguette'가 되는 것입니다. |
[3-4] DELETE (삭제)
1. DELETE from menu where name='Icecream';
= menu 테이블에서 name이 'Icecream'인 Row(행) 삭제
- DELETE from menu : menu 테이블에서 데이터를 삭제
- where name='Icecream' : name 값이 'Icecream'인 Row(행)만 삭제 대상
| number | id | name |
| 1 | 101 | Cabernet Sauvignon |
| 2 | 102 | Chardonnay |
| 3 | 103 | Champagne Brut |
| 4 | 201 | Baguette |
| 5 | 301 | Pomodoro pasta |
| 6 | 302 | Carbonara pasta |
| 7 | 303 | Vongole pasta |
| 8 | 304 | Lasagna |
| 9 | 401 | Tiramisu |
| [보충 설명] 위의 예시의 경우, name 값이 'Icecream'인 행들을 전부 삭제하는 것입니다. 즉, name 값이 'Icecream'인 행이 여러 개인 경우 그 모든 행들을 삭제합니다. |
2. DELETE from menu;
= menu 테이블에 있는 모든 Row(행)들을 삭제
- 굉장히 위험한 DELETE 형태입니다.
- 조건이 없어서 전체에 적용되기 때문에 테이블 구조만 남은 채로 모든 데이터가 삭제됩니다.
[3-5] UNION
UNION = 2개 이상의 SELECT 결과를 하나로 합치는 구문
- 단일 테이블 또는 여러 데이블에서 데이터 결합 가능
- 3가지 규칙을 가짐
+ 1. 각 SELECT의 Column(열) 개수는 동일해야 함
+ 2. 각 Column(열)의 데이터 타입이 유사해야 함
+ 3. Column(열)의 순서가 동일해야 함
- 추가적으로 UNION은 중복된 행이 있으면 제거함
| [보충 설명] 각 테이블의 열 개수가 동일할 필요는 없습니다. 테이블의 열 개수가 다르더라도 SELECT로 지정하는 열의 개수가 같으면 됩니다. 데이터 타입이 유사하다는 SELECT 문에서 같은 순서에 위치한 열끼리는 문자열은 문자열끼리, 정수형은 정수형끼리 같이 서로 호환 가능한 데이터 타입이어야 한다는 뜻입니다. 중복된 행을 제거한다는 뜻은, 두 SELECT문을 합쳤을 때, 똑같은 행이 2개 존재하면 하나를 제거하여 1번만 출력한다는 뜻입니다. |
예시를 위해 두 가지 Table을 만들어보겠습니다
coffee 테이블
| name | id | price |
| Espresso | 101 | 4000 |
| Latte | 234 | 6000 |
| Mocha | 283 | 7000 |
| Affogato | 555 | 9000 |
tea 테이블
| name | num | price |
| Matcha | 222 | 5000 |
| Chamomile | 757 | 5000 |
| Peppermint | 923 | 6000 |
| Lemon | 478 | 7000 |
| Rooibos | 111 | 5000 |
1. Select name, id, price from coffee UNION Select name, num, price from tea;
= coffee 테이블과 tea 테이블에서 각각 name, (id/num), price를 조회한 뒤, 두 SELECT 결과를 하나의 결과 집합으로 합쳐 출력
| name | id | price |
| Espresso | 101 | 4000 |
| Latte | 234 | 6000 |
| Mocha | 283 | 7000 |
| Affogato | 555 | 9000 |
| Matcha | 222 | 5000 |
| Chamomile | 757 | 5000 |
| Peppermint | 923 | 6000 |
| Lemon | 478 | 7000 |
| Rooibos | 111 | 5000 |
| [보충 설명] 선택된 열의 개수가 3개로 동일하고, 데이터 타입도 (문자열, 정수형, 정수형) 순서로 동일하기 때문에 UNION의 조건들을 모두 만족했습니다. 추가적으로 Column 이름은 첫 번째 SELECT 문의 Column을 기준으로 결정됩니다. |
2. Select name, price from coffee UNION Select name, price from coffee;
= coffee 테이블에서 name, price를 2번 조회한 뒤, 두 SELECT 결과를 하나의 결과 집합으로 합쳐 출력
| name | price |
| Espresso | 4000 |
| Latte | 6000 |
| Mocha | 7000 |
| Affogato | 9000 |
- 같은 테이블로도 UNION을 사용할 수 있습니다.
- UNION은 중복된 행을 제거해서 결과적으로 한 번 출력된 결과와 같은 결과를 보여줍니다.
- UNION ALL 같은 경우는 중복 제거를 하지 않기에 각 행들이 두 번씩 조회됩니다.
- (UNION ALL이 궁금하면 따로 찾아보세요)
[TryHackMe] SQL Injection - EP.1 (Task 1~3). END.
[TryHackMe] SQL Injection - EP.2 (Task 4~5). Continue...
https://anbymata.tistory.com/49
[THM] SQL Injection - EP.2 (Task 4~5)
TryHackMe - "SQL Injection". Task 4~5. Write-up + Extra Study!출처: https://tryhackme.com/room/sqlinjectionlm SQL InjectionLearn how to detect and exploit SQL Injection vulnerabilitiestryhackme.com [4] What is SQL Injection?SQL Injection- 사용자 입
anbymata.tistory.com
'TryHackMe > Web Hacking' 카테고리의 다른 글
| [THM] XSS - EP.1 (Task 1~3) (1) | 2026.02.25 |
|---|---|
| [THM] SQL Injection - EP.3 (Task 6~10). 完 (0) | 2026.02.16 |
| [THM] SQL Injection - EP.2 (Task 4~5) (0) | 2026.02.07 |
| [TryHackMe] OWASP Top 10: 2021 - EP.2 (Task 5~8) (0) | 2025.11.10 |
| [TryHackMe] OWASP Top 10: 2021 - EP.1 (Task 1~4) (0) | 2025.11.08 |