pico- WinAntiDBG0x100

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char Block; // [esp+0h] [ebp-8h]
  char Blocka; // [esp+0h] [ebp-8h]
  WCHAR *lpOutputString; // [esp+4h] [ebp-4h]

  if ((unsigned __int8)sub_401130())
  {
    OutputDebugStringW("\n");
    OutputDebugStringW("\n");
    sub_4011B0();
    if (sub_401200())
    {
      OutputDebugStringW(
        L"### Level 1: Why did the clever programmer become a gardener? Because they discovered their talent for growing a"
        " 'patch' of roses!\n");
      sub_401440(7);
      if (IsDebuggerPresent())
      {
        OutputDebugStringW(L"### Oops! The debugger was detected. Try to bypass this check to get the flag!\n");
      }
      else
      {
        sub_401440(11);
        sub_401530(dword_405404);
        lpOutputString = (WCHAR *)sub_4013B0(dword_405408);
        if (lpOutputString)
        {
          OutputDebugStringW(L"### Good job! Here's your flag:\n");
          OutputDebugStringW(L"### ~~~ ");
          OutputDebugStringW(lpOutputString);
          OutputDebugStringW(L"\n");
          OutputDebugStringW(L"### (Note: The flag could become corrupted if the process state is tampered with in any way.)\n\n");
          j_j_free(lpOutputString);
        }
        else
        {
          OutputDebugStringW(L"### Something went wrong...\n");
        }
      }
    }
    else
    {
      OutputDebugStringW(L"### Error reading the 'config.bin' file... Challenge aborted.\n");
    }
    free(::Block);
  }
  else
  {
    sub_401060((char *)lpMultiByteStr, Block);
    sub_401060("### To start the challenge, you'll need to first launch this program using a debugger!\n", Blocka);
  }
  OutputDebugStringW(L"\n");
  OutputDebugStringW(L"\n");
  return 0;
}

ida 디컴파일 전체 코드 

뜯어서 보자 

if (IsDebuggerPresent())
{
  OutputDebugStringW(L"### Oops! The debugger was detected. Try to bypass this check to get the flag!\n");
}
else
{
  sub_401440(11);
  sub_401530(dword_405404);
  lpOutputString = (WCHAR *)sub_4013B0(dword_405408);
  if (lpOutputString)
  {
    OutputDebugStringW(L"### Good job! Here's your flag:\n");
    OutputDebugStringW(L"### ~~~ ");
    OutputDebugStringW(lpOutputString);
    OutputDebugStringW(L"\n");
    OutputDebugStringW(L"### (Note: The flag could become corrupted if the process state is tampered with in any way.)\n\n");
    j_j_free(lpOutputString);
  }
}

여기 IsDebuggerPresent만 우회하면 될듯?

스크린샷 2025-04-06 125839.png

xdbg 열어주고 winantidbg0x100.exe 모듈에서 문자열 참조하면

스크린샷 2025-04-06 131932.png

위 문자열이 보임

대충 Good job! 눌러서 해당 위치로 움직이고 스크롤 좀만 올려보면

스크린샷 2025-04-06 125941.png

IsDebuggerPresent call 위치 발견

BP 걸어주자

스크린샷 2025-04-06 132036.png

f9로 call까지 와주고 f8 누르면 EAX값이 1일거임

아까 if문에서도 봤듯이 이걸 0으로 바꿔줘야 함

eax 값 더블클릭해서 0으로 바꿔줌

스크린샷 2025-04-06 132122.png

F8 계속 누르다보면 위처럼 picoCTF 플래그가 보일거임

스크린샷 2025-04-06 132218.png

stack에서 보면 위와 같음

Cross Origin Resource Sharing

일단 위 글 보고 SOP이랑 CORS 정리

  1. SOP이란..
    Same-Origin-Policy
    같은 Origin이서만 document를 읽거나 script를 읽을 수 있음
    origin? protocol, host, port로 이루어져 있는..(걍 url이라고 이해)

이 정책이 있는 이유?
-> 아래 시나리오를 생각해볼 수 있음

SOP 시나리오

여기서 SOP를 쓴다면 5번에서 유출을 방지할 수 있다
(해커가 넣은 iframe의 origin과 상위 document의 origin이 다르기 때문에)

  1. 그래서 CORS란?
    어쩌다가 다른 origin 통신이 필요할 때 사용하는 기능? 기술?이다
    방법은 아래 세 가지
  2. postMessage
  3. JSONP
  4. CORS HEADER

  5. Checking if a whitelisted string is found is a bad approach
    auth_token을 보여주고 이것을 훔치라고 한다.

Checking if a whitelisted string is found

Another example

Yet another example

Final example

안되는디 ㅜㅜ

Error example

Another error example

BountyCon 2020 - Anti What

Image 1

안 열림

Image 2

기드라 굿

int main(undefined8 param_1,undefined8 *param_2)
{
  int iVar1;
  long lVar2;
  long in_FS_OFFSET;
  int local_15c;
  termios local_158;
  long local_10;

  local_10 = *(long *)(in_FS_OFFSET + 0x28);
  local_15c = 0;
  lVar2 = ptrace(PTRACE_TRACEME,0,1,0);
  if (lVar2 == 0) {
    local_15c = 2;
  }
  lVar2 = ptrace(PTRACE_TRACEME,0,1,0);
  if (lVar2 == -1) {
    local_15c = local_15c * 3;
  }
  if (local_15c == 6) {
    RC4_set_key((RC4_KEY *)&stack0xfffffffffffffee8,0x32,key);
    RC4((RC4_KEY *)&stack0xfffffffffffffee8,0x4e,(uchar *)&ptext,(uchar *)&ptext);
    runPayload();
    puts("Press any key to quit...");
    tcgetattr(0,&local_158);
    local_158.c_lflag = local_158.c_lflag & 0xfffffffd;
    local_158.c_cc[6] = '\x01';
    local_158.c_cc[5] = '\0';
    tcsetattr(0,0,&local_158);
    getchar();
    iVar1 = 0;
  }
  else {
    iVar1 = unlink((char *)*param_2);
  }
  if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) {
                    /* WARNING: Subroutine does not return */
    __stack_chk_fail();
  }
  return iVar1;
}

main을 보면 위와 같다.

local_15c를 6으로 만들면 뭔가 개많이 실행이 됨

근데 local_15c는 ptrace의 반환값인 lVar2 값에 의해 조정 가능

—–> ptrace 우회가 필요!!!

  1. ==을 !=으로 바꾸기

Image 3

if를 누르면 그에 해당하는 어셈블리 코드가 좌측에 나옴

Image 4

74를 75로 바꿔주면 JZ가 JNZ로 바뀜

  1. if부분을 통으로 0x90(NOP)으로 채우기

Image 5

  1. 기드라 저장이 힘들어서 아이다로 어셈블함

Image 6

저장하고 ubuntu에서 실행

일단 뭔가 runPayload까지 실행해보고 싶어서

Image 7

해봤는데 바로 플래그가 나옴

…그치만 일단 설명을 해야하니까

Image 8

runPayload() 함수를 보자 v1에 malloc으로 메모리를 할당하고 unpackPayload를 함

할당된 곳에 배열과 ptext값을 넣고 있음 + runPayload 하기 전 ptext는 RC4구문을 거침

  1. 어셈블로 ptrace bypass하기
  2. RC4로 돌린 ptext 구하고 저장된 배열 조립해서 result 구하기

Vectors

Vectors

how lattices appear in crypto 떠들어보신다고 함(운동 갔다가 카공 하려니까 기운 빠져서 날카로움)

linear algebra에 대해 짚고 넘어가야 하는데(선형대수학이라 함)

벡터 V는 필드 F에서 이진수 연산으로 구성된 set(집합)이다.
v∈V 그리고 a(스칼라) ∈ F일 때, 두 벡터 간의 덧셈은 다른 벡터를 생성한다: v+w=z
v,w,z ∈V 그리고 vectorscalar 곱셈은 벡터를 생성한다: av=w와 a∈ F

두 평면 벡터가 있을 때, v∈V는 숫자들의 쌍으로 표현 가능하다(좌표 말하는듯) v=(a,b) (a,b는 R에 속함)
이때 덧셈과 곱셈은 다음과 같이 표현이 가능하다.
v+w=(a,b)+(c,d)=(a+c,b+d)
cv=c(a,b)=(ac, bc)
그리고 inner product(요소 말하는 건가내적, 두 벡터를 가지고 scalar를 뱉는) 다음과 같이 표현 가능
v
w=a (v,w ∈V, a∈ F)
근데 요렇게도 가능함 -> vw=(a,b)(c,d)=ac+bd

Q. 3차원에서도 생각해보라 함
v=(2,6,3), w=(1,0,0), u=(7,7,2)일 때, 3(2v-w)2u 계산하기
풀어서 써보면.. 2u(6v-3w) 다 풀진 않았네 암튼암튼 괄호 안 먼저 계산
6v-3w=(12,36,18)+(-3,0,0)=(9,36,18)
(14,14,4)(9,36,18)=(126,504,72)
안되는데..

  • 라업 내용
    내적이 되니까 vw=(a,b)(c,d)=ac+bd 이 식 가져와서 126+504+72=702
    그리고 참고한 라업은 python으로 풀었더라고.. 나도 파이썬으로 풀어야겟드아..
def scalar(a,v):
    #곱셈 경우만 생각 
    for i in range(len(v)):
        v[i]=a*v[i]
    return v

def twovecmul(v,w):
    for i in range(len(v)):
        v[i]=v[i]*w[i]
    return v

def twovecadd(v,w):
    for i in range(len(v)):
        v[i]=v[i]+w[i]
    return v

def innerproduct(v):
    ans=0
    for i in v:
        ans=ans+i
    return ans 

'''
3*(2v-w)*2u를 av 꼴로 나타내면...
6u(2v-w)
'''
v=[2,6,3]
w=[1,0,0]
u=[7,7,2]

print(innerproduct(twovecmul(scalar(6,u),twovecadd(scalar(2,v),scalar(-1,w)))))

[NullCon2025] Paginator

<?php
ini_set("error_reporting", 0);
ini_set("display_errors", 0);

if(isset($_GET['source'])) {
    highlight_file(__FILE__);
}

include "flag.php";

$db = new SQLite3('/tmp/db.db');
try {
  $db->exec("CREATE TABLE pages (id INTEGER PRIMARY KEY, title TEXT UNIQUE, content TEXT)");
  $db->exec("INSERT INTO pages (title, content) VALUES ('Flag', '" . base64_encode($FLAG) . "')");
  $db->exec("INSERT INTO pages (title, content) VALUES ('Page 1', 'This is not a flag, but just a boring page.')");
  $db->exec("INSERT INTO pages (title, content) VALUES ('Page 2', 'This is not a flag, but just a boring page.')");
  $db->exec("INSERT INTO pages (title, content) VALUES ('Page 3', 'This is not a flag, but just a boring page.')");
  $db->exec("INSERT INTO pages (title, content) VALUES ('Page 4', 'This is not a flag, but just a boring page.')");
  $db->exec("INSERT INTO pages (title, content) VALUES ('Page 5', 'This is not a flag, but just a boring page.')");
  $db->exec("INSERT INTO pages (title, content) VALUES ('Page 6', 'This is not a flag, but just a boring page.')");
  $db->exec("INSERT INTO pages (title, content) VALUES ('Page 7', 'This is not a flag, but just a boring page.')");
  $db->exec("INSERT INTO pages (title, content) VALUES ('Page 8', 'This is not a flag, but just a boring page.')");
  $db->exec("INSERT INTO pages (title, content) VALUES ('Page 9', 'This is not a flag, but just a boring page.')");
  $db->exec("INSERT INTO pages (title, content) VALUES ('Page 10', 'This is not a flag, but just a boring page.')");
} catch (Exception $e) {
  //var_dump($e);
}

if(isset($_GET['p']) && str_contains($_GET['p'], ",")) {
  [$min, $max] = explode(",", $_GET['p']);
  if(intval($min) <= 1 ) {
    die("This post is not accessible...");
  }
  try {
    $q = "SELECT * FROM pages WHERE id >= $min AND id <= $max";
    $result = $db->query($q);
    while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
      echo $row['title'] . " (ID=" . $row['id'] . ") has content: \"" . $row['content'] . "\"<br>";
    }
  } catch (Exception $e) {
    echo "Try harder!";
  }
} else {
    echo "Try harder!";
}
?>
<html>
    <head>
        <title>Paginator</title>
    </head>
    <body>
        <h1>Paginator</h1>
        <a href="/?p=2,10">Show me pages 2-10</a>
        <p>To view the source code, <a href="/?source">click here.</a>
    </body>
</html>

db 쿼리를 보내는 것을 보아 높은 확률로 sql injection 아닐까 했다.

Image

ID를 1도 출력할 수 있게 or을 넣었다

Image