Android开发学着学着发现了一些奇奇怪怪的技术,我得回去再看看Java的技术,依旧是B站上面的教程,六百集,不过不是全部看一遍,怪我之前学的不扎实,关注了一些Java编程的公众号,学到了很多安全之外的技术,比如优化好几百万的数据表查询,其中用到的思想确实很开阔眼界,也有一些框架使用,之后开发一些自动化项目都是可以用得上的
说到自动化,我最近在整理SO自动化的资料,这部分的基础知识其实不多,但是做好了基础的分析之后,在这个基础上去做很多其它事情,就很有意思了,比如漏洞挖掘,协议分析等
胖友,听说过拒绝服务吗?
CVE-2017-0780,Android Message的拒绝服务
- https://android.googlesource.com/platform/packages/apps/Messaging/+/06cbd7f26ba58399f296d85fd155442c7f2ac837%5E%21/#F0
补丁捕获了创建FrameSequenceDrawable
对象时可能抛出的异常
从补丁位置处开始分析
@Override
public Drawable getDrawable(Resources resources) {
return new FrameSequenceDrawable(mFrameSequence);
}
对象FrameSequenceDrawable
定义如下
- http://androidxref.com/7.1.1_r6/xref/frameworks/ex/framesequence/src/android/support/rastermill/FrameSequenceDrawable.java
它有两个构造方法,第一个不用管,我们看第二个,它会调用方法acquireAndValidateBitmap()
public FrameSequenceDrawable(FrameSequence frameSequence) {
this(frameSequence, sAllocatingBitmapProvider);
}
public FrameSequenceDrawable(FrameSequence frameSequence, BitmapProvider bitmapProvider) {
if (frameSequence == null || bitmapProvider == null) throw new IllegalArgumentException();
mFrameSequence = frameSequence;
mFrameSequenceState = frameSequence.createState();
final int width = frameSequence.getWidth();
final int height = frameSequence.getHeight();
mBitmapProvider = bitmapProvider;
mFrontBitmap = acquireAndValidateBitmap(bitmapProvider, width, height); // <--
mBackBitmap = acquireAndValidateBitmap(bitmapProvider, width, height); // <--
mSrcRect = new Rect(0, 0, width, height);
mPaint = new Paint();
mPaint.setFilterBitmap(true);
mFrontBitmapShader
= new BitmapShader(mFrontBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mBackBitmapShader
= new BitmapShader(mBackBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mLastSwap = 0;
mNextFrameToDecode = -1;
mFrameSequenceState.getFrame(0, mFrontBitmap, -1);
initializeDecodingThread();
}
方法acquireBitmap()
可能返回空,而方法acquireAndValidateBitmap()
没有做异常捕获,后面直接调用空对象操作,会造成拒绝服务
private static Bitmap acquireAndValidateBitmap(BitmapProvider bitmapProvider,
int minWidth, int minHeight) {
Bitmap bitmap = bitmapProvider.acquireBitmap(minWidth, minHeight);
if (bitmap.getWidth() < minWidth
|| bitmap.getHeight() < minHeight
|| bitmap.getConfig() != Bitmap.Config.ARGB_8888) {
throw new IllegalArgumentException("Invalid bitmap provided");
}
return bitmap;
}
方法acquireBitmap()
最后会调用到方法nativeCreate()
,是一个Native函数
函数注册
static const JNINativeMethod gBitmapMethods[] = {
{ "nativeCreate", "([IIIIIIZ)Landroid/graphics/Bitmap;",
(void*)Bitmap_creator },
...
};
有兴趣的同学可以完整的跟一下
static jobject Bitmap_creator(JNIEnv* env, jobject, jintArray jColors,
jint offset, jint stride, jint width, jint height,
jint configHandle, jboolean isMutable) {
SkColorType colorType = GraphicsJNI::legacyBitmapConfigToColorType(configHandle);
if (NULL != jColors) {
size_t n = env->GetArrayLength(jColors);
if (n < SkAbs32(stride) * (size_t)height) {
doThrowAIOOBE(env);
return NULL;
}
}
// ARGB_4444 is a deprecated format, convert automatically to 8888
if (colorType == kARGB_4444_SkColorType) {
colorType = kN32_SkColorType;
}
SkBitmap bitmap;
bitmap.setInfo(SkImageInfo::Make(width, height, colorType, kPremul_SkAlphaType));
Bitmap* nativeBitmap = GraphicsJNI::allocateJavaPixelRef(env, &bitmap, NULL);
if (!nativeBitmap) {
return NULL;
}
if (jColors != NULL) {
GraphicsJNI::SetPixels(env, jColors, offset, stride,
0, 0, width, height, bitmap);
}
return GraphicsJNI::createBitmap(env, nativeBitmap,
getPremulBitmapCreateFlags(isMutable));
}
想法:话说这种漏洞完全可以自动化啊,不是Fuzz,通过搜索含有抛出异常的函数,往回找调用栈,看是不是所有抛出的异常都被捕获了
我今天发现一个神器,用来搜索API文档贼好用,叫Dash,设置个快捷键,指哪打哪