Hello World升级版

0x00:

偶然在知乎上看到一个问题,特殊的方式输出hello world,后来知道这是cnss的招新题目,感觉还挺有意思的,做了下记录下来。

题目要求

1
2
3
4
1.不用 “ ”  输出Hello World
2.不用 ; 输出Hello World
3.不用# 输出Hello World
4.不用括号输出Hello World (包括各种括号(),<>,{},[]都不能用 )

0x01: level 1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ cat test.c
#include <stdio.h>


int main(void){
putchar(72);
putchar(101);
putchar(108);
putchar(108);
putchar(111);
putchar(32);
putchar(119);
putchar(111);
putchar(114);
putchar(108);
putchar(100);
putchar(10);

return 0;
}
1
2
3
# muhe @ muheMacBookPro in /tmp [18:10:11]
$ ./test
Hello world

0x02: level 2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ cat test.c

int main(void){
if(putchar(72)) {}
if(putchar(101)) {}
if(putchar(108)) {}
if(putchar(108)) {}
if(putchar(111)) {}
if(putchar(32)) {}
if(putchar(119)) {}
if(putchar(114)) {}
if(putchar(108)) {}
if(putchar(100)) {}
if(putchar(10)) {}
}

1
2
3
4
5
6
7
8
9
10
11
# muhe @ muheMacBookPro in /tmp [18:15:10]
$ clang test.c -o test
test.c:3:8: warning: implicit declaration of function 'putchar' is invalid in C99
[-Wimplicit-function-declaration]
if(putchar(72)) {}
^
1 warning generated.

# muhe @ muheMacBookPro in /tmp [18:15:15]
$ ./test
Hello wrld

0x03: level 3

主要是#符号的替代。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ cat test.c
%:include <stdio.h>

int main(void){
if(putchar(72)) {}
if(putchar(101)) {}
if(putchar(108)) {}
if(putchar(108)) {}
if(putchar(111)) {}
if(putchar(32)) {}
if(putchar(119)) {}
if(putchar(114)) {}
if(putchar(108)) {}
if(putchar(100)) {}
if(putchar(10)) {}
}
1
2
3
4
5
6
# muhe @ muheMacBookPro in /tmp [18:18:03]
$ clang test.c -o test

# muhe @ muheMacBookPro in /tmp [18:18:05]
$ ./test
Hello wrld

0x04: level 4

这个好难想…shellcode行么我想说…
msfvenom直接生成一个…
那么问题来了,sc也要执行啊,咋规避括号,难道要手写一个PE/ELF文件么。

0x05: 结语

挺有意思的问题,这个东西仁者见仁,智者见智,知乎上见到太多方式了,毕竟putchar很丑陋,轮子哥那个代码还是挺好看的。至于level 4,有人提到了hack c,很可惜UB…