[root@localhost tcpip]# cat ./semaphore.c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>

void *read(void *arg);
void *accu(void *arg);
int num;
sem_t sem_one;
sem_t sem_two;

int main(int argc, char *argv[]){
        pthread_t id_t1, id_t2;
        sem_init(&sem_one, 0, 0);
        sem_init(&sem_two, 0, 1);

        pthread_create(&id_t1, NULL, read, NULL);
        pthread_create(&id_t2, NULL, accu, NULL);

        pthread_join(id_t1, NULL);
        pthread_join(id_t2, NULL);

        sem_destroy(&sem_one);
        sem_destroy(&sem_two);
        return 0;
}

void *read(void *arg){
        int i;
        for(i=0; i<5; i++)
        {
                fputs("Input num : ",stdout);
                sem_wait(&sem_two);
                scanf("%d",&num);
                sem_post(&sem_one);
        }
        return NULL;
}

void *accu(void *arg){
        int result=0, i;
        for(i=0; i<5; i++)
        {
                sem_wait(&sem_one);
                result+=num;
                sem_post(&sem_two);
        }
        printf("Result : %d \n",result);
        return NULL;
}

[root@localhost tcpip]# cat ./mutex.c
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
#define NUM_THREAD 100

void *thread_inc(void *arg);
void *thread_des(void *arg);

long long num=0;
pthread_mutex_t mutex;

int main(int argc, char *argv[]){
        pthread_t thread_id[NUM_THREAD];
        int i;

        pthread_mutex_init(&mutex, NULL);
        for(i=0; i<NUM_THREAD; i++)
        {
                if(i%2){
                        pthread_create(&(thread_id[i]), NULL, thread_inc, NULL);
                }
                else{
                        pthread_create(&(thread_id[i]), NULL, thread_des, NULL);
                }
        }
        for(i=0; i<NUM_THREAD; i++)
        {
                pthread_join(thread_id[i], NULL);
        }
        printf("result : %lld \n", num);
        pthread_mutex_destroy(&mutex);
        return 0;
}

void *thread_inc(void *arg){
        int i;
        pthread_mutex_lock(&mutex);
        for(i=0; i<50000000; i++)
        {
                num+=1;
        }
        pthread_mutex_unlock(&mutex);
        return NULL;
}

void *thread_des(void *arg){
        int i;
        for(i=0; i<50000000; i++)
        {
                pthread_mutex_lock(&mutex);
                num-=1;
                pthread_mutex_unlock(&mutex);
        }
        return NULL;
}

[root@localhost tcpip]# cat ./epoll_serv.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/epoll.h>

#define BUF_SIZE 100
#define EPOLL_SIZE 50

int main(int argc, char *argv[]){
        int serv_sock, clnt_sock;
        struct sockaddr_in serv_addr, clnt_addr;
        socklen_t addr_size;
        int str_len, i;
        char buf[BUF_SIZE]={0,};

        struct epoll_event *ep_events;
        struct epoll_event event;
        int epfd, event_cnt;

        if(argc!=2){
                printf("Usage : %s <PORT> \n",argv[0]);
                exit(1);
        }

        serv_sock=socket(PF_INET, SOCK_STREAM, 0);
        memset(&serv_addr, 0, sizeof(serv_addr));
        serv_addr.sin_family=AF_INET;
        serv_addr.sin_addr.s_addr=htonl(INADDR_ANY);
        serv_addr.sin_port=htons(atoi(argv[1]));

        if(bind(serv_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr))==-1){
                perror("bind");
        }
        if(listen(serv_sock, 5)==-1){
                perror("listen");
        }

        epfd=epoll_create(EPOLL_SIZE);
        ep_events=malloc(sizeof(struct epoll_event)*EPOLL_SIZE);
        event.events=EPOLLIN;
        event.data.fd=serv_sock;

        epoll_ctl(epfd, EPOLL_CTL_ADD, serv_sock, &event);

        while(1)
        {
                event_cnt=epoll_wait(epfd, ep_events, EPOLL_SIZE, -1);
                if(event_cnt==-1){
                        puts("epoll_wait() error");
                        break;
                }
                for(i=0; i<event_cnt; i++)
                {
                        if(ep_events[i].data.fd==serv_sock){
                                addr_size=sizeof(clnt_addr);
                                clnt_sock=accept(serv_sock, (struct sockaddr*)&clnt_addr, &addr_size);
                                event.events=EPOLLIN;
                                event.data.fd=clnt_sock;
                                epoll_ctl(epfd, EPOLL_CTL_ADD, clnt_sock, &event);
                                printf("New Client Connected : %d \n", clnt_sock);
                        }
                        else{
                                str_len=read(ep_events[i].data.fd, buf, BUF_SIZE);
                                if(str_len==0){
                                        epoll_ctl(epfd, EPOLL_CTL_DEL, ep_events[i].data.fd, NULL);
                                        close(ep_events[i].data.fd);
                                        printf("Close Client : %d \n", ep_events[i].data.fd);
                                }
                                else{
                                        write(ep_events[i].data.fd, buf, str_len);
                                }
                        }
                }
        }
        close(serv_sock);
        close(epfd);
        return 0;
}

まず、ソースコードを見てみる

setresuid/setresgid : SET R(eal), E(ffective), S(aved) UID/GID
現在動作中のプロセスの権限を変更する

簡単に言うと、このshellshockプログラムを実行して、flagを読まないといけない。

googleでshellshockで検索たら色んな資料が出てきてどんな脆弱性かを勉強した!

その中で一番良かったところが

<http://operatingsystems.tistory.com/entry/Shellshock-CVE20146271>ここだった!

ということでpayloadを作成してやってみたら、flag読み成功!!

[root@localhost tcpip]# cat ./news_recv.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <unistd.h>
#define BUF_SIZE 30

int main(int argc, char *argv[]){
        int recv_sock;
        int str_len;
        struct sockaddr_in addr;
        char buf[BUF_SIZE];
        struct ip_mreq join_addr;

        if(argc!=3){
                printf("Usage : %s <GroupIP> <PORT> \n", argv[0]);
                exit(1);
        }

        recv_sock=socket(PF_INET, SOCK_DGRAM, 0);
        memset(&addr, 0, sizeof(addr));
        addr.sin_family=AF_INET;
        addr.sin_addr.s_addr=htonl(INADDR_ANY);
        addr.sin_port=htons(atoi(argv[2]));

        if(bind(recv_sock, (struct sockaddr*)&addr, sizeof(addr))==-1){
                perror("bind");
        }

        join_addr.imr_multiaddr.s_addr=inet_addr(argv[1]);       //マルチキャストグループ IP
        join_addr.imr_interface.s_addr=htonl(INADDR_ANY);  //グループに加入するホストIP

        setsockopt(recv_sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void*)&join_addr, sizeof(join_addr));

        while(1)
        {
                str_len=recvfrom(recv_sock, buf, BUF_SIZE-1, 0, NULL, 0);
                if(str_len<0)
                        break;
                buf[str_len]=0;
                fputs(buf, stdout);
        }
        close(recv_sock);
        return 0;
}