Skip to content

Commit

Permalink
增加了插件相关的内容,让他更好用了
Browse files Browse the repository at this point in the history
  • Loading branch information
v1ll4n committed Nov 13, 2021
1 parent e1ef1a9 commit 2951e04
Show file tree
Hide file tree
Showing 6 changed files with 269 additions and 38 deletions.
91 changes: 77 additions & 14 deletions app/renderer/src/main/src/pages/MainOperator.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
import React, {useEffect, useState} from "react";
import {Button, Col, Divider, Image, Input, Layout, Menu, Popconfirm, Popover, Row, Space, Spin, Tabs, Tag} from "antd";
import {
Button,
Col,
Divider,
Image,
Input,
Layout,
Menu,
Modal,
Popconfirm,
Popover,
Row,
Space,
Spin,
Tabs,
Tag
} from "antd";
import {ContentByRoute, MenuDataProps, Route, RouteMenuData} from "../routes/routeSpec";
import {
CloseOutlined,
Expand All @@ -16,7 +32,8 @@ import {AutoUpdateYakModuleButton, YakitVersion, YakVersion} from "../utils/basi
import {CompletionTotal, setCompletions} from "../utils/monacoSpec/yakCompletionSchema";
import {randomString} from "../utils/randomUtil";
import MDEditor from '@uiw/react-md-editor';
import {genDefaultPagination, QueryYakScriptsResponse, YakScript} from "./invoker/schema";
import {genDefaultPagination, QueryYakScriptRequest, QueryYakScriptsResponse, YakScript} from "./invoker/schema";
import {showByCursorContainer} from "../utils/showByCursor";

export interface MainProp {
tlsGRPC?: boolean
Expand Down Expand Up @@ -77,6 +94,30 @@ export const Main: React.FC<MainProp> = (props) => {
const [currentTabKey, setCurrentTabKey] = useState("");
const [tabLoading, setTabLoading] = useState(false);

const closeCacheByRoute = (r: Route) => {
setPageCache(pageCache.filter(i => `${i.route}` !== `${r}`))
}

const closeAllCache = () => {
Modal.confirm({
title: "确定要关闭所有 Tabs?",
content: "这样将会关闭所有进行中的进程",
onOk: () => {
setPageCache([])
}
})
}

const closeOtherCache = (id: string) => {
Modal.confirm({
title: "确定要除此之外所有 Tabs?",
content: "这样将会关闭所有进行中的进程",
onOk: () => {
setPageCache(pageCache.filter(i => i.id === id))
}
})
}

const removeCache = (id: string) => {
setPageCache(pageCache.filter(i => i.id !== id))
};
Expand Down Expand Up @@ -127,7 +168,8 @@ export const Main: React.FC<MainProp> = (props) => {

ipcRenderer.invoke("QueryYakScript", {
Pagination: genDefaultPagination(1000), IsGeneralModule: true,
}).then((data: QueryYakScriptsResponse) => {
Type: "yak",
} as QueryYakScriptRequest).then((data: QueryYakScriptsResponse) => {
setExtraGeneralModule(data.Data)
})
}
Expand Down Expand Up @@ -435,17 +477,38 @@ export const Main: React.FC<MainProp> = (props) => {
>
<EditOutlined/>
</Popover>
<CloseOutlined onClick={() => {
setTabLoading(true)
const key = i.id;
const targetIndex = getCacheIndex(key)
if (targetIndex > 0 && pageCache[targetIndex - 1]) {
const targetCache = pageCache[targetIndex - 1];
setCurrentTabKey(targetCache.id)
}
removeCache(key);
setTimeout(() => setTabLoading(false), 300)
}}/>
<CloseOutlined
onContextMenu={(e) => {
showByCursorContainer({
content: <>
<Space direction={"vertical"}>
<Button
type={"link"}
onClick={() => {
closeAllCache()
}}
size={"small"}>关闭所有Tabs</Button>
<Button type={"link"}
onClick={() => closeCacheByRoute(i.route)}
size={"small"}>关闭同类Tabs</Button>
<Button type={"link"}
onClick={() => closeOtherCache(i.id)}
size={"small"}>关闭其他Tabs</Button>
</Space>
</>
}, e.clientX, e.clientY)
}}
onClick={() => {
setTabLoading(true)
const key = i.id;
const targetIndex = getCacheIndex(key)
if (targetIndex > 0 && pageCache[targetIndex - 1]) {
const targetCache = pageCache[targetIndex - 1];
setCurrentTabKey(targetCache.id)
}
removeCache(key);
setTimeout(() => setTabLoading(false), 300)
}}/>
</Space>}>
<Spin spinning={tabLoading}>
{i.node}
Expand Down
169 changes: 163 additions & 6 deletions app/renderer/src/main/src/pages/invoker/YakScriptCreator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@ import {InputItem, ManyMultiSelectForString, ManySelectOne, SelectOne, SwitchIte
import {YakScript, YakScriptParam} from "./schema";
import {YakEditor} from "../../utils/editors";
import {PlusOutlined} from "@ant-design/icons";
import {showModal} from "../../utils/showModal";
import {showDrawer, showModal} from "../../utils/showModal";
import {failed, info} from "../../utils/notification";
import {putValueToParams, YakScriptParamsSetter} from "./YakScriptParamsSetter";
import {YakScriptRunner} from "./ExecYakScript";
import {FullscreenOutlined, FullscreenExitOutlined} from "@ant-design/icons"

export interface YakScriptCreatorFormProp {
onCreated?: (i: YakScript) => any
modified?: YakScript
onChanged?: (i: YakScript) => any
}

const {ipcRenderer} = window.require("electron");
Expand All @@ -20,6 +22,7 @@ export const mitmPluginTemplate = `# mitm plugin template
yakit_output(MITM_PARAMS)
#-----------------------MITM Hooks I/O-------------------------
/*
#如何使用插件参数?
Expand All @@ -30,11 +33,32 @@ urlKeyword = MITM_PARAMS["url_keyword"]
yakit_output(i: any) // 可以只输出到 "Console 界面"
yakit_save(i: any) // 可以输出并保存到数据库中,在 "插件输出" 中查看
*/
#----------------MITM Hooks Test And Quick Debug-----------------
/*
# __test__ 是 yakit mitm 插件用于调试的函数 【注意:这个函数在 MITM hooks劫持环境下不会被导入】
在这个函数中,你可以使用 yakit.GenerateYakitMITMHooksParams(method: string, url: string, opts ...http.Option) 来方便的生成可供 hooks 调用的参数,参考代码模版中的用法~
*/
#--------------------------WORKSPACE-----------------------------
__test__ = func() {
results, err := yakit.GenerateYakitMITMHooksParams("GET", "https://example.com")
if err != nil {
return
}
isHttps, url, reqRaw, rspRaw, body = results
mirrorHTTPFlow(results...)
mirrorFilteredHTTPFlow(results...)
mirrorNewWebsite(results...)
mirrorNewWebsitePath(results...)
mirrorNewWebsitePathParams(results...)
}
# mirrorHTTPFlow 会镜像所有的流量到这里,包括 .js / .css / .jpg 这类一般会被劫持程序过滤的请求
mirrorHTTPFlow = func(isHttps /*bool*/, url /*string*/, req /*[]byte*/, rsp /*[]byte*/, body /*[]byte*/) {
Expand All @@ -59,7 +83,6 @@ mirrorNewWebsitePath = func(isHttps /*bool*/, url /*string*/, req /*[]byte*/, rs
mirrorNewWebsitePathParams = func(isHttps /*bool*/, url /*string*/, req /*[]byte*/, rsp /*[]byte*/, body /*[]byte*/) {
}
`

export const mitmPluginTemplateShort = `# mirrorHTTPFlow 会镜像所有的流量到这里,包括 .js / .css / .jpg 这类一般会被劫持程序过滤的请求
Expand Down Expand Up @@ -103,9 +126,18 @@ export const YakScriptCreatorForm: React.FC<YakScriptCreatorFormProp> = (props)
});
const [paramsLoading, setParamsLoading] = useState(false);
const [modified, setModified] = useState<YakScript | undefined>(props.modified);
const [fullscreen, setFullscreen] = useState(false);
const [loading, setLoading] = useState(false);

const isNucleiPoC = params.Type === "nuclei";

const debugButton = (primary?: boolean) => {
if (loading) {
return <Button disabled={true}>执行中...无法调试</Button>
}
return
}

useEffect(() => {
if (paramsLoading) {
setTimeout(() => {
Expand Down Expand Up @@ -135,6 +167,7 @@ export const YakScriptCreatorForm: React.FC<YakScriptCreatorFormProp> = (props)
ipcRenderer.invoke("SaveYakScript", params).then((data) => {
info("创建 / 保存 Yak 脚本成功")
props.onCreated && props.onCreated(params)
props.onChanged && props.onChanged(data)
}).catch(e => {
failed(`保存 Yak 模块失败: ${e}`)
})
Expand Down Expand Up @@ -246,27 +279,59 @@ export const YakScriptCreatorForm: React.FC<YakScriptCreatorFormProp> = (props)

</List>
</Form.Item> : ""}
<Form.Item label={"源码"}>
<div style={{height: 400}}>
<Form.Item label={"源码"} help={<>
<Button icon={<FullscreenOutlined/>}
onClick={() => {
setFullscreen(true)
let m = showDrawer({
title: "Edit Code",
width: "100%",
closable: false,
keyboard: false,
content: <>
<YakScriptLargeEditor
script={params}
onExit={(data) => {
m.destroy()
setFullscreen(false)
ipcRenderer.invoke("QueryYakScript", {})
}}
onUpdate={(data: YakScript) => {
props.onChanged && props.onChanged(data)
setParams({...data})
}}
/>
</>
})
}}
type={"link"} style={{
marginBottom: 12, marginTop: 6
}}>大屏模式</Button>
</>}>
{!fullscreen && <div style={{height: 400}}>
<YakEditor
type={"yak"}
setValue={Content => setParams({...params, Content})}
value={params.Content}
/>
</div>
</div>}
</Form.Item>
<Form.Item colon={false} label={" "}>
<Space>
<Button type="primary" htmlType="submit"> {modified ? "修改当前" : "创建新的"} Yak 模块 </Button>
<Button
// type={primary ? "primary" : undefined}
disabled={[
"mitm",
// "mitm",
"",
].includes(params.Type)}
onClick={() => {
setLoading(true)
ipcRenderer.invoke("SaveYakScript", params).then((data: YakScript) => {
info("创建 / 保存 Yak 脚本成功")
setModified(data)
setParams(data)
props.onChanged && props.onChanged(data)
// YakScriptParamsSetter
if (data.Params.length <= 0) {
showModal({
Expand Down Expand Up @@ -295,6 +360,8 @@ export const YakScriptCreatorForm: React.FC<YakScriptCreatorFormProp> = (props)

}).catch(e => {
failed(`保存 Yak 模块失败: ${e}`)
}).finally(() => {
setTimeout(() => setLoading(false), 400)
})
}}> 调试:创建(修改)并立即执行 </Button>
</Space>
Expand Down Expand Up @@ -368,4 +435,94 @@ export const CreateYakScriptParamForm: React.FC<CreateYakScriptParamFormProp> =
</Form.Item>
</Form>
</>
};

export interface YakScriptLargeEditorProp {
script: YakScript
onUpdate: (data: YakScript) => any
onExit: (data: YakScript) => any
}

export const YakScriptLargeEditor: React.FC<YakScriptLargeEditorProp> = (props) => {
const {script} = props;
const [params, setParams] = useState<YakScript>({...script})

useEffect(() => {
setParams({...script})
}, [props.script])

return <>
<Card title={`ScriptName: ${params.ScriptName}`} extra={[
<Space>
<Button danger={true} onClick={() => {
// m.destroy()
// setFullscreen(false)
ipcRenderer.invoke("SaveYakScript", params).then((data) => {
info("创建 / 保存 Yak 脚本成功")
props.onUpdate(data)
// setModified(data)
}).catch(e => {
failed(`保存 Yak 模块失败: ${e}`)
}).finally(() => {
props.onExit(params)
})
}}>退出编辑界面</Button>
<Button
disabled={[
// "mitm",
"",
].includes(params.Type)}
onClick={() => {
ipcRenderer.invoke("SaveYakScript", params).then((data: YakScript) => {
info("创建 / 保存 Yak 脚本成功")
props.onUpdate(data)
// setModified(data)
// setParams(data)
// props.onChanged && props.onChanged(data)
// YakScriptParamsSetter
if (data.Params.length <= 0) {
showModal({
title: "立即执行", width: 1000,
content: <>
<YakScriptRunner script={data} params={[]}/>
</>
})
} else {
let m = showModal({
title: "确认想要执行的参数",
width: "70%",
content: <>
<YakScriptParamsSetter params={[]} {...data} onParamsConfirm={params => {
m.destroy()
showModal({
title: "立即执行", width: 1000,
content: <>
<YakScriptRunner script={data} params={params}/>
</>
})
}}/>
</>
})
}

}).catch(e => {
failed(`保存 Yak 模块失败: ${e}`)
}).finally(() => {
// setTimeout(() => setLoading(false), 400)
})
}}> 调试:创建(修改)并立即执行 </Button>
</Space>
]} bodyStyle={{padding: 0}}>
<div style={{
width: "100%",
height: 1000,
}}>
<YakEditor
type={"yak"}
setValue={Content => setParams({...params, Content})}
value={params.Content}
/>
</div>
</Card>
</>
};
Loading

0 comments on commit 2951e04

Please sign in to comment.