从pwnable.kr入门pwn (2) leg

dr003   ·   发表于 2021-02-05 11:57:48   ·   CTF&WP专版

题目信息

汇编代码

  1. (gdb) disass main
  2. Dump of assembler code for function main:
  3. 0x00008d3c <+0>: push {r4, r11, lr}
  4. 0x00008d40 <+4>: add r11, sp, #8
  5. 0x00008d44 <+8>: sub sp, sp, #12
  6. 0x00008d48 <+12>: mov r3, #0
  7. 0x00008d4c <+16>: str r3, [r11, #-16]
  8. 0x00008d50 <+20>: ldr r0, [pc, #104] ; 0x8dc0 <main+132>
  9. 0x00008d54 <+24>: bl 0xfb6c <printf>
  10. 0x00008d58 <+28>: sub r3, r11, #16
  11. 0x00008d5c <+32>: ldr r0, [pc, #96] ; 0x8dc4 <main+136>
  12. 0x00008d60 <+36>: mov r1, r3
  13. 0x00008d64 <+40>: bl 0xfbd8 <__isoc99_scanf>
  14. 0x00008d68 <+44>: bl 0x8cd4 <key1>
  15. 0x00008d6c <+48>: mov r4, r0
  16. 0x00008d70 <+52>: bl 0x8cf0 <key2>
  17. 0x00008d74 <+56>: mov r3, r0
  18. 0x00008d78 <+60>: add r4, r4, r3
  19. 0x00008d7c <+64>: bl 0x8d20 <key3>
  20. 0x00008d80 <+68>: mov r3, r0
  21. 0x00008d84 <+72>: add r2, r4, r3
  22. 0x00008d88 <+76>: ldr r3, [r11, #-16]
  23. 0x00008d8c <+80>: cmp r2, r3
  24. 0x00008d90 <+84>: bne 0x8da8 <main+108>
  25. 0x00008d94 <+88>: ldr r0, [pc, #44] ; 0x8dc8 <main+140>
  26. 0x00008d98 <+92>: bl 0x1050c <puts>
  27. 0x00008d9c <+96>: ldr r0, [pc, #40] ; 0x8dcc <main+144>
  28. 0x00008da0 <+100>: bl 0xf89c <system>
  29. 0x00008da4 <+104>: b 0x8db0 <main+116>
  30. 0x00008da8 <+108>: ldr r0, [pc, #32] ; 0x8dd0 <main+148>
  31. 0x00008dac <+112>: bl 0x1050c <puts>
  32. 0x00008db0 <+116>: mov r3, #0
  33. 0x00008db4 <+120>: mov r0, r3
  34. 0x00008db8 <+124>: sub sp, r11, #8
  35. 0x00008dbc <+128>: pop {r4, r11, pc}
  36. 0x00008dc0 <+132>: andeq r10, r6, r12, lsl #9
  37. 0x00008dc4 <+136>: andeq r10, r6, r12, lsr #9
  38. 0x00008dc8 <+140>: ; <UNDEFINED> instruction: 0x0006a4b0
  39. 0x00008dcc <+144>: ; <UNDEFINED> instruction: 0x0006a4bc
  40. 0x00008dd0 <+148>: andeq r10, r6, r4, asr #9
  41. End of assembler dump.
  42. (gdb) disass key1
  43. Dump of assembler code for function key1:
  44. 0x00008cd4 <+0>: push {r11} ; (str r11, [sp, #-4]!)
  45. 0x00008cd8 <+4>: add r11, sp, #0
  46. 0x00008cdc <+8>: mov r3, pc
  47. 0x00008ce0 <+12>: mov r0, r3
  48. 0x00008ce4 <+16>: sub sp, r11, #0
  49. 0x00008ce8 <+20>: pop {r11} ; (ldr r11, [sp], #4)
  50. 0x00008cec <+24>: bx lr
  51. End of assembler dump.
  52. (gdb) disass key2
  53. Dump of assembler code for function key2:
  54. 0x00008cf0 <+0>: push {r11} ; (str r11, [sp, #-4]!)
  55. 0x00008cf4 <+4>: add r11, sp, #0
  56. 0x00008cf8 <+8>: push {r6} ; (str r6, [sp, #-4]!)
  57. 0x00008cfc <+12>: add r6, pc, #1
  58. 0x00008d00 <+16>: bx r6
  59. 0x00008d04 <+20>: mov r3, pc
  60. 0x00008d06 <+22>: adds r3, #4
  61. 0x00008d08 <+24>: push {r3}
  62. 0x00008d0a <+26>: pop {pc}
  63. 0x00008d0c <+28>: pop {r6} ; (ldr r6, [sp], #4)
  64. 0x00008d10 <+32>: mov r0, r3
  65. 0x00008d14 <+36>: sub sp, r11, #0
  66. 0x00008d18 <+40>: pop {r11} ; (ldr r11, [sp], #4)
  67. 0x00008d1c <+44>: bx lr
  68. End of assembler dump.
  69. (gdb) disass key3
  70. Dump of assembler code for function key3:
  71. 0x00008d20 <+0>: push {r11} ; (str r11, [sp, #-4]!)
  72. 0x00008d24 <+4>: add r11, sp, #0
  73. 0x00008d28 <+8>: mov r3, lr
  74. 0x00008d2c <+12>: mov r0, r3
  75. 0x00008d30 <+16>: sub sp, r11, #0
  76. 0x00008d34 <+20>: pop {r11} ; (ldr r11, [sp], #4)
  77. 0x00008d38 <+24>: bx lr
  78. End of assembler dump.
  79. (gdb)

c语言代码

  1. include <stdio.h>
  2. include <fcntl.h>
  3. int key1(){
  4. asm("mov r3, pc\n");
  5. }
  6. int key2(){
  7. asm(
  8. "push {r6}\n"
  9. "add r6, pc, $1\n"
  10. "bx r6\n"
  11. ".code 16\n"
  12. "mov r3, pc\n"
  13. "add r3, $0x4\n"
  14. "push {r3}\n"
  15. "pop {pc}\n"
  16. ".code 32\n"
  17. "pop {r6}\n"
  18. );
  19. }
  20. int key3(){
  21. asm("mov r3, lr\n");
  22. }
  23. int main(){
  24. int key=0;
  25. printf("Daddy has very strong arm! : ");
  26. scanf("%d", &key);
  27. if( (key1()+key2()+key3()) == key ){
  28. printf("Congratz!\n");
  29. int fd = open("flag", O_RDONLY);
  30. char buf[100];
  31. int r = read(fd, buf, 100);
  32. write(0, buf, r);
  33. }
  34. else{
  35. printf("I have strong leg :P\n");
  36. }
  37. return 0;
  38. }
  39. ## 解题思路
从C代码入手
从main函数开始

获取key使得key等于key1()+key2()+key3()
然后就会出flag

key1

mov r3, pc
把pc存到r3
//pc 总是包含下一个要被执行的指令的位置

key2

“push {r6}\n” //压栈
“add r6, pc, $1\n”//$1 偏移量 //r6+pc+1
“bx r6\n”//
“.code 16\n”
“mov r3, pc\n” //pc存到r3
“add r3, $0x4\n” //r3+4
“push {r3}\n” //压栈
“pop {pc}\n” //出栈
“.code 32\n”
“pop {r6}\n” //出栈

key3

mov r3, lr
//lr (总是)包含着退出时要装载到 pc 中的值

再看到汇编代码
key1

0x00008cd4 <+0>: push {r11} ; (str r11, [sp, #-4]!)
0x00008cd8 <+4>: add r11, sp, #0 //r11+sp存sp

//sp 指向当前的栈
0x00008cdc <+8>: mov r3, pc//r3存pc
0x00008ce0 <+12>: mov r0, r3//r0存r3
0x00008ce4 <+16>: sub sp, r11, #0 //sp-r11存到sp
0x00008ce8 <+20>: pop {r11} ; (ldr r11, [sp], #4)
0x00008cec <+24>: bx lr

key2

0x00008cf0 <+0>: push {r11} ; (str r11, [sp, #-4]!)
0x00008cf4 <+4>: add r11, sp, #0
0x00008cf8 <+8>: push {r6} ; (str r6, [sp, #-4]!)
0x00008cfc <+12>: add r6, pc, #1 //r6存 r6+pc+1
0x00008d00 <+16>: bx r6
0x00008d04 <+20>: mov r3, pc //r3存pc
0x00008d06 <+22>: adds r3, #4 //r3+4
0x00008d08 <+24>: push {r3}
0x00008d0a <+26>: pop {pc}
0x00008d0c <+28>: pop {r6} ; (ldr r6, [sp], #4)
0x00008d10 <+32>: mov r0, r3 //r0存r3
0x00008d14 <+36>: sub sp, r11, #0 //sp-r11存到sp
0x00008d18 <+40>: pop {r11} ; (ldr r11, [sp], #4)
0x00008d1c <+44>: bx lr

key3

0x00008d20 <+0>: push {r11} ; (str r11, [sp, #-4]!)
0x00008d24 <+4>: add r11, sp, #0
0x00008d28 <+8>: mov r3, lr
0x00008d2c <+12>: mov r0, r3
0x00008d30 <+16>: sub sp, r11, #0
0x00008d34 <+20>: pop {r11} ; (ldr r11, [sp], #4)
0x00008d38 <+24>: bx lr

payload

r0作为输出则key1返回值pc 0x00008ce4
//执行第一条指令时,第二条指令正在译码阶段,而第三条指令正在取指阶段。在执行第一条指令时,PC寄存器应指向第三条指令。也即,当处理器为三级流水线结构时,PC寄存器总是指向随后的第三条指令。
key2返回值pc+4 0x00008d0c
key3返回值lr(返回主函数地址) 0x00008d80
三个值相加 0x1A770
scanf 中 %d 只识别“十进制整数”
所以是108400

用户名金币积分时间理由
veek 30.00 0 2021-02-06 09:09:11

打赏我,让我更有动力~

0 Reply   |  Until 2021-2-5 | 876 View
LoginCan Publish Content
返回顶部 投诉反馈

© 2016 - 2024 掌控者 All Rights Reserved.