一個是HTTP信息、堆棧信息,另外則是把所有信息聚集起來然后發送給服務器,用WEB界面進行展示
堆棧信息
這部分比較好做,因為php本身就有debug_print_backtrace
函數可以實現,稍微改一改即可。
把這三部分去掉即可,這樣便可以獲取到底層函數的調用棧。
當然還有一個就是獲取每個被調用函數的參數。
void debug_backtrace_args(zval *arg_array,char *tmp_result)
{
zval **tmp;
HashPosition iterator;
int i = 0;
zend_hash_internal_pointer_reset_ex(arg_array->value.ht, &iterator);
while (zend_hash_get_current_data_ex(arg_array->value.ht, (void **) &tmp, &iterator) == SUCCESS) {
if (i++) {
strcat(tmp_result,", ");
}
strcat(tmp_result,Z_STRVAL_PP(tmp));
zend_hash_move_forward_ex(arg_array->value.ht, &iterator);
}
}
HTTP信息
這部分也可以從php源碼里面找到一些,比如請求的url之類的
static void sapi_thttpd_register_variables(zval *track_vars_array TSRMLS_DC)
{
php_register_variable("PHP_SELF", SG(request_info).request_uri, track_vars_array TSRMLS_CC);
php_register_variable("SERVER_SOFTWARE", SERVER_SOFTWARE, track_vars_array TSRMLS_CC);
php_register_variable("GATEWAY_INTERFACE", "CGI/1.1", track_vars_array TSRMLS_CC);
php_register_variable("REQUEST_METHOD", (char *) SG(request_info).request_method, track_vars_array TSRMLS_CC);
php_register_variable("REQUEST_URI", SG(request_info).request_uri, track_vars_array TSRMLS_CC);
php_register_variable("PATH_TRANSLATED", SG(request_info).path_translated, track_vars_array TSRMLS_CC);
}
我這里獲取簡單一點
static void get_http_info(char *info){
sprintf(info,"%s %s\r\n\
Cookie: %s \r\n\
Data: %s",SG(request_info).request_method,SG(request_info).request_uri,SG(request_info).cookie_data,SG(request_info).post_data);
發送信息
為了方便點就利用http來發送,在github
找一份已經封裝好的庫
int post(int sd, struct http_url *url, char *data) {
char buf[1024] = {0};
int data_len = strlen(data) - 1;
snprintf(
buf,
sizeof(buf),
"\
POST /%s HTTP/1.1\r\n\
User-Agent: Mozilla/4.0 (Linux)\r\n\
Host: %s\r\n\
Accept: */*\r\n\
Content-Length: %d\r\n\
Connection: close\r\n\
\r\n\
%s\r\n\
\r\n",
url->query,
url->host,
data_len,
data);
if (http_send(sd, buf)) {
perror("http_send");
return -1;
}
return 0;
}
static void http_get_request(char *data){
struct http_url *url;
struct http_message msg;
int sd;
if (!(url = http_parse_url("http://10.211.55.4/lemon_api.php")) ||
!(sd = http_connect(url))) {
free(url);
perror("http_connect");
return -1;
}
memset(&msg, 0, sizeof(msg));
if (!post(sd, url, data)) {
while (http_response(sd, &msg) > 0) {
if (msg.content) {
write(1, msg.content, msg.length);
}
}
}
free(url);
close(sd);
if (msg.header.code != 200) {
fprintf(
stderr,
"error: returned HTTP code %d\n",
msg.header.code);
}
}
github給了一個post數據的樣例,不過它那出現一點小問題,就是在post
函數里面,buf
未初始化。
信息展示
測試代碼
<?php
function aa(){
$a = @$_GET['i'];
$b = "sys"."tem";
$command = "echo ".$a." iaml3m0n ";
$b($command);
}
aa();
{'http':'R0VUIC8yLnBocD9pPWBpZGAmaTE9bGVtb24NCiAgQ29va2llOiAgKG51bGwpIA0KICBEYXRhOiAgKG51bGwp','stack':'IzAgc3lzdGVtKGVjaG8gYGlkYCBpYW1sM20wbiApIGNhbGxlZCBhdCBbL3Zhci93d3cvaHRtbC9iaXNoZS8xLnBocDo3XQojMSBhYSgpIGNhbGxlZCBhdCBbL3Zhci93d3cvaHRtbC9iaXNoZS8xLnBocDoxMF0KIzIgaW5jbHVkZSgvdmFyL3d3dy9odG1sL2Jpc2hlLzEucGhwKSBjYWxsZWQgYXQgWy92YXIvd3d3L2h0bWwvYmlzaGUvMi5waHA6Ml0K'}
解碼出來:
#0 system(echo `id` iaml3m0n ) called at [/var/www/html/bishe/1.php:7]
#1 aa() called at [/var/www/html/bishe/1.php:10]
#2 include(/var/www/html/bishe/1.php) called at [/var/www/html/bishe/2.php:2]
GET /2.php?i=`id`&i1=lemon
Cookie: (null)
Data: (null)