Skip to content

Commit

Permalink
分享导入流程优化
Browse files Browse the repository at this point in the history
  • Loading branch information
VillanCh committed Aug 27, 2022
1 parent c5174ea commit 3e9a5d1
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 97 deletions.
162 changes: 87 additions & 75 deletions app/renderer/src/main/src/pages/fuzzer/HTTPFuzzerPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ import {failed, info, success} from "../../utils/notification"
import {AutoSpin} from "../../components/AutoSpin"
import {ResizeBox} from "../../components/ResizeBox"
import {useGetState, useMemoizedFn} from "ahooks"
import {getRemoteValue, getValue, saveValue, setRemoteValue} from "../../utils/kv"
import {getRemoteValue, getValue, saveValue, setRemoteValue, setRemoteValueTTL} from "../../utils/kv"
import {HTTPFuzzerHistorySelector} from "./HTTPFuzzerHistory"
import {PayloadManagerPage} from "../payloadManager/PayloadManager"
import {HackerPlugin} from "../hacker/HackerPlugin"
Expand Down Expand Up @@ -133,7 +133,7 @@ export interface FuzzerResponse {
StatusCode: number
Host: string
ContentType: string
Headers: {Header: string; Value: string}[]
Headers: { Header: string; Value: string }[]
ResponseRaw: Uint8Array
RequestRaw: Uint8Array
BodyLength: number
Expand Down Expand Up @@ -213,10 +213,10 @@ function filterIsEmpty(f: FuzzResponseFilter): boolean {
)
}

function copyAsUrl(f: {Request: string; IsHTTPS: boolean}) {
function copyAsUrl(f: { Request: string; IsHTTPS: boolean }) {
ipcRenderer
.invoke("ExtractUrl", f)
.then((data: {Url: string}) => {
.then((data: { Url: string }) => {
callCopyToClipboard(data.Url)
})
.catch((e) => {
Expand Down Expand Up @@ -371,7 +371,7 @@ export const HTTPFuzzerPage: React.FC<HTTPFuzzerPageProp> = (props) => {
ipcRenderer.invoke("HTTPFuzzer", {HistoryWebFuzzerId: id}, fuzzToken).then(() => {
ipcRenderer
.invoke("GetHistoryHTTPFuzzerTask", {Id: id})
.then((data: {OriginRequest: HistoryHTTPFuzzerTask}) => {
.then((data: { OriginRequest: HistoryHTTPFuzzerTask }) => {
setHistoryTask(data.OriginRequest)
})
})
Expand Down Expand Up @@ -507,7 +507,8 @@ export const HTTPFuzzerPage: React.FC<HTTPFuzzerPageProp> = (props) => {
return Buffer.from(item.ResponseRaw).toString("utf8").match(new RegExp(keyword, "g"))
})
setFilterContent(filters)
} catch (error) {}
} catch (error) {
}
}, 500)
)
}
Expand Down Expand Up @@ -535,8 +536,8 @@ export const HTTPFuzzerPage: React.FC<HTTPFuzzerPageProp> = (props) => {
search === ""
? content || []
: (content || []).filter((i) => {
return Buffer.from(i.ResponseRaw).toString().includes(search)
})
return Buffer.from(i.ResponseRaw).toString().includes(search)
})
const successResults = filtredResponses.filter((i) => i.Ok)
const failedResults = filtredResponses.filter((i) => !i.Ok)

Expand Down Expand Up @@ -567,7 +568,8 @@ export const HTTPFuzzerPage: React.FC<HTTPFuzzerPageProp> = (props) => {
let reason = "未知原因"
try {
reason = content[0]!.Reason
} catch (e) {}
} catch (e) {
}
return (
<HTTPPacketEditor
system={props.system}
Expand Down Expand Up @@ -613,7 +615,7 @@ export const HTTPFuzzerPage: React.FC<HTTPFuzzerPageProp> = (props) => {
readOnly={true}
extra={
<Space>
{loading && <Spin size={"small"} spinning={loading} />}
{loading && <Spin size={"small"} spinning={loading}/>}
{onlyOneResponse ? (
<Space>
{content[0].IsHTTPS && <Tag>{content[0].IsHTTPS ? "https" : ""}</Tag>}
Expand All @@ -629,7 +631,7 @@ export const HTTPFuzzerPage: React.FC<HTTPFuzzerPageProp> = (props) => {
})
}}
type={"primary"}
icon={<ProfileOutlined />}
icon={<ProfileOutlined/>}
>
详情
</Button>
Expand All @@ -640,7 +642,7 @@ export const HTTPFuzzerPage: React.FC<HTTPFuzzerPageProp> = (props) => {
setContent([])
}}
danger={true}
icon={<DeleteOutlined />}
icon={<DeleteOutlined/>}
/>
</Space>
</Space>
Expand Down Expand Up @@ -718,58 +720,64 @@ export const HTTPFuzzerPage: React.FC<HTTPFuzzerPageProp> = (props) => {
}

setLoading(true)
ipcRenderer
.invoke("IsMultipartFormDataRequest", {
Request: StringToUint8Array(props.request || "", "utf8")
})
.then((e: {IsMultipartFormData: boolean}) => {
if (e.IsMultipartFormData) {
showModal({
title: "潜在的数据包编码问题提示",
content: (
<Space direction={"vertical"}>
<Space>
getRemoteValue(ALLOW_MULTIPART_DATA_ALERT).then(e => {
if (e === "1") {
setLoading(false)
return
}
ipcRenderer
.invoke("IsMultipartFormDataRequest", {
Request: StringToUint8Array(props.request || "", "utf8")
})
.then((e: { IsMultipartFormData: boolean }) => {
if (e.IsMultipartFormData) {
const notify = showModal({
title: "潜在的数据包编码问题提示",
content: (
<Space direction={"vertical"}>
<Space>
<Typography>
<Text>当前数据包包含一个</Text>
<Text mark={true}>原始文件内容 mutlipart/form-data</Text>
<Text>文件中的不可见字符进入编辑器将会被编码导致丢失信息。</Text>
</Typography>
</Space>
<Typography>
<Text>当前数据包包含一个</Text>
<Text mark={true}>原始文件内容 mutlipart/form-data</Text>
<Text>文件中的不可见字符进入编辑器将会被编码导致丢失信息。</Text>
<Text>一般来说,上传文件内容不包含不可见字符时,没有信息丢失风险</Text>
</Typography>
</Space>
<Space>
<Typography>
<Button
type={"link"}
size={"small"}
onClick={() => {
ipcRenderer
.invoke("FixUploadPacket", {
Request: StringToUint8Array(props.request || "", "utf8")
})
.then((fixed: {Request: Uint8Array}) => {
setRequest(Uint8ArrayToString(fixed.Request, "utf8"))
refreshRequest()
})
}}
>
点击替换
</Button>
<Text>后,会替换掉原始文件内容</Text>
</Typography>
</Space>
<br />
<Space>
<Typography>
<Text>如需要插入具体文件内容,可右键</Text>
<Text mark={true}>插入文件</Text>
<Text>如果上传文件内容包含图片,将有可能导致</Text>
<Text mark={true}>PNG 格式的图片被异常编码,</Text>
<Text>破坏图片格式,导致</Text>
<Text mark={true}>图片马</Text>
<Text>上传失败</Text>
</Typography>
<br/>
<Space>
<Typography>
<Text>如需要插入具体文件内容,可右键</Text>
<Text mark={true}>插入文件</Text>
</Typography>
</Space>
<br/>
<Checkbox onChange={(e) => {
if (e.target.checked) {
setRemoteValueTTL(ALLOW_MULTIPART_DATA_ALERT, "1", 3600 * 24 * 7)
notify.destroy()
} else {
setRemoteValueTTL(ALLOW_MULTIPART_DATA_ALERT, "0", 3600 * 24 * 7)
}
}}>一周内不提醒</Checkbox>
<Button type={"primary"} onClick={() => notify.destroy()}>我知道了</Button>
</Space>
</Space>
),
width: "40%"
})
}
})
.finally(() => setLoading(false))
),
width: "40%"
})
}
}).finally(() => setLoading(false))
}).catch(e => {
setLoading(false)
})
}, [props.request])
const getShareContent = useMemoizedFn((callback) => {
const params: ShareValueProps = {
Expand Down Expand Up @@ -839,7 +847,17 @@ export const HTTPFuzzerPage: React.FC<HTTPFuzzerPageProp> = (props) => {
发送数据包
</Button>
)}
<ShareData module='fuzzer' getShareContent={getShareContent} />
<Checkbox checked={isHttps} onChange={() => setIsHttps(!isHttps)}>
强制 HTTPS
</Checkbox>
<SwitchItem
label={"高级配置"}
formItemStyle={{marginBottom: 0}}
value={advancedConfig}
setValue={setAdvancedConfig}
size={"small"}
/>
<ShareData module='fuzzer' getShareContent={getShareContent}/>
<Popover
trigger={"click"}
placement={"bottom"}
Expand All @@ -854,20 +872,12 @@ export const HTTPFuzzerPage: React.FC<HTTPFuzzerPageProp> = (props) => {
</div>
}
>
<Button size={"small"} type={"link"} icon={<HistoryOutlined />}>
<Button size={"small"} type={"link"} icon={<HistoryOutlined/>}>
历史
</Button>
</Popover>
<Checkbox checked={isHttps} onChange={() => setIsHttps(!isHttps)}>
强制 HTTPS
</Checkbox>
<SwitchItem
label={"高级配置"}
formItemStyle={{marginBottom: 0}}
value={advancedConfig}
setValue={setAdvancedConfig}
size={"small"}
/>


{droppedCount > 0 && <Tag color={"red"}>已丢弃[{droppedCount}]个响应</Tag>}
{onlyOneResponse && content[0].Ok && (
<Form.Item style={{marginBottom: 0}}>
Expand Down Expand Up @@ -900,7 +910,7 @@ export const HTTPFuzzerPage: React.FC<HTTPFuzzerPageProp> = (props) => {
)}
{loading && (
<Space>
<Spin size={"small"} />
<Spin size={"small"}/>
<div style={{color: "#3a8be3"}}>sending packets</div>
</Space>
)}
Expand Down Expand Up @@ -1294,7 +1304,8 @@ export const HTTPFuzzerPage: React.FC<HTTPFuzzerPageProp> = (props) => {
refreshRequest()
}
})
.finally(() => {})
.finally(() => {
})
}}
size={"small"}
>
Expand Down Expand Up @@ -1331,7 +1342,7 @@ export const HTTPFuzzerPage: React.FC<HTTPFuzzerPageProp> = (props) => {
</div>
}
>
<Button size={"small"} type={"link"} icon={<HistoryOutlined />} />
<Button size={"small"} type={"link"} icon={<HistoryOutlined/>}/>
</Popover>
</Space>
}
Expand Down Expand Up @@ -1439,7 +1450,8 @@ export const HTTPFuzzerPage: React.FC<HTTPFuzzerPageProp> = (props) => {
setUrlPacketShow(false)
}
})
.finally(() => {})
.finally(() => {
})
}}
size={"small"}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,24 +74,22 @@ export const ShareData: React.FC<ShareDataProps> = (props) => {
}, 200)
})
})

const rightClick = useMemoizedFn((e: { clientX: number, clientY: number }) => {
showByCursorMenu({
content: [
{title: "分享当前 Web Fuzzer", onClick: getValue},
{title: "导入 Web Fuzzer", onClick: onImportShare}
],
}, e.clientX, e.clientY)
})

return (
<>
<Tooltip title={"左键设置参数,右键可通过ID导入资源"}>
<Button type='default' icon={<ShareIcon/>} onClick={getValue} onContextMenuCapture={e => {
showByCursorMenu({
content: [
{
title: "通过 ID 导入资源", onClick: () => {
onImportShare()
}
},
{title: "通过 ID 分享资源", onClick: getValue}
],
}, e.clientX, e.clientY)
}}>
分享
</Button>
</Tooltip>
<Button size={"small"} type='primary' icon={<ShareIcon/>} onClick={rightClick}
onContextMenuCapture={rightClick}>
分享 / 导入
</Button>
<Modal title='分享' visible={isModalVisible} onCancel={handleCancel} footer={null}>
<div className='content-value'>
<span className='label-text'>设置有效期:</span>
Expand Down Expand Up @@ -127,13 +125,12 @@ export const ShareData: React.FC<ShareDataProps> = (props) => {
</Button>
{shareResData.share_id && (
<CopyToClipboard
text={
shareResData.extract_code
? `${shareResData.share_id}\r\n密码:${shareResData.extract_code}`
: `${shareResData.share_id}`
}
text={shareResData.extract_code
? `${shareResData.share_id}\r\n密码:${shareResData.extract_code}`
: `${shareResData.share_id}`}
onCopy={(text, ok) => {
if (ok) success("已复制到粘贴板")
if (ok)
success("已复制到粘贴板")
}}
>
<Button type={!!shareResData?.share_id ? "primary" : "default"}>复制分享</Button>
Expand Down

0 comments on commit 3e9a5d1

Please sign in to comment.