NOTE해킹하는 부엉이 - [초보자를 위한 PHP Tricks + RCE 기법들 소개] 발표를 정리하여 작성했습니다.
해당 발표의 발표자이신one3147님의 동의를 받고 작성하는 글입니다
요즘 CTF 나갈 때마다 느끼는 생각이 nodejs말고 다른 환경이 나오면 무기력해진다는 것이다.
nodejs는 계속 다뤄왔으니 해킹을 시작했을때부터 접근하기 쉬웠고 꽤 난이도 있는 문제들도 많이 풀어왔다.
그러나 php랑 python으로 작성된 백엔드 바이너리를 볼 때마다 벽을 느끼곤한다
어떻게 보완할지 고민하던 와중 TeamH4C에서 진행하는 해킹하는 부엉이들에서 One님이 진행하신 해당 발표를 접하게 되었고 정리해보려한다
PHP Tricks?
php에서는 (N)e(K) 형태의 문법을 지원한다. 이게 뭐냐면 대충 2e12로 표현하면 php가 같이 해석한다는거다.
이게 어떤식으로 악용 가능하냐면
if(md5('QNKCDZO') == 0)위와 같이 해시를 검증한다면 0e8304...이 되고 로 해석되어 True를 반환하게 된다.
이게 PHP 느슨한 비교를 사용하는 기법이랑 이어질 수가 있는데
if('1e2' == 100) {}문자열 삽입 -> number 타입과 비교 -> 1e2가 100으로 해석
PHP 문법
function sayHi() {
echo 'hi'
}
'hi'();-
php에서는 문자열 뒤에다
()넣어서 호출해도 함수가 호출된다고 한다. -
preg_로 시작하는 함수들은 정규표현식을 기반으로 구현된다. 따라서 ReDos 가능성이 존재한다
PHP LFI, RCE
<?php
include $_GET['path']
?>CTF하다보면 이런 코드 한 번쯤은 봤을 것이다
file:/// 프로토콜이랑 php wrapper들을 허용해서 LFI가 발생한다.
이는 이후 설명할 LFI to RCE로 연계 가능하다
그리고 자주 보이던 allow_url_includes가 켜져있으면 이런 코드에서 http 프로토콜 또한 허용해 include 한다.
allow_url_includes = On 이라면 원격에 있는 웹셸파일을 포함시켜 RCE하는 식의 기법도 있다
Log Poisoning RCE
LOG 파일에 payload를 주입해 LFI로 파일을 불러와 실행시키는 기법이다.
그냥 링크에 때려박으면 인코딩 되어 로그로 쓰여지기에, User Agent 같은 곳에 페이로드 삽입 후 /var/log/apache2/access.log 로그파일을 불러와 익스한다.
그러나 일반적으로는 access.log에 excute perm이 없어 RCE가 불가하기에 서버에서 파일에 실행 권한을 부여하는 취약점이 있지 않은 이상 트리거가 어렵다
PHP Session RCE
session 정보는 /var/lib/php/sessions/session_(session) 형태로 저장된다.
id나 password(대부분 해시 되겠지만) 같이 session에 저장되는 정보들에 php payload를 작성하고 LFI로 해당 파일을 로드한다면 페이로드를 실행할 수 있다
PHP Session Upload Progress RCE
session.upload_progress.enabled가 On일 때, 업로드 기능이 있는 엔드포인트에 다음과 같은 명령어를 전송하여 익스한다
curl url.kr/upload.php -H 'Cookie: PHPSESSID=mysession' -F 'PHP_SESSION_UPLOAD_PROGRESS=(BASE64 ENCODED RCE PAYLOAD)' -F 'upload=@/etc/passwd'그러면 /var/lib/php/sessions/session_my_sess가 생성되어 인코딩된 페이로드가 저장되고, 이를 LFI 포인트에서 php://filter/convert.base64-decode/resource=으로 불러와 RCE 가능하다
만약 session.upload_progress.cleanup 옵션이 켜져있다면 upload progress 이후 바로 제거되기에 익스할 틈이 안난다
따라서 이땐 Dos등 race condition 가능한 포인트를 찾은 후 큰 파일을 업로드하여 cleanup 타이밍을 지연시켜야한다.
PHP + Nginx LFI to RCE
https://bierbaumer.net/security/php-lfi-with-nginx-assistance/ 이거 읽어보고 적극적으로 활용해보도록 하자
Others
발표에선 언급 되지 않았으나 몇 개 더 찾아봤다
-
file(),hash_file(),file_get_contents(),copy()같은 함수에 값을 넣을 수 있다면 자료보고 익스를 시도해보자.error_based로 세션파일 내용 알아낼 수 있다. -
LFI 우회 기법중에
shell.p\\hp처럼\두 번 넣으면 우회되는 기법이 있다 -
해캠, SSU CTF에서 나왔던 기법이다.
$_GET['my_name.kr'];
// https://url?my_name.kr=1쿼리를 이처럼 받는다면 정상적으로 쿼리를 넣기 힘들 것이다. .이 _로 치환되어 해석해 버리기 때문이다.
_을 [로 대체해주자. SSU CTF 당시 어떤분의 설명에 의하면 [가 _로 치환되며 내부 조건문을 탈출하고 .은 건들지 않게 된다고 한다.
https://url?my[name.kr=1- 발표에서 BOM Mapping도 나왔는데 나중에 정리해보겠다
정말 도움 되었다..! 웹 해킹 공부 시작 초반부터 One님 블로그 정독하며 공부해왔는데 다시 한 번 감사하다는 말씀 드리고 싶다