[HTB] Facts (Easy_Linux)
🔐 보호된 게시글
이 게시글을 보려면 비밀번호를 입력해주세요
시작에 앞서
오랜만에 여행을 다녀온 후 진행한 HTB 문제풀이다.
그것도 이번엔 놓치지 않고 Season 10에 나온 문제들을 풀기 시작했다. 이미 늦게 시작한 듯 하긴 하다만.
이번 문제는 Linux이며 권한 상승은 정말 간단하고 쉬웠지만, 이상하리마치 유저 획득에서 좀 많이 해매었던 문제라고 볼 수 있겠다.
어쩌면 내가 CVE가 아닌 직접 오픈소스 코드를 뜯어보거나 웹 페이지들을 분석해서 풀어보려하여 더 그랬을 수도 있겠다.
정찰 및 정보 수집 (Reconnaissance & Enumeration)
처음 ip를 받아 nmap 기본 스크립트를 돌려보았을 때에 22번 포트에 ssh가, 80번 포트에서는 http://facts.htb/로 리다이렉트 된다는 것을 알았기에 /etc/hosts에 도메인을 추가해줬다.
그 후 다시 스캔을 진행하니,
위처럼 facts라는 타이틀의 사이트를 발견할 수 있었다.
사이트에 접속하여 보면 뭔가 그냥 여러 정보가 있다고 설명이 쓰여있다. 킬링타임용 사이트라는데 뭐하는 곳이려나?
일단 Wappalyzer을 통해 사이트 스택을 살펴보니 Ruby로 만들어졌다 등이 있었으나 아직 내 눈엔 딱히 중요해보이는 것이 없었다.
메인 페이지를 계속 살펴보자면 아래쪽엔 회사 정보나 리뷰가 있고,
게시글이 있어 들어가보니,
곰 사진과 아래엔 댓글들이 있었다.
근데 이 외에 뭔가 클릭을 통해 넘어갈 수 있는 로그인 페이지도 없고(댓글 어케 달았누) 게시글을 올릴 수 있는 부분도 없고, 다운 받거나 뭔갈 올릴 수 있는 부분도 없었다. 그러니 이제 디렉터리 브루트포싱을 위해 gobuster 혹은 dirsearch를 돌려보자.
사실 도구를 이용할 때에 gobuster에 쓴 list(directory-list-2.3-small.txt) 가 너무 커서 그런지 좀 많이 오래걸렸기에 충분히 수상한 것이 있다 싶어 모든 리스트를 쓰기 전에 멈췄고 추가적인 dirsearch의 결과도 거의 비슷했다.
- /index
- /search
- /rss
- /sitemap
- /en
- /page
- /welcome
- /admin
- /post
- /ajax
- /Index
- /up
- /404
- /robots
- /error
- /captcha
위 링크들을 다 들어가보긴 했는데
첨보는 up.php는 그린 스크린처럼 아무 것도 없이 그저 초록색만 있었고,
search는 이름 그대로 검색 하는 부분이였는데 혹시 이 검색창에 공격할 수 있는 부분이 있지 않을까 예상은 해보았으나 딱히 찾지 못했기에 다음으로 넘어갔다.
rss는
라고 하는데 딱히 의미가 없어보였고,
바~로 요기! /admin/login이 우리가 찾던 로그인이 가능한 페이지였다!
근데 좀 특이했던건 이 페이지의 url이 /admin에 있다는건데 그럼 여기 회원가입을 하면 그냥 어드민으로써 로그인 할 수 있다는 의미인걸까? 하는 생각과 함꼐 회원가입 후 로그인을 진행했다.
초기 침투 (Initial Foothold / Exploitation)
회원가입 부분은 매우 간단하니 진짜 회원가입 하듯 진행하면 되고, 이후 로그인에 성공하게되면 위처럼 dashboard를 볼 수가 있는데 보아하니 뭔가 내가 사이트를 만들고 그것에 대한 dashboard 여야하는 듯 한데….
아까 예상했듯 이름만 /admin이지 아무래도 user의 계정으로 로그인 되어 사이트를 만들거나 할 수는 없었다. 게다가 댓글을 달 수 있는 것도 아니였고. 그럼 계정을 만드는 의미가 있나?
그나마 추가적인 정보라면 Camaleon CMS로 만들어졌으며 버전 2.9.0이라는 것이겠다.
대시보드에서는 할 수 있는 것이 없으니 Profile을 눌러 계정 프로필로 넘어가면,
개인정보 수정을 할 수 있게 되는데
여기서도 뭘 할 수 있을까 둘러보다 Role이라는 부분이 좀 거슬렸다.
아무래도 지금 내가 Client이기에 뭔가 페널에서 더 볼 수 있는 것이 없는듯 했고 코드를 보니 Client말고 Administrator, contributor, editor도 존재함을 확인할 수 있었다.
그리고 여기서 Change Photo나 Update, Change Password 등을 하며 Burpsuite로 찍어봤는데
여기서 Change Password 부분을 진행할 때 유일하게 /admin/users/5/update_ajax를 통해 정보를 변경시킨 다는 것을 알 수 있었다.
다른 변경은 /admin/users/5를 통해 진행되었고 여기에서는 뭘 변경하든 추가적으로 되는 것이 없었고, 유일하게 좀 다른 update_ajax를 노려보기로 했다… 만! 나는 이런 리퀘스트 정보나 이런걸 수정해본 적이 없었기 때문에 솔직히 뭘 써넣어야 하는지 전혀 감을 잡지 못했다.
그래서 공식 camaleon cms 코드를 들어가 둘러보기로 했다.
그리고 공식 github(오픈소스라서)를 하나씩 열어가며 구경하다다 params부분에 정보를 넣는다는 것을 알게되었고…
그럼에도 역시 뭘 해야할지 감을 못잡았다. 애초에 뒤에 나오겠지만 이 부분을 봐도 이게 취약한지 뭔지 전혀 알 수 있는 부분이 아니기도 했고 말이다.
그래서 이번엔 제미니 선생님께 도움을 요청했고 다음 과정을 통해 관리자 권한을 얻을 수 있다는 것을 알 수 있었다.
너무 작아서 보일지는 모르겠지만 위 과정이 비밀번호 변경 요청을 보낼 때에 날라가는 정보들이고 본래는 password_confirmation%5D=0000으로 끝나야 하지만 마지막 부분에 추가로 &password[role]=admin을 추가해 내 권한을 admin으로 변경하는 요청을 보냈다.
그렇게! 내 계정은 관리자 권한(admin)을 얻게 되었다.
취약점에 대해서 (CVE-2025-2304)
위에서 문제를 풀 때 이해한 내용은 사실 잘못된 부분이 있었다. 특히 코드 분석 부분.
그러나 사실 이게 그냥 camaleon CMS 2.9.0 exploit이라고 검색만 해도 나오는 CVE가 있었다는 사실. 하긴 그러니까 이번 HTB에 머신이 올라온거겠지?
CVE는 CVE-2025-2304로 우리가 했던 작업 그대로이다.
그리고 위 CVE 익스플로잇 코드를 보니 내가 처음에 user[role]=admin 라고 시도 했었는데 그게 아니라 password[role]=admin으로 해야 했다는 것을 알 수 있었다.
다만 내가 위에서 말했듯 내가 찾았던 부분은 딱히 취약하다고 볼만한 부분이 존재하지 않았고 (그니까 사실 내가 코드 분석을 잘못했고 그냥 문제를 풀기 위해 짱구 굴리다가 해결했다는 의미…)
그렇다보니 사실 내가 보고있던 공식 Camaleon CMS의 코드들은 이미 패치가 끝난 2.9.1이였는데 위 이미지처럼 이미 모두 패치가 끝난 코드를 보면서 ‘아 여기가 취약점이네’ 이러고 있었던 것이다. 세상에…
그래서 찾아낸 2.9.0 버전의 취약 코드인데 d3vn0mi/cve-2025-2304-poc 여기에서 발췌했다.
Alien0ne/CVE-2025-2304 여기에도 자세히 나와있긴 한데 이번 문제를 풀때랑 비교했을 때 좀 이상한 것은 위에 나온 d3vn0mi의 readme에서는 내가 처음 시도했다가 실패했던 user[role]=admin을 사용하고 Alien0ne의 코드에서는 password[role]=admin을 사용한다는 것이다.
이왕 잘못 이해한 김에 다시 블로그를 작성하며 poc 코드들을 좀 읽어봤는데
d3vn0mi의 README에서만 그렇게 써둔거지 사실 모든 가능성을 열어두고 싹다 시도해보는거였다.
그저 차이점이라면 권한 상승(프로필)을 시도할 때에 나는 비밀번호 변경(Password Change)를 시도했었기에 password[role]이 되어야 했던거고 만약 프로필 수정 (Update Profile)을 했다면 user[role]을 했어야 했던 것이다.
그럼 다시 취약한 코드로 돌아와,
1
@user.update(params.require(:password).permit!)
여기서 permit! 이 문제아였다. 이렇게 쓰게되면 password라는 이름의 묶음(Key)안에 들어있는 모든 데이터를 DB에 업데이트하겠다고 허용하는 상황이 되기에 공격자(ME) 가 HTTP 패킷을 가로채서(Burpsuite) password[role]=admin을 추가하자 서버는 “password묶음 안에 role이 있네? 이것도 업데이트 해줄게!” 라며 계정을 관리자로 승격시켜버린 것이다.
그럼 2.9.1 버전에서는 어떻게 업데이트가 되었는지 볼까?
1
@user.update(password: attrs.require(:password), password_confirmation: attrs.require(:password_confirmation))
위 코드부분처럼 이젠 덩어리를 업데이트 하는게 아니라 password와 password_confirmation만 업데이트하도록 변경되었다.
다시 초기 침투로 돌아와
취약점을 이용해 admin 계정을 얻게 되었고 일반 유저일 때와 달리 왼쪽 패널에 훨씬 많은 것들이 보이기 시작했다.
그렇게 둘러보던 중 Site -> Configuration Site에서 AWS 정보를 찾아낼 수 있었다.
그렇게 찾아낸 정보를 토대로
aws configure --profile facts를 통해 AWS설정을 진행하고
randomfacts와 internal을 둘러보면 internal에만 접속할 수 있었고
중요해보이는 .ssh에 들어있는 파일을들 다운받아줬다.
사실 궁금해서 다 다운받았었다.
authorized_keys에는 Ed25519 키를 사용하고 있다는 것을 알려주고 있고 id_ed25519를 이용해 SSH 접속을 위한 Private Key는 얻긴 했으나 접속을 시도해 보았을 때에 분명 비밀번호가 있었기에 결국 john을 이용해 크래킹을 시도할 수 밖에 없었다.
근데 이 자체로 john을 돌릴 수는 없기에 ssh2john.py 툴을 이용해 해시를 추출하고
rockyou.txt를 이용해 크래킹을 시도했고 dragonballz라는 비밀번호를 찾아냈다!
하지만 지금 상황에서 정작 계정에 대한 내용이 없기에 ssh에 로그인 할 수 있는 경로가 없었다.
그리고 이번에는 사실 위 부분에서 시간을 너무 썼기에 바로 CVE를 찾아보기 시작했고
CVE-2024-46987를 찾아냈다.
무려 경로 탐색 취약점을 이용한 파일 다운로드가 가능했다.
근데 사실 CVE를 보면 알듯이 이게 좀 오래된 취약점이였는데보니까 분명히 2.8.0버전의 취약점이였지만 strangely work on 2.9.0 too라고 쓰여있다.
그렇게 https:///admin/media/download_private_file?file=../../../../../../etc/passwd을 통해 리눅스 사용자 정보가 담긴 파일을 꺼내와 확인해보니 trivia라는 유저가 눈에 띄였다.
아니, 사실 모든 유저로 시도했는데 잘 생각해보니 이거랑 william이 그나마 가능성이 있어보였다.
그렇게 ssh 접속에 성공했고
지금 로그인한 trivia가 아닌 william의 파일에 들어가 user.txt를 읽을 수 있었다.
스크립트 키디는 쉬우나 코드 분석은 어렵구나…
권한 상승 (Privilege Escalation)
여기부턴 권한 상승인데 또 출근해야해서.. 2026-02-12 22:46