반응형

CS에 대해 공부하던 중 주어진 code에 의구심을 품게된 부분이 있어 알아보았습니다.

 

자료형 크기 확인(sizeof)

code

#include <stdio.h>

int main() {
        printf("Size of char: %zu bytes\n", sizeof(char));
        printf("Size of short: %zu bytes\n", sizeof(short));
        printf("Size of int: %zu bytes\n", sizeof(int));
        printf("Size of long: %zu bytes\n", sizeof(long));
        printf("Size of long long: %zu bytes\n", sizeof(long long));
        printf("Size of float: %zu bytes\n", sizeof(float));
        printf("Size of double: %zu bytes\n", sizeof(double));
        printf("Size of long double: %zu bytes\n", sizeof(long double));
        printf("Size of pointer: %zu bytes\n", sizeof(void*));
        return 0;
}

이때, %u가 아닌 %zu를 사용하는 이유는?

A: 우선, sizeof()의 경우 크기를 나타내는 함수 이므로, 양수이다. 이 말인 즉슨 unsigned를 사용하는 것이다.

여기서 근데 unsigned에 대한 type specifier는 %u이고, size_t의 경우는 %zu이다.

 

그렇다면 왜 %zu일까... 구글링 결과 %d를 사용하는 경우도 있고, %u를 사용하는 경우도 있긴했다.

아마 코드의 이식성으로 인하여 사용한 것이 아닐까 싶다...! 더하여, size_t는 unsigned int와 같은 의미이기에 혼용가능한 것 같다.

%u는 32bit냐 64bit냐에 따라 변화가 있을수도 있다고 한다.

 

[+] 공식 문서들을 참고해보았다. 내 예상이 얼추 들어맞은 것 같다만.. 

우선, sizeof()로 인해 %zu를 쓴다기보단, printf()에서 %zu로 쓰도록 C99에 나와있는 것 같다.(이부분은 찾지 못함 ㅠ)

그리고 이전에는 %zu와 %iu 로 나뉘어 msvc에서는 %iu, gcc는 %zu로 사용하였지만 이는 오래전 이야기라고 한다.

https://stackoverflow.com/questions/2524611/how-can-one-print-a-size-t-variable-portably-using-the-printf-family

https://stackoverflow.com/questions/15610053/correct-printf-format-specifier-for-size-t-zu-or-iu

 

[+] %zu대신 %u를 써야하는 이유는 이식성 때문이 맞다. 이는 size_t에 대한 공식 문서와 아래의 블로그를 참고하면 이해하는데에 훨씬 도움이 될것이라 여겨진다.

https://en.cppreference.com/w/c/types/size_t

https://en.cppreference.com/w/cpp/language/sizeof

https://blog.naver.com/oxcow119/220550770300

말이 두서없이 쓰였지만.. 아래의 링크와 위의 말들을 종합해서 이해하는 데에 도움이 되었으면 한다.

그리고 덕분에 size_t가 loop에 의해 메모리나 문자열의 길이를 구한다는 사실을 알게되었다.

또한 unsigned long은 사실 %lu라는 형식 지정자가 있으나, 본 실습의 목적은 sizeof()에 의해 size_t로 출력하는 것이므로 %zu가 권장되는 형식지정자이다. 이 부분 역시 호환성으로 인해 %zu가 권장되는거다!

 

결국 컴퓨터를 배울때마다 항상 중요시되는 호환성! 편의성! 요놈들이 진짜 중요한거다

요놈들에 대해서도 왜? 호환성이  야무져? 이게 왜 편해? 라는데 진짜 그리고 파도파도 이해가 안되면... 앨런 튜링센세를 뵙고오던..C contributer를 뵙고오던...그냥 받아들이던지.. 하는게 답인거 같다ㅠ

 

 

====================

이하의 내용은 간단한 실습들입니다.

 

overflow 재현

code

#include <stdio.h>
#include <limits.h>

int main(){
        char value = CHAR_MAX;
        printf("Original value: %d\n", value);

        value = value+1;
        printf("Value after adding 1: %d\n", value);

        return 0;
}

result

그렇다면 underflow로 해보자!

code

#include <stdio.h>
#include <limits.h>

int main(){
        char value = CHAR_MIN;
        printf("Original value: %d\n", value);

        value = value-1;
        printf("Value after subtracting 1: %d\n", value);

        return 0;
}

result

====================

cf.

gcc -o main main.c -g //디버깅 심볼 포함

일반적으로는 분석의 방해를 위하여 디버깅 심볼을 포함시키지 않는다.

디버깅 심볼을 날릴 시, IDA등의 decompiler로 보기에 난해하다..!!!

(gdb) b main //중단점 설정
(gdb) r //함수를 만날 경우 내불로 들어가지 않고 실행됨
(gdb) n //다음 줄 실행
(gdb) p value // p[변수명] 변수값 출력
(gdb) p/t value // p/[출력형식][변수명]: 출력형식에 맞추어 변수값 출력

==================

특정 위치의 비트를 끄는 c언어 프로그램 작성후 확인 실습

 

1. 특정 비트만큼 1을 시프트한다 (1 << position)

2. 모든 비를 NOT을 활용하여 반전 시킨다.

3. AND연산을 수행함으로써 특정 비트를 끌 수 있다.

 

Answer

#include <stdio.h>

int is_bit_set(unsigned char value, int position) {
        return (value&(1 << position)) != 0;
}

unsigned char set_bit(unsigned char value, int position) {
        return value | ( 1 << position);
}

unsigned char clear_bit(unsigned char value, int position) {
        return  value & ~( 1 << position);
}

int main() {
        unsigned char value = 0b00001000;

        if(is_bit_set(value, 3)) {
                printf("3rd bit is set!\n");
        }
        else {
                printf("3rd bit is not set!\n");
        }

        value = set_bit(value, 2);
        printf("Value after setting 2nd bit: %d\n", value);

        value = clear_bit(value, 2);
        printf("Value after setting 2nd bit: %d\n", value);


        return 0;
}

사용자가 position을 입력받도록 하는 code

#include <stdio.h>

int is_bit_set(unsigned char value, int position) {
        return (value&(1 << position)) != 0;
}

unsigned char set_bit(unsigned char value, int position) {
        return value | ( 1 << position);
}

unsigned char clear_bit(unsigned char value, int position) {
        return  value & ~( 1 << position);
}

int main() {
        unsigned char value = 0b00001000;
        int position = 0;

        if(is_bit_set(value, 3)) {
                printf("3rd bit is set!\n");
        }
        else {
                printf("3rd bit is not set!\n");
        }

        printf("input the position: ");
        scanf("%d", &position);

        value = set_bit(value, position);
        printf("Value after setting 2nd bit: %d\n", value);

        value = clear_bit(value, position);
        printf("Value after setting 2nd bit: %d\n", value);

		return 0;
}

 

=======================

c언어가 기계어가 되는 과정

 

헤더파일(*.h) + 소스코드(*.c) --(pre processing)--> 전처리된 소스코드 파일(*.i) ----(compile)----> 어셈블리어 파일(*.s)

----(assembly)---> 오프젝트파일 (*.o)들 + 라이브러리(*.a, *so) -----(linking)---> 실행파일

기본 코드로 실습

#include <stdio.h>

int main() {
        printf("Hello world!");
        return 0;
}

gcc -E hello.c -o hello.i

gcc -S hello.c -o hello.s   (어셈블리어 확인가능)

gcc -c hello.c -o hello.o  (readelf로 확인)

object file: 소스코드가 컴파일된 후의 중간 결과물, linker에 의해 실행 가능한 바이너리나 라이브러리로 만들어지기 전의 형태

 

특징

1. 바이너리 형태, but 이 파일 자체로는 실행 불가능하며, 다른 오브젝트 파일이나 라이브러리와 링크되어야 실행 가능.

2. 재배치 가능, 다른 object file이나 라이브러리와 링크되어 완전한 프로그램 형성.

3. 심볼 테이블 포함

4. 특정 architecture, OS, compiler에 따라 다르게 생성될 수 있음.

 

 

readelf, objdump, 010에디터 등으로 확인가능

아래의 화면은 HxD로 확인한 결과

 

gcc hello.o -o main

cf. 각단계의 파일을 모두 비교했을 시 과정에 의해 사이즈가 늘어났다가 줄어든다.

 

 

반응형

'System Hacking' 카테고리의 다른 글

heap overlapping  (0) 2024.05.09
Docker file - 18.04 세팅(pwn)  (0) 2024.02.12
pwnable.kr - flag  (0) 2023.09.10
basic_heap_overflow  (0) 2023.08.22
Mitigation  (0) 2023.01.17
반응형

후하..첨보는게 또 나왔다.

우선 아래와 같이 나온다.

문제를 한번 받아보자

wget으로~~~~~~~~~~~

 

실행권한을 주고 실행시켜보면?

결국은 strcpy로 복사해온다는거 같은디.... 까봐야지 알거같다.

 

음...아무것도 안보인다.

ida로 확인해보아도 뭘 볼수 없다ㅠ

readelf나 file 명령으로도 뭔가를 얻을 순 없었다.

호옥시나 뭔가 있나해서 HxD로 한번 까봤다.

음? 뭔가 한번씩 까보던 ELF파일과는 다르다.

 

UPK로 패킹(?)된 파일이었다 ㄷㄷ

그리하여 검색해보니 아래와 같이 나왔다.

https://reverseengineering.stackexchange.com/questions/11486/how-to-unpack-manually-an-upx-packed-elf-file

 

How to unpack manually an upx packed elf file

I am trying to learn to manually unpack an upx packed elf file. The examples I have found are for Windows, mostly with Ollydbg, and as I see the first step is to look for pushad and popad instructi...

reverseengineering.stackexchange.com

해보자

sudo apt install upx

upx -d -o un_flag flag

이제 다시 gdb로 ㄱㄱ

packing이 풀리니 주르르르를륵 나온다 ㅋㅋ

 

disas main을 수행해보면, main+32에서 flag가 rdx에 담기는 것을 볼 수 있다.

그렇다면! main+39즈음에 bp를 걸고 확인하자!

 

 

flag가 보인다!

반응형

'System Hacking' 카테고리의 다른 글

Docker file - 18.04 세팅(pwn)  (0) 2024.02.12
computer structure  (0) 2023.09.10
basic_heap_overflow  (0) 2023.08.22
Mitigation  (0) 2023.01.17
Stack Canary  (0) 2022.11.25
반응형

처음 접속시 화면이다.

제출해보면, your not admin이라고 나온다.

우선적으로 sql injection을 시도하려했는데, 입력받는 공간이 정확히 5이다.

injection을 위하여 length를 50으로 늘려주고, 기본 쿼리를 넣어보았다.

 

ez~

또 다른 풀이는 제출시, url 에 박히는 것을 활용하면된다.

https://webhacking.kr/challenge/js-6/?id=admin

 

admin자리에 admin'--를 넣어주어도 풀린다.

 

반응형

'webhacking.kr' 카테고리의 다른 글

webhacking.kr [old-38]  (0) 2023.07.16
webhacking.kr [old-36]  (0) 2023.07.15
webhacking.kr [old-27]  (0) 2023.07.15
webhacking.kr [old-25]  (0) 2023.07.15
webhacking.kr [old-27]  (0) 2023.07.15
반응형

이전의 succubus문제와 유사하게 풀면된다.

<?php 
  include "./config.php"; 
  login_chk(); 
  $db = dbconnect();
  $_GET['id'] = strrev(addslashes($_GET['id']));
  $_GET['pw'] = strrev(addslashes($_GET['pw']));
  if(preg_match('/prob|_|\.|\(\)/i', $_GET[id])) exit("No Hack ~_~"); 
  if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~"); 
  $query = "select id from prob_zombie_assassin where id='{$_GET[id]}' and pw='{$_GET[pw]}'"; 
  echo "<hr>query : <strong>{$query}</strong><hr><br>"; 
  $result = @mysqli_fetch_array(mysqli_query($db,$query)); 
  if($result['id']) solve("zombie_assassin"); 
  highlight_file(__FILE__); 
?>

여기서 알아야할 함수는 두가지이다.

addslashes : ', " , %00(null) 뒤에 역슬래시를 추가한다.

strrev() : 문자열을 반대순서로 입력한다.

ex. strrev(test) -> tset

 

일부러 addslashes를 이용하는 payload를 구성하면 아래와 같다.

id="&pw=or 1=1%23

 

이제 입력하기 위해 역순으로 만들어준다. 이 때, %23역시 32%로 만들어주면 #으로 인식하지 못하기에 %23은 그대로 입력해주어야한다.

그리하여 최종적인 payload는 아래와 같다.

?id="&pw=%231=1%20ro

 이렇게 보내면, highlight친 부분이 문자열로 처리되기에 뚫리는 것이다.

반응형

'wargame' 카테고리의 다른 글

simple-operation  (0) 2023.09.18
Broken Buffalo Wings  (0) 2023.09.10
phpreg  (0) 2023.08.27
type confusion  (0) 2023.08.27
tmitter  (0) 2023.08.26
반응형

이걸 왜 ctf때 못 풀었지... 너무 쉬운건데 아쉬웠다ㅠㅠㅠ

두가지 step을 돌파하면 flag를 준다.

첫화면이다. nickname과 password가 나온다.

step 1에 대한 code snippet은 아래와 같다.

            // pw filtering
            if (preg_match("/[a-zA-Z]/", $input_pw)) {
              echo "alphabet in the pw :(";
            }
            else{
              $name = preg_replace("/nyang/i", "", $input_name);
              $pw = preg_replace("/\d*\@\d{2,3}(31)+[^0-8]\!/", "d4y0r50ng", $input_pw);

              if ($name === "dnyang0310" && $pw === "d4y0r50ng+1+13") {
                echo '<h4>Step 2 : Almost done...</h4><div class="door_box"><div class="door_black"></div><div class="door"><div class="door_cir"></div></div></div>'

필터링을 우회하고, 정규표현식을 만족하며 $name === "dnyang0310" && $pw === "d4y0r50ng+1+13" 요롷게 되도록 만들어야한다.

name은 nyang을 없애버리는 것을 오히려 이용하면 되고,

pw에 대해 해석해보면, 

\d* : 0개 이상의 숫자

\@ : 문자그대로 @

\d{2,3} : 2개에서 3개의 연속된 숫자

(31)+ : 문자그대로 31

[^0-8] : 숫자 0부터 8 사이가 아닌 어떤 문자

\! : 문자 그대로 !

 

더하여 pw filtering부분에서 알파벳을 쓰면 안된다고 나와있다. 모든 조건을 만족하는 것은 아래와 같다.

dnyanyangng0310
123@123319!+1+13

다음 step은 뭔가 입력받는 곳이 존재한다.

code에 의하면 shell command를 입력받는다.

cat flag를 바로 시도해보았다.

필터링이 존재한다.

 // cmd filtering
                else if (preg_match("/flag/i", $cmd)) {
                  echo "<pre>Error!</pre>";
                }

여기서도 정규표현식이 활용된다. cat fl* 이런식으로 쓰면,  fl 로 시작하는 파일을 불러온다.

그러나 결과가 안나온다.

생각해보니 현 디렉터리에 flag파일이 없을 수 있다는 생각이 들어서 확인해보았다.

역시나 없다.

한줄로만 command를 보낼 수 있기에 ; 를 활용하여 여기저기 디렉터리를 좀 뒤져보았다.

아래의 명령을 보낼 시 찾을 수 있다.

cd ../dream; ls

이제 아래의 command를 보내면 flag가 나온다.

cd ../dream; cat fl*

반응형

'wargame' 카테고리의 다른 글

Broken Buffalo Wings  (0) 2023.09.10
LoS - zombie assassin  (0) 2023.08.27
type confusion  (0) 2023.08.27
tmitter  (0) 2023.08.26
Robot-only  (0) 2023.07.21
반응형

php 의 느슨한 비교로 인해 발생하는 취약점이다.

== 비교에 대한 matrix는 아래와 같다.

이제 문제의 코드를 보겠다.

<?php
 if (isset($_GET['view-source'])) {
     show_source(__FILE__);
    exit();
 }
 if (isset($_POST['json'])) {
     usleep(500000);
     require("./lib.php"); // include for FLAG.
    $json = json_decode($_POST['json']);
    $key = gen_key();
    if ($json->key == $key) {
        $ret = ["code" => true, "flag" => $FLAG];
    } else {
        $ret = ["code" => false];
    }
    die(json_encode($ret));
 }

 function gen_key(){
     $key = uniqid("welcome to wargame.kr!_", true);
    $key = sha1($key);
     return $key;
 }
?>

==비교를 하고 있으며 웹페이지에서  제출되는 값을 비교하여 참 거짓을 판별한다.

이때, 제출되는 payload를 보면, json형식으로 {key:value} 요롷게 전송되는 것을 볼 수 있다.

여기서 1234를 true로 전송해주면 상기의 표에 의해 비교했을때 true이므로 풀린다.

반응형

'wargame' 카테고리의 다른 글

LoS - zombie assassin  (0) 2023.08.27
phpreg  (0) 2023.08.27
tmitter  (0) 2023.08.26
Robot-only  (0) 2023.07.21
file-csp-1  (0) 2023.07.02

+ Recent posts