文章目录
概述
pwnable是一个经典的CTF中PWN方向练习的专业网站,本文记录的题目是leg,主要考察的是基于ARM的寄存器与汇编相关知识点。
题目
题目描述
题目提示 Daddy told me I should study arm,已经很明确的说明了与ARM有关,同时提供了两个文件下载
- http://pwnable.kr/bin/leg.c
- http://pwnable.kr/bin/leg.asm
连接信息
通过ssh登录靶机
ssh leg@pwnable.kr -p2222 (pw:guest)
查看家目录
查看leg.c
#include <stdio.h>
#include <fcntl.h>
int key1(){
asm("mov r3, pc\n");
}
int key2(){
asm(
"push {r6}\n"
"add r6, pc, $1\n"
"bx r6\n"
".code 16\n"
"mov r3, pc\n"
"add r3, $0x4\n"
"push {r3}\n"
"pop {pc}\n"
".code 32\n"
"pop {r6}\n"
);
}
int key3(){
asm("mov r3, lr\n");
}
int main(){
int key=0;
printf("Daddy has very strong arm! : ");
scanf("%d",
if( (key1()+key2()+key3()) == key ){
printf("Congratz!\n");
int fd = open("flag", O_RDONLY);
char buf[100];
int r = read(fd, buf, 100);
write(0, buf, r);
}
else{
printf("I have strong leg :P\n");
}
return 0;
}
源代码分析
可以看到,得到flag的条件为三个函数key1()、key2()、key3()相加的结果与输入的key值相等即可。
查看leg.asm
除了提供C语言的源代码,还提供了汇编语言的代码
main()的主要代码片段
0x00008d60 <+36>: mov r1, r3
0x00008d64 <+40>: bl 0xfbd8 <__isoc99_scanf>
0x00008d68 <+44>: bl 0x8cd4 <key1>
0x00008d6c <+48>: mov r4, r0
0x00008d70 <+52>: bl 0x8cf0 <key2>
0x00008d74 <+56>: mov r3, r0
0x00008d78 <+60>: add r4, r4, r3
0x00008d7c <+64>: bl 0x8d20 <key3>
0x00008d80 <+68>: mov r3, r0
0x00008d84 <+72>: add r2, r4, r3
函数key1(),可以看到把结果保存到r3,其值为$pc,为0x00008ce4,即 (下一条指令地址+4)
0x00008cdc <+8>: mov r3, pc
0x00008ce0 <+12>: mov r0, r3
0x00008ce4 <+16>: sub sp, r11, #0
函数key2(),可以看到把结果保存到r3,其值为$pc+4,为0x00008d0c,即 ((下一条指令地址+4)+4)
0x00008d04 <+20>: mov r3, pc
0x00008d06 <+22>: adds r3, #4
0x00008d08 <+24>: push {r3}
函数key3(),可以看到把结果保存到r3,其值为$lr,即返回地址0x00008d80
0x00008d28 <+8>: mov r3, lr
0x00008d2c <+12>: mov r0, r3
0x00008d30 <+16>: sub sp, r11, #0
题目解法
通过汇编代码分析,得到三个函数key1()、key2()、key3()的值,相加结果为
In [1]: 0x00008ce4 + 0x00008d0c + 0x00008d80
Out[1]: 108400
则key输入108400即可