Extract($_POST) or ($_GET)[php.net]
PHP에서
Extract
()
함수를 사용함에 있어서 발생할 수 있는 위험성을 알아본다.
Extract() 함수
Extract($_GET)과 같이 선언 될 경우
$_GET[id]가 의미하는 바와 $id가 의미하는 바가 같아진다.
서버 사이드 변수 조작(holyshield_CTF)
<?php $up="abc"; extract($_GET); $down="efg"; echo "u p : $up<br>"; echo "down: $down"; ?>
위와 소스코드와 같은 경우 extract 함수 위에 선언된 변수($up)의 경우 사용자 마음대로 수정이 가능하다.
http://localhost/index.php?up=123&down=456
u p : 123 down: efg
필터링 우회 (크리스마스 CTF)
<?php session_start(); extract($_GET); extract($_POST); foreach ( $_GET as $key => $value ) $$key = addslashes($value); foreach ( $_POST as $key => $value ) $$key = addslashes($value); echo "$uid <br>"; echo $_SESSION['uid']; ?>
위에 코드는 사용자 입력값에 대해 addslashes
를 하여 SQLi를 막는다.
GET data ?uid='123
라고 입력할 경우 \'123
와 같이 출력된다.
우회 방법 1
extract 문을 보면 GET 다음에 POST를 extract해주고 있다.
그말인 즉슨 $_POST가 _GET을 덮어 쓸수 있다는 뜻이다.
GET data = ?_SESSION[uid]='123
위와 같이 데이터를 주게 되면
POST data = ('_GET':'123')
POST에서 보낸 _GET이 기존의 _GET을 대체하게 되며,
진짜 _GET으로 보낸 $_SESSION[uid]
에 '123
이 대입 되며 세션 uid엔 ‘123이 저장된다.
또한 GET data ?uid='silnex
이렇게 보낼경우에도 당연히 uid에 ‘silnex 값이 고스란이 저장된다.
우회 방법 2 (hard?)
우회방법 1에선 _POST로 _GET을 덥어 씌웠다.
하지만 _GET으로 _GET을 덥어 씌울 수 있다.(??)
실제로
GET data ?_SESSION[uid]=silnex'&uid='123&_GET
위 데이터를 전송하게 되면 _GET이 _GET을 덮어서 uid와 세션uid에
각각 silnex’와 ‘123이 들어가게 된다.
point
Extract함수는 자기 자신 위에 존재하는 변수를 덮어 씌울 수 있다.
안녕하세요, 질문이 있어서 댓글드립니다.
첫번째 우회방법처럼 진행하면 GET으로 보낸 첫번째 데이터가 싱글쿼터가 붙어 세션에 저장되는데,
차 후에 POST로 _GET 변수를 덦어 써도 의미 없는거 아닌가요?
훔,, 예전에 작성한 글이라그런지 설명이 많이 빈약하군요;;
2번 우회 방법과 동일한 이유로 얻기위해 _GET으로 기존의 _GET을 덮어 씌우는 겁니다.