原创 NOVASEC
1、需要实现Java读取.wav或.mp3文件并进行播放
2、要在CS CLient找到主机上线的信号通知
参考 https://github.com/heangping/JavaRecorder/blob/master/src/JavaRecorder.java
import common.CommonUtils;
import javax.sound.sampled.*;
import java.io.*;
import java.util.*;
public class AudioPlayer {
private static AudioPlayer audioPlayer = null;
private static boolean playing = false; //记录当前播放器状态,以免重复播放
private static String defaultFormatString = null; //对不支持的wav文件都转为默认格式
private static List<String> SupportFormats = null; //记录系统支持的播放音频格式
//初始化
private AudioPlayer(){
SupportFormats = getSupportFormats();
//CommonUtils.print_info(String.format("Init Audio Player Support Formats: %s", SupportFormats.size()));
defaultFormatString = getDefaultFormat(SupportFormats);
CommonUtils.print_info(String.format("Init Audio Player Default Format: [%s]", defaultFormatString));
}
//单例模式,防止多次分析当前支持的环境
public static void initInstance() {
if (audioPlayer == null) {
audioPlayer = new AudioPlayer();
}
}
//获取支持的音频编码列表
private List<String> getSupportFormats() {
List<String> formatStrList = new ArrayList<>();
Mixer.Info[] mixerInfoArray = AudioSystem.getMixerInfo();
for (Mixer.Info mixerInfo : mixerInfoArray) {
Mixer mixer = AudioSystem.getMixer(mixerInfo);
Line.Info[] sourceLineInfoArray = mixer.getSourceLineInfo();
for (Line.Info sourceLineInfo : sourceLineInfoArray) {
if (sourceLineInfo instanceof DataLine.Info) {
DataLine.Info dataLineInfo = (DataLine.Info) sourceLineInfo;
AudioFormat[] formats = dataLineInfo.getFormats();
for (AudioFormat format : formats) {
// format.getSampleRate(), format.getSampleSizeInBits(), format.getChannels(),
// format.getEncoding(), format.getFrameSize(), format.getFrameRate()
//实际只需要(加密方式|chan|bits)三元组即可,其他都是可以计算出来的额
String formatStr = String.format("%s<->%s<->%s", format.getEncoding(), format.getSampleSizeInBits(), format.getChannels());
if (!formatStrList.contains(formatStr)){ formatStrList.add(formatStr); }
}
}
}
}
return formatStrList;
}
//获取默认转换音频格式
private String getDefaultFormat(List<String> supports){
if (supports.size()>0){
//优先使用16bit音频 1声道
String s1 = String.format("%s<->%s<->%s", "PCM_SIGNED", "16", "1");
if (supports.contains(s1)) return s1;
//次优使用16bit音频 2声道
String s2 = String.format("%s<->%s<->%s", "PCM_SIGNED", "16", "2");
if (supports.contains(s2)) return s2;
//否则使用第一个音频
return supports.get(0);
}
return null;
}
//判断输入的格式是否可以播放
private static boolean isSupportedFormat(String AudioFile) {
try {
AudioInputStream audioInputStream = getAudioInputStream(AudioFile);
AudioFormat format = audioInputStream.getFormat();
String formatStr = String.format("%s<->%s<->%s", format.getEncoding(), format.getSampleSizeInBits(), format.getChannels());
//AudioSystem.isFileTypeSupported(audioFormat.getType(), inputStream);
return SupportFormats.contains(formatStr);
} catch (Exception e) {
//e.printStackTrace();
CommonUtils.print_error(String.format("%s Check Support Error: %s", AudioFile, e.getMessage()));
return false;
}
}
//转换音频格式为可播放的类型
private static String convertFormat(String rawPath, String newPath, AudioFormat expectFormat) {
try {
//获取输入流内容
AudioInputStream audioInputStream = getAudioInputStream(rawPath);
// 进行音频格式转换
AudioInputStream convertedStream = AudioSystem.getAudioInputStream(expectFormat, audioInputStream);
// 写入转换后的音频文件//不会写入到jar文件内,写入到同名目录,目录不存在会报错的
// 使用mkdirs()方法创建目录(包括父目录)
File newFile = new File(newPath);
newFile.mkdirs();
AudioSystem.write(convertedStream, AudioFileFormat.Type.WAVE, newFile);
//CommonUtils.print_info(String.format("Success Convert Audio Format: %s -> %s", rawPath, newPath));
return newPath;
} catch (IOException e) {
//e.printStackTrace();
CommonUtils.print_info(String.format("Audio Format Convert Error: %s -> %s", rawPath, e.getMessage()));
return null;
}
}
//获取媒体音频格式
private static AudioFormat getAudioFormat(String fileName){
// AudioFormat rawFormat = AudioSystem.getAudioFileFormat(new File(fileName)).getFormat();
try {
InputStream inputStream = FileUtil.JarReadFileStream(fileName);
AudioFormat audioFormat = AudioSystem.getAudioInputStream(new BufferedInputStream(inputStream)).getFormat();
return audioFormat;
} catch (UnsupportedAudioFileException e) {
CommonUtils.print_error(String.format("%s -> %s", fileName, e.getMessage()));
} catch (IOException e) {
CommonUtils.print_error(String.format("%s -> %s", fileName, e.getMessage()));
}
return null;
}
//获取媒体输入流
private static AudioInputStream getAudioInputStream(String fileName) {
try {
//AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(new File(fileName));
InputStream inputStream = FileUtil.JarReadFileStream(fileName);
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(new BufferedInputStream(inputStream));
return audioInputStream;
} catch (IOException e) {
CommonUtils.print_error(String.format("%s -> %s", fileName, e.getMessage()));
} catch (UnsupportedAudioFileException e) {
CommonUtils.print_error(String.format("%s -> %s", fileName, e.getMessage()));
}
return null;
}
//自动检测音乐是否能够播放
private static String checkAndConvert(String fileName, boolean overlay) {
//判断文件是否可以播放,不可以播放进行格式转换 java11时isSupportedAudioFormat错误
if(isSupportedFormat(fileName)){
return fileName;
}
//进行格式转换修复
//从原始文件中获取 sampleRate
float sampleRate = 16000 ;
AudioFormat rawFormat = getAudioFormat(fileName);
if (rawFormat != null){
sampleRate = rawFormat.getSampleRate();
}
//获取本系统支持的格式
String[] defaultOP = defaultFormatString.split("<->",3);
AudioFormat.Encoding targetEncoding = new AudioFormat.Encoding(defaultOP[0]);
int sampleSizeInBits = Integer.parseInt(defaultOP[1]);
int channels = Integer.parseInt(defaultOP[2]);
// 目标音频格式
AudioFormat newAudioFormat = new AudioFormat(targetEncoding, sampleRate, sampleSizeInBits, channels, (sampleSizeInBits / 8) * channels, sampleRate, false);
//生成新的文件
if (overlay){
fileName = convertFormat(fileName, fileName, newAudioFormat);
}else {
fileName = convertFormat(fileName, fileName+".new.wav", newAudioFormat);
}
//检查新的文件是否可以播放
if(!CommonUtils.isNullOrEmpty(fileName) && isSupportedFormat(fileName)){
CommonUtils.print_info(String.format("Converted Audio Supported: [%s]", fileName));
return fileName;
}
return null;
}
//播放音频
private static boolean simplePlayAudio(String fileName) {
try {
// 获取音频输入流
AudioInputStream audioInputStream = getAudioInputStream(fileName);
AudioFormat audioFormat = audioInputStream.getFormat();
CommonUtils.print_info(String.format("Audio Info: [%s] -> Encoding: [%s]", fileName, audioFormat.toString()));
DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class, audioFormat);
SourceDataLine sourceDataLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo);
sourceDataLine.open();
sourceDataLine.start();
byte buf[] = new byte[0xFF];
int len;
while ((len = audioInputStream.read(buf, 0, buf.length)) != -1) {
sourceDataLine.write(buf, 0, len);
}
sourceDataLine.drain();
sourceDataLine.close();
audioInputStream.close();
return true;
} catch (Exception e) {
//e.printStackTrace();
CommonUtils.print_info(String.format("%s Play Error", fileName));
return false;
}finally {
playing = false;
}
}
//自动检测并播放音频
public static void checkAndPlayAudio(String fileName, boolean overlay) {
if (playing || null == audioPlayer || CommonUtils.isNullOrEmpty(defaultFormatString) ) {
CommonUtils.print_error("Player is Not Init Or Player is Using, Skip!!!");
return;
}
//独占模式 每次只播放一个音频
playing = true;
//检查和自动修复wav格式问题
fileName = checkAndConvert(fileName, overlay);
if (CommonUtils.isNullOrEmpty(fileName)){
CommonUtils.print_error(String.format("Audio Check And Convert Not Passed: [%s]", fileName));
return;
}
//进行播放测试
simplePlayAudio(fileName);
}
public static void checkAndPlayAudio(String event){
CommonUtils.print_info(String.format("Play Audio By [%s]", event));
new Thread(() -> {
checkAndPlayAudio("resources/audio.wav",true);
}).start();
}
public static void main(String[] args) throws UnsupportedEncodingException {
//无法播放的类型
String wav_2 = "C:/Users/XXX/Desktop/Audio.wav";
//获取实例
AudioPlayer.initInstance();
AudioPlayer.checkAndPlayAudio(wav_2,false);
}
}
if (!(obj instanceof Directive)) {
if (!this.syncing) {
if (obj instanceof Scriptable) {
Scriptable scriptable = (Scriptable)obj;
String eventName = scriptable.eventName();
Stack arguments = scriptable.eventArguments();
this.engine.getEventManager().fireEvent(eventName, arguments);
//添加初始化上线响铃操作
if("beacon_initial".equals(eventName.trim())) AudioPlayer.checkAndPlayAudio(eventName);
}
...省略
1、修改JARM/JA3 指纹[通过随机化https算法]
2、支持初次上线铃声通知
3、无需javaAgent完善修复XSS RCE漏洞
PS:所有代码依旧 保留Java8级别的兼容性.
在学习本文技术或工具使用前,请您务必审慎阅读、充分理解各条款内容。
1、本团队分享的任何类型技术、工具文章等文章仅面向合法授权的企业安全建设行为与个人学习行为,严禁任何组织或个人使用本团队技术或工具进行非法活动。
2、在使用本文相关工具及技术进行测试时,您应确保该行为符合当地的法律法规,并且已经取得了足够的授权。如您仅需要测试技术或工具的可行性,建议请自行搭建靶机环境,请勿对非授权目标进行扫描。
3、如您在使用本工具的过程中存在任何非法行为,您需自行承担相应后果,我们将不承担任何法律及连带责任。
4、本团队目前未发起任何对外公开培训项目和其他对外收费项目,严禁任何组织或个人使用本团队名义进行非法盈利。
5、本团队所有分享工具及技术文章,严禁不经过授权的公开分享。
如果发现上述禁止行为,我们将保留追究您法律责任的权利,并由您自身承担由禁止行为造成的任何后果。
END
如您有任何投稿、问题、建议、需求、合作、请后台留言NOVASEC公众号!
或添加NOVASEC-酒零 以便于及时回复。
感谢大哥们的对NOVASEC的支持点赞和关注
加入我们与萌新一起成长吧!
本团队任何技术及文件仅用于学习分享,请勿用于任何违法活动,感谢大家的支持!!