이번에 해킹과 보안에 대해 공부할 계기가 필요해서 스터디를 하게 되었다.

스터디에서 웹해킹부터 시작하기로 했는데 첫번째 목표가 Suninatas Webhacking 문제 풀이이다.

문제에 대한 풀이를 하며 내가 깨달은 부분에 대해서만 간략하게 적고자 한다.


< 알아야 할 것 >

위 코드는 ASP 라고 하는 동적으로 서버에서 작동하는 페이지라고 한다. 

시작과 끝이 <%, %> 인 것을 통해 간단하게 알아볼 수 있다.

Mid(str,n1,n2)는 문자열을 자르는 함수로, 문자열 str 을 n1 번째 부터 n2 개를 자르는 함수이다.

ASP 에서 &은 문자열을 합치는 연산자이다.


< 풀이 >

문자열을 입력받아 a를 aad로 치환하여 result라는 변수에 저장하고,

저장된 내용의 i를 in으로 치환하여 다시 한 번 result 에 저장한다.

그 뒤 result 를 2번째부터 2개, 4번째부터 6개를 잘라 각각 result1, result2에다 저장하고 

& 연산자를 통해 합쳐 다시 result에 저장한다.


그 뒤 Respose.write result 는 result 를 출력하는 코드라 별 신경은 쓰지 않아도 될 것같고

if 문의 result = "admin"일 때 pw = "????????" 라는 것의 pw가 잘 이해는 안 됬는데

결론적으로 result = "admin"이면 될 것 같았다.


그래서 결과로 나와야 할 admin 부터 반대로 해봤는데 admin의 ad는 result1에서 나와야 하고,

admin의 min은 result2에서 나와야 한다. 따라서 result1은 *ad****, result2는 ***min 이여야 한다.

이때 a -> aad , i -> in 이므로 ami를 입력하면 aadmin으로 admin 이 나오게 된다.


< 알아가야 할 것 >

웹페이지를 만들기 위해 ASP를 알아가보자.

'Hacking > Web Hacking' 카테고리의 다른 글

Suninatas 6번 문제  (0) 2018.09.07
Suninatas 5번 문제  (0) 2018.09.05
Suninatas 4번 문제  (0) 2018.09.05
Suninatas 3번 문제  (0) 2018.09.05
Suninatas 2번 문제  (0) 2018.09.05

1. char *p = "ABCDEFG"의 형태일 때 각각의 차이점은 무엇인가?

① *( p+3 )

② ( *p ) +3

③ *p + 3

④ p + 3


< 1번 소스코드 >



< 실행 결과 >









< 설명 >


*p 는 "ABCDEFG" 의 주소값이다.

내가 위의 보기에서 1, 2, 3은 "ABCDEFG"의 주소값을 보니 5fbff808가 나왔는데,

여기에서 3을 더하면 5fbff80b가 되어 "D"가 출력되게 된다.

반면, 4번은 그냥 p에 3을 더했기 때문에 이상한 값이 나온다.



2. char *p = {"ABCDE","KBS","XYZ"}; 일 때 다음 명령어들의 차이점은 무엇인가?

① p++

② *p++

③ (*p)++



< 소스 코드 >


1번 소스코드 : 


2번 소스코드 :





3번 소스코드 : 



-> 1, 2 출력 결과      

 -> 3 출력 결과



< 설명 >



2번 문제를 설명하기 위하여 한가지 코드를 짜보았다.

위의 문제의 1, 2, 3번의 차이는 *연산자와 ++연산자의 우선순위 차이이다.

32비트 운영 체제의 경우에 주소가 0x4씩 커진다.


*p++ = p가 가진 주소가 0x10인 경우, 0x14로 바뀐다.

(*p)++ = p가 가진 주소가 0x10인 경우, 0x10에 1이라는 값을 가지는 경우, 주소 0x10의 값이 2로 바뀐다.

*(p++) = *p++


이런 차이가 있다.




3. 다음 프로그램의 출력 결과를 예측해보아라.



나는 *c 라는 것은 주소값을 가리켜야 하는데 가르켜야 할 주소값이 없으니 입력을 받고 출력을 하지 못할 것 같다고 생각했다.


< 결과 >



내 생각이 맞았다. 난 Xcode를 사용해서 다른데에서는 어떻게 반응할지는 모르겠지만, 에러가 났다.

.

.

코드를 수정하여 이 코드가 돌아갈 수 있도록 해 보았다.




*c 라는 포인트 배열이 input 이라는 배열을 가리키게 하여 코드가 실행될 수 있도록 하였다.

▼▼▼ 출력 결과 실행이 잘 된다  ▼▼▼





4. char * p[] = {"ABC","XY","BJW","JMLEE"}; 일 때 다음 각각의 포인터의 연산 결과를 구하여라.

① *p

② *p([2] + 1)

③ *(*(p + 3) + 2)



1번만 실행할 경우 A가 출력 되지만, 2~3번은 에러가 나며 출력되지 않는다.

내가 예상한 결과는 2번의 경우 p[2]는 "BJW" 이고 +1이니 J를 예상하였고,

3번의 경우 *(p+3)은 p[3]이고 여기에 +2이니 L을 예상하였는데 에러가 나서 당황하였다.




내가 포인터를 잘못 이해하고 있는건지 모르겠다.

▶ 제가 만약 잘못하고 있는게 있으면 댓글로 달아주면 감사하겠습니다.



5. 입력받은 문자열 거꾸로 출력하는 프로그램을 만들어라.




< 코드 설명 >


위의 코드는  p 포인터 배열을 만든 뒤, Input을 받고, p[i]을 NULL 전까지 주소값를 증가시켰다.

마지막으로 for문으로 NULL 전부터 0까지 출력하게 하여 거꾸로 출력하는 프로그램을 만들어 보았다.



< 출력 결과 >






6. a가 배열이고, b가 문자열의 포인터일 때 배열 a에 b 문자열을 복사하는 함수를 만들어라.





< 코드 설명 >


이 코드는 a 배열과 b 포인터 배열을 선언하여 a를 입력받고 strcpy를 사용하여 b에 a를 저장하여 Output으로 b를 출력하였다.

결과는 아래와 같이 제대로 되었다.





7. char c[]="ABCDE" 일 때, c++과 같은 명령을 사용할 수 없는 이유를 구하여라.


c[]는 일반 배열이기 때문에 문자여서 c++를 하면 오류가 나게된다.

하지만 char *c[]를 하여 포인트 배열로 만들면 주소값의 형태를 띄게 되어 c++를 하면 주소값+1이 되어,

A의 주소값 +1 = B가 되어 BCDE가 출력되게 된다.

'Programming > C' 카테고리의 다른 글

함수 포인터  (0) 2015.08.27
[ Project ] Wild!  (0) 2015.08.27
[ Project ] Stack_Linked List  (0) 2015.08.27
연결 리스트 ( Linked List )  (0) 2015.08.27
구조체 ( Struct )  (0) 2015.08.27

전에 글에서 16비트 체제에선 ax,bx,cx,dx,si,di,bp,sp로 썼다는 것을 봤을 것이다.

32비트 체제로 넘어가서는 앞에 e(extend)를 넣어주어 eax,ebx,ecx,edx,esi,edi,ebp,esp로 사용한다.

그리고 64비트 체제에서는 앞에 r을 붙여 rax,rbx,rcx,rdx,rsi,rdi,rbp,rsp로 사용한다.


Ι................Ι................Ι................Ι................Ι................Ι................Ι................Ι................Ι

(<- 8비트 ->)  -> EX ) AL,BL,CL,DL,SIL,DIL,BPL,SPL

(<------16 비트 ------>) -> EX ) AX, BX, CX, DX, SI, DI, BP, SP

(<---------------- 32비트 ---------------->) -> EX ) EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP

(<------------------------------------- 64비트 -------------------------------------->)

L> RAX, RBX, RCX, RDX, RSI, RDI, RBP,RSP


64 비트 체제 전에는 그냥 파라미터를 전달했지만, 64비트 체제에서는 레지스터리를 통해서 파라미터를 전달한다.



64비트 체제에서는 리눅스와 윈도우의 파라미터 전달 방식이 나뉘어 집니다.


리눅스에서는 파라미터를 전달할 때 6개 레지스터를 사용한다.

 

RDI : 첫번째 인자

RSI : 두번째 인자

RDX : 세번째 인자

RCX : 네번째 인자

R8 : 다섯번째 인자 -> 추가된 범용 레지스터

R9 : 여섯번째 인자 -> 추가된 범용 레지스터


인자가 7개 이상일 경우부터는 스택을 같이 사용한다.



윈도우는 리눅스와 달리 레지스터를 4개까지 사용한다.


RCX : 첫번째 인자

RDX : 두번째 인자

R8 : 세번째 인자 -> 추가된 범용 레지스터

R9 : 네번째 인자 -> 추가된 범용 레지스터


리눅스와 마찬가지로 5개 이상일 경우 스택과 같이 사용한다.