源码很长

    长代码审计(SSRF ME) - 图1

    长代码审计(SSRF ME) - 图2

    长代码审计(SSRF ME) - 图3

    我们先来分析一下源码:

    由开头我们可以知道这是flask框架写的

    其中有三个路由

    长代码审计(SSRF ME) - 图4

    • /geneSign:获得url中parma参数,通过getSign(action,param)生成摘要
    • /De1ta:获得cookie中的action和sign
      waf(param)长代码审计(SSRF ME) - 图5
      然后创建task对象,调用exce()方法,json格式返回
    • /:返回源码

    三个函数

    长代码审计(SSRF ME) - 图6

    • getSign:返回secert_key+param+action的哈希值
    • md5
    • waf:禁止了file和gopher协议

    task类

    长代码审计(SSRF ME) - 图7

    • checkSign:检查cookie中的sign
    • Exec:检查cookie中的action,如果scan在action中,将param的文件内容写入result.txt,如果read在action中,独处result.txt的内容

    hint提示flag在flag.txt中,想要读到他

    • action=scan,param=flag.txt 将flag.txt的内容读到result.txt中
    • 然后action=read,将result.txt的内容读出

    绕过点sign

    • checkSign会检查cookie中的sign==getSign(param,action)

    困难点

    • secert_key的值未知

    思路一:利用exce()直接读

    可以看出判断读和写的是两个if关系,也就是说如果action中既有scan,又有read,那么就会一次执行scan和read

    为什么呢?

    31行和41行对action的值进行了判断,但是他们这里用的是in而不是”==”,这意味着我们可以包含两种action

    sign值的构造

    回到getSign函数

    长代码审计(SSRF ME) - 图8

    对于secert_key+param+action

    虽然我们不知道secert_key

    但是我们发现param=flag.txt,action=readscan长代码审计(SSRF ME) - 图9

    和param=flag.txtread,action=scan

    长代码审计(SSRF ME) - 图10

    最后的哈希值应该是一样的

    为什么呢?

    因为这里是字符串连接起来的,举个例子

    长代码审计(SSRF ME) - 图11

    所以我们现在需要令action里面有scan和read这两个参数

    所以我们现在需要长代码审计(SSRF ME) - 图12

    虽然key不知道,但是这里

    长代码审计(SSRF ME) - 图13

    访问这个页面,我们可以得到一个getSign返回的md5值,不过action已经被写死为scan了。

    但是最后的时候我们还是需要读取flag.txt,所以我们令param为flag.txtread

    这样scan和read都在里面了

    访问这个网站我们可以得到sign

    长代码审计(SSRF ME) - 图14

    抓包上传参数就好

    长代码审计(SSRF ME) - 图15