IT评测·应用市场-qidao123.com
标题:
看不见的彼方:互换空间——小菜一碟
[打印本页]
作者:
河曲智叟
时间:
2024-12-1 04:44
标题:
看不见的彼方:互换空间——小菜一碟
有个蓝色的链接,先去看看两年前的题目标write up
(https://github.com/USTC-Hackergame/hackergame2022-writeups/blob/master/official/%E7%9C%8B%E4%B8%8D%E8%A7%81%E7%9A%84%E5%BD%BC%E6%96%B9/README.md)
从别人的write up中相识到,可以用信号和IPC来传递数据,而这个IPC指的就是消息队列(msgget 等)和共享内存(shmget 等),留意一定要使用System V的 API,因为posix的那几个会依赖文件系统而不能使用。
历程间通信的题目解决了,接下来就是内存限制的处置处罚了。固然不能完全复制,但是一次复制个2MiB 照旧没题目标。开一个2MiB大小的共享内存空间,然后前半部分用来把A的文件内容传给B,后半部分用来把 B 的文件内容传给 A,写入到文件的时候直接原位置覆盖写入即可。每次传递两个1MiB 大小的文件片断,再加上用消息队列跨历程同步,整个事情就成了。
容器内存限制 316 MiB,你提交的程序文件会复制为两份,分别占用一份内存空间。环境限制总 PID 数为 32。对于 chroot 内部的历程,只有 /space 可读写。/space(/home/pwn/A/space/ 和 /home/pwn/B/space/)为 tmpfs,使用内存空间。
已经尝试过让AI天生代码,但照旧不行,代码这块我不认识,下面是大佬的write up的代码:
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/msg.h>
#include <sys/shm.h>
void perror_exit(char* message){
perror(message);
exit(-1);
}
struct message {
long type;
char buffer[4];
};
int main()
{
printf("a start\n");
int mqab=msgget(12450,0666 |IPC_CREAT);
if(mqab<0){
perror_exit("msgget swapab error");
}
int mqba=msgget(12451,0666 |IPC_CREAT);
if(mqba<0){
perror_exit("msgget swapba error");
}
int shm=shmget(12452,2*1024*1024,0666 |IPC_CREAT);
if(mqba<0){
perror_exit("shmget error");
}
void* mem=shmat(shm,0,0);
if(mem==(void*)(-1)){
perror_exit("shmat error");
}
int fd=open("/space/file",O_RDWR);
if(fd<0){
perror_exit("open error");
}
printf("a ok\n");
char* read_start=((char*)(mem));
char* write_start=((char*)(mem))+1024*1024;
for(int i=0;i<128;i++){
int segment_start=i*1024*1024;
// 读出文件内容
off_t read_off=lseek(fd,segment_start,SEEK_SET);
if(read_off<0){
perror_exit("lseek error");
}
int read_count=0;
while(read_count<1024*1024){
int read_len=read(fd,read_start+read_count,1024*1024-read_count);
if(read_len<0){
perror_exit("read error");
}
read_count+=read_len;
}
// 发送同步信号
struct message out;
out.type=1;
if (msgsnd(mqab, &out, sizeof (struct message), 0) <0) {
perror_exit("msgsnd error");
}
// 接收同步信号
struct message in;
if (msgrcv(mqba, &in, sizeof (struct message),0, 0) <0) {
perror_exit("msgrcv error");
}
// 写回文件内容
off_t write_off=lseek(fd,segment_start,SEEK_SET);
if(write_off<0){
perror_exit("lseek error");
}
int write_count=0;
while(write_count<1024*1024){
int write_len=write(fd,write_start+write_count,1024*1024-write_count);
if(write_len<0){
perror_exit("write error");
}
write_count+=write_len;
}
}
printf("a complete\n");
}
复制代码
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/msg.h>
#include <sys/shm.h>
void perror_exit(char* message){
perror(message);
exit(-1);
}
struct message {
long type;
char buffer[4];
};
int main()
{
printf("b start\n");
int mqab=msgget(12450,0666 |IPC_CREAT);
if(mqab<0){
perror_exit("msgget swapab error");
}
int mqba=msgget(12451,0666 |IPC_CREAT);
if(mqba<0){
perror_exit("msgget swapba error");
}
int shm=shmget(12452,2*1024*1024,0666 |IPC_CREAT);
if(mqba<0){
perror_exit("shmget error");
}
void* mem=shmat(shm,0,0);
if(mem==(void*)(-1)){
perror_exit("shmat error");
}
int fd=open("/space/file",O_RDWR);
if(fd<0){
perror_exit("open error");
}
printf("b ok\n");
char* read_start=((char*)(mem))+1024*1024;
char* write_start=((char*)(mem));
for(int i=0;i<128;i++){
int segment_start=i*1024*1024;
// 接收同步信号
struct message in;
if (msgrcv(mqab, &in, sizeof (struct message),0, 0) <0) {
perror_exit("msgrcv error");
}
// 读出文件内容
off_t read_off=lseek(fd,segment_start,SEEK_SET);
if(read_off<0){
perror_exit("lseek error");
}
int read_count=0;
while(read_count<1024*1024){
int read_len=read(fd,read_start+read_count,1024*1024-read_count);
if(read_len<0){
perror_exit("read error");
}
read_count+=read_len;
}
// 写回文件内容
off_t write_off=lseek(fd,segment_start,SEEK_SET);
if(write_off<0){
perror_exit("lseek error");
}
int write_count=0;
while(write_count<1024*1024){
int write_len=write(fd,write_start+write_count,1024*1024-write_count);
if(write_len<0){
perror_exit("write error");
}
write_count+=write_len;
}
// 发送同步信号
struct message out;
out.type=1;
if (msgsnd(mqba, &out, sizeof (struct message), 0) <0) {
perror_exit("msgsnd error");
}
}
printf("b complete\n");
}
复制代码
编译之后上传文件:
乐成得到flag:flag{just A p1ece 0f cake_2e65492b77}
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 IT评测·应用市场-qidao123.com (https://dis.qidao123.com/)
Powered by Discuz! X3.4