本文章主要分两部分
1.漏洞说明
2.Android端测试应用和工具,用于测试机型是否受到影响
谷歌在2020年3月的Android安全公告中提到,新更新已经提供了CVE-2020-0069补丁来解决针对联发科芯片的一个严重安全漏洞。
这个漏洞是利用MTK平台上一个驱动产生的,可以以root用户运行命令。
https://www.xda-developers.com/mediatek-su-rootkit-exploit/ 原作者发布地址
我的csdn资源链接,https://download.csdn.net/download/OneT1me/12523755 免积分
使用方法
To get a temporary privileged shell:
1. Push mtk-su to /data/local/tmp
2. Give exec permissions to mtk-su
3. Run ./mtk-su
使用方式翻译和解释 add by https://blog.csdn.net/OneT1me
1.使用adb命令,将文件push到/data/local/tmp 目录下
2.给这个文件云心权限,具体是chmod +x mtk-su
3.运行mtk-su ./mtk-su
4.如果shell变成#则说明成功
注意,这个适用于mtk的32位及64位系统,如果安卓系统的安全补丁时间在2020年3月份之后的无法生效,谷歌已经推送安全更新修复该问题,或者系统定制厂商拿的rom版本是mtk在2019年4月份之后释放的也无法使用已经修复
同时我也上传到了我的CSDN,可以去这里下载 https://download.csdn.net/download/OneT1me/12523755
2.Android端测试工具
直接写了
也可以在以下两个链接中获取
我的github: https://github.com/binwu/MtkSuTest 源码
我的csdn资源 https://download.csdn.net/download/OneT1me/12524171 APK文件
以下是界面代码
MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener, MtkSuTool.CommandResultCallback {
private Button bt_release_64, bt_release_32, bt_run;
private EditText et_cmd;
private TextView tv_result;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MtkSuTool.getInstance(this).releaseSu(R.raw.mtksu);//default release 32bit file
initView();
MtkSuTool.getInstance(this).regCallBack(this);
}
private void initView() {
bt_release_32 = findViewById(R.id.bt_release_32);
bt_release_64 = findViewById(R.id.bt_release_64);
bt_run = findViewById(R.id.bt_run);
et_cmd = findViewById(R.id.et_cmd);
tv_result = findViewById(R.id.tv_result);
bt_release_32.setOnClickListener(this);
bt_release_64.setOnClickListener(this);
bt_run.setOnClickListener(this);
}
@Override
public void onClick(View v) {
int id = v.getId();
switch (id) {
case R.id.bt_release_32:
MtkSuTool.getInstance(this).releaseSu(R.raw.mtksu);
break;
case R.id.bt_release_64:
MtkSuTool.getInstance(this).releaseSu(R.raw.mtksu64);
break;
case R.id.bt_run:
MtkSuTool.getInstance(this).runExec(et_cmd.getText().toString());
break;
}
}
@Override
public void onResult(final String result) {
runOnUiThread(new Runnable() {
@Override
public void run() {
tv_result.setText(tv_result.getText() + "\n" + result);
}
});
}
}
MtkSuTool.java
public class MtkSuTool {
private static final String TAG = "SuTool";
private static String RELEASE_DIR_PATH = "/data/local/tmp";
private static String RELEASE_FILE_PATH = RELEASE_DIR_PATH + "/su";
private static Context mContext;
private static MtkSuTool suTool;
private WeakReference<CommandResultCallback> weakReferenceCommandResultCallback;
private MtkSuTool(Context context) {
this.mContext = context;
RELEASE_DIR_PATH = context.getFilesDir().getAbsolutePath();
RELEASE_FILE_PATH = RELEASE_DIR_PATH + "/su";
}
public static MtkSuTool getInstance(Context context) {
if (suTool == null) {
suTool = new MtkSuTool(context);
}
return suTool;
}
public void regCallBack(CommandResultCallback commandResultCallback) {
weakReferenceCommandResultCallback = new WeakReference<>(commandResultCallback);
}
//释放su文件
public boolean releaseSu(int res_mtk) {
try {
InputStream inputStream = mContext.getResources().openRawResource(res_mtk);
if (inputStream == null) {
Log.e(TAG, "releaseSu: inputStream null");
return false;
}
File file = new File(RELEASE_FILE_PATH);
if (file.exists()) {
file.delete();
}
file.createNewFile();
OutputStream outputStream = new FileOutputStream(file);
byte[] buffer = new byte[8 * 1024];
int length = -1;
while ((length = inputStream.read(buffer)) != -1) {
byte[] b = new byte[length];
System.arraycopy(buffer, 0, b, 0, length);
outputStream.write(b);
outputStream.flush();
}
outputStream.close();
inputStream.close();
Runtime.getRuntime().exec("chmod +x " + RELEASE_FILE_PATH);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public void runExec(String cmd) {
try {
Process process = Runtime.getRuntime().exec("./" + RELEASE_FILE_PATH + " -c " + cmd);
new ReadThread(process.getInputStream(), "read").start();
} catch (IOException e) {
e.printStackTrace();
}
}
class ReadThread extends Thread {
InputStream inputStream;
String name = "None Name";
public ReadThread(InputStream inputStream, String name) {
this.inputStream = inputStream;
this.name = name;
}
@Override
public void run() {
super.run();
try {
byte[] buffer = new byte[1024 * 8];
int length = 0;
while (true) {
while ((length = inputStream.read(buffer)) != -1) {
byte[] tmp = new byte[length];
System.arraycopy(buffer, 0, tmp, 0, length);
Log.i(TAG, "run: " + new String((tmp)));
if (weakReferenceCommandResultCallback != null && weakReferenceCommandResultCallback.get() != null) {
weakReferenceCommandResultCallback.get().onResult(new String(tmp));
}
buffer = new byte[1024 * 8];
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public interface CommandResultCallback {
void onResult(String result);
}
}
以上