Welcome back to another bonus video.
I mean, meanwhile, we are having more bonus video than regular videos.
But yeah, this is why we are here.
I would like to show you everything I know regarding to app hacking and therefore we might have a lot
of bonus content.
All right.
In this video over here, we want to exploit the content provider within our own malicious application.
So we will perform all three attack vectors, which we have seen in the last video, the first one,
the SQL injection, the next one, the path bypass.
So the custom permission bypass.
And last but not least, we simply ask for this permission and see if the user grants us these.
If this is the case, then we can also query the internal passwords of our password.
Safe.
Amazing.
Right?
Therefore, let's go to write our application.
We need our Android studio.
So within tools Android studio, Ben, here we have it.
So let's start this.
We're still talking about the safe application and yeah, we will start with the SQL injection.
So we will write our own content resolver, which is asking the content provider to provide those content
in form of those methods.
Insert, update, query, delete.
And then we will use the query method to, to inject our own SQL syntax.
Yes.
Sounds absolutely complex, but if you have watched the last video where we did all of this in the activity
manager at the end, it wasn't that complex.
And within our own application, I mean, the approach is still exactly the same.
All right.
So now let's create a new project.
So new project, we choose empty activity because we want to have it as clean as possible.
And then, let's see, we name this unsafe backup.
I guess that's that's a good application name.
A language.
Chava and I go back to nougat but the the target bit SDK is appealable 30 and there we have to adjust
a lot of things.
So the whole privacy concept has changed in Android 11 and higher.
And therefore I would like to show you all of this how to write an own application which still can exploit
those issues even on modern smartphones right now.
Because later, if we talk about browser and all this stuff, this will not work on modern smartphones
anymore.
In two or three years, this will be completely gone.
We have to take the new approach over here and yeah, this is why we are here, right?
So therefore let's move on.
Okay, so we go back to nougat, but we are targeting the the version 11 OC and now we have to wait
until the Gradle process has been finished.
So this might take a while.
And I will see you in a moment.
All right.
One moment later, we are back.
So this one over here, this is our workspace.
We've got our main activity.
We've got our own create method.
What's missing?
The interaction with the content provider, of course.
So how can we interact with this one?
Well, if you think back to the theory part, the content provider or the access to the content provider
is working in the following way.
We have to define a content resolver, and the content resolver is asking the content provider to provide
the content after what we get back and cursor, which is simply.
Justin Yeah, let's, let's say in point into the database entry.
So with this cursor we can access those data.
All right.
Okay.
So how can we do this?
Well, it's not that hard, to be honest.
We just have to consider some things which has been new in Android 11 regarding to the privacy of an
application.
And this is also the reason why I would like to show you all this stuff because later, if you talk
about tools like browser and things like this, those tools won't work anymore in the future.
So regarding to newer smartphones, API level 30 and higher, so Android 11 and higher, there has been
a lot of change in the privacy settings and this will deny access for for the driver's application,
for example.
Therefore, we need to know how to do this on our own and this is why we are here.
And yeah, I would suggest let's simply do this for this content provider.
So therefore I would suggest let's simply start over here.
So let's start by accessing the password table.
The password table is included in the content provider, in the DB content provider, and this one has
been exported.
So we can simply interact with this one.
If we can interact with this one and if everything works, then we can perform our text, our SQL injection,
our user permission bypass.
And last but not least, what was it?
Yes, it's not really an attack.
It's simply just asking to give the customer permission.
This one over here.
Those two.
If you're having those two permissions, then we can we can also access the key table.
All right.
Okay.
But first, let's see, how can we interact with the passwords table in this one over here?
And first of all, I mean, we have to get this, URI.
So this part can be simply copied out of this, and we cannot include it over here.
So we have to define a new URI.
And this is our URI and this is our alias to access the password table in this application.
All right.
So the addressing easy.
But now the question, how can we create our own content resolver?
And this part, it's easier than you think because that's already the method which is doing everything.
So we can simply call get content resolver here.
We already have it and then we can access those methods.
We can already see query.
We also have insert yes, insert update and things like this.
So here we are getting or be defining our content resolver and our application.
And then we are asking this content provider to provide access to those methods, insert query, update
and also delete.
So these are being defined over here, but we can access them with the content resolver if the application
gives us access, which is the case for the password table, because this has been exported through.
All right.
So therefore, let's see back to this one.
Let's simply access to query method.
So query.
And here we have now two types of methods.
So we've got one with projection string selection ax.
This is exactly the one we want to have.
And this one I'm not sure.
Very args cancel.
It doesn't matter.
You want to have this one.
Okay.
And now we have to provide all those parameters.
I mean, Uri, this should be clear, right?
Uri is our URI.
Okay.
Then we have to define the projection arguments, and this may be later pretty important for our SQL
injection, but for now, we simply keep it null.
Which means if we do not provide any projection access, everything from this passport table will be
will be selected.
All right.
And we do the same for the selection, also for selection AX.
And last but not least, also for sort of sort order.
Yes.
Okay.
This method is returning back in cursor.
So we need to get this cursor.
We have to define it over here.
Query, cursor, let's import it.
And then we are already done.
And this is how we can access the data from the C passwords table.
Amazing, right?
Absolutely.
So to print this out, we could use it in the following way system, system.out.println, and then we
can use our query cursor.
But here we are now having a little bit of a problem because our query cursor is an object, so it's
a cursor object and therefore we cannot simply print out an object.
If you're printing out an object, we simply just get something like ET and then this, for example,
maybe.
So this is just an address.
This is the address of this object, but it's not the content.
If you want to get the content, we have to use something.
Or I guess it's database utils.
Yes, it's database utils.
And here we've got let's see, cursor to string.
Something like this.
Cursor dump was a dumb.
Dumb cursor.
Yes.
Dumb cursor to string.
So this will take the whole cursor object everything, every information that's included inside there
and will provide string for us so we can save this in a variable or we can simply print this directly
out over here.
So very close.
All right.
So this is now everything we need to access the passports table and also to print it out in a readable
format.
All right.
Okay.
Let's see if this works.
We use run app.
So on the left, we've gotten smartphone and app level version 30 and we've got a lot of privacy settings
in there.
And this might be the reason.
Let's see a look at.
Yes.
If you're searching for system out.
Nothing is inside here.
Let's see.
No.
There's no system out.
So our cursor object is not being accessed.
And indeed, if you print out this cursor, let's see.
Cursor.
Let's do this.
Okay.
I guess the loggerhead seems to hang a little bit and therefore let's use the AdBlock Lochhead in case
if you are using the ADB shell out of the Android studio, we cancel the connection from the Android
studio and yeah, we can simply use it on our own right now.
So AdBlock at.
Let's see.
Um.
Okay.
I guess we have to search for this.
So let's clean the lock cat and then let's search for system dot out.
Make this a little bit larger and let's simply relaunch this app.
Yes, we can see the cursor is null, so the whole object is null, which means it seems like we're
not having access.
And yes, indeed we are not having access.
But now the question why do we not have access?
Because the application is running on the smartphone and this content provider has been exported.
So that's everything we need to know, right?
Unfortunately, not because an Android 11 is already mentioned.
There was a huge change regarding to the privacy.
So those applications has been automatically locked down a little bit.
If you want to interact right now with this application, we need to tell that we are visible for this
application.
I mean, this is not a big deal because we are the attacker or the attacking application and we want
to access the application.
So therefore, if you tell this thief that we are visible for this application right now, we do not
lose any sensitive information.
But we have to tell this in our application.
And this is why I would like to show you all the stuff over here, because if we later take a look at
the browser application, those approaches won't work anymore because the browser is not aware of the
app visibility in Android version 11 and higher.
And it won't be because browser will not be supported anymore.
Therefore, we need to be able to write our own applications to perform all these tasks.
All right.
So now the question, how can we make our application visible for this application?
And to be honest, this is also something I need to look up because you have to define it in the Android
manifest.
But I'm not sure about those texts.
I guess it's very and the package name and but before we are running in circles, let's simply look
this up.
So let's see.
Okay, so the keywords are Android app and visibility and we can see package visibility in Android 11
and let's see.
Okay.
Change us.
Let's see.
Package as visible in Android.
Okay.
Here, we've got the generic information.
Some pictures are still visible automatically.
Might be system applications.
Not sure.
And yes, I guess this is this is the path we are looking for.
So we have to define those queries.
Let's see.
Yes.
Within the Android manifest, we have to define this query.
So here we have it.
Och, yes, it's Claire Rhys.
So this is.
These are things I cannot remember, but I know that they are exist and we can simply look this up.
It's not a big deal.
And then I guess the the other attribute was a package even that forgot it.
Let's simply take this whole.
Okay.
So here we have to define the package, but we want to be visible for so therefore it is the safe application
and we can fetch the information from the package name out of the Android manifest of the CIF application.
All right.
And this is all right now.
Yes.
So this should work back to the main activity.
Let's see if we can make a reconnection with ADB.
Okay.
So let's see.
Let's open a new terminal and then let's restart the ADB server.
So it's been restarted.
And now let's see.
Now we can select it over here and then we should have it back.
Yes.
Looks good.
Okay.
Now let's install this application.
Over here, we are now printing the query object, so we should get an address.
But yeah, we will see that it works if this one is not returning null anymore.
So let's install this application.
And.
And let's search for system out.
Yes, perfect cursor.
And then we've got this cursor object over here.
So here's the address of this cursor object.
Nice.
So we have now queried the passwords table of this application.
All right, let's print out the text, because otherwise it would be super lame.
Do you still remember how we can do this?
How to get out in string out of this cursor object?
Of course you do.
DB o database utils.
Yes.
I guess you were right on this one.
OC database utils and then cursor two string.
I see it already here.
Nice.
All right.
And let's see if this works.
Run!
So application is being reinstalled and over here.
Perfect.
Nice.
Here we have now all this data.
We can see this our cursor and T we've got the ID service username password is unprintable.
We will we will deal later with the with the block data and the email.
All right.
So these are the data out of the out of the content provider from this application from the passwords
table.
Nice.
But let's do a little bit of modification because we do not have access to the LOGCAT later on.
So therefore let's print them directly out in our application.
So therefore we just have to make a little bit of an adjustment to the layout.
I mean, this is not required right now, but it looks super fancy and therefore we do this.
All right, let's see.
Within the resource directory, we've got this layout activity, main layout, and here we've got the
text view already in there.
We are using this text view to print out this data.
I mean, this looks absolutely yeah, absolutely zero solid.
And therefore, this would be a nice proof of concept or demonstration for the customer.
So how can we do this?
Well, we go into the code menu and we have to provide an ID to this one so that we can address it later
on in our code ID and then ID text view.
Yes.
Okay.
So now we've got an ID for this text view and we can address this text view based on this ID.
All right.
Okay.
Let's also change the background of this application, Android background, and let's make this blank
and let's make this text over here.
It's not helloworld.
It is hacking in progress.
So that's the text that's normally displayed, but it will be pretty fast overwritten with our data
we are fetching from those tables, but nevertheless let's keep this as some kind of placeholder and
then android collar and let's, let's, let's take this color.
This looks cool.
And then also Android text size.
28 DPI.
This should be good.
And I guess we got to.
Yes, got to go.
Maybe let's add some padding.
Last but not least, padding left.
Well, let's say 100 OC.
Now we are done.
Yes.
Okay.
So now let's take this part.
So here we are having a text view.
We this text view, and we have to assign this text view within our own create method.
So within our own create method, we, we are fetching the ID from this text view and we assign this
to this object.
So text view, we are type casting it and then we are using file view by ID and now we are using our
ID.
We have provided before exactly like this.
And then instead of in system out, we're using text view, set text.
Yes.
Okay.
One last little change within the manifest.
Let's get rid of the of the action bar on top because there's a super annoying and we can do this in
and here within the theme we simply delete this this part and then we are using a theme design, no
action bar.
Okay, let's install this application and let's see how it looks like, I guess.
Pretty amazing.
So.
Those data should be now filled in the text view we have inserted in our layout, which has been already
inserted over there.
So our hello world.
Okay.
Yes, we have to do a little bit of an adjustment.
The text size is a little bit too large.
So let's go down to 20 maybe.
And also the padding is a little bit it's way too high close.
I would say close.
Is it really just something like 14?
The sound so, so little.
But I guess 14 is good.
So let's see.
Yes.
Okay.
I guess we stick to this one right now.
So nevertheless, I mean, it's amazing to see those those data from another application on our screen
right now.
I mean, as an attacker, of course, we do not have to display them on a screen.
We could also send them to an HTTP server via https, of course.
So all the attackers should should take care about an encrypted connection.
And then, yes, we can simply fetch that.
So therefore no physical access for the smartphone would be required.
But I guess this is good enough from proof of concept right now.
All right, so now let's get back to our attack vector.
Yes.
Let's simply comment this in here.
This is very the passports table verified.
It is working.
Okay.
So let's take this this part and now let's adjust our things.
So.
Now what we want to do is the following.
We start with the simple bypass, the user's permission bypass.
So our application receives application normally requires those two permissions, but we have seen if
we end or sorry if we add this one at the end of our URI, then we can simply bypass this permission.
So let's do this.
Then let's fetch this.
Yuri.
Okay.
And let's also describe this over here.
All right.
I mean, we do not have to change anything besides the euro.
This is all.
And this would work right now out of the box.
Amazing, right?
Let's see.
We simply run this.
And now instead of those passport entries, there should be those clear text password and also the pin.
Let's see.
Amazing.
It works.
We've got the password and the pin.
I mean, isn't this crazy?
We are opening our own application and it shows the passport of another application of passport.
Safe application.
Absolutely right.
Okay.
But to be honest, I mean, this year was a little bit too easy, right?
So simply appending this or also this.
Yeah, but it works.
It works.
Okay.
This is our first attempt.
Yes, of course.
Afterwards, I will share the the whole application code for this one.
So let's get to our second attempt.
And this one is now what do we want to choose a SQL injection or what's missing and the user's permission.
So therefore we have to go for the SQL injection.
Okay.
So, SQL injection.
We need to query the passports table to insert our own SQL statement.
The SQL statement will be inserted in the projection, so SQL statement will be inserted via the projection
parameter, and we have to figure out what the prediction parameter is.
But I guess that's not a big deal.
So the projection or the SQL syntax is something like select all from past what's there and then a bunch
of other stuff.
And we want to change this to select all from key.
Remember now we are addressing the the table name, not the URI scheme or I do not have it anymore.
This one, this is the URI scheme and this one is being referenced by a keys, but the table name is
simply just key.
So therefore in the SQL statement we directly have to address the key table, not this scheme.
Okay.
So we want to have something like select all from key and then we comment out the rest, which means
everything here, which is something like passports where there be simply just ignored.
Okay, this means our protection needs to be this path over here.
So this path, and I guess that's all.
So this is our our attempt and let's do this, okay?
Before we perform our SQL injection, let's see if we can if we can access data via the program parameter.
So let's simply add an protection parameter, something like this, because then we are having select
all from passports and you should get back data.
And if this works, then we can play around with this one.
All right.
Okay.
So therefore, we want to access the passports table and now let's see what type is this program parameter?
It is.
It's a string array.
Okay.
So therefore we have to define a new string array and the alternate in this prediction, new string
array.
And we can define a new string array in this way.
All right.
And this is all.
Yes, this should work.
So if we start this right now, we should get back the same data like we have seen before with the passwords
table, because now we are doing nothing different, but we are using our projection parameter in here.
Let's see.
Yes.
Works perfect.
So now all we need to do is we need to insert our SQL statement here, which is all from key, and that's
all.
And this is our SQL injection.
So let's see.
Oops, let's run this.
It would be also interesting if you are inserting in single quote if you get back the error message,
but I guess not.
Yes.
Nice.
So we can see this is working now.
We're having our SQL injection via the passwords table into the key table based on the content provider.
I mean.
Well, this is it's pretty amazing already.
And last but not least, yes, we are now accessing the keys table.
Our third attempt is accessing the keys table and we are using those two permissions.
So this is we are now asking the user to give us these permissions.
And if the user grants us these permissions, then we can simply access those data over here.
So, yeah, let's simply do this right.
Okay.
So therefore, we are copying those two or maybe let's let's define our plan first.
So this is the second of ten works.
My comments are getting less even.
Even farther we go.
Whoops.
No.
This is now our third attempt and granting the custom permissions of most of the C application.
The things we have to consider are the following.
We have to define them in the manifest.
Oh, let me think.
Yes, I guess we also have to yes, we have to do the asking, so we need to ask for them during runtime.
So this has been included in Android version six and it's the it's the common.
So there will be this pop up the first time we are using those permissions.
And if we are not asking, then those permissions won't be granted and we cannot access the content
provider.
So we definitely have to ask for them.
But I guess that's all.
Yes.
This is all.
Okay, so let's do this within the manifest.
Yes.
We have to change this.
This is the definition of custom permission.
And if you want to use this, we have to use user's permission.
So here.
Oh, yes.
Okay.
Regarding to this one, I guess we are having trouble because this is Android specific label and description
needs to be defined in in these strings.
So we need to create strings for those.
I mean, we could use them or we could also simply delete this.
Then I guess there's something like unrecognized.
Okay.
I will show you both really quick.
So in case if you want to define and label, we have to go into strings, which is within values.
Strings.
And then we have to define a new one.
String and then name.
And then let's see, let's call this permission description and then we can insert the text here.
Yes.
And then we can address this in this way.
So our label is now.
Hmm.
Let's see.
I already forgot it.
Perm description.
There we have it.
Okay.
So, yes, here we have deleted it.
Here we have created this label, so let's use this label.
But I'm not sure if this works anyway in this way.
Okay.
So now we have the permission included in our application, but if we install this app, it won't be
automatically granted.
Therefore, we have to ask the user to enable this and we can do this in the following way.
So first, let's get the code.
Okay.
So
yes, we can do it in this way and we want to vary key this way.
So this is being protected.
Let's see.
Maybe let's see if this doesn't work because this should be the case.
Yes.
The application seems to crash.
Let's see.
Why do we have that?
I guess.
Here.
Yes, here we can see our application is the UID 10,124 and it requires to have those permissions.
We have set them in the Android manifest.
Yes.
But if you take a look at the application itself.
Oops.
Settings.
And we can see too has been denied.
So these are our two permissions allow editing of the of the key stuff over here.
So those has been denied.
Therefore, we have to ask the user to grant us those permissions and we can do this in the following
way.
So we need to do this.
That's closest.
We need to do this over here before we we are starting our content provider interaction and this can
be done in the following way.
Oh, let's see if I can remember this app combat activity and then okay, so maybe it is active.
Yes, it's activity combat this way and then a request permission.
And here we have not all three options.
Okay.
The first one is our activity.
That's easy because this is the this object, this is the main activity.
And then we're having this string of our permission.
Okay, so this is this one over here.
Let's let's simply just take read keys.
All right.
And then last but not least, there's this request code.
I do not remember this anymore, so let's see.
Okay, so here we are in the activity combat class.
Let's see.
Permission, request, permission.
This method.
Okay.
We've got an activity permission and we've got in range from zero request code.
Okay, let's see.
Request code.
Here we have it.
Application specific request code to match with the resort reporter tool.
Ah, yes.
Now I remember.
Okay.
So if we have, if we are asking multiple times, then we can keep track on if this permission has been
already granted or not.
So we can take whatever value we like.
It has to be greater.
Equal to zero.
Okay, perfect.
So let's get back over here.
Let's simply take.
It's over 9000.
So 9001.
Yes, the permission is it's a string array.
Okay, so let's define a new.
Oh, I guess we have it already here.
So permission.
And now let's define.
New string array and then we can use this here.
Okay.
So this should work?
I hope so.
Let's see.
Run!
Okay.
If the application starts, there should be this pop up right now because we are directly accessing.
Yes, okay.
Yes.
Allow see if backup to perform an unknown action.
I mean, of course, what could go wrong?
Right.
So let's say allow.
And.
There we have it.
Nice.
So we have we can see this one is now developed entry even if the the path which has been circumvented
in our first attempt has been set correctly with regular expression, then we can still use it in this
way if we are asking nicely the user to give us those permissions.
Okay.
I guess it's better if you make a copy of this one because this works and we do not know if the our
second attempt will work right now and then we've gotten fallback.
Okay.
So this is our yeah, this is our syntax regarding to querying the passwords table.
Okay.
So now we've got this problem with this this block value.
So let's run this maybe once again.
Yes.
So here we can perfectly see everything that's in stream can be easily printed out within our database
utils dump cursor method.
But this password is consisting of binary data and binary data cannot be printed out in this way and
therefore we just have to place order unprintable.
And for example, if you open a new terminal and we want to print out and carry it, return new line
this way.
If we if we print this out, then we can see, okay, here are here are data in there, but we do not
know how many and which data.
I mean, yes, there might be some new lines and it might be two new lines.
By the way, if we're using echo without parameter, it's automatically appending a new line.
So if we're using Echo with Dash PN, then we can see there's only one new line.
So now we know that's new line character.
But how many carriage return do we have?
I mean, one, it could be also three, could be four.
We do not know.
So therefore we cannot print binary data out in this way.
What we need to do is we need to encode them.
But more to this later.
But first, let's see how we can get those binary data.
So what we want to do is we want to fetch our rows.
So here we can see this, this row ID zero, which means the more entries we've got, the more rows
we have.
So this is zero.
Then we might also have one, two, three.
It depends on the amount of entries and we want to go through every entry and then we want to we want
to get all those, those password blobs over there to store them separately, because then we can we
can use a certain encoding to print them out.
All right.
Yes.
This sounds absolutely complex.
And to be honest, this is really heavy Android lifting right now.
You do not need to know anything of this.
So what we're going to do right now is we are writing this code that you have in reference for this
in case if you need some proof of concept from customer, then you can simply rewatch this video.
Otherwise you can simply just lean back and relax.
If this part is interesting for you, perfect.
In case if this is overwhelming you don't worry.
After this video, you can completely forget everything you have seen over here, at least regarding
to this part right now, because this is absolutely not required to move on in this course.
It's already mentioned is a bonus video.
And this bonus video is to provide additional information not required in this course, but it's simply
showing you how to deal with this stuff, which can come handy.
Alrighty.
Okay.
So let's see.
Okay.
We've got one row ID, which is zero, and here we've got our columns underscore ID, service, username,
password.
All right.
So what we need to do right now is and this is our cursor object and we need to first make sure that
we are having an cursor object so we can do this by, by checking if the cursor object is not equal
to not.
We have seen, if we, if we are not allowed to query this passport's table, then we're getting back
in null and the application would fail if we try to move on at this point.
So therefore we check if you're having an object.
So if our app is visible for this if application and then we're also checking if we're having entries
in our database and we can do this with query cursor count, get count.
Yes, of course, get count.
And then we check if it's greater than zero.
Okay.
So checking if we are having entries in our passports table.
Okay.
Now we need to make sure when we are reaching the passports column so this can be done in the following
way.
Let's assign an index variable, maybe index and our index is now let's see our cursor and then yes,
get column index or throw.
And now we say, okay, we want to have the column index of our password column because having the index
field which is let's see, it should be.
And this one is zero one, two three.
So it is index three, but it's the fourth entry because we start counting at zero.
So now we have this index field and this can be used to yet to fetch the data so we can address this
this column based on the index and we can get out the data based on the index.
All right.
So now we've got this index and now let's make sure if our index or that the index is greater, equal
to zero, because otherwise we won't have this passports table, sorry, this passports column.
And if this is the case, then yeah, we want to get all the data de blob data.
So query cursor, get blob.
And here we can see we have now to provide the index and let's create a new array where we can store
those data.
So it's byte array, password blob.
Let's also initialize this with zero.
Okay.
And now.
Yes, I guess we can try printing it out.
I mean, of course, this won't work.
Yes, I guess we are getting an address or something like this in there.
But we we can already see if we are printing this out and how often we are printing this out.
Maybe there's an electrical error in there.
So let's see.
Let's rerun this application.
Doesn't crash?
I hope not.
Och, it's crashing.
Let's see.
Oh.
Okay.
The index is out of range.
We are not having a typo in there.
We are checking it and we are having this.
Maybe one thing we need to make sure is that we are at the beginning of our cursor.
Uh, it's this the problem might be.
So our cursor has a lot of entries, and it depends on the position of the cursor.
If you are using query, not sure if it gets to the end.
So therefore we need to set the cursor back to the beginning.
Yes.
Cursor stuff is absolutely complicated and this took me a month to understand.
It's required in accessing contacts and SMS, for example.
So those shady things, therefore it's maybe good to know.
But yeah, it's also a little bit.
It's a pain.
So how can we do this?
We are using if and then we're using very cursor move to first this is returning back boolean value
but it's also setting the cursor to the beginning.
I find this absolutely confusing because we are doing two steps and it's not that clear over here.
Good.
Right.
Okay, so let's take this.
I hope this was the mistake.
Let's see.
Observing everything here.
Smartphone look at.
Yes.
Perfect.
So, yeah, absolutely ridiculous.
If you're comparing this cursor, this cursor might be set to the end.
And therefore, we we are trying to access an index which is not available anymore.
But now we can see we've got the system out and here we have not all byte array.
Nice, isn't it.
Yes, it's just an address.
So we cannot do anything with this one.
We need to we need to get back the values out of this one.
Okay.
How can we do this?
Well, we've got a nice method for this.
And the method is base64.
So Base64 isn't encoding, and this can be used to print out non printable ASCII characters.
As already mentioned, Base64 will be heavily used during this course because this is an it's a common
encoding and yeah, it's, it's nice to identify and you can do a bunch of stuff with Base64 in case
if you're not familiar with Base64, then please watch the bonus video regarding to it because otherwise
this video won't be will be way too long right now.
Okay, so let's see if you want to print out those byte array.
We can use base 64.
We already have it dot and CO to string.
Yes, this is exactly the method.
So this is taking in by the array as input.
Perfect.
This is our password blob.
And then we're having this flex.
But this flex is simply just base 64 has some can be used in different type of encoding.
So for example, special characters like Underscore are not normally used in the RFC.
That's a certain char set and we simply just help with the flex.
We do not do any fancy.
We are using the common char set and we we are not providing any additional characters to our encoding.
So treat it as normal base64 encoding and the flag for this one, for this standard value is zero.
So we are using base64 decode.
No.
A little bit confused.
Oh sorry encode two string, we want to encode it and then password block and zero zero our flags,
which is simply just common base64 encoding.
All right, so now let's run this and let's see.
This should work already.
I'm a little bit excited.
Nice.
Here we have it right now.
So our password, which is unprintable, is now being printed out over here.
Amazing, right?
So we can use this right now to get back those byte values.
So if you are echoing this out this time with dash loops, I'm not sure about this one, but this one
has been cached.
So so if you're echoing this with not appending a new line because we want to print it out exactly as
it is, we do not want to append our own characters to the string right now and then we can use base
64 slash DX.
Sorry, this is now the output and we can see why our smart phone is saying unprintable.
I mean, what is this this question mark over here?
This one, this one might be new line character.
So what's this?
We cannot deal with this one, but basically four can.
And now we've got the we've got the raw bytes.
And to print out or get back the raw bytes in an hex value we can use x x x x dx dash p will take those
bytes and will give us an hex representation of those bytes.
So if you type this through x 60 dash p, then we have finally those raw bytes in there in a nice hex
representation.
Amazing, right?
Absolutely.
So let's append this password also to our output over here.
So not.
Not only there.
Let's see.
Okay, let's comment it out over here and then let's append it to our text.
So let's create a new string output.
And this one is right now.
Let's keep it here.
So this is the first part.
Oops.
So this one is the first part.
And then we are appending our base64
output.
We are pending a new line character and then password encoded equals and we append this part.
And then the assembly printing out this.
We still got this cursor.
All right.
So now at the end, there should be this password encoded and this base64 encoded string in there.
So let's see.
I mean, we could also directly print out the the hex representation, but I guess this is enough Android
app development right now if you're having the ASCII values over there.
Yes, we have it.
Perfect.
So now we also got this password, which was before unprintable.
So by having those this this base64 encoded string, we can simply use this and yeah, run it through
60 like we have done it over here.
All righty.
So this is the end for this video right now.
And once again, it escalated pretty quickly.
So therefore, let's summarize this real quick.
Okay.
So afterwards, I will provide you the source code of this application that you have everything.
So we did start with simply comparing and passwords table different content provider.
All right.
Then we have done some crazy Android app development and over here those were our attack vectors, the,
the initial idea of this video so how to interact with content provider and yeah to exploit in content
provider.
The first attempt was I'm not sure anymore.
I guess it was bypassing the user's permission.
And then we had our SQL injection to access the protected table via the unprotected ones.
And last but not least, we we added those users permission into our own application and nicely ask
the user to provide us those permissions.
In case if the user clicked on this, all the passwords would be gone.
So this would be the absolute worst case for the user.
And the user just has to click it once.
So we can we can use this as a pop up over and over again.
All right.
So this is all for this feature right now.
All right.
So this video once again has become a little bit longer than expected.
Sorry for this, but I guess the things we have learned over here, they are really necessary or they
are essential to to deal with those stuff.
Also, new applications.
Otherwise, you you have to figure this out by yourself, how to deal with app visibility, print out
block data and then content provider and things like this.
Therefore, I would like to include all the things in this video to show you everything that I know
that you do not have to search it anymore.
Alrighty.
Okay.
And the next one, we will take a look at the path traversal vulnerability.
And then we are I guess we are done afterwards with content providers in case if you have any questions,
leave a comment under the video.
Otherwise, I'm looking forward to see you in the next one.
See you there.