2017-09-20 1 views
2

일부 바이너리 문제로 원격 서버에 SSHd됩니다.비 ASCII 문자를 tty (ssh를 통해)에있는 프로그램의 stdin에 씁니다.

텍스트를 입력하라는 질문이 나옵니다. fgets()을 사용하여 stdin을 읽었으며, 내가 복사되어있는 곳에서 오버플로가 가능하고 근처의 변수를 덮어 쓸 수 있다는 것을 알고 있습니다.

문제는 내가 필요로하는 주소 값, \x84\x04 등 내가 echo -ne "\x84"을 것 떠들썩한 파티를 사용하거나 C 육각 배열을 사용 할 수있는 경우를 입력하는 방법을 몰라하지만 난 그 종류를 할 수 없다 여기에있는 것.

16 진수를 ASCII 변환기로 사용하고 이진 문자를 복사하고 이진 값을 보내기 위해 expect 스크립트를 사용했지만 두 가지 모두 동일한 문제가 발생했습니다. x84는 여분의 char을 추가하고 x04는 전혀 쓰지 않습니다.

유닉스 tty에서 ssh를 통해 ASCII 문자로 표현할 수없는 값을 메모리에 안정적으로 기록하는 가장 좋은 방법은 무엇입니까?

+1

귀하의 질문에 혼란이 있습니다. 터미널에 제어 문자를 입력하는 방법이나 C 프로그램이 읽은 것을 메모리에 쓰는 방법을 묻고 있습니까? – Barmar

+0

바이너리 데이터로 작업하고 있다면,'fgets()'와 친구들을 사용해서는 안됩니다. 그것은 텍스트 데이터를 읽기위한 것입니다. –

+0

죄송합니다, 지금 전화하고 있습니다. 아마 전. 내가 AAAA를 작성하면 x41x41x41x41 등이 메모리에 저장됩니다. 필자가 \ x84를 쓰면 x78x38x34 등으로 기록됩니다. fgets가 ascii로 모든 것을 해석하고 이스케이프 시퀀스를 허용하지 않는 것처럼 16 진수 값을 쓰는 데 문제가 있습니다. – GhostSparkles

답변

3

높은 문자의 경우 복사/붙여 넣기가 가능합니다.

echo -ne "\x84" | xclip -i 바탕 화면에 Linux가 실행중인 경우 터미널 에뮬레이터에서 마우스 가운데 버튼을 클릭하십시오. (이거나 아닐 수도 있습니다. 아래 참조). 또는 echo ... | ssh [email protected]이 작동 할 수 있습니다.

ssh -T 또는 다른 터미널 에뮬레이터의 해당 옵션도 "의사 터미널 할당 비활성화"옵션이 될 수 있으므로 원격 측의 프로그램은 stdin이 pseudo-terminal 할당이 아닌 sshd의 파이프가되도록합니다. 터미널이라고 생각합니다. 이것은 ^s^v과 같은 것들을 사용하지 못하게 할 것이라고 나는 생각한다.

반대로, echo foo | ssh -tt은 ssh에 내용을 넣고 있어도 리모트 쪽에서 tty를 요구하게됩니다.


SSH는 TTY 층을 통해 수신 프로그램의 stdin에 도달을 통해 확인 바이너리 데이터를 만들기 위해 덜 침입 방법은 제어 - v (16 진수의 0 * 16)와 함께 모든 바이트를 선행하는 것입니다.

Barmar는 문자 그대로 다음 문자 (lnext in stty -a 출력)를 가리 킵니다. 전에 사용하면 페이로드의 모든 바이트를 사용할 수 있습니다. 그것은 평범한 캐릭터보다 훨씬 앞선 수신자의 TTY 레이어에 의해 제거됩니다.

# LANG=C sed to replace every byte with ^V byte 
# using bash $'' to put a literal control-V on sed's command line 
echo "hello" | LANG=C sed $'s/./\x16&/g' | hd 
     16 68 16 65 16 6c 16 6c 16 6f 0a     |.h.e.l.l.o.| 

당신은 hexdump -C (일명 hd)에 입력하여 로컬로이 모든 것을 테스트 할 수 있습니다. 터미널에서 실행하고 몇 가지 물건을 입력하거나 붙여 넣은 다음 종료 할 때까지 control-D를 누릅니다.

$ echo -ne "\x01\xff\x99" | LANG=C sed $'s/./\x16&/g' | hd 
00000000 16 01 16 ff 16 99         |......| 
00000006 
     # yup, correct bytes from sed 
$ echo -ne "\x01\xff\x99" | LANG=C sed $'s/./\x16&/g' | xclip -i 
$ LANG=C hd 
^A��  (middle click, return, control-d) 
00000000 01 ef bf bd ef bf bd 0a       |........| 
    # nope, that munged my data :/ 

$ xclip -o | hd 
00000000 16 01 16 ff 16 99         |......| 

는 그래서 X 선택 자체는 정확하지만, 내가 붙여 넣기로 Konsole을가하거나 munged, 또는 hexdump에 Konsole을에서 길에 TTY 층에 의해 점점? 후자가있을 것 같지 않습니다; 아마 그것은 붙여 넣기 문제입니다. Konsole의 "인코딩"설정은 UTF-8입니다. 일반 ASCII 설정이없는 것 같습니다.

LANG=C xterm 또는 그 밖의 문자로 시도하거나 문자 expect을 올바르게 입력하면 실제로 이진 데이터를 이스케이프 코드가 아닌 ssh으로 보낼 수 있습니다. 더 이상 strcpy는 것 이스케이프 시퀀스를 처리하지 않습니다 물론


fgets. 일반적으로 C 함수는 그렇지 않습니다. 그러나 C에서 컴파일러은 컴파일시에문자열 리터럴 내에서 이스케이프 시퀀스를 처리합니다.

+1

'모든 바이트 앞에 control-v (16 진수 0x16)'를 쓰면 완벽하게 작동합니다. 16 진수를 보내려면 pexpect 스크립트를 사용했습니다. Barmar의 답변에 좋은 확장. 둘 다 upvoted. '수신자의 TTY 레이어가 일반 문자보다 훨씬 더 흥미 롭습니다. – GhostSparkles

3

키보드에서 제어 문자를 입력하여 0x00에서 0x1f 범위의 문자를 쓸 수 있습니다. 컨트롤 키를 누른 상태에서 ASCII Chart의 세 번째 열에 문자를 입력하면 첫 번째 열에 해당 코드가 표시됩니다.

일부 제어 문자는 터미널 드라이버 (프로세스를 종료하기 위해, 예를 들어 는 Ctl-C)에 특별한 의미를 가지고, 당신은 FET의-V로 이전하여 문자를 입력 할 수 있습니다.

그리고 당신은 는 Ctl-V는 삭제를 입력하여 0x7f를 얻을 수 있습니다 (이 백 스페이스을 labeld를 할 수있는 이전 버전 삭제 문자, 즉 별도의 키패드에있을 수 있습니다 삭제하지 전방).

위의 문자를 입력하는 쉬운 방법이 있는지 확실하지 않습니다. 터미널 에뮬레이터의 설정에 따라 해당 ASCII 문자를 입력하는 동안 Alt 키를 누른 상태에서 높은 비트 세트를 가져올 수 있습니다. 예 : Alt-A0xc1 (0x80 | 0x41)을 전송합니다.

+0

터미널에서 UTF-8 가정을 극복 할 수 있으면 상위 비트 세트로 데이터를 복사/붙여 넣기 할 수도 있습니다. –

관련 문제